2 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
3 * Copyright (c) 2017-2018 The strace developers.
6 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "test_nlattr.h"
16 #include <linux/if_arp.h>
17 #ifdef HAVE_LINUX_IF_LINK_H
18 # include <linux/if_link.h>
20 #include <linux/rtnetlink.h>
23 # define IFLA_LINKINFO 18
26 # define IFLA_VF_PORTS 24
28 #define IFLA_LINK_NETNSID 37
31 #ifndef IFLA_INFO_KIND
32 # define IFLA_INFO_KIND 1
36 # define IFLA_VF_PORT 1
40 init_ifinfomsg(struct nlmsghdr *const nlh, const unsigned int msg_len)
42 SET_STRUCT(struct nlmsghdr, nlh,
44 .nlmsg_type = RTM_GETLINK,
45 .nlmsg_flags = NLM_F_DUMP
48 struct ifinfomsg *const msg = NLMSG_DATA(nlh);
49 SET_STRUCT(struct ifinfomsg, msg,
50 .ifi_family = AF_UNIX,
51 .ifi_type = ARPHRD_LOOPBACK,
52 .ifi_index = ifindex_lo(),
58 print_ifinfomsg(const unsigned int msg_len)
60 printf("{len=%u, type=RTM_GETLINK, flags=NLM_F_DUMP"
61 ", seq=0, pid=0}, {ifi_family=AF_UNIX"
62 ", ifi_type=ARPHRD_LOOPBACK"
63 ", ifi_index=" IFINDEX_LO_STR
64 ", ifi_flags=IFF_UP, ifi_change=0}",
71 skip_if_unavailable("/proc/self/fd/");
73 static const struct rtnl_link_stats st = {
74 .rx_packets = 0xabcdefac,
75 .tx_packets = 0xbcdacdab,
76 .rx_bytes = 0xcdbafaab,
77 .tx_bytes = 0xdafabadb,
78 .rx_errors = 0xeabcdaeb,
79 .tx_errors = 0xfefabeab,
80 .rx_dropped = 0xadbafafb,
81 .tx_dropped = 0xbdffabda,
82 .multicast = 0xcdabdfea,
83 .collisions = 0xefadbaeb,
84 .rx_length_errors = 0xfabffabd,
85 .rx_over_errors = 0xafbafabc,
86 .rx_crc_errors = 0xbfdabdad,
87 .rx_frame_errors = 0xcfdabfad,
88 .rx_fifo_errors = 0xddfdebad,
89 .rx_missed_errors = 0xefabdcba,
90 .tx_aborted_errors = 0xefdadbfa,
91 .tx_carrier_errors = 0xfaefbada,
92 .tx_fifo_errors = 0xaebdffab,
93 .tx_heartbeat_errors = 0xbadebaaf,
94 .tx_window_errors = 0xcdafbada,
95 .rx_compressed = 0xdeffadbd,
96 .tx_compressed = 0xefdadfab
98 const int fd = create_nl_socket(NETLINK_ROUTE);
99 const unsigned int hdrlen = sizeof(struct ifinfomsg);
100 void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
101 NLA_HDRLEN + sizeof(st));
103 static char pattern[4096];
104 fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
106 const unsigned int nla_type = 0xffff & NLA_TYPE_MASK;
107 char nla_type_str[256];
108 sprintf(nla_type_str, "%#x /* IFLA_??? */", nla_type);
109 TEST_NLATTR_(fd, nlh0, hdrlen,
110 init_ifinfomsg, print_ifinfomsg,
111 nla_type, nla_type_str,
113 print_quoted_hex(pattern, 4));
115 const int32_t netnsid = 0xacbdabda;
116 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
117 init_ifinfomsg, print_ifinfomsg,
118 IFLA_LINK_NETNSID, pattern, netnsid,
119 printf("%d", netnsid));
121 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
122 init_ifinfomsg, print_ifinfomsg,
123 IFLA_STATS, pattern, st,
124 PRINT_FIELD_U("{", st, rx_packets);
125 PRINT_FIELD_U(", ", st, tx_packets);
126 PRINT_FIELD_U(", ", st, rx_bytes);
127 PRINT_FIELD_U(", ", st, tx_bytes);
128 PRINT_FIELD_U(", ", st, rx_errors);
129 PRINT_FIELD_U(", ", st, tx_errors);
130 PRINT_FIELD_U(", ", st, rx_dropped);
131 PRINT_FIELD_U(", ", st, tx_dropped);
132 PRINT_FIELD_U(", ", st, multicast);
133 PRINT_FIELD_U(", ", st, collisions);
134 PRINT_FIELD_U(", ", st, rx_length_errors);
135 PRINT_FIELD_U(", ", st, rx_over_errors);
136 PRINT_FIELD_U(", ", st, rx_crc_errors);
137 PRINT_FIELD_U(", ", st, rx_frame_errors);
138 PRINT_FIELD_U(", ", st, rx_fifo_errors);
139 PRINT_FIELD_U(", ", st, rx_missed_errors);
140 PRINT_FIELD_U(", ", st, tx_aborted_errors);
141 PRINT_FIELD_U(", ", st, tx_carrier_errors);
142 PRINT_FIELD_U(", ", st, tx_fifo_errors);
143 PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
144 PRINT_FIELD_U(", ", st, tx_window_errors);
145 PRINT_FIELD_U(", ", st, rx_compressed);
146 PRINT_FIELD_U(", ", st, tx_compressed);
147 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
148 PRINT_FIELD_U(", ", st, rx_nohandler);
152 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
153 const unsigned int sizeof_stats =
154 offsetofend(struct rtnl_link_stats, tx_compressed);
155 TEST_NLATTR(fd, nlh0, hdrlen,
156 init_ifinfomsg, print_ifinfomsg,
157 IFLA_STATS, sizeof_stats, &st, sizeof_stats,
158 PRINT_FIELD_U("{", st, rx_packets);
159 PRINT_FIELD_U(", ", st, tx_packets);
160 PRINT_FIELD_U(", ", st, rx_bytes);
161 PRINT_FIELD_U(", ", st, tx_bytes);
162 PRINT_FIELD_U(", ", st, rx_errors);
163 PRINT_FIELD_U(", ", st, tx_errors);
164 PRINT_FIELD_U(", ", st, rx_dropped);
165 PRINT_FIELD_U(", ", st, tx_dropped);
166 PRINT_FIELD_U(", ", st, multicast);
167 PRINT_FIELD_U(", ", st, collisions);
168 PRINT_FIELD_U(", ", st, rx_length_errors);
169 PRINT_FIELD_U(", ", st, rx_over_errors);
170 PRINT_FIELD_U(", ", st, rx_crc_errors);
171 PRINT_FIELD_U(", ", st, rx_frame_errors);
172 PRINT_FIELD_U(", ", st, rx_fifo_errors);
173 PRINT_FIELD_U(", ", st, rx_missed_errors);
174 PRINT_FIELD_U(", ", st, tx_aborted_errors);
175 PRINT_FIELD_U(", ", st, tx_carrier_errors);
176 PRINT_FIELD_U(", ", st, tx_fifo_errors);
177 PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
178 PRINT_FIELD_U(", ", st, tx_window_errors);
179 PRINT_FIELD_U(", ", st, rx_compressed);
180 PRINT_FIELD_U(", ", st, tx_compressed);
182 #endif /* HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER */
184 static const struct rtnl_link_ifmap map = {
185 .mem_start = 0xadcbefedefbcdedb,
186 .mem_end = 0xefcbeabdecdcdefa,
187 .base_addr = 0xaddbeabdfaacdbae,
192 const unsigned int sizeof_ifmap =
193 offsetofend(struct rtnl_link_ifmap, port);
194 const unsigned int plen = sizeof_ifmap - 1 > DEFAULT_STRLEN
196 : (int) sizeof_ifmap - 1;
197 /* len < sizeof_ifmap */
198 TEST_NLATTR(fd, nlh0, hdrlen,
199 init_ifinfomsg, print_ifinfomsg,
200 IFLA_MAP, plen, pattern, plen,
201 print_quoted_hex(pattern, plen));
203 /* short read of sizeof_ifmap */
204 TEST_NLATTR(fd, nlh0, hdrlen,
205 init_ifinfomsg, print_ifinfomsg,
206 IFLA_MAP, sizeof_ifmap, &map, sizeof_ifmap - 1,
207 printf("%p", RTA_DATA(TEST_NLATTR_nla)));
210 TEST_NLATTR(fd, nlh0, hdrlen,
211 init_ifinfomsg, print_ifinfomsg,
212 IFLA_MAP, sizeof_ifmap, &map, sizeof_ifmap,
213 PRINT_FIELD_X("{", map, mem_start);
214 PRINT_FIELD_X(", ", map, mem_end);
215 PRINT_FIELD_X(", ", map, base_addr);
216 PRINT_FIELD_U(", ", map, irq);
217 PRINT_FIELD_U(", ", map, dma);
218 PRINT_FIELD_U(", ", map, port);
221 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64
222 static const struct rtnl_link_stats64 st64 = {
223 .rx_packets = 0xadcbefedefbcdedb,
224 .tx_packets = 0xbdabdedabdcdeabd,
225 .rx_bytes = 0xcdbaefbaeadfabec,
226 .tx_bytes = 0xdbaedbafabbeacdb,
227 .rx_errors = 0xefabfdaefabaefab,
228 .tx_errors = 0xfaebfabfabbaeabf,
229 .rx_dropped = 0xacdbaedbadbabeba,
230 .tx_dropped = 0xbcdeffebdabeadbe,
231 .multicast = 0xeeffbaeabaeffabe,
232 .collisions = 0xffbaefcefbafacef,
233 .rx_length_errors = 0xaabbdeabceffdecb,
234 .rx_over_errors = 0xbbdcdadebadeaeed,
235 .rx_crc_errors= 0xccdeabecefaedbef,
236 .rx_frame_errors = 0xddbedaedebcedaef,
237 .rx_fifo_errors = 0xeffbadefafdaeaab,
238 .rx_missed_errors = 0xfefaebccceadeecd,
239 .tx_aborted_errors = 0xabcdadefcdadef,
240 .tx_carrier_errors = 0xbccdafaeeaaefe,
241 .tx_fifo_errors = 0xcddefdbedeadce,
242 .tx_heartbeat_errors = 0xedaededdadcdea,
243 .tx_window_errors = 0xfdacdeaccedcda,
244 .rx_compressed = 0xacdbbcacdbccef,
245 .tx_compressed = 0xbcdadefcdedfea
247 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
248 init_ifinfomsg, print_ifinfomsg,
249 IFLA_STATS64, pattern, st64,
250 PRINT_FIELD_U("{", st64, rx_packets);
251 PRINT_FIELD_U(", ", st64, tx_packets);
252 PRINT_FIELD_U(", ", st64, rx_bytes);
253 PRINT_FIELD_U(", ", st64, tx_bytes);
254 PRINT_FIELD_U(", ", st64, rx_errors);
255 PRINT_FIELD_U(", ", st64, tx_errors);
256 PRINT_FIELD_U(", ", st64, rx_dropped);
257 PRINT_FIELD_U(", ", st64, tx_dropped);
258 PRINT_FIELD_U(", ", st64, multicast);
259 PRINT_FIELD_U(", ", st64, collisions);
260 PRINT_FIELD_U(", ", st64, rx_length_errors);
261 PRINT_FIELD_U(", ", st64, rx_over_errors);
262 PRINT_FIELD_U(", ", st64, rx_crc_errors);
263 PRINT_FIELD_U(", ", st64, rx_frame_errors);
264 PRINT_FIELD_U(", ", st64, rx_fifo_errors);
265 PRINT_FIELD_U(", ", st64, rx_missed_errors);
266 PRINT_FIELD_U(", ", st64, tx_aborted_errors);
267 PRINT_FIELD_U(", ", st64, tx_carrier_errors);
268 PRINT_FIELD_U(", ", st64, tx_fifo_errors);
269 PRINT_FIELD_U(", ", st64, tx_heartbeat_errors);
270 PRINT_FIELD_U(", ", st64, tx_window_errors);
271 PRINT_FIELD_U(", ", st64, rx_compressed);
272 PRINT_FIELD_U(", ", st64, tx_compressed);
273 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
274 PRINT_FIELD_U(", ", st64, rx_nohandler);
278 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
279 const unsigned int sizeof_stats64 =
280 offsetofend(struct rtnl_link_stats64, tx_compressed);
281 TEST_NLATTR(fd, nlh0, hdrlen,
282 init_ifinfomsg, print_ifinfomsg,
283 IFLA_STATS64, sizeof_stats64, &st64, sizeof_stats64,
284 PRINT_FIELD_U("{", st64, rx_packets);
285 PRINT_FIELD_U(", ", st64, tx_packets);
286 PRINT_FIELD_U(", ", st64, rx_bytes);
287 PRINT_FIELD_U(", ", st64, tx_bytes);
288 PRINT_FIELD_U(", ", st64, rx_errors);
289 PRINT_FIELD_U(", ", st64, tx_errors);
290 PRINT_FIELD_U(", ", st64, rx_dropped);
291 PRINT_FIELD_U(", ", st64, tx_dropped);
292 PRINT_FIELD_U(", ", st64, multicast);
293 PRINT_FIELD_U(", ", st64, collisions);
294 PRINT_FIELD_U(", ", st64, rx_length_errors);
295 PRINT_FIELD_U(", ", st64, rx_over_errors);
296 PRINT_FIELD_U(", ", st64, rx_crc_errors);
297 PRINT_FIELD_U(", ", st64, rx_frame_errors);
298 PRINT_FIELD_U(", ", st64, rx_fifo_errors);
299 PRINT_FIELD_U(", ", st64, rx_missed_errors);
300 PRINT_FIELD_U(", ", st64, tx_aborted_errors);
301 PRINT_FIELD_U(", ", st64, tx_carrier_errors);
302 PRINT_FIELD_U(", ", st64, tx_fifo_errors);
303 PRINT_FIELD_U(", ", st64, tx_heartbeat_errors);
304 PRINT_FIELD_U(", ", st64, tx_window_errors);
305 PRINT_FIELD_U(", ", st64, rx_compressed);
306 PRINT_FIELD_U(", ", st64, tx_compressed);
308 #endif /* HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER */
309 #endif /* HAVE_STRUCT_RTNL_LINK_STATS64 */
311 struct nlattr nla = {
312 .nla_len = sizeof(nla),
313 .nla_type = IFLA_INFO_KIND,
315 TEST_NLATTR(fd, nlh0, hdrlen,
316 init_ifinfomsg, print_ifinfomsg,
317 IFLA_LINKINFO, sizeof(nla), &nla, sizeof(nla),
318 printf("{nla_len=%u, nla_type=IFLA_INFO_KIND}",
321 nla.nla_type = IFLA_VF_PORT;
322 TEST_NLATTR(fd, nlh0, hdrlen,
323 init_ifinfomsg, print_ifinfomsg,
324 IFLA_VF_PORTS, sizeof(nla), &nla, sizeof(nla),
325 printf("{nla_len=%u, nla_type=IFLA_VF_PORT}",
328 static const struct {
332 { 0, "IFLA_EVENT_NONE" },
333 { 6, "IFLA_EVENT_BONDING_OPTIONS" },
334 { ARG_STR(0x7) " /* IFLA_EVENT_??? */" },
335 { ARG_STR(0xdeadfeed) " /* IFLA_EVENT_??? */" },
337 for (size_t i = 0; i < ARRAY_SIZE(ifla_events); i++) {
338 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
339 init_ifinfomsg, print_ifinfomsg,
340 IFLA_EVENT, pattern, ifla_events[i].val,
341 printf("%s", ifla_events[i].str));
344 puts("+++ exited with 0 +++");