177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes/*
277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes * Copyright (c) 2016-2018 The strace developers.
577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * All rights reserved.
677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes *
777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * Redistribution and use in source and binary forms, with or without
877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * modification, are permitted provided that the following conditions
977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * are met:
1077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * 1. Redistributions of source code must retain the above copyright
1177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes *    notice, this list of conditions and the following disclaimer.
1277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * 2. Redistributions in binary form must reproduce the above copyright
1377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes *    notice, this list of conditions and the following disclaimer in the
1477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes *    documentation and/or other materials provided with the distribution.
1577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * 3. The name of the author may not be used to endorse or promote products
1677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes *    derived from this software without specific prior written permission.
1777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes *
1877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes */
2977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
3077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include "defs.h"
3177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include "netlink_route.h"
3277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include "nlattr.h"
3377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include "print_fields.h"
3477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
3577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include "netlink.h"
3677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#ifdef HAVE_LINUX_IF_LINK_H
3777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes# include <linux/if_link.h>
3877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#endif
3977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include <linux/rtnetlink.h>
4077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
4177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include "xlat/rtnl_ifla_brport_attrs.h"
4277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include "xlat/rtnl_ifla_info_attrs.h"
4377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include "xlat/rtnl_ifla_port_attrs.h"
4477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include "xlat/rtnl_ifla_vf_port_attrs.h"
4577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include "xlat/rtnl_ifla_xdp_attrs.h"
4677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include "xlat/rtnl_link_attrs.h"
4777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#include "xlat/xdp_flags.h"
4877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
4977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic bool
5077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesdecode_rtnl_link_stats(struct tcb *const tcp,
5177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		       const kernel_ulong_t addr,
5277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		       const unsigned int len,
5377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		       const void *const opaque_data)
5477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes{
5577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	struct rtnl_link_stats st;
5677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	const unsigned int min_size =
5777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		offsetofend(struct rtnl_link_stats, tx_compressed);
5877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	const unsigned int def_size = sizeof(st);
5977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	const unsigned int size =
6077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		(len >= def_size) ? def_size :
6177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes				    ((len == min_size) ? min_size : 0);
6277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
6377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	if (!size)
6477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		return false;
6577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
6677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	if (!umoven_or_printaddr(tcp, addr, size, &st)) {
6777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U("{", st, rx_packets);
6877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_packets);
6977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_bytes);
7077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_bytes);
7177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_errors);
7277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_errors);
7377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_dropped);
7477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_dropped);
7577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, multicast);
7677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, collisions);
7777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
7877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_length_errors);
7977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_over_errors);
8077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_crc_errors);
8177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_frame_errors);
8277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_fifo_errors);
8377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_missed_errors);
8477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
8577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_aborted_errors);
8677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_carrier_errors);
8777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_fifo_errors);
8877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
8977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_window_errors);
9077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
9177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_compressed);
9277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_compressed);
9377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
9477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		if (len >= def_size)
9577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			PRINT_FIELD_U(", ", st, rx_nohandler);
9677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#endif
9777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		tprints("}");
9877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	}
9977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
10077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return true;
10177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes}
10277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
10377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic bool
10477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesdecode_ifla_bridge_id(struct tcb *const tcp,
10577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      const kernel_ulong_t addr,
10677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      const unsigned int len,
10777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      const void *const opaque_data)
10877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes{
10977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#ifdef HAVE_STRUCT_IFLA_BRIDGE_ID
11077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	struct ifla_bridge_id id;
11177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
11277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	if (len < sizeof(id))
11377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		return false;
11477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	else if (!umove_or_printaddr(tcp, addr, &id)) {
11577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		tprintf("{prio=[%u, %u], addr=%02x:%02x:%02x:%02x:%02x:%02x}",
11677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			id.prio[0], id.prio[1],
11777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			id.addr[0], id.addr[1], id.addr[2],
11877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			id.addr[3], id.addr[4], id.addr[5]);
11977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	}
12077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
12177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return true;
12277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#else
12377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return false;
12477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#endif
12577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes}
12677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
12777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic const nla_decoder_t ifla_brport_nla_decoders[] = {
12877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_STATE]			= decode_nla_u8,
12977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_PRIORITY]			= decode_nla_u16,
13077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_COST]			= decode_nla_u32,
13177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_MODE]			= decode_nla_u8,
13277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_GUARD]			= decode_nla_u8,
13377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_PROTECT]			= decode_nla_u8,
13477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_FAST_LEAVE]		= decode_nla_u8,
13577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_LEARNING]			= decode_nla_u8,
13677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_UNICAST_FLOOD]		= decode_nla_u8,
13777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_PROXYARP]			= decode_nla_u8,
13877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_LEARNING_SYNC]		= decode_nla_u8,
13977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_PROXYARP_WIFI]		= decode_nla_u8,
14077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_ROOT_ID]			= decode_ifla_bridge_id,
14177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_BRIDGE_ID]			= decode_ifla_bridge_id,
14277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_DESIGNATED_PORT]		= decode_nla_u16,
14377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_DESIGNATED_COST]		= decode_nla_u16,
14477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_ID]			= decode_nla_u16,
14577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_NO]			= decode_nla_u16,
14677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_TOPOLOGY_CHANGE_ACK]	= decode_nla_u8,
14777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_CONFIG_PENDING]		= decode_nla_u8,
14877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_MESSAGE_AGE_TIMER]		= decode_nla_u64,
14977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_FORWARD_DELAY_TIMER]	= decode_nla_u64,
15077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_HOLD_TIMER]		= decode_nla_u64,
15177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_FLUSH]			= NULL,
15277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_MULTICAST_ROUTER]		= decode_nla_u8,
15377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_PAD]			= NULL,
15477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_MCAST_FLOOD]		= decode_nla_u8,
15577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_MCAST_TO_UCAST]		= decode_nla_u8,
15677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_VLAN_TUNNEL]		= decode_nla_u8,
15777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BRPORT_BCAST_FLOOD]		= decode_nla_u8
15877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes};
15977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
16077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic bool
16177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesdecode_ifla_protinfo(struct tcb *const tcp,
16277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		     const kernel_ulong_t addr,
16377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		     const unsigned int len,
16477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		     const void *const opaque_data)
16577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes{
16677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	decode_nlattr(tcp, addr, len, rtnl_ifla_brport_attrs,
16777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      "IFLA_BRPORT_???", ifla_brport_nla_decoders,
16877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      ARRAY_SIZE(ifla_brport_nla_decoders), opaque_data);
16977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
17077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return true;
17177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes}
17277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
17377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic bool
17477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesdecode_rtnl_link_ifmap(struct tcb *const tcp,
17577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		       const kernel_ulong_t addr,
17677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		       const unsigned int len,
17777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		       const void *const opaque_data)
17877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes{
17977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	struct rtnl_link_ifmap map;
18077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	const unsigned int sizeof_ifmap =
18177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		offsetofend(struct rtnl_link_ifmap, port);
18277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
18377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	if (len < sizeof_ifmap)
18477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		return false;
18577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	else if (!umoven_or_printaddr(tcp, addr, sizeof_ifmap, &map)) {
18677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_X("{", map, mem_start);
18777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_X(", ", map, mem_end);
18877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_X(", ", map, base_addr);
18977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", map, irq);
19077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", map, dma);
19177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", map, port);
19277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		tprints("}");
19377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	}
19477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
19577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return true;
19677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes}
19777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
19877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic const nla_decoder_t ifla_linkinfo_nla_decoders[] = {
19977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_INFO_KIND]	= decode_nla_str,
20077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_INFO_DATA]	= NULL, /* unimplemented */
20177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_INFO_XSTATS]	= NULL, /* unimplemented */
20277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_INFO_SLAVE_KIND]	= decode_nla_str,
20377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_INFO_SLAVE_DATA]	= NULL, /* unimplemented */
20477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes};
20577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
20677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic bool
20777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesdecode_ifla_linkinfo(struct tcb *const tcp,
20877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		     const kernel_ulong_t addr,
20977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		     const unsigned int len,
21077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		     const void *const opaque_data)
21177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes{
21277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	decode_nlattr(tcp, addr, len, rtnl_ifla_info_attrs,
21377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      "IFLA_INFO_???", ifla_linkinfo_nla_decoders,
21477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      ARRAY_SIZE(ifla_linkinfo_nla_decoders), opaque_data);
21577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
21677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return true;
21777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes}
21877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
21977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic bool
22077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesdecode_rtnl_link_stats64(struct tcb *const tcp,
22177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		         const kernel_ulong_t addr,
22277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			 const unsigned int len,
22377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			 const void *const opaque_data)
22477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes{
22577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#ifdef HAVE_STRUCT_RTNL_LINK_STATS64
22677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	struct rtnl_link_stats64 st;
22777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	const unsigned int min_size =
22877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		offsetofend(struct rtnl_link_stats64, tx_compressed);
22977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	const unsigned int def_size = sizeof(st);
23077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	const unsigned int size =
23177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		(len >= def_size) ? def_size :
23277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes				    ((len == min_size) ? min_size : 0);
23377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
23477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	if (!size)
23577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		return false;
23677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
23777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	if (!umoven_or_printaddr(tcp, addr, size, &st)) {
23877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U("{", st, rx_packets);
23977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_packets);
24077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_bytes);
24177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_bytes);
24277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_errors);
24377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_errors);
24477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_dropped);
24577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_dropped);
24677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, multicast);
24777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, collisions);
24877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
24977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_length_errors);
25077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_over_errors);
25177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_crc_errors);
25277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_frame_errors);
25377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_fifo_errors);
25477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_missed_errors);
25577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
25677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_aborted_errors);
25777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_carrier_errors);
25877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_fifo_errors);
25977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
26077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_window_errors);
26177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
26277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, rx_compressed);
26377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", st, tx_compressed);
26477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
26577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		if (len >= def_size)
26677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			PRINT_FIELD_U(", ", st, rx_nohandler);
26777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#endif
26877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		tprints("}");
26977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	}
27077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
27177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return true;
27277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#else
27377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return false;
27477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#endif
27577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes}
27677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
27777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic bool
27877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesdecode_ifla_port_vsi(struct tcb *const tcp,
27977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		     const kernel_ulong_t addr,
28077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		     const unsigned int len,
28177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		     const void *const opaque_data)
28277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes{
28377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#ifdef HAVE_STRUCT_IFLA_PORT_VSI
28477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	struct ifla_port_vsi vsi;
28577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
28677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	if (len < sizeof(vsi))
28777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		return false;
28877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	else if (!umove_or_printaddr(tcp, addr, &vsi)) {
28977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U("{", vsi, vsi_mgr_id);
29077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_STRING(", ", vsi, vsi_type_id,
29177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes				   sizeof(vsi.vsi_type_id), QUOTE_FORCE_HEX);
29277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		PRINT_FIELD_U(", ", vsi, vsi_type_version);
29377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		tprints("}");
29477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	}
29577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
29677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return true;
29777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#else
29877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return false;
29977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes#endif
30077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes}
30177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
30277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic const nla_decoder_t ifla_port_nla_decoders[] = {
30377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PORT_VF]			= decode_nla_u32,
30477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PORT_PROFILE]		= decode_nla_str,
30577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PORT_VSI_TYPE]		= decode_ifla_port_vsi,
30677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PORT_INSTANCE_UUID]	= NULL, /* default parser */
30777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PORT_HOST_UUID]		= NULL, /* default parser */
30877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PORT_REQUEST]		= decode_nla_u8,
30977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PORT_RESPONSE]		= decode_nla_u16
31077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes};
31177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
31277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic bool
31377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesdecode_ifla_port(struct tcb *const tcp,
31477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		 const kernel_ulong_t addr,
31577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		 const unsigned int len,
31677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		 const void *const opaque_data)
31777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes{
31877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	decode_nlattr(tcp, addr, len, rtnl_ifla_port_attrs,
31977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      "IFLA_VF_PORT_???", ifla_port_nla_decoders,
32077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      ARRAY_SIZE(ifla_port_nla_decoders), opaque_data);
32177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
32277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return true;
32377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes}
32477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
32577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic const nla_decoder_t ifla_vf_port_nla_decoders[] = {
32677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_VF_PORT] = decode_ifla_port
32777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes};
32877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
32977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic bool
33077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesdecode_ifla_vf_ports(struct tcb *const tcp,
33177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		     const kernel_ulong_t addr,
33277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		     const unsigned int len,
33377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		     const void *const opaque_data)
33477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes{
33577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	decode_nlattr(tcp, addr, len, rtnl_ifla_vf_port_attrs,
33677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      "IFLA_VF_PORT_???", ifla_vf_port_nla_decoders,
33777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      ARRAY_SIZE(ifla_vf_port_nla_decoders), opaque_data);
33877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
33977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return true;
34077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes}
34177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
34277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic bool
34377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesdecode_ifla_xdp_flags(struct tcb *const tcp,
34477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      const kernel_ulong_t addr,
34577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      const unsigned int len,
34677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      const void *const opaque_data)
34777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes{
34877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	uint32_t flags;
34977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
35077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	if (len < sizeof(flags))
35177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		return false;
35277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	else if (!umove_or_printaddr(tcp, addr, &flags))
35377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		printflags(xdp_flags, flags, "XDP_FLAGS_???");
35477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
35577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return true;
35677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes}
35777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
35877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic const nla_decoder_t ifla_xdp_nla_decoders[] = {
359b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes	[IFLA_XDP_FD]		= decode_nla_fd,
36077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_XDP_ATTACHED]	= decode_nla_u8,
36177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_XDP_FLAGS]	= decode_ifla_xdp_flags,
36277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_XDP_PROG_ID]	= decode_nla_u32
36377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes};
36477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
36577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic bool
36677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesdecode_ifla_xdp(struct tcb *const tcp,
36777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		const kernel_ulong_t addr,
36877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		const unsigned int len,
36977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		const void *const opaque_data)
37077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes{
37177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	decode_nlattr(tcp, addr, len, rtnl_ifla_xdp_attrs,
37277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      "IFLA_XDP_???", ifla_xdp_nla_decoders,
37377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		      ARRAY_SIZE(ifla_xdp_nla_decoders), opaque_data);
37477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
37577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	return true;
37677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes}
37777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
37877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughesstatic const nla_decoder_t ifinfomsg_nla_decoders[] = {
37977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_ADDRESS]		= NULL, /* unimplemented */
38077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_BROADCAST]	= NULL, /* unimplemented */
38177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_IFNAME]		= decode_nla_str,
38277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_MTU]		= decode_nla_u32,
38377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_LINK]		= decode_nla_u32,
38477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_QDISC]		= decode_nla_str,
38577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_STATS]		= decode_rtnl_link_stats,
38677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_COST]		= NULL, /* unused */
38777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PRIORITY]		= NULL, /* unused */
38877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_MASTER]		= decode_nla_u32,
38977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_WIRELESS]		= NULL, /* unimplemented */
39077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PROTINFO]		= decode_ifla_protinfo,
39177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_TXQLEN]		= decode_nla_u32,
39277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_MAP]		= decode_rtnl_link_ifmap,
39377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_WEIGHT]		= decode_nla_u32,
39477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_OPERSTATE]	= decode_nla_u8,
39577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_LINKMODE]		= decode_nla_u8,
39677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_LINKINFO]		= decode_ifla_linkinfo,
39777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_NET_NS_PID]	= decode_nla_u32,
39877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_IFALIAS]		= decode_nla_str,
39977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_NUM_VF]		= decode_nla_u32,
40077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_VFINFO_LIST]	= NULL, /* unimplemented */
40177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_STATS64]		= decode_rtnl_link_stats64,
40277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_VF_PORTS]		= decode_ifla_vf_ports,
40377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PORT_SELF]	= decode_ifla_port,
40477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_AF_SPEC]		= NULL, /* unimplemented */
40577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_GROUP]		= decode_nla_u32,
406b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes	[IFLA_NET_NS_FD]	= decode_nla_fd,
40777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_EXT_MASK]		= decode_nla_u32,
40877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PROMISCUITY]	= decode_nla_u32,
40977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_NUM_TX_QUEUES]	= decode_nla_u32,
41077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_NUM_RX_QUEUES]	= decode_nla_u32,
41177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_CARRIER]		= decode_nla_u8,
41277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PHYS_PORT_ID]	= NULL, /* default parser */
41377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_CARRIER_CHANGES]	= decode_nla_u32,
41477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PHYS_SWITCH_ID]	= NULL, /* default parser */
41577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_LINK_NETNSID]	= decode_nla_s32,
41677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PHYS_PORT_NAME]	= decode_nla_str,
41777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PROTO_DOWN]	= decode_nla_u8,
41877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_GSO_MAX_SEGS]	= decode_nla_u32,
41977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_GSO_MAX_SIZE]	= decode_nla_u32,
42077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_PAD]		= NULL,
42177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_XDP]		= decode_ifla_xdp,
42277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	[IFLA_EVENT]		= decode_nla_u32
42377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes};
42477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
42577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott HughesDECL_NETLINK_ROUTE_DECODER(decode_ifinfomsg)
42677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes{
42777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	struct ifinfomsg ifinfo = { .ifi_family = family };
42877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	size_t offset = sizeof(ifinfo.ifi_family);
42977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	bool decode_nla = false;
43077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
43177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	PRINT_FIELD_XVAL("{", ifinfo, ifi_family, addrfams, "AF_???");
43277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
43377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	tprints(", ");
43477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	if (len >= sizeof(ifinfo)) {
43577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		if (!umoven_or_printaddr(tcp, addr + offset,
43677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes					 sizeof(ifinfo) - offset,
437b755614143ce6aab5265ed32c1bb6c8f748e7898Elliott Hughes					 (char *) &ifinfo + offset)) {
43877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			PRINT_FIELD_XVAL("", ifinfo, ifi_type,
43977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes					 arp_hardware_types, "ARPHRD_???");
44077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			PRINT_FIELD_IFINDEX(", ", ifinfo, ifi_index);
44177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			PRINT_FIELD_FLAGS(", ", ifinfo, ifi_flags,
44277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes					  iffflags, "IFF_???");
44377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			PRINT_FIELD_X(", ", ifinfo, ifi_change);
44477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			decode_nla = true;
44577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		}
44677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	} else
44777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		tprints("...");
44877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	tprints("}");
44977c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes
45077c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	offset = NLMSG_ALIGN(sizeof(ifinfo));
45177c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	if (decode_nla && len > offset) {
45277c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		tprints(", ");
45377c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes		decode_nlattr(tcp, addr + offset, len - offset,
45477c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			      rtnl_link_attrs, "IFLA_???",
45577c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			      ifinfomsg_nla_decoders,
45677c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes			      ARRAY_SIZE(ifinfomsg_nla_decoders), NULL);
45777c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes	}
45877c3ff8e0644f1e120e4b2ebc7222150b0446f3bElliott Hughes}
459