2 * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
3 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
4 * Copyright (c) 2016-2017 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"
36 #ifdef HAVE_LINUX_IF_LINK_H
37 # include <linux/if_link.h>
39 #include <linux/rtnetlink.h>
41 #include "xlat/rtnl_ifla_brport_attrs.h"
42 #include "xlat/rtnl_ifla_info_attrs.h"
43 #include "xlat/rtnl_ifla_port_attrs.h"
44 #include "xlat/rtnl_ifla_vf_port_attrs.h"
45 #include "xlat/rtnl_ifla_xdp_attrs.h"
46 #include "xlat/rtnl_link_attrs.h"
47 #include "xlat/xdp_flags.h"
50 decode_rtnl_link_stats(struct tcb *const tcp,
51 const kernel_ulong_t addr,
52 const unsigned int len,
53 const void *const opaque_data)
55 struct rtnl_link_stats st;
56 const unsigned int min_size =
57 offsetofend(struct rtnl_link_stats, tx_compressed);
58 const unsigned int def_size = sizeof(st);
59 const unsigned int size =
60 (len >= def_size) ? def_size :
61 ((len == min_size) ? min_size : 0);
66 if (!umoven_or_printaddr(tcp, addr, size, &st)) {
67 PRINT_FIELD_U("{", st, rx_packets);
68 PRINT_FIELD_U(", ", st, tx_packets);
69 PRINT_FIELD_U(", ", st, rx_bytes);
70 PRINT_FIELD_U(", ", st, tx_bytes);
71 PRINT_FIELD_U(", ", st, rx_errors);
72 PRINT_FIELD_U(", ", st, tx_errors);
73 PRINT_FIELD_U(", ", st, rx_dropped);
74 PRINT_FIELD_U(", ", st, tx_dropped);
75 PRINT_FIELD_U(", ", st, multicast);
76 PRINT_FIELD_U(", ", st, collisions);
78 PRINT_FIELD_U(", ", st, rx_length_errors);
79 PRINT_FIELD_U(", ", st, rx_over_errors);
80 PRINT_FIELD_U(", ", st, rx_crc_errors);
81 PRINT_FIELD_U(", ", st, rx_frame_errors);
82 PRINT_FIELD_U(", ", st, rx_fifo_errors);
83 PRINT_FIELD_U(", ", st, rx_missed_errors);
85 PRINT_FIELD_U(", ", st, tx_aborted_errors);
86 PRINT_FIELD_U(", ", st, tx_carrier_errors);
87 PRINT_FIELD_U(", ", st, tx_fifo_errors);
88 PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
89 PRINT_FIELD_U(", ", st, tx_window_errors);
91 PRINT_FIELD_U(", ", st, rx_compressed);
92 PRINT_FIELD_U(", ", st, tx_compressed);
93 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
95 PRINT_FIELD_U(", ", st, rx_nohandler);
104 decode_ifla_bridge_id(struct tcb *const tcp,
105 const kernel_ulong_t addr,
106 const unsigned int len,
107 const void *const opaque_data)
109 #ifdef HAVE_STRUCT_IFLA_BRIDGE_ID
110 struct ifla_bridge_id id;
112 if (len < sizeof(id))
114 else if (!umove_or_printaddr(tcp, addr, &id)) {
115 tprintf("{prio=[%u, %u], addr=%02x:%02x:%02x:%02x:%02x:%02x}",
116 id.prio[0], id.prio[1],
117 id.addr[0], id.addr[1], id.addr[2],
118 id.addr[3], id.addr[4], id.addr[5]);
127 static const nla_decoder_t ifla_brport_nla_decoders[] = {
128 [IFLA_BRPORT_STATE] = decode_nla_u8,
129 [IFLA_BRPORT_PRIORITY] = decode_nla_u16,
130 [IFLA_BRPORT_COST] = decode_nla_u32,
131 [IFLA_BRPORT_MODE] = decode_nla_u8,
132 [IFLA_BRPORT_GUARD] = decode_nla_u8,
133 [IFLA_BRPORT_PROTECT] = decode_nla_u8,
134 [IFLA_BRPORT_FAST_LEAVE] = decode_nla_u8,
135 [IFLA_BRPORT_LEARNING] = decode_nla_u8,
136 [IFLA_BRPORT_UNICAST_FLOOD] = decode_nla_u8,
137 [IFLA_BRPORT_PROXYARP] = decode_nla_u8,
138 [IFLA_BRPORT_LEARNING_SYNC] = decode_nla_u8,
139 [IFLA_BRPORT_PROXYARP_WIFI] = decode_nla_u8,
140 [IFLA_BRPORT_ROOT_ID] = decode_ifla_bridge_id,
141 [IFLA_BRPORT_BRIDGE_ID] = decode_ifla_bridge_id,
142 [IFLA_BRPORT_DESIGNATED_PORT] = decode_nla_u16,
143 [IFLA_BRPORT_DESIGNATED_COST] = decode_nla_u16,
144 [IFLA_BRPORT_ID] = decode_nla_u16,
145 [IFLA_BRPORT_NO] = decode_nla_u16,
146 [IFLA_BRPORT_TOPOLOGY_CHANGE_ACK] = decode_nla_u8,
147 [IFLA_BRPORT_CONFIG_PENDING] = decode_nla_u8,
148 [IFLA_BRPORT_MESSAGE_AGE_TIMER] = decode_nla_u64,
149 [IFLA_BRPORT_FORWARD_DELAY_TIMER] = decode_nla_u64,
150 [IFLA_BRPORT_HOLD_TIMER] = decode_nla_u64,
151 [IFLA_BRPORT_FLUSH] = NULL,
152 [IFLA_BRPORT_MULTICAST_ROUTER] = decode_nla_u8,
153 [IFLA_BRPORT_PAD] = NULL,
154 [IFLA_BRPORT_MCAST_FLOOD] = decode_nla_u8,
155 [IFLA_BRPORT_MCAST_TO_UCAST] = decode_nla_u8,
156 [IFLA_BRPORT_VLAN_TUNNEL] = decode_nla_u8,
157 [IFLA_BRPORT_BCAST_FLOOD] = decode_nla_u8
161 decode_ifla_protinfo(struct tcb *const tcp,
162 const kernel_ulong_t addr,
163 const unsigned int len,
164 const void *const opaque_data)
166 decode_nlattr(tcp, addr, len, rtnl_ifla_brport_attrs,
167 "IFLA_BRPORT_???", ifla_brport_nla_decoders,
168 ARRAY_SIZE(ifla_brport_nla_decoders), opaque_data);
174 decode_rtnl_link_ifmap(struct tcb *const tcp,
175 const kernel_ulong_t addr,
176 const unsigned int len,
177 const void *const opaque_data)
179 struct rtnl_link_ifmap map;
180 const unsigned int sizeof_ifmap =
181 offsetofend(struct rtnl_link_ifmap, port);
183 if (len < sizeof_ifmap)
185 else if (!umoven_or_printaddr(tcp, addr, sizeof_ifmap, &map)) {
186 PRINT_FIELD_X("{", map, mem_start);
187 PRINT_FIELD_X(", ", map, mem_end);
188 PRINT_FIELD_X(", ", map, base_addr);
189 PRINT_FIELD_U(", ", map, irq);
190 PRINT_FIELD_U(", ", map, dma);
191 PRINT_FIELD_U(", ", map, port);
198 static const nla_decoder_t ifla_linkinfo_nla_decoders[] = {
199 [IFLA_INFO_KIND] = decode_nla_str,
200 [IFLA_INFO_DATA] = NULL, /* unimplemented */
201 [IFLA_INFO_XSTATS] = NULL, /* unimplemented */
202 [IFLA_INFO_SLAVE_KIND] = decode_nla_str,
203 [IFLA_INFO_SLAVE_DATA] = NULL, /* unimplemented */
207 decode_ifla_linkinfo(struct tcb *const tcp,
208 const kernel_ulong_t addr,
209 const unsigned int len,
210 const void *const opaque_data)
212 decode_nlattr(tcp, addr, len, rtnl_ifla_info_attrs,
213 "IFLA_INFO_???", ifla_linkinfo_nla_decoders,
214 ARRAY_SIZE(ifla_linkinfo_nla_decoders), opaque_data);
220 decode_rtnl_link_stats64(struct tcb *const tcp,
221 const kernel_ulong_t addr,
222 const unsigned int len,
223 const void *const opaque_data)
225 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64
226 struct rtnl_link_stats64 st;
227 const unsigned int min_size =
228 offsetofend(struct rtnl_link_stats64, tx_compressed);
229 const unsigned int def_size = sizeof(st);
230 const unsigned int size =
231 (len >= def_size) ? def_size :
232 ((len == min_size) ? min_size : 0);
237 if (!umoven_or_printaddr(tcp, addr, size, &st)) {
238 PRINT_FIELD_U("{", st, rx_packets);
239 PRINT_FIELD_U(", ", st, tx_packets);
240 PRINT_FIELD_U(", ", st, rx_bytes);
241 PRINT_FIELD_U(", ", st, tx_bytes);
242 PRINT_FIELD_U(", ", st, rx_errors);
243 PRINT_FIELD_U(", ", st, tx_errors);
244 PRINT_FIELD_U(", ", st, rx_dropped);
245 PRINT_FIELD_U(", ", st, tx_dropped);
246 PRINT_FIELD_U(", ", st, multicast);
247 PRINT_FIELD_U(", ", st, collisions);
249 PRINT_FIELD_U(", ", st, rx_length_errors);
250 PRINT_FIELD_U(", ", st, rx_over_errors);
251 PRINT_FIELD_U(", ", st, rx_crc_errors);
252 PRINT_FIELD_U(", ", st, rx_frame_errors);
253 PRINT_FIELD_U(", ", st, rx_fifo_errors);
254 PRINT_FIELD_U(", ", st, rx_missed_errors);
256 PRINT_FIELD_U(", ", st, tx_aborted_errors);
257 PRINT_FIELD_U(", ", st, tx_carrier_errors);
258 PRINT_FIELD_U(", ", st, tx_fifo_errors);
259 PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
260 PRINT_FIELD_U(", ", st, tx_window_errors);
262 PRINT_FIELD_U(", ", st, rx_compressed);
263 PRINT_FIELD_U(", ", st, tx_compressed);
264 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
266 PRINT_FIELD_U(", ", st, rx_nohandler);
278 decode_ifla_port_vsi(struct tcb *const tcp,
279 const kernel_ulong_t addr,
280 const unsigned int len,
281 const void *const opaque_data)
283 #ifdef HAVE_STRUCT_IFLA_PORT_VSI
284 struct ifla_port_vsi vsi;
286 if (len < sizeof(vsi))
288 else if (!umove_or_printaddr(tcp, addr, &vsi)) {
289 PRINT_FIELD_U("{", vsi, vsi_mgr_id);
290 PRINT_FIELD_STRING(", ", vsi, vsi_type_id,
291 sizeof(vsi.vsi_type_id), QUOTE_FORCE_HEX);
292 PRINT_FIELD_U(", ", vsi, vsi_type_version);
302 static const nla_decoder_t ifla_port_nla_decoders[] = {
303 [IFLA_PORT_VF] = decode_nla_u32,
304 [IFLA_PORT_PROFILE] = decode_nla_str,
305 [IFLA_PORT_VSI_TYPE] = decode_ifla_port_vsi,
306 [IFLA_PORT_INSTANCE_UUID] = NULL, /* default parser */
307 [IFLA_PORT_HOST_UUID] = NULL, /* default parser */
308 [IFLA_PORT_REQUEST] = decode_nla_u8,
309 [IFLA_PORT_RESPONSE] = decode_nla_u16
313 decode_ifla_port(struct tcb *const tcp,
314 const kernel_ulong_t addr,
315 const unsigned int len,
316 const void *const opaque_data)
318 decode_nlattr(tcp, addr, len, rtnl_ifla_port_attrs,
319 "IFLA_VF_PORT_???", ifla_port_nla_decoders,
320 ARRAY_SIZE(ifla_port_nla_decoders), opaque_data);
325 static const nla_decoder_t ifla_vf_port_nla_decoders[] = {
326 [IFLA_VF_PORT] = decode_ifla_port
330 decode_ifla_vf_ports(struct tcb *const tcp,
331 const kernel_ulong_t addr,
332 const unsigned int len,
333 const void *const opaque_data)
335 decode_nlattr(tcp, addr, len, rtnl_ifla_vf_port_attrs,
336 "IFLA_VF_PORT_???", ifla_vf_port_nla_decoders,
337 ARRAY_SIZE(ifla_vf_port_nla_decoders), opaque_data);
343 decode_ifla_xdp_flags(struct tcb *const tcp,
344 const kernel_ulong_t addr,
345 const unsigned int len,
346 const void *const opaque_data)
350 if (len < sizeof(flags))
352 else if (!umove_or_printaddr(tcp, addr, &flags))
353 printflags(xdp_flags, flags, "XDP_FLAGS_???");
358 static const nla_decoder_t ifla_xdp_nla_decoders[] = {
359 [IFLA_XDP_FD] = decode_nla_fd,
360 [IFLA_XDP_ATTACHED] = decode_nla_u8,
361 [IFLA_XDP_FLAGS] = decode_ifla_xdp_flags,
362 [IFLA_XDP_PROG_ID] = decode_nla_u32
366 decode_ifla_xdp(struct tcb *const tcp,
367 const kernel_ulong_t addr,
368 const unsigned int len,
369 const void *const opaque_data)
371 decode_nlattr(tcp, addr, len, rtnl_ifla_xdp_attrs,
372 "IFLA_XDP_???", ifla_xdp_nla_decoders,
373 ARRAY_SIZE(ifla_xdp_nla_decoders), opaque_data);
378 static const nla_decoder_t ifinfomsg_nla_decoders[] = {
379 [IFLA_ADDRESS] = NULL, /* unimplemented */
380 [IFLA_BROADCAST] = NULL, /* unimplemented */
381 [IFLA_IFNAME] = decode_nla_str,
382 [IFLA_MTU] = decode_nla_u32,
383 [IFLA_LINK] = decode_nla_u32,
384 [IFLA_QDISC] = decode_nla_str,
385 [IFLA_STATS] = decode_rtnl_link_stats,
386 [IFLA_COST] = NULL, /* unused */
387 [IFLA_PRIORITY] = NULL, /* unused */
388 [IFLA_MASTER] = decode_nla_u32,
389 [IFLA_WIRELESS] = NULL, /* unimplemented */
390 [IFLA_PROTINFO] = decode_ifla_protinfo,
391 [IFLA_TXQLEN] = decode_nla_u32,
392 [IFLA_MAP] = decode_rtnl_link_ifmap,
393 [IFLA_WEIGHT] = decode_nla_u32,
394 [IFLA_OPERSTATE] = decode_nla_u8,
395 [IFLA_LINKMODE] = decode_nla_u8,
396 [IFLA_LINKINFO] = decode_ifla_linkinfo,
397 [IFLA_NET_NS_PID] = decode_nla_u32,
398 [IFLA_IFALIAS] = decode_nla_str,
399 [IFLA_NUM_VF] = decode_nla_u32,
400 [IFLA_VFINFO_LIST] = NULL, /* unimplemented */
401 [IFLA_STATS64] = decode_rtnl_link_stats64,
402 [IFLA_VF_PORTS] = decode_ifla_vf_ports,
403 [IFLA_PORT_SELF] = decode_ifla_port,
404 [IFLA_AF_SPEC] = NULL, /* unimplemented */
405 [IFLA_GROUP] = decode_nla_u32,
406 [IFLA_NET_NS_FD] = decode_nla_fd,
407 [IFLA_EXT_MASK] = decode_nla_u32,
408 [IFLA_PROMISCUITY] = decode_nla_u32,
409 [IFLA_NUM_TX_QUEUES] = decode_nla_u32,
410 [IFLA_NUM_RX_QUEUES] = decode_nla_u32,
411 [IFLA_CARRIER] = decode_nla_u8,
412 [IFLA_PHYS_PORT_ID] = NULL, /* default parser */
413 [IFLA_CARRIER_CHANGES] = decode_nla_u32,
414 [IFLA_PHYS_SWITCH_ID] = NULL, /* default parser */
415 [IFLA_LINK_NETNSID] = decode_nla_s32,
416 [IFLA_PHYS_PORT_NAME] = decode_nla_str,
417 [IFLA_PROTO_DOWN] = decode_nla_u8,
418 [IFLA_GSO_MAX_SEGS] = decode_nla_u32,
419 [IFLA_GSO_MAX_SIZE] = decode_nla_u32,
421 [IFLA_XDP] = decode_ifla_xdp,
422 [IFLA_EVENT] = decode_nla_u32
425 DECL_NETLINK_ROUTE_DECODER(decode_ifinfomsg)
427 struct ifinfomsg ifinfo = { .ifi_family = family };
428 size_t offset = sizeof(ifinfo.ifi_family);
429 bool decode_nla = false;
431 PRINT_FIELD_XVAL("{", ifinfo, ifi_family, addrfams, "AF_???");
434 if (len >= sizeof(ifinfo)) {
435 if (!umoven_or_printaddr(tcp, addr + offset,
436 sizeof(ifinfo) - offset,
437 (void *) &ifinfo + offset)) {
438 PRINT_FIELD_XVAL("", ifinfo, ifi_type,
439 arp_hardware_types, "ARPHRD_???");
440 PRINT_FIELD_IFINDEX(", ", ifinfo, ifi_index);
441 PRINT_FIELD_FLAGS(", ", ifinfo, ifi_flags,
442 iffflags, "IFF_???");
443 PRINT_FIELD_X(", ", ifinfo, ifi_change);
450 offset = NLMSG_ALIGN(sizeof(ifinfo));
451 if (decode_nla && len > offset) {
453 decode_nlattr(tcp, addr + offset, len - offset,
454 rtnl_link_attrs, "IFLA_???",
455 ifinfomsg_nla_decoders,
456 ARRAY_SIZE(ifinfomsg_nla_decoders), NULL);