2 * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4 * Copyright (c) 2016-2018 The strace developers.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "netlink_route.h"
33 #include "print_fields.h"
37 #include <netinet/in.h>
39 #ifdef HAVE_LINUX_IF_LINK_H
40 # include <linux/if_link.h>
42 #include <linux/rtnetlink.h>
44 #include "xlat/in6_addr_gen_mode.h"
45 #include "xlat/inet_devconf_indices.h"
46 #include "xlat/inet6_devconf_indices.h"
47 #include "xlat/inet6_if_flags.h"
48 #include "xlat/rtnl_ifla_af_spec_inet_attrs.h"
49 #include "xlat/rtnl_ifla_af_spec_inet6_attrs.h"
50 #include "xlat/rtnl_ifla_brport_attrs.h"
51 #include "xlat/rtnl_ifla_events.h"
52 #include "xlat/rtnl_ifla_info_attrs.h"
53 #include "xlat/rtnl_ifla_info_data_bridge_attrs.h"
54 #include "xlat/rtnl_ifla_info_data_tun_attrs.h"
55 #include "xlat/rtnl_ifla_port_attrs.h"
56 #include "xlat/rtnl_ifla_vf_port_attrs.h"
57 #include "xlat/rtnl_ifla_xdp_attrs.h"
58 #include "xlat/rtnl_link_attrs.h"
59 #include "xlat/snmp_icmp6_stats.h"
60 #include "xlat/snmp_ip_stats.h"
61 #include "xlat/tun_device_types.h"
62 #include "xlat/xdp_flags.h"
65 decode_rtnl_link_stats(struct tcb *const tcp,
66 const kernel_ulong_t addr,
67 const unsigned int len,
68 const void *const opaque_data)
70 struct rtnl_link_stats st;
71 const unsigned int min_size =
72 offsetofend(struct rtnl_link_stats, tx_compressed);
73 const unsigned int def_size = sizeof(st);
74 const unsigned int size =
75 (len >= def_size) ? def_size :
76 ((len == min_size) ? min_size : 0);
81 if (!umoven_or_printaddr(tcp, addr, size, &st)) {
82 PRINT_FIELD_U("{", st, rx_packets);
83 PRINT_FIELD_U(", ", st, tx_packets);
84 PRINT_FIELD_U(", ", st, rx_bytes);
85 PRINT_FIELD_U(", ", st, tx_bytes);
86 PRINT_FIELD_U(", ", st, rx_errors);
87 PRINT_FIELD_U(", ", st, tx_errors);
88 PRINT_FIELD_U(", ", st, rx_dropped);
89 PRINT_FIELD_U(", ", st, tx_dropped);
90 PRINT_FIELD_U(", ", st, multicast);
91 PRINT_FIELD_U(", ", st, collisions);
93 PRINT_FIELD_U(", ", st, rx_length_errors);
94 PRINT_FIELD_U(", ", st, rx_over_errors);
95 PRINT_FIELD_U(", ", st, rx_crc_errors);
96 PRINT_FIELD_U(", ", st, rx_frame_errors);
97 PRINT_FIELD_U(", ", st, rx_fifo_errors);
98 PRINT_FIELD_U(", ", st, rx_missed_errors);
100 PRINT_FIELD_U(", ", st, tx_aborted_errors);
101 PRINT_FIELD_U(", ", st, tx_carrier_errors);
102 PRINT_FIELD_U(", ", st, tx_fifo_errors);
103 PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
104 PRINT_FIELD_U(", ", st, tx_window_errors);
106 PRINT_FIELD_U(", ", st, rx_compressed);
107 PRINT_FIELD_U(", ", st, tx_compressed);
108 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
110 PRINT_FIELD_U(", ", st, rx_nohandler);
119 decode_ifla_bridge_id(struct tcb *const tcp,
120 const kernel_ulong_t addr,
121 const unsigned int len,
122 const void *const opaque_data)
129 if (len < sizeof(id))
131 else if (!umove_or_printaddr(tcp, addr, &id)) {
132 tprintf("{prio=[%u, %u]", id.prio[0], id.prio[1]);
133 PRINT_FIELD_MAC(", ", id, addr);
140 static const nla_decoder_t ifla_brport_nla_decoders[] = {
141 [IFLA_BRPORT_STATE] = decode_nla_u8,
142 [IFLA_BRPORT_PRIORITY] = decode_nla_u16,
143 [IFLA_BRPORT_COST] = decode_nla_u32,
144 [IFLA_BRPORT_MODE] = decode_nla_u8,
145 [IFLA_BRPORT_GUARD] = decode_nla_u8,
146 [IFLA_BRPORT_PROTECT] = decode_nla_u8,
147 [IFLA_BRPORT_FAST_LEAVE] = decode_nla_u8,
148 [IFLA_BRPORT_LEARNING] = decode_nla_u8,
149 [IFLA_BRPORT_UNICAST_FLOOD] = decode_nla_u8,
150 [IFLA_BRPORT_PROXYARP] = decode_nla_u8,
151 [IFLA_BRPORT_LEARNING_SYNC] = decode_nla_u8,
152 [IFLA_BRPORT_PROXYARP_WIFI] = decode_nla_u8,
153 [IFLA_BRPORT_ROOT_ID] = decode_ifla_bridge_id,
154 [IFLA_BRPORT_BRIDGE_ID] = decode_ifla_bridge_id,
155 [IFLA_BRPORT_DESIGNATED_PORT] = decode_nla_u16,
156 [IFLA_BRPORT_DESIGNATED_COST] = decode_nla_u16,
157 [IFLA_BRPORT_ID] = decode_nla_u16,
158 [IFLA_BRPORT_NO] = decode_nla_u16,
159 [IFLA_BRPORT_TOPOLOGY_CHANGE_ACK] = decode_nla_u8,
160 [IFLA_BRPORT_CONFIG_PENDING] = decode_nla_u8,
161 [IFLA_BRPORT_MESSAGE_AGE_TIMER] = decode_nla_u64,
162 [IFLA_BRPORT_FORWARD_DELAY_TIMER] = decode_nla_u64,
163 [IFLA_BRPORT_HOLD_TIMER] = decode_nla_u64,
164 [IFLA_BRPORT_FLUSH] = NULL,
165 [IFLA_BRPORT_MULTICAST_ROUTER] = decode_nla_u8,
166 [IFLA_BRPORT_PAD] = NULL,
167 [IFLA_BRPORT_MCAST_FLOOD] = decode_nla_u8,
168 [IFLA_BRPORT_MCAST_TO_UCAST] = decode_nla_u8,
169 [IFLA_BRPORT_VLAN_TUNNEL] = decode_nla_u8,
170 [IFLA_BRPORT_BCAST_FLOOD] = decode_nla_u8,
171 [IFLA_BRPORT_GROUP_FWD_MASK] = decode_nla_u16,
172 [IFLA_BRPORT_NEIGH_SUPPRESS] = decode_nla_u8,
173 [IFLA_BRPORT_ISOLATED] = decode_nla_u8
177 decode_ifla_protinfo(struct tcb *const tcp,
178 const kernel_ulong_t addr,
179 const unsigned int len,
180 const void *const opaque_data)
182 decode_nlattr(tcp, addr, len, rtnl_ifla_brport_attrs,
184 ARRSZ_PAIR(ifla_brport_nla_decoders), opaque_data);
190 decode_rtnl_link_ifmap(struct tcb *const tcp,
191 const kernel_ulong_t addr,
192 const unsigned int len,
193 const void *const opaque_data)
195 struct rtnl_link_ifmap map;
196 const unsigned int sizeof_ifmap =
197 offsetofend(struct rtnl_link_ifmap, port);
199 if (len < sizeof_ifmap)
201 else if (!umoven_or_printaddr(tcp, addr, sizeof_ifmap, &map)) {
202 PRINT_FIELD_X("{", map, mem_start);
203 PRINT_FIELD_X(", ", map, mem_end);
204 PRINT_FIELD_X(", ", map, base_addr);
205 PRINT_FIELD_U(", ", map, irq);
206 PRINT_FIELD_U(", ", map, dma);
207 PRINT_FIELD_U(", ", map, port);
215 decode_nla_linkinfo_kind(struct tcb *const tcp,
216 const kernel_ulong_t addr,
217 const unsigned int len,
218 const void *const opaque_data)
220 struct ifla_linkinfo_ctx *ctx = (void *) opaque_data;
222 memset(ctx->kind, '\0', sizeof(ctx->kind));
224 if (umovestr(tcp, addr, sizeof(ctx->kind), ctx->kind) <= 0) {
226 * If we haven't seen NUL or an error occurred, set kind to
232 printstr_ex(tcp, addr, len, QUOTE_0_TERMINATED);
238 decode_nla_linkinfo_xstats_can(struct tcb *const tcp,
239 const kernel_ulong_t addr,
240 const unsigned int len,
241 const void *const opaque_data)
243 struct strace_can_device_stats {
245 uint32_t error_warning;
246 uint32_t error_passive;
248 uint32_t arbitration_lost;
251 const unsigned int def_size = sizeof(st);
252 const unsigned int size = (len >= def_size) ? def_size : 0;
257 if (umoven_or_printaddr(tcp, addr, size, &st))
260 PRINT_FIELD_U("{", st, bus_error);
261 PRINT_FIELD_U(", ", st, error_warning);
262 PRINT_FIELD_U(", ", st, error_passive);
263 PRINT_FIELD_U(", ", st, bus_off);
264 PRINT_FIELD_U(", ", st, arbitration_lost);
265 PRINT_FIELD_U(", ", st, restarts);
272 decode_nla_linkinfo_xstats(struct tcb *const tcp,
273 const kernel_ulong_t addr,
274 const unsigned int len,
275 const void *const opaque_data)
277 struct ifla_linkinfo_ctx *ctx = (void *) opaque_data;
278 nla_decoder_t func = NULL;
280 if (!strcmp(ctx->kind, "can"))
281 func = decode_nla_linkinfo_xstats_can;
284 return func(tcp, addr, len, opaque_data);
289 static const nla_decoder_t ifla_info_data_bridge_nla_decoders[] = {
290 [IFLA_BR_UNSPEC] = NULL,
291 [IFLA_BR_FORWARD_DELAY] = decode_nla_u32,
292 [IFLA_BR_HELLO_TIME] = decode_nla_u32,
293 [IFLA_BR_MAX_AGE] = decode_nla_u32,
294 [IFLA_BR_AGEING_TIME] = decode_nla_u32,
295 [IFLA_BR_STP_STATE] = decode_nla_u32,
296 [IFLA_BR_PRIORITY] = decode_nla_u16,
297 [IFLA_BR_VLAN_FILTERING] = decode_nla_u8,
298 [IFLA_BR_VLAN_PROTOCOL] = decode_nla_ether_proto,
299 [IFLA_BR_GROUP_FWD_MASK] = decode_nla_x16,
300 [IFLA_BR_ROOT_ID] = decode_ifla_bridge_id,
301 [IFLA_BR_BRIDGE_ID] = decode_ifla_bridge_id,
302 [IFLA_BR_ROOT_PORT] = decode_nla_u16,
303 [IFLA_BR_ROOT_PATH_COST] = decode_nla_u32,
304 [IFLA_BR_TOPOLOGY_CHANGE] = decode_nla_u8,
305 [IFLA_BR_TOPOLOGY_CHANGE_DETECTED] = decode_nla_u8,
306 [IFLA_BR_HELLO_TIMER] = decode_nla_u64,
307 [IFLA_BR_TCN_TIMER] = decode_nla_u64,
308 [IFLA_BR_TOPOLOGY_CHANGE_TIMER] = decode_nla_u64,
309 [IFLA_BR_GC_TIMER] = decode_nla_u64,
310 [IFLA_BR_GROUP_ADDR] = NULL, /* MAC address */
311 [IFLA_BR_FDB_FLUSH] = NULL, /* unspecified */
312 [IFLA_BR_MCAST_ROUTER] = decode_nla_u8,
313 [IFLA_BR_MCAST_SNOOPING] = decode_nla_u8,
314 [IFLA_BR_MCAST_QUERY_USE_IFADDR] = decode_nla_u8,
315 [IFLA_BR_MCAST_QUERIER] = decode_nla_u8,
316 [IFLA_BR_MCAST_HASH_ELASTICITY] = decode_nla_u32,
317 [IFLA_BR_MCAST_HASH_MAX] = decode_nla_u32,
318 [IFLA_BR_MCAST_LAST_MEMBER_CNT] = decode_nla_u32,
319 [IFLA_BR_MCAST_STARTUP_QUERY_CNT] = decode_nla_u32,
320 [IFLA_BR_MCAST_LAST_MEMBER_INTVL] = decode_nla_u64,
321 [IFLA_BR_MCAST_MEMBERSHIP_INTVL] = decode_nla_u64,
322 [IFLA_BR_MCAST_QUERIER_INTVL] = decode_nla_u64,
323 [IFLA_BR_MCAST_QUERY_INTVL] = decode_nla_u64,
324 [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = decode_nla_u64,
325 [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = decode_nla_u64,
326 [IFLA_BR_NF_CALL_IPTABLES] = decode_nla_u8,
327 [IFLA_BR_NF_CALL_IP6TABLES] = decode_nla_u8,
328 [IFLA_BR_NF_CALL_ARPTABLES] = decode_nla_u8,
329 [IFLA_BR_VLAN_DEFAULT_PVID] = decode_nla_u16,
330 [IFLA_BR_PAD] = NULL,
331 [IFLA_BR_VLAN_STATS_ENABLED] = decode_nla_u8,
332 [IFLA_BR_MCAST_STATS_ENABLED] = decode_nla_u8,
333 [IFLA_BR_MCAST_IGMP_VERSION] = decode_nla_u8,
334 [IFLA_BR_MCAST_MLD_VERSION] = decode_nla_u8,
338 decode_nla_linkinfo_data_bridge(struct tcb *const tcp,
339 const kernel_ulong_t addr,
340 const unsigned int len,
341 const void *const opaque_data)
343 decode_nlattr(tcp, addr, len, rtnl_ifla_info_data_bridge_attrs,
345 ARRSZ_PAIR(ifla_info_data_bridge_nla_decoders),
352 decode_nla_tun_type(struct tcb *const tcp,
353 const kernel_ulong_t addr,
354 const unsigned int len,
355 const void *const opaque_data)
357 const struct decode_nla_xlat_opts opts = {
358 .xlat = tun_device_types,
359 .xlat_size = ARRAY_SIZE(tun_device_types),
365 return decode_nla_xval(tcp, addr, len, &opts);
368 static const nla_decoder_t ifla_info_data_tun_nla_decoders[] = {
369 [IFLA_TUN_UNSPEC] = NULL,
370 [IFLA_TUN_OWNER] = decode_nla_uid,
371 [IFLA_TUN_GROUP] = decode_nla_gid,
372 [IFLA_TUN_TYPE] = decode_nla_tun_type,
373 [IFLA_TUN_PI] = decode_nla_u8,
374 [IFLA_TUN_VNET_HDR] = decode_nla_u8,
375 [IFLA_TUN_PERSIST] = decode_nla_u8,
376 [IFLA_TUN_MULTI_QUEUE] = decode_nla_u8,
377 [IFLA_TUN_NUM_QUEUES] = decode_nla_u32,
378 [IFLA_TUN_NUM_DISABLED_QUEUES] = decode_nla_u32,
382 decode_nla_linkinfo_data_tun(struct tcb *const tcp,
383 const kernel_ulong_t addr,
384 const unsigned int len,
385 const void *const opaque_data)
387 decode_nlattr(tcp, addr, len, rtnl_ifla_info_data_tun_attrs,
389 ARRSZ_PAIR(ifla_info_data_tun_nla_decoders),
396 decode_nla_linkinfo_data(struct tcb *const tcp,
397 const kernel_ulong_t addr,
398 const unsigned int len,
399 const void *const opaque_data)
401 struct ifla_linkinfo_ctx *ctx = (void *) opaque_data;
402 nla_decoder_t func = NULL;
404 if (!strcmp(ctx->kind, "bridge"))
405 func = decode_nla_linkinfo_data_bridge;
406 else if (!strcmp(ctx->kind, "tun"))
407 func = decode_nla_linkinfo_data_tun;
410 return func(tcp, addr, len, opaque_data);
415 static const nla_decoder_t ifla_linkinfo_nla_decoders[] = {
416 [IFLA_INFO_KIND] = decode_nla_linkinfo_kind,
417 [IFLA_INFO_DATA] = decode_nla_linkinfo_data,
418 [IFLA_INFO_XSTATS] = decode_nla_linkinfo_xstats,
419 [IFLA_INFO_SLAVE_KIND] = decode_nla_str,
420 [IFLA_INFO_SLAVE_DATA] = NULL, /* unimplemented */
424 decode_ifla_linkinfo(struct tcb *const tcp,
425 const kernel_ulong_t addr,
426 const unsigned int len,
427 const void *const opaque_data)
429 struct ifla_linkinfo_ctx ctx = { .kind = "", };
431 decode_nlattr(tcp, addr, len, rtnl_ifla_info_attrs,
432 "IFLA_INFO_???", ARRSZ_PAIR(ifla_linkinfo_nla_decoders),
439 decode_rtnl_link_stats64(struct tcb *const tcp,
440 const kernel_ulong_t addr,
441 const unsigned int len,
442 const void *const opaque_data)
444 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64
445 struct rtnl_link_stats64 st;
446 const unsigned int min_size =
447 offsetofend(struct rtnl_link_stats64, tx_compressed);
448 const unsigned int def_size = sizeof(st);
449 const unsigned int size =
450 (len >= def_size) ? def_size :
451 ((len == min_size) ? min_size : 0);
456 if (!umoven_or_printaddr(tcp, addr, size, &st)) {
457 PRINT_FIELD_U("{", st, rx_packets);
458 PRINT_FIELD_U(", ", st, tx_packets);
459 PRINT_FIELD_U(", ", st, rx_bytes);
460 PRINT_FIELD_U(", ", st, tx_bytes);
461 PRINT_FIELD_U(", ", st, rx_errors);
462 PRINT_FIELD_U(", ", st, tx_errors);
463 PRINT_FIELD_U(", ", st, rx_dropped);
464 PRINT_FIELD_U(", ", st, tx_dropped);
465 PRINT_FIELD_U(", ", st, multicast);
466 PRINT_FIELD_U(", ", st, collisions);
468 PRINT_FIELD_U(", ", st, rx_length_errors);
469 PRINT_FIELD_U(", ", st, rx_over_errors);
470 PRINT_FIELD_U(", ", st, rx_crc_errors);
471 PRINT_FIELD_U(", ", st, rx_frame_errors);
472 PRINT_FIELD_U(", ", st, rx_fifo_errors);
473 PRINT_FIELD_U(", ", st, rx_missed_errors);
475 PRINT_FIELD_U(", ", st, tx_aborted_errors);
476 PRINT_FIELD_U(", ", st, tx_carrier_errors);
477 PRINT_FIELD_U(", ", st, tx_fifo_errors);
478 PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
479 PRINT_FIELD_U(", ", st, tx_window_errors);
481 PRINT_FIELD_U(", ", st, rx_compressed);
482 PRINT_FIELD_U(", ", st, tx_compressed);
483 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
485 PRINT_FIELD_U(", ", st, rx_nohandler);
497 decode_ifla_port_vsi(struct tcb *const tcp,
498 const kernel_ulong_t addr,
499 const unsigned int len,
500 const void *const opaque_data)
502 #ifdef HAVE_STRUCT_IFLA_PORT_VSI
503 struct ifla_port_vsi vsi;
505 if (len < sizeof(vsi))
507 else if (!umove_or_printaddr(tcp, addr, &vsi)) {
508 PRINT_FIELD_U("{", vsi, vsi_mgr_id);
509 PRINT_FIELD_STRING(", ", vsi, vsi_type_id,
510 sizeof(vsi.vsi_type_id), QUOTE_FORCE_HEX);
511 PRINT_FIELD_U(", ", vsi, vsi_type_version);
521 static const nla_decoder_t ifla_port_nla_decoders[] = {
522 [IFLA_PORT_VF] = decode_nla_u32,
523 [IFLA_PORT_PROFILE] = decode_nla_str,
524 [IFLA_PORT_VSI_TYPE] = decode_ifla_port_vsi,
525 [IFLA_PORT_INSTANCE_UUID] = NULL, /* default parser */
526 [IFLA_PORT_HOST_UUID] = NULL, /* default parser */
527 [IFLA_PORT_REQUEST] = decode_nla_u8,
528 [IFLA_PORT_RESPONSE] = decode_nla_u16
532 decode_ifla_port(struct tcb *const tcp,
533 const kernel_ulong_t addr,
534 const unsigned int len,
535 const void *const opaque_data)
537 decode_nlattr(tcp, addr, len, rtnl_ifla_port_attrs,
538 "IFLA_VF_PORT_???", ARRSZ_PAIR(ifla_port_nla_decoders),
544 static const nla_decoder_t ifla_vf_port_nla_decoders[] = {
545 [IFLA_VF_PORT] = decode_ifla_port
549 decode_ifla_vf_ports(struct tcb *const tcp,
550 const kernel_ulong_t addr,
551 const unsigned int len,
552 const void *const opaque_data)
554 decode_nlattr(tcp, addr, len, rtnl_ifla_vf_port_attrs,
555 "IFLA_VF_PORT_???", ARRSZ_PAIR(ifla_vf_port_nla_decoders),
562 decode_ifla_xdp_flags(struct tcb *const tcp,
563 const kernel_ulong_t addr,
564 const unsigned int len,
565 const void *const opaque_data)
569 if (len < sizeof(flags))
571 else if (!umove_or_printaddr(tcp, addr, &flags))
572 printflags(xdp_flags, flags, "XDP_FLAGS_???");
577 static const nla_decoder_t ifla_xdp_nla_decoders[] = {
578 [IFLA_XDP_FD] = decode_nla_fd,
579 [IFLA_XDP_ATTACHED] = decode_nla_u8,
580 [IFLA_XDP_FLAGS] = decode_ifla_xdp_flags,
581 [IFLA_XDP_PROG_ID] = decode_nla_u32
585 decode_ifla_xdp(struct tcb *const tcp,
586 const kernel_ulong_t addr,
587 const unsigned int len,
588 const void *const opaque_data)
590 decode_nlattr(tcp, addr, len, rtnl_ifla_xdp_attrs,
591 "IFLA_XDP_???", ARRSZ_PAIR(ifla_xdp_nla_decoders),
598 decode_ifla_event(struct tcb *const tcp,
599 const kernel_ulong_t addr,
600 const unsigned int len,
601 const void *const opaque_data)
605 if (len < sizeof(ev))
607 else if (!umove_or_printaddr(tcp, addr, &ev))
608 printxval(rtnl_ifla_events, ev, "IFLA_EVENT_???");
615 decode_ifla_inet_conf(struct tcb *const tcp,
616 const kernel_ulong_t addr,
617 const unsigned int len,
618 const void *const opaque_data)
621 size_t cnt = len / sizeof(elem);
626 print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
627 tfetch_mem, print_int32_array_member, NULL,
628 PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
629 | XLAT_STYLE_FMT_D, ARRSZ_PAIR(inet_devconf_indices),
635 static const nla_decoder_t ifla_inet_nla_decoders[] = {
636 [IFLA_INET_CONF] = decode_ifla_inet_conf,
640 decode_ifla_inet6_flags(struct tcb *const tcp,
641 const kernel_ulong_t addr,
642 const unsigned int len,
643 const void *const opaque_data)
645 const struct decode_nla_xlat_opts opts = {
646 ARRSZ_PAIR(inet6_if_flags), "IF_???",
650 return decode_nla_flags(tcp, addr, len, &opts);
654 decode_ifla_inet6_conf(struct tcb *const tcp,
655 const kernel_ulong_t addr,
656 const unsigned int len,
657 const void *const opaque_data)
660 size_t cnt = len / sizeof(elem);
665 print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
666 tfetch_mem, print_int32_array_member, NULL,
667 PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
668 | XLAT_STYLE_FMT_D, ARRSZ_PAIR(inet6_devconf_indices),
675 decode_ifla_inet6_stats(struct tcb *const tcp,
676 const kernel_ulong_t addr,
677 const unsigned int len,
678 const void *const opaque_data)
681 size_t cnt = len / sizeof(elem);
686 print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
687 tfetch_mem, print_uint64_array_member, NULL,
688 PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
689 | XLAT_STYLE_FMT_U, ARRSZ_PAIR(snmp_ip_stats),
696 decode_ifla_inet6_cacheinfo(struct tcb *const tcp,
697 const kernel_ulong_t addr,
698 const unsigned int len,
699 const void *const opaque_data)
702 uint32_t max_reasm_len;
704 uint32_t reachable_time;
705 uint32_t retrans_time;
708 if (len < sizeof(ci))
710 else if (!umove_or_printaddr(tcp, addr, &ci)) {
711 PRINT_FIELD_U("{", ci, max_reasm_len);
712 PRINT_FIELD_U(", ", ci, tstamp);
713 PRINT_FIELD_U(", ", ci, reachable_time);
714 PRINT_FIELD_U(", ", ci, retrans_time);
722 decode_ifla_inet6_icmp6_stats(struct tcb *const tcp,
723 const kernel_ulong_t addr,
724 const unsigned int len,
725 const void *const opaque_data)
728 size_t cnt = len / sizeof(elem);
733 print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
734 tfetch_mem, print_uint64_array_member, NULL,
735 PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
736 | XLAT_STYLE_FMT_U, ARRSZ_PAIR(snmp_icmp6_stats),
743 decode_ifla_inet6_token(struct tcb *const tcp,
744 const kernel_ulong_t addr,
745 const unsigned int len,
746 const void *const opaque_data)
750 if (len < sizeof(in6))
752 else if (!umove_or_printaddr(tcp, addr, &in6))
753 print_inet_addr(AF_INET6, &in6, sizeof(in6), NULL);
759 decode_ifla_inet6_agm(struct tcb *const tcp,
760 const kernel_ulong_t addr,
761 const unsigned int len,
762 const void *const opaque_data)
764 const struct decode_nla_xlat_opts opts = {
765 ARRSZ_PAIR(in6_addr_gen_mode), "IN6_ADDR_GEN_MODE_???",
770 return decode_nla_xval(tcp, addr, len, &opts);
773 static const nla_decoder_t ifla_inet6_nla_decoders[] = {
774 [IFLA_INET6_FLAGS] = decode_ifla_inet6_flags,
775 [IFLA_INET6_CONF] = decode_ifla_inet6_conf,
776 [IFLA_INET6_STATS] = decode_ifla_inet6_stats,
777 [IFLA_INET6_MCAST] = NULL, /* unused */
778 [IFLA_INET6_CACHEINFO] = decode_ifla_inet6_cacheinfo,
779 [IFLA_INET6_ICMP6STATS] = decode_ifla_inet6_icmp6_stats,
780 [IFLA_INET6_TOKEN] = decode_ifla_inet6_token,
781 [IFLA_INET6_ADDR_GEN_MODE] = decode_ifla_inet6_agm,
784 static const struct nla_decoder_table_desc {
785 const struct xlat *xlat;
787 const nla_decoder_t *table;
789 } ifla_af_spec_protos[] = {
791 rtnl_ifla_af_spec_inet_attrs, "IFLA_INET_???",
792 ARRSZ_PAIR(ifla_inet_nla_decoders),
795 rtnl_ifla_af_spec_inet6_attrs, "IFLA_INET6_???",
796 ARRSZ_PAIR(ifla_inet6_nla_decoders),
801 decode_ifla_af(struct tcb *const tcp,
802 const kernel_ulong_t addr,
803 const unsigned int len,
804 const void *const opaque_data)
806 uintptr_t proto = (uintptr_t) opaque_data;
807 const struct nla_decoder_table_desc *desc
808 = proto < ARRAY_SIZE(ifla_af_spec_protos)
809 ? ifla_af_spec_protos + proto : NULL;
811 if (!desc || !desc->table)
814 decode_nlattr(tcp, addr, len,
815 desc->xlat, desc->dflt, desc->table, desc->size, NULL);
821 decode_ifla_af_spec(struct tcb *const tcp,
822 const kernel_ulong_t addr,
823 const unsigned int len,
824 const void *const opaque_data)
826 nla_decoder_t af_spec_decoder = &decode_ifla_af;
828 decode_nlattr(tcp, addr, len, addrfams, "AF_???",
829 &af_spec_decoder, 0, opaque_data);
834 static const nla_decoder_t ifinfomsg_nla_decoders[] = {
835 [IFLA_ADDRESS] = NULL, /* unimplemented */
836 [IFLA_BROADCAST] = NULL, /* unimplemented */
837 [IFLA_IFNAME] = decode_nla_str,
838 [IFLA_MTU] = decode_nla_u32,
839 [IFLA_LINK] = decode_nla_u32,
840 [IFLA_QDISC] = decode_nla_str,
841 [IFLA_STATS] = decode_rtnl_link_stats,
842 [IFLA_COST] = NULL, /* unused */
843 [IFLA_PRIORITY] = NULL, /* unused */
844 [IFLA_MASTER] = decode_nla_u32,
845 [IFLA_WIRELESS] = NULL, /* unimplemented */
846 [IFLA_PROTINFO] = decode_ifla_protinfo,
847 [IFLA_TXQLEN] = decode_nla_u32,
848 [IFLA_MAP] = decode_rtnl_link_ifmap,
849 [IFLA_WEIGHT] = decode_nla_u32,
850 [IFLA_OPERSTATE] = decode_nla_u8,
851 [IFLA_LINKMODE] = decode_nla_u8,
852 [IFLA_LINKINFO] = decode_ifla_linkinfo,
853 [IFLA_NET_NS_PID] = decode_nla_u32,
854 [IFLA_IFALIAS] = decode_nla_str,
855 [IFLA_NUM_VF] = decode_nla_u32,
856 [IFLA_VFINFO_LIST] = NULL, /* unimplemented */
857 [IFLA_STATS64] = decode_rtnl_link_stats64,
858 [IFLA_VF_PORTS] = decode_ifla_vf_ports,
859 [IFLA_PORT_SELF] = decode_ifla_port,
860 [IFLA_AF_SPEC] = decode_ifla_af_spec,
861 [IFLA_GROUP] = decode_nla_u32,
862 [IFLA_NET_NS_FD] = decode_nla_fd,
863 [IFLA_EXT_MASK] = decode_nla_u32,
864 [IFLA_PROMISCUITY] = decode_nla_u32,
865 [IFLA_NUM_TX_QUEUES] = decode_nla_u32,
866 [IFLA_NUM_RX_QUEUES] = decode_nla_u32,
867 [IFLA_CARRIER] = decode_nla_u8,
868 [IFLA_PHYS_PORT_ID] = NULL, /* default parser */
869 [IFLA_CARRIER_CHANGES] = decode_nla_u32,
870 [IFLA_PHYS_SWITCH_ID] = NULL, /* default parser */
871 [IFLA_LINK_NETNSID] = decode_nla_s32,
872 [IFLA_PHYS_PORT_NAME] = decode_nla_str,
873 [IFLA_PROTO_DOWN] = decode_nla_u8,
874 [IFLA_GSO_MAX_SEGS] = decode_nla_u32,
875 [IFLA_GSO_MAX_SIZE] = decode_nla_u32,
877 [IFLA_XDP] = decode_ifla_xdp,
878 [IFLA_EVENT] = decode_ifla_event,
879 [IFLA_NEW_NETNSID] = decode_nla_s32,
880 [IFLA_IF_NETNSID] = decode_nla_s32,
881 [IFLA_CARRIER_UP_COUNT] = decode_nla_u32,
882 [IFLA_CARRIER_DOWN_COUNT] = decode_nla_u32,
883 [IFLA_NEW_IFINDEX] = decode_nla_ifindex,
886 DECL_NETLINK_ROUTE_DECODER(decode_ifinfomsg)
888 struct ifinfomsg ifinfo = { .ifi_family = family };
889 size_t offset = sizeof(ifinfo.ifi_family);
890 bool decode_nla = false;
892 PRINT_FIELD_XVAL("{", ifinfo, ifi_family, addrfams, "AF_???");
895 if (len >= sizeof(ifinfo)) {
896 if (!umoven_or_printaddr(tcp, addr + offset,
897 sizeof(ifinfo) - offset,
898 (char *) &ifinfo + offset)) {
899 PRINT_FIELD_XVAL_SORTED_SIZED("", ifinfo, ifi_type,
901 arp_hardware_types_size,
903 PRINT_FIELD_IFINDEX(", ", ifinfo, ifi_index);
904 PRINT_FIELD_FLAGS(", ", ifinfo, ifi_flags,
905 iffflags, "IFF_???");
906 PRINT_FIELD_X(", ", ifinfo, ifi_change);
913 offset = NLMSG_ALIGN(sizeof(ifinfo));
914 if (decode_nla && len > offset) {
916 decode_nlattr(tcp, addr + offset, len - offset,
917 rtnl_link_attrs, "IFLA_???",
918 ARRSZ_PAIR(ifinfomsg_nla_decoders), NULL);