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_attached_mode.h"
58 #include "xlat/rtnl_ifla_xdp_attrs.h"
59 #include "xlat/rtnl_link_attrs.h"
60 #include "xlat/snmp_icmp6_stats.h"
61 #include "xlat/snmp_ip_stats.h"
62 #include "xlat/tun_device_types.h"
63 #include "xlat/xdp_flags.h"
66 decode_rtnl_link_stats(struct tcb *const tcp,
67 const kernel_ulong_t addr,
68 const unsigned int len,
69 const void *const opaque_data)
71 struct rtnl_link_stats st;
72 const unsigned int min_size =
73 offsetofend(struct rtnl_link_stats, tx_compressed);
74 const unsigned int def_size = sizeof(st);
75 const unsigned int size =
76 (len >= def_size) ? def_size :
77 ((len == min_size) ? min_size : 0);
82 if (!umoven_or_printaddr(tcp, addr, size, &st)) {
83 PRINT_FIELD_U("{", st, rx_packets);
84 PRINT_FIELD_U(", ", st, tx_packets);
85 PRINT_FIELD_U(", ", st, rx_bytes);
86 PRINT_FIELD_U(", ", st, tx_bytes);
87 PRINT_FIELD_U(", ", st, rx_errors);
88 PRINT_FIELD_U(", ", st, tx_errors);
89 PRINT_FIELD_U(", ", st, rx_dropped);
90 PRINT_FIELD_U(", ", st, tx_dropped);
91 PRINT_FIELD_U(", ", st, multicast);
92 PRINT_FIELD_U(", ", st, collisions);
94 PRINT_FIELD_U(", ", st, rx_length_errors);
95 PRINT_FIELD_U(", ", st, rx_over_errors);
96 PRINT_FIELD_U(", ", st, rx_crc_errors);
97 PRINT_FIELD_U(", ", st, rx_frame_errors);
98 PRINT_FIELD_U(", ", st, rx_fifo_errors);
99 PRINT_FIELD_U(", ", st, rx_missed_errors);
101 PRINT_FIELD_U(", ", st, tx_aborted_errors);
102 PRINT_FIELD_U(", ", st, tx_carrier_errors);
103 PRINT_FIELD_U(", ", st, tx_fifo_errors);
104 PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
105 PRINT_FIELD_U(", ", st, tx_window_errors);
107 PRINT_FIELD_U(", ", st, rx_compressed);
108 PRINT_FIELD_U(", ", st, tx_compressed);
109 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
111 PRINT_FIELD_U(", ", st, rx_nohandler);
120 decode_ifla_bridge_id(struct tcb *const tcp,
121 const kernel_ulong_t addr,
122 const unsigned int len,
123 const void *const opaque_data)
130 if (len < sizeof(id))
132 else if (!umove_or_printaddr(tcp, addr, &id)) {
133 tprintf("{prio=[%u, %u]", id.prio[0], id.prio[1]);
134 PRINT_FIELD_MAC(", ", id, addr);
141 static const nla_decoder_t ifla_brport_nla_decoders[] = {
142 [IFLA_BRPORT_STATE] = decode_nla_u8,
143 [IFLA_BRPORT_PRIORITY] = decode_nla_u16,
144 [IFLA_BRPORT_COST] = decode_nla_u32,
145 [IFLA_BRPORT_MODE] = decode_nla_u8,
146 [IFLA_BRPORT_GUARD] = decode_nla_u8,
147 [IFLA_BRPORT_PROTECT] = decode_nla_u8,
148 [IFLA_BRPORT_FAST_LEAVE] = decode_nla_u8,
149 [IFLA_BRPORT_LEARNING] = decode_nla_u8,
150 [IFLA_BRPORT_UNICAST_FLOOD] = decode_nla_u8,
151 [IFLA_BRPORT_PROXYARP] = decode_nla_u8,
152 [IFLA_BRPORT_LEARNING_SYNC] = decode_nla_u8,
153 [IFLA_BRPORT_PROXYARP_WIFI] = decode_nla_u8,
154 [IFLA_BRPORT_ROOT_ID] = decode_ifla_bridge_id,
155 [IFLA_BRPORT_BRIDGE_ID] = decode_ifla_bridge_id,
156 [IFLA_BRPORT_DESIGNATED_PORT] = decode_nla_u16,
157 [IFLA_BRPORT_DESIGNATED_COST] = decode_nla_u16,
158 [IFLA_BRPORT_ID] = decode_nla_u16,
159 [IFLA_BRPORT_NO] = decode_nla_u16,
160 [IFLA_BRPORT_TOPOLOGY_CHANGE_ACK] = decode_nla_u8,
161 [IFLA_BRPORT_CONFIG_PENDING] = decode_nla_u8,
162 [IFLA_BRPORT_MESSAGE_AGE_TIMER] = decode_nla_u64,
163 [IFLA_BRPORT_FORWARD_DELAY_TIMER] = decode_nla_u64,
164 [IFLA_BRPORT_HOLD_TIMER] = decode_nla_u64,
165 [IFLA_BRPORT_FLUSH] = NULL,
166 [IFLA_BRPORT_MULTICAST_ROUTER] = decode_nla_u8,
167 [IFLA_BRPORT_PAD] = NULL,
168 [IFLA_BRPORT_MCAST_FLOOD] = decode_nla_u8,
169 [IFLA_BRPORT_MCAST_TO_UCAST] = decode_nla_u8,
170 [IFLA_BRPORT_VLAN_TUNNEL] = decode_nla_u8,
171 [IFLA_BRPORT_BCAST_FLOOD] = decode_nla_u8,
172 [IFLA_BRPORT_GROUP_FWD_MASK] = decode_nla_u16,
173 [IFLA_BRPORT_NEIGH_SUPPRESS] = decode_nla_u8,
174 [IFLA_BRPORT_ISOLATED] = decode_nla_u8,
175 [IFLA_BRPORT_BACKUP_PORT] = decode_nla_ifindex,
179 decode_ifla_protinfo(struct tcb *const tcp,
180 const kernel_ulong_t addr,
181 const unsigned int len,
182 const void *const opaque_data)
184 decode_nlattr(tcp, addr, len, rtnl_ifla_brport_attrs,
186 ARRSZ_PAIR(ifla_brport_nla_decoders), opaque_data);
192 decode_rtnl_link_ifmap(struct tcb *const tcp,
193 const kernel_ulong_t addr,
194 const unsigned int len,
195 const void *const opaque_data)
197 struct rtnl_link_ifmap map;
198 const unsigned int sizeof_ifmap =
199 offsetofend(struct rtnl_link_ifmap, port);
201 if (len < sizeof_ifmap)
203 else if (!umoven_or_printaddr(tcp, addr, sizeof_ifmap, &map)) {
204 PRINT_FIELD_X("{", map, mem_start);
205 PRINT_FIELD_X(", ", map, mem_end);
206 PRINT_FIELD_X(", ", map, base_addr);
207 PRINT_FIELD_U(", ", map, irq);
208 PRINT_FIELD_U(", ", map, dma);
209 PRINT_FIELD_U(", ", map, port);
217 decode_nla_linkinfo_kind(struct tcb *const tcp,
218 const kernel_ulong_t addr,
219 const unsigned int len,
220 const void *const opaque_data)
222 struct ifla_linkinfo_ctx *ctx = (void *) opaque_data;
224 memset(ctx->kind, '\0', sizeof(ctx->kind));
226 if (umovestr(tcp, addr, sizeof(ctx->kind), ctx->kind) <= 0) {
228 * If we haven't seen NUL or an error occurred, set kind to
234 printstr_ex(tcp, addr, len, QUOTE_0_TERMINATED);
240 decode_nla_linkinfo_xstats_can(struct tcb *const tcp,
241 const kernel_ulong_t addr,
242 const unsigned int len,
243 const void *const opaque_data)
245 struct strace_can_device_stats {
247 uint32_t error_warning;
248 uint32_t error_passive;
250 uint32_t arbitration_lost;
253 const unsigned int def_size = sizeof(st);
254 const unsigned int size = (len >= def_size) ? def_size : 0;
259 if (umoven_or_printaddr(tcp, addr, size, &st))
262 PRINT_FIELD_U("{", st, bus_error);
263 PRINT_FIELD_U(", ", st, error_warning);
264 PRINT_FIELD_U(", ", st, error_passive);
265 PRINT_FIELD_U(", ", st, bus_off);
266 PRINT_FIELD_U(", ", st, arbitration_lost);
267 PRINT_FIELD_U(", ", st, restarts);
274 decode_nla_linkinfo_xstats(struct tcb *const tcp,
275 const kernel_ulong_t addr,
276 const unsigned int len,
277 const void *const opaque_data)
279 struct ifla_linkinfo_ctx *ctx = (void *) opaque_data;
280 nla_decoder_t func = NULL;
282 if (!strcmp(ctx->kind, "can"))
283 func = decode_nla_linkinfo_xstats_can;
286 return func(tcp, addr, len, opaque_data);
291 static const nla_decoder_t ifla_info_data_bridge_nla_decoders[] = {
292 [IFLA_BR_UNSPEC] = NULL,
293 [IFLA_BR_FORWARD_DELAY] = decode_nla_u32,
294 [IFLA_BR_HELLO_TIME] = decode_nla_u32,
295 [IFLA_BR_MAX_AGE] = decode_nla_u32,
296 [IFLA_BR_AGEING_TIME] = decode_nla_u32,
297 [IFLA_BR_STP_STATE] = decode_nla_u32,
298 [IFLA_BR_PRIORITY] = decode_nla_u16,
299 [IFLA_BR_VLAN_FILTERING] = decode_nla_u8,
300 [IFLA_BR_VLAN_PROTOCOL] = decode_nla_ether_proto,
301 [IFLA_BR_GROUP_FWD_MASK] = decode_nla_x16,
302 [IFLA_BR_ROOT_ID] = decode_ifla_bridge_id,
303 [IFLA_BR_BRIDGE_ID] = decode_ifla_bridge_id,
304 [IFLA_BR_ROOT_PORT] = decode_nla_u16,
305 [IFLA_BR_ROOT_PATH_COST] = decode_nla_u32,
306 [IFLA_BR_TOPOLOGY_CHANGE] = decode_nla_u8,
307 [IFLA_BR_TOPOLOGY_CHANGE_DETECTED] = decode_nla_u8,
308 [IFLA_BR_HELLO_TIMER] = decode_nla_u64,
309 [IFLA_BR_TCN_TIMER] = decode_nla_u64,
310 [IFLA_BR_TOPOLOGY_CHANGE_TIMER] = decode_nla_u64,
311 [IFLA_BR_GC_TIMER] = decode_nla_u64,
312 [IFLA_BR_GROUP_ADDR] = NULL, /* MAC address */
313 [IFLA_BR_FDB_FLUSH] = NULL, /* unspecified */
314 [IFLA_BR_MCAST_ROUTER] = decode_nla_u8,
315 [IFLA_BR_MCAST_SNOOPING] = decode_nla_u8,
316 [IFLA_BR_MCAST_QUERY_USE_IFADDR] = decode_nla_u8,
317 [IFLA_BR_MCAST_QUERIER] = decode_nla_u8,
318 [IFLA_BR_MCAST_HASH_ELASTICITY] = decode_nla_u32,
319 [IFLA_BR_MCAST_HASH_MAX] = decode_nla_u32,
320 [IFLA_BR_MCAST_LAST_MEMBER_CNT] = decode_nla_u32,
321 [IFLA_BR_MCAST_STARTUP_QUERY_CNT] = decode_nla_u32,
322 [IFLA_BR_MCAST_LAST_MEMBER_INTVL] = decode_nla_u64,
323 [IFLA_BR_MCAST_MEMBERSHIP_INTVL] = decode_nla_u64,
324 [IFLA_BR_MCAST_QUERIER_INTVL] = decode_nla_u64,
325 [IFLA_BR_MCAST_QUERY_INTVL] = decode_nla_u64,
326 [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = decode_nla_u64,
327 [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = decode_nla_u64,
328 [IFLA_BR_NF_CALL_IPTABLES] = decode_nla_u8,
329 [IFLA_BR_NF_CALL_IP6TABLES] = decode_nla_u8,
330 [IFLA_BR_NF_CALL_ARPTABLES] = decode_nla_u8,
331 [IFLA_BR_VLAN_DEFAULT_PVID] = decode_nla_u16,
332 [IFLA_BR_PAD] = NULL,
333 [IFLA_BR_VLAN_STATS_ENABLED] = decode_nla_u8,
334 [IFLA_BR_MCAST_STATS_ENABLED] = decode_nla_u8,
335 [IFLA_BR_MCAST_IGMP_VERSION] = decode_nla_u8,
336 [IFLA_BR_MCAST_MLD_VERSION] = decode_nla_u8,
340 decode_nla_linkinfo_data_bridge(struct tcb *const tcp,
341 const kernel_ulong_t addr,
342 const unsigned int len,
343 const void *const opaque_data)
345 decode_nlattr(tcp, addr, len, rtnl_ifla_info_data_bridge_attrs,
347 ARRSZ_PAIR(ifla_info_data_bridge_nla_decoders),
354 decode_nla_tun_type(struct tcb *const tcp,
355 const kernel_ulong_t addr,
356 const unsigned int len,
357 const void *const opaque_data)
359 const struct decode_nla_xlat_opts opts = {
360 .xlat = tun_device_types,
361 .xlat_size = ARRAY_SIZE(tun_device_types),
367 return decode_nla_xval(tcp, addr, len, &opts);
370 static const nla_decoder_t ifla_info_data_tun_nla_decoders[] = {
371 [IFLA_TUN_UNSPEC] = NULL,
372 [IFLA_TUN_OWNER] = decode_nla_uid,
373 [IFLA_TUN_GROUP] = decode_nla_gid,
374 [IFLA_TUN_TYPE] = decode_nla_tun_type,
375 [IFLA_TUN_PI] = decode_nla_u8,
376 [IFLA_TUN_VNET_HDR] = decode_nla_u8,
377 [IFLA_TUN_PERSIST] = decode_nla_u8,
378 [IFLA_TUN_MULTI_QUEUE] = decode_nla_u8,
379 [IFLA_TUN_NUM_QUEUES] = decode_nla_u32,
380 [IFLA_TUN_NUM_DISABLED_QUEUES] = decode_nla_u32,
384 decode_nla_linkinfo_data_tun(struct tcb *const tcp,
385 const kernel_ulong_t addr,
386 const unsigned int len,
387 const void *const opaque_data)
389 decode_nlattr(tcp, addr, len, rtnl_ifla_info_data_tun_attrs,
391 ARRSZ_PAIR(ifla_info_data_tun_nla_decoders),
398 decode_nla_linkinfo_data(struct tcb *const tcp,
399 const kernel_ulong_t addr,
400 const unsigned int len,
401 const void *const opaque_data)
403 struct ifla_linkinfo_ctx *ctx = (void *) opaque_data;
404 nla_decoder_t func = NULL;
406 if (!strcmp(ctx->kind, "bridge"))
407 func = decode_nla_linkinfo_data_bridge;
408 else if (!strcmp(ctx->kind, "tun"))
409 func = decode_nla_linkinfo_data_tun;
412 return func(tcp, addr, len, opaque_data);
417 static const nla_decoder_t ifla_linkinfo_nla_decoders[] = {
418 [IFLA_INFO_KIND] = decode_nla_linkinfo_kind,
419 [IFLA_INFO_DATA] = decode_nla_linkinfo_data,
420 [IFLA_INFO_XSTATS] = decode_nla_linkinfo_xstats,
421 [IFLA_INFO_SLAVE_KIND] = decode_nla_str,
422 [IFLA_INFO_SLAVE_DATA] = NULL, /* unimplemented */
426 decode_ifla_linkinfo(struct tcb *const tcp,
427 const kernel_ulong_t addr,
428 const unsigned int len,
429 const void *const opaque_data)
431 struct ifla_linkinfo_ctx ctx = { .kind = "", };
433 decode_nlattr(tcp, addr, len, rtnl_ifla_info_attrs,
434 "IFLA_INFO_???", ARRSZ_PAIR(ifla_linkinfo_nla_decoders),
441 decode_rtnl_link_stats64(struct tcb *const tcp,
442 const kernel_ulong_t addr,
443 const unsigned int len,
444 const void *const opaque_data)
446 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64
447 struct rtnl_link_stats64 st;
448 const unsigned int min_size =
449 offsetofend(struct rtnl_link_stats64, tx_compressed);
450 const unsigned int def_size = sizeof(st);
451 const unsigned int size =
452 (len >= def_size) ? def_size :
453 ((len == min_size) ? min_size : 0);
458 if (!umoven_or_printaddr(tcp, addr, size, &st)) {
459 PRINT_FIELD_U("{", st, rx_packets);
460 PRINT_FIELD_U(", ", st, tx_packets);
461 PRINT_FIELD_U(", ", st, rx_bytes);
462 PRINT_FIELD_U(", ", st, tx_bytes);
463 PRINT_FIELD_U(", ", st, rx_errors);
464 PRINT_FIELD_U(", ", st, tx_errors);
465 PRINT_FIELD_U(", ", st, rx_dropped);
466 PRINT_FIELD_U(", ", st, tx_dropped);
467 PRINT_FIELD_U(", ", st, multicast);
468 PRINT_FIELD_U(", ", st, collisions);
470 PRINT_FIELD_U(", ", st, rx_length_errors);
471 PRINT_FIELD_U(", ", st, rx_over_errors);
472 PRINT_FIELD_U(", ", st, rx_crc_errors);
473 PRINT_FIELD_U(", ", st, rx_frame_errors);
474 PRINT_FIELD_U(", ", st, rx_fifo_errors);
475 PRINT_FIELD_U(", ", st, rx_missed_errors);
477 PRINT_FIELD_U(", ", st, tx_aborted_errors);
478 PRINT_FIELD_U(", ", st, tx_carrier_errors);
479 PRINT_FIELD_U(", ", st, tx_fifo_errors);
480 PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
481 PRINT_FIELD_U(", ", st, tx_window_errors);
483 PRINT_FIELD_U(", ", st, rx_compressed);
484 PRINT_FIELD_U(", ", st, tx_compressed);
485 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
487 PRINT_FIELD_U(", ", st, rx_nohandler);
499 decode_ifla_port_vsi(struct tcb *const tcp,
500 const kernel_ulong_t addr,
501 const unsigned int len,
502 const void *const opaque_data)
504 #ifdef HAVE_STRUCT_IFLA_PORT_VSI
505 struct ifla_port_vsi vsi;
507 if (len < sizeof(vsi))
509 else if (!umove_or_printaddr(tcp, addr, &vsi)) {
510 PRINT_FIELD_U("{", vsi, vsi_mgr_id);
511 PRINT_FIELD_STRING(", ", vsi, vsi_type_id,
512 sizeof(vsi.vsi_type_id), QUOTE_FORCE_HEX);
513 PRINT_FIELD_U(", ", vsi, vsi_type_version);
523 static const nla_decoder_t ifla_port_nla_decoders[] = {
524 [IFLA_PORT_VF] = decode_nla_u32,
525 [IFLA_PORT_PROFILE] = decode_nla_str,
526 [IFLA_PORT_VSI_TYPE] = decode_ifla_port_vsi,
527 [IFLA_PORT_INSTANCE_UUID] = NULL, /* default parser */
528 [IFLA_PORT_HOST_UUID] = NULL, /* default parser */
529 [IFLA_PORT_REQUEST] = decode_nla_u8,
530 [IFLA_PORT_RESPONSE] = decode_nla_u16
534 decode_ifla_port(struct tcb *const tcp,
535 const kernel_ulong_t addr,
536 const unsigned int len,
537 const void *const opaque_data)
539 decode_nlattr(tcp, addr, len, rtnl_ifla_port_attrs,
540 "IFLA_VF_PORT_???", ARRSZ_PAIR(ifla_port_nla_decoders),
546 static const nla_decoder_t ifla_vf_port_nla_decoders[] = {
547 [IFLA_VF_PORT] = decode_ifla_port
551 decode_ifla_vf_ports(struct tcb *const tcp,
552 const kernel_ulong_t addr,
553 const unsigned int len,
554 const void *const opaque_data)
556 decode_nlattr(tcp, addr, len, rtnl_ifla_vf_port_attrs,
557 "IFLA_VF_PORT_???", ARRSZ_PAIR(ifla_vf_port_nla_decoders),
564 decode_ifla_xdp_flags(struct tcb *const tcp,
565 const kernel_ulong_t addr,
566 const unsigned int len,
567 const void *const opaque_data)
571 if (len < sizeof(flags))
573 else if (!umove_or_printaddr(tcp, addr, &flags))
574 printflags(xdp_flags, flags, "XDP_FLAGS_???");
580 decode_ifla_xdp_attached(struct tcb *const tcp,
581 const kernel_ulong_t addr,
582 const unsigned int len,
583 const void *const opaque_data)
585 const struct decode_nla_xlat_opts opts = {
586 .xlat = rtnl_ifla_xdp_attached_mode,
587 .xlat_size = ARRAY_SIZE(rtnl_ifla_xdp_attached_mode),
589 .dflt = "XDP_ATTACHED_???",
593 return decode_nla_xval(tcp, addr, len, &opts);
596 static const nla_decoder_t ifla_xdp_nla_decoders[] = {
597 [IFLA_XDP_FD] = decode_nla_fd,
598 [IFLA_XDP_ATTACHED] = decode_ifla_xdp_attached,
599 [IFLA_XDP_FLAGS] = decode_ifla_xdp_flags,
600 [IFLA_XDP_PROG_ID] = decode_nla_u32,
601 [IFLA_XDP_DRV_PROG_ID] = decode_nla_u32,
602 [IFLA_XDP_SKB_PROG_ID] = decode_nla_u32,
603 [IFLA_XDP_HW_PROG_ID] = decode_nla_u32,
607 decode_ifla_xdp(struct tcb *const tcp,
608 const kernel_ulong_t addr,
609 const unsigned int len,
610 const void *const opaque_data)
612 decode_nlattr(tcp, addr, len, rtnl_ifla_xdp_attrs,
613 "IFLA_XDP_???", ARRSZ_PAIR(ifla_xdp_nla_decoders),
620 decode_ifla_event(struct tcb *const tcp,
621 const kernel_ulong_t addr,
622 const unsigned int len,
623 const void *const opaque_data)
627 if (len < sizeof(ev))
629 else if (!umove_or_printaddr(tcp, addr, &ev))
630 printxval(rtnl_ifla_events, ev, "IFLA_EVENT_???");
637 decode_ifla_inet_conf(struct tcb *const tcp,
638 const kernel_ulong_t addr,
639 const unsigned int len,
640 const void *const opaque_data)
643 size_t cnt = len / sizeof(elem);
648 print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
649 tfetch_mem, print_int32_array_member, NULL,
650 PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
651 | XLAT_STYLE_FMT_D, ARRSZ_PAIR(inet_devconf_indices),
657 static const nla_decoder_t ifla_inet_nla_decoders[] = {
658 [IFLA_INET_CONF] = decode_ifla_inet_conf,
662 decode_ifla_inet6_flags(struct tcb *const tcp,
663 const kernel_ulong_t addr,
664 const unsigned int len,
665 const void *const opaque_data)
667 const struct decode_nla_xlat_opts opts = {
668 ARRSZ_PAIR(inet6_if_flags), "IF_???",
672 return decode_nla_flags(tcp, addr, len, &opts);
676 decode_ifla_inet6_conf(struct tcb *const tcp,
677 const kernel_ulong_t addr,
678 const unsigned int len,
679 const void *const opaque_data)
682 size_t cnt = len / sizeof(elem);
687 print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
688 tfetch_mem, print_int32_array_member, NULL,
689 PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
690 | XLAT_STYLE_FMT_D, ARRSZ_PAIR(inet6_devconf_indices),
697 decode_ifla_inet6_stats(struct tcb *const tcp,
698 const kernel_ulong_t addr,
699 const unsigned int len,
700 const void *const opaque_data)
703 size_t cnt = len / sizeof(elem);
708 print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
709 tfetch_mem, print_uint64_array_member, NULL,
710 PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
711 | XLAT_STYLE_FMT_U, ARRSZ_PAIR(snmp_ip_stats),
718 decode_ifla_inet6_cacheinfo(struct tcb *const tcp,
719 const kernel_ulong_t addr,
720 const unsigned int len,
721 const void *const opaque_data)
724 uint32_t max_reasm_len;
726 uint32_t reachable_time;
727 uint32_t retrans_time;
730 if (len < sizeof(ci))
732 else if (!umove_or_printaddr(tcp, addr, &ci)) {
733 PRINT_FIELD_U("{", ci, max_reasm_len);
734 PRINT_FIELD_U(", ", ci, tstamp);
735 PRINT_FIELD_U(", ", ci, reachable_time);
736 PRINT_FIELD_U(", ", ci, retrans_time);
744 decode_ifla_inet6_icmp6_stats(struct tcb *const tcp,
745 const kernel_ulong_t addr,
746 const unsigned int len,
747 const void *const opaque_data)
750 size_t cnt = len / sizeof(elem);
755 print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
756 tfetch_mem, print_uint64_array_member, NULL,
757 PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
758 | XLAT_STYLE_FMT_U, ARRSZ_PAIR(snmp_icmp6_stats),
765 decode_ifla_inet6_token(struct tcb *const tcp,
766 const kernel_ulong_t addr,
767 const unsigned int len,
768 const void *const opaque_data)
772 if (len < sizeof(in6))
774 else if (!umove_or_printaddr(tcp, addr, &in6))
775 print_inet_addr(AF_INET6, &in6, sizeof(in6), NULL);
781 decode_ifla_inet6_agm(struct tcb *const tcp,
782 const kernel_ulong_t addr,
783 const unsigned int len,
784 const void *const opaque_data)
786 const struct decode_nla_xlat_opts opts = {
787 ARRSZ_PAIR(in6_addr_gen_mode), "IN6_ADDR_GEN_MODE_???",
792 return decode_nla_xval(tcp, addr, len, &opts);
795 static const nla_decoder_t ifla_inet6_nla_decoders[] = {
796 [IFLA_INET6_FLAGS] = decode_ifla_inet6_flags,
797 [IFLA_INET6_CONF] = decode_ifla_inet6_conf,
798 [IFLA_INET6_STATS] = decode_ifla_inet6_stats,
799 [IFLA_INET6_MCAST] = NULL, /* unused */
800 [IFLA_INET6_CACHEINFO] = decode_ifla_inet6_cacheinfo,
801 [IFLA_INET6_ICMP6STATS] = decode_ifla_inet6_icmp6_stats,
802 [IFLA_INET6_TOKEN] = decode_ifla_inet6_token,
803 [IFLA_INET6_ADDR_GEN_MODE] = decode_ifla_inet6_agm,
806 static const struct nla_decoder_table_desc {
807 const struct xlat *xlat;
809 const nla_decoder_t *table;
811 } ifla_af_spec_protos[] = {
813 rtnl_ifla_af_spec_inet_attrs, "IFLA_INET_???",
814 ARRSZ_PAIR(ifla_inet_nla_decoders),
817 rtnl_ifla_af_spec_inet6_attrs, "IFLA_INET6_???",
818 ARRSZ_PAIR(ifla_inet6_nla_decoders),
823 decode_ifla_af(struct tcb *const tcp,
824 const kernel_ulong_t addr,
825 const unsigned int len,
826 const void *const opaque_data)
828 uintptr_t proto = (uintptr_t) opaque_data;
829 const struct nla_decoder_table_desc *desc
830 = proto < ARRAY_SIZE(ifla_af_spec_protos)
831 ? ifla_af_spec_protos + proto : NULL;
833 if (!desc || !desc->table)
836 decode_nlattr(tcp, addr, len,
837 desc->xlat, desc->dflt, desc->table, desc->size, NULL);
843 decode_ifla_af_spec(struct tcb *const tcp,
844 const kernel_ulong_t addr,
845 const unsigned int len,
846 const void *const opaque_data)
848 nla_decoder_t af_spec_decoder = &decode_ifla_af;
850 decode_nlattr(tcp, addr, len, addrfams, "AF_???",
851 &af_spec_decoder, 0, opaque_data);
856 static const nla_decoder_t ifinfomsg_nla_decoders[] = {
857 [IFLA_ADDRESS] = NULL, /* unimplemented */
858 [IFLA_BROADCAST] = NULL, /* unimplemented */
859 [IFLA_IFNAME] = decode_nla_str,
860 [IFLA_MTU] = decode_nla_u32,
861 [IFLA_LINK] = decode_nla_u32,
862 [IFLA_QDISC] = decode_nla_str,
863 [IFLA_STATS] = decode_rtnl_link_stats,
864 [IFLA_COST] = NULL, /* unused */
865 [IFLA_PRIORITY] = NULL, /* unused */
866 [IFLA_MASTER] = decode_nla_u32,
867 [IFLA_WIRELESS] = NULL, /* unimplemented */
868 [IFLA_PROTINFO] = decode_ifla_protinfo,
869 [IFLA_TXQLEN] = decode_nla_u32,
870 [IFLA_MAP] = decode_rtnl_link_ifmap,
871 [IFLA_WEIGHT] = decode_nla_u32,
872 [IFLA_OPERSTATE] = decode_nla_u8,
873 [IFLA_LINKMODE] = decode_nla_u8,
874 [IFLA_LINKINFO] = decode_ifla_linkinfo,
875 [IFLA_NET_NS_PID] = decode_nla_u32,
876 [IFLA_IFALIAS] = decode_nla_str,
877 [IFLA_NUM_VF] = decode_nla_u32,
878 [IFLA_VFINFO_LIST] = NULL, /* unimplemented */
879 [IFLA_STATS64] = decode_rtnl_link_stats64,
880 [IFLA_VF_PORTS] = decode_ifla_vf_ports,
881 [IFLA_PORT_SELF] = decode_ifla_port,
882 [IFLA_AF_SPEC] = decode_ifla_af_spec,
883 [IFLA_GROUP] = decode_nla_u32,
884 [IFLA_NET_NS_FD] = decode_nla_fd,
885 [IFLA_EXT_MASK] = decode_nla_u32,
886 [IFLA_PROMISCUITY] = decode_nla_u32,
887 [IFLA_NUM_TX_QUEUES] = decode_nla_u32,
888 [IFLA_NUM_RX_QUEUES] = decode_nla_u32,
889 [IFLA_CARRIER] = decode_nla_u8,
890 [IFLA_PHYS_PORT_ID] = NULL, /* default parser */
891 [IFLA_CARRIER_CHANGES] = decode_nla_u32,
892 [IFLA_PHYS_SWITCH_ID] = NULL, /* default parser */
893 [IFLA_LINK_NETNSID] = decode_nla_s32,
894 [IFLA_PHYS_PORT_NAME] = decode_nla_str,
895 [IFLA_PROTO_DOWN] = decode_nla_u8,
896 [IFLA_GSO_MAX_SEGS] = decode_nla_u32,
897 [IFLA_GSO_MAX_SIZE] = decode_nla_u32,
899 [IFLA_XDP] = decode_ifla_xdp,
900 [IFLA_EVENT] = decode_ifla_event,
901 [IFLA_NEW_NETNSID] = decode_nla_s32,
902 [IFLA_IF_NETNSID] = decode_nla_s32,
903 [IFLA_CARRIER_UP_COUNT] = decode_nla_u32,
904 [IFLA_CARRIER_DOWN_COUNT] = decode_nla_u32,
905 [IFLA_NEW_IFINDEX] = decode_nla_ifindex,
908 DECL_NETLINK_ROUTE_DECODER(decode_ifinfomsg)
910 struct ifinfomsg ifinfo = { .ifi_family = family };
911 size_t offset = sizeof(ifinfo.ifi_family);
912 bool decode_nla = false;
914 PRINT_FIELD_XVAL("{", ifinfo, ifi_family, addrfams, "AF_???");
917 if (len >= sizeof(ifinfo)) {
918 if (!umoven_or_printaddr(tcp, addr + offset,
919 sizeof(ifinfo) - offset,
920 (char *) &ifinfo + offset)) {
921 PRINT_FIELD_XVAL_SORTED_SIZED("", ifinfo, ifi_type,
923 arp_hardware_types_size,
925 PRINT_FIELD_IFINDEX(", ", ifinfo, ifi_index);
926 PRINT_FIELD_FLAGS(", ", ifinfo, ifi_flags,
927 iffflags, "IFF_???");
928 PRINT_FIELD_X(", ", ifinfo, ifi_change);
935 offset = NLMSG_ALIGN(sizeof(ifinfo));
936 if (decode_nla && len > offset) {
938 decode_nlattr(tcp, addr + offset, len - offset,
939 rtnl_link_attrs, "IFLA_???",
940 ARRSZ_PAIR(ifinfomsg_nla_decoders), NULL);