Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rtnl_link.c 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. /*
  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.
  5. * All rights reserved.
  6. *
  7. * SPDX-License-Identifier: LGPL-2.1-or-later
  8. */
  9. #include "defs.h"
  10. #include "netlink_route.h"
  11. #include "nlattr.h"
  12. #include "print_fields.h"
  13. #include "netlink.h"
  14. #include <netinet/in.h>
  15. #ifdef HAVE_LINUX_IF_LINK_H
  16. # include <linux/if_link.h>
  17. #endif
  18. #include <linux/rtnetlink.h>
  19. #include "xlat/in6_addr_gen_mode.h"
  20. #include "xlat/inet_devconf_indices.h"
  21. #include "xlat/inet6_devconf_indices.h"
  22. #include "xlat/inet6_if_flags.h"
  23. #include "xlat/rtnl_ifla_af_spec_inet_attrs.h"
  24. #include "xlat/rtnl_ifla_af_spec_inet6_attrs.h"
  25. #include "xlat/rtnl_ifla_brport_attrs.h"
  26. #include "xlat/rtnl_ifla_events.h"
  27. #include "xlat/rtnl_ifla_info_attrs.h"
  28. #include "xlat/rtnl_ifla_info_data_bridge_attrs.h"
  29. #include "xlat/rtnl_ifla_info_data_tun_attrs.h"
  30. #include "xlat/rtnl_ifla_port_attrs.h"
  31. #include "xlat/rtnl_ifla_vf_port_attrs.h"
  32. #include "xlat/rtnl_ifla_xdp_attached_mode.h"
  33. #include "xlat/rtnl_ifla_xdp_attrs.h"
  34. #include "xlat/rtnl_link_attrs.h"
  35. #include "xlat/snmp_icmp6_stats.h"
  36. #include "xlat/snmp_ip_stats.h"
  37. #include "xlat/tun_device_types.h"
  38. #include "xlat/xdp_flags.h"
  39. typedef struct {
  40. uint32_t rx_packets;
  41. uint32_t tx_packets;
  42. uint32_t rx_bytes;
  43. uint32_t tx_bytes;
  44. uint32_t rx_errors;
  45. uint32_t tx_errors;
  46. uint32_t rx_dropped;
  47. uint32_t tx_dropped;
  48. uint32_t multicast;
  49. uint32_t collisions;
  50. uint32_t rx_length_errors;
  51. uint32_t rx_over_errors;
  52. uint32_t rx_crc_errors;
  53. uint32_t rx_frame_errors;
  54. uint32_t rx_fifo_errors;
  55. uint32_t rx_missed_errors;
  56. uint32_t tx_aborted_errors;
  57. uint32_t tx_carrier_errors;
  58. uint32_t tx_fifo_errors;
  59. uint32_t tx_heartbeat_errors;
  60. uint32_t tx_window_errors;
  61. uint32_t rx_compressed;
  62. uint32_t tx_compressed;
  63. uint32_t rx_nohandler; /**< Added by v4.6-rc1~91^2~329^2~2 */
  64. } struct_rtnl_link_stats;
  65. /** Added by Linux commit v2.6.35-rc1~473^2~759 */
  66. typedef struct {
  67. uint64_t rx_packets;
  68. uint64_t tx_packets;
  69. uint64_t rx_bytes;
  70. uint64_t tx_bytes;
  71. uint64_t rx_errors;
  72. uint64_t tx_errors;
  73. uint64_t rx_dropped;
  74. uint64_t tx_dropped;
  75. uint64_t multicast;
  76. uint64_t collisions;
  77. uint64_t rx_length_errors;
  78. uint64_t rx_over_errors;
  79. uint64_t rx_crc_errors;
  80. uint64_t rx_frame_errors;
  81. uint64_t rx_fifo_errors;
  82. uint64_t rx_missed_errors;
  83. uint64_t tx_aborted_errors;
  84. uint64_t tx_carrier_errors;
  85. uint64_t tx_fifo_errors;
  86. uint64_t tx_heartbeat_errors;
  87. uint64_t tx_window_errors;
  88. uint64_t rx_compressed;
  89. uint64_t tx_compressed;
  90. uint64_t rx_nohandler; /**< Added by v4.6-rc1~91^2~329^2~2 */
  91. } struct_rtnl_link_stats64;
  92. /** Added by Linux commit v2.6.35-rc1~473^2~33 */
  93. typedef struct {
  94. uint8_t vsi_mgr_id;
  95. uint8_t vsi_type_id[3];
  96. uint8_t vsi_type_version;
  97. uint8_t pad[3];
  98. } struct_ifla_port_vsi;
  99. #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
  100. static_assert(sizeof(struct_rtnl_link_stats)
  101. == sizeof(struct rtnl_link_stats),
  102. "struct rtnl_link_stats size mismatch"
  103. ", please update the decoder");
  104. #endif
  105. #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER
  106. static_assert(sizeof(struct_rtnl_link_stats64)
  107. == sizeof(struct rtnl_link_stats64),
  108. "struct rtnl_link_stats64 size mismatch"
  109. ", please update the decoder");
  110. #endif
  111. #ifdef HAVE_STRUCT_IFLA_PORT_VSI
  112. static_assert(sizeof(struct_ifla_port_vsi) == sizeof(struct ifla_port_vsi),
  113. "struct ifla_port_vsi size mismatch, please update the decoder");
  114. #endif
  115. static bool
  116. decode_rtnl_link_stats(struct tcb *const tcp,
  117. const kernel_ulong_t addr,
  118. const unsigned int len,
  119. const void *const opaque_data)
  120. {
  121. struct_rtnl_link_stats st;
  122. const unsigned int min_size =
  123. offsetofend(struct_rtnl_link_stats, tx_compressed);
  124. const unsigned int def_size = sizeof(st);
  125. const unsigned int size =
  126. (len >= def_size) ? def_size :
  127. ((len == min_size) ? min_size : 0);
  128. if (!size)
  129. return false;
  130. if (!umoven_or_printaddr(tcp, addr, size, &st)) {
  131. PRINT_FIELD_U("{", st, rx_packets);
  132. PRINT_FIELD_U(", ", st, tx_packets);
  133. PRINT_FIELD_U(", ", st, rx_bytes);
  134. PRINT_FIELD_U(", ", st, tx_bytes);
  135. PRINT_FIELD_U(", ", st, rx_errors);
  136. PRINT_FIELD_U(", ", st, tx_errors);
  137. PRINT_FIELD_U(", ", st, rx_dropped);
  138. PRINT_FIELD_U(", ", st, tx_dropped);
  139. PRINT_FIELD_U(", ", st, multicast);
  140. PRINT_FIELD_U(", ", st, collisions);
  141. PRINT_FIELD_U(", ", st, rx_length_errors);
  142. PRINT_FIELD_U(", ", st, rx_over_errors);
  143. PRINT_FIELD_U(", ", st, rx_crc_errors);
  144. PRINT_FIELD_U(", ", st, rx_frame_errors);
  145. PRINT_FIELD_U(", ", st, rx_fifo_errors);
  146. PRINT_FIELD_U(", ", st, rx_missed_errors);
  147. PRINT_FIELD_U(", ", st, tx_aborted_errors);
  148. PRINT_FIELD_U(", ", st, tx_carrier_errors);
  149. PRINT_FIELD_U(", ", st, tx_fifo_errors);
  150. PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
  151. PRINT_FIELD_U(", ", st, tx_window_errors);
  152. PRINT_FIELD_U(", ", st, rx_compressed);
  153. PRINT_FIELD_U(", ", st, tx_compressed);
  154. if (len >= def_size)
  155. PRINT_FIELD_U(", ", st, rx_nohandler);
  156. tprints("}");
  157. }
  158. return true;
  159. }
  160. static bool
  161. decode_ifla_bridge_id(struct tcb *const tcp,
  162. const kernel_ulong_t addr,
  163. const unsigned int len,
  164. const void *const opaque_data)
  165. {
  166. struct {
  167. uint8_t prio[2];
  168. uint8_t addr[6];
  169. } id;
  170. if (len < sizeof(id))
  171. return false;
  172. else if (!umove_or_printaddr(tcp, addr, &id)) {
  173. tprintf("{prio=[%u, %u]", id.prio[0], id.prio[1]);
  174. PRINT_FIELD_MAC(", ", id, addr);
  175. tprints("}");
  176. }
  177. return true;
  178. }
  179. static const nla_decoder_t ifla_brport_nla_decoders[] = {
  180. [IFLA_BRPORT_STATE] = decode_nla_u8,
  181. [IFLA_BRPORT_PRIORITY] = decode_nla_u16,
  182. [IFLA_BRPORT_COST] = decode_nla_u32,
  183. [IFLA_BRPORT_MODE] = decode_nla_u8,
  184. [IFLA_BRPORT_GUARD] = decode_nla_u8,
  185. [IFLA_BRPORT_PROTECT] = decode_nla_u8,
  186. [IFLA_BRPORT_FAST_LEAVE] = decode_nla_u8,
  187. [IFLA_BRPORT_LEARNING] = decode_nla_u8,
  188. [IFLA_BRPORT_UNICAST_FLOOD] = decode_nla_u8,
  189. [IFLA_BRPORT_PROXYARP] = decode_nla_u8,
  190. [IFLA_BRPORT_LEARNING_SYNC] = decode_nla_u8,
  191. [IFLA_BRPORT_PROXYARP_WIFI] = decode_nla_u8,
  192. [IFLA_BRPORT_ROOT_ID] = decode_ifla_bridge_id,
  193. [IFLA_BRPORT_BRIDGE_ID] = decode_ifla_bridge_id,
  194. [IFLA_BRPORT_DESIGNATED_PORT] = decode_nla_u16,
  195. [IFLA_BRPORT_DESIGNATED_COST] = decode_nla_u16,
  196. [IFLA_BRPORT_ID] = decode_nla_u16,
  197. [IFLA_BRPORT_NO] = decode_nla_u16,
  198. [IFLA_BRPORT_TOPOLOGY_CHANGE_ACK] = decode_nla_u8,
  199. [IFLA_BRPORT_CONFIG_PENDING] = decode_nla_u8,
  200. [IFLA_BRPORT_MESSAGE_AGE_TIMER] = decode_nla_u64,
  201. [IFLA_BRPORT_FORWARD_DELAY_TIMER] = decode_nla_u64,
  202. [IFLA_BRPORT_HOLD_TIMER] = decode_nla_u64,
  203. [IFLA_BRPORT_FLUSH] = NULL,
  204. [IFLA_BRPORT_MULTICAST_ROUTER] = decode_nla_u8,
  205. [IFLA_BRPORT_PAD] = NULL,
  206. [IFLA_BRPORT_MCAST_FLOOD] = decode_nla_u8,
  207. [IFLA_BRPORT_MCAST_TO_UCAST] = decode_nla_u8,
  208. [IFLA_BRPORT_VLAN_TUNNEL] = decode_nla_u8,
  209. [IFLA_BRPORT_BCAST_FLOOD] = decode_nla_u8,
  210. [IFLA_BRPORT_GROUP_FWD_MASK] = decode_nla_u16,
  211. [IFLA_BRPORT_NEIGH_SUPPRESS] = decode_nla_u8,
  212. [IFLA_BRPORT_ISOLATED] = decode_nla_u8,
  213. [IFLA_BRPORT_BACKUP_PORT] = decode_nla_ifindex,
  214. };
  215. static bool
  216. decode_ifla_protinfo(struct tcb *const tcp,
  217. const kernel_ulong_t addr,
  218. const unsigned int len,
  219. const void *const opaque_data)
  220. {
  221. decode_nlattr(tcp, addr, len, rtnl_ifla_brport_attrs,
  222. "IFLA_BRPORT_???",
  223. ARRSZ_PAIR(ifla_brport_nla_decoders), opaque_data);
  224. return true;
  225. }
  226. static bool
  227. decode_rtnl_link_ifmap(struct tcb *const tcp,
  228. const kernel_ulong_t addr,
  229. const unsigned int len,
  230. const void *const opaque_data)
  231. {
  232. struct rtnl_link_ifmap map;
  233. const unsigned int sizeof_ifmap =
  234. offsetofend(struct rtnl_link_ifmap, port);
  235. if (len < sizeof_ifmap)
  236. return false;
  237. else if (!umoven_or_printaddr(tcp, addr, sizeof_ifmap, &map)) {
  238. PRINT_FIELD_X("{", map, mem_start);
  239. PRINT_FIELD_X(", ", map, mem_end);
  240. PRINT_FIELD_X(", ", map, base_addr);
  241. PRINT_FIELD_U(", ", map, irq);
  242. PRINT_FIELD_U(", ", map, dma);
  243. PRINT_FIELD_U(", ", map, port);
  244. tprints("}");
  245. }
  246. return true;
  247. }
  248. bool
  249. decode_nla_linkinfo_kind(struct tcb *const tcp,
  250. const kernel_ulong_t addr,
  251. const unsigned int len,
  252. const void *const opaque_data)
  253. {
  254. struct ifla_linkinfo_ctx *ctx = (void *) opaque_data;
  255. memset(ctx->kind, '\0', sizeof(ctx->kind));
  256. if (umovestr(tcp, addr, sizeof(ctx->kind), ctx->kind) <= 0) {
  257. /*
  258. * If we haven't seen NUL or an error occurred, set kind to
  259. * an empty string.
  260. */
  261. ctx->kind[0] = '\0';
  262. }
  263. printstr_ex(tcp, addr, len, QUOTE_0_TERMINATED);
  264. return true;
  265. }
  266. bool
  267. decode_nla_linkinfo_xstats_can(struct tcb *const tcp,
  268. const kernel_ulong_t addr,
  269. const unsigned int len,
  270. const void *const opaque_data)
  271. {
  272. struct strace_can_device_stats {
  273. uint32_t bus_error;
  274. uint32_t error_warning;
  275. uint32_t error_passive;
  276. uint32_t bus_off;
  277. uint32_t arbitration_lost;
  278. uint32_t restarts;
  279. } st;
  280. const unsigned int def_size = sizeof(st);
  281. const unsigned int size = (len >= def_size) ? def_size : 0;
  282. if (!size)
  283. return false;
  284. if (umoven_or_printaddr(tcp, addr, size, &st))
  285. return true;
  286. PRINT_FIELD_U("{", st, bus_error);
  287. PRINT_FIELD_U(", ", st, error_warning);
  288. PRINT_FIELD_U(", ", st, error_passive);
  289. PRINT_FIELD_U(", ", st, bus_off);
  290. PRINT_FIELD_U(", ", st, arbitration_lost);
  291. PRINT_FIELD_U(", ", st, restarts);
  292. tprints("}");
  293. return true;
  294. }
  295. bool
  296. decode_nla_linkinfo_xstats(struct tcb *const tcp,
  297. const kernel_ulong_t addr,
  298. const unsigned int len,
  299. const void *const opaque_data)
  300. {
  301. struct ifla_linkinfo_ctx *ctx = (void *) opaque_data;
  302. nla_decoder_t func = NULL;
  303. if (!strcmp(ctx->kind, "can"))
  304. func = decode_nla_linkinfo_xstats_can;
  305. if (func)
  306. return func(tcp, addr, len, opaque_data);
  307. return false;
  308. }
  309. static const nla_decoder_t ifla_info_data_bridge_nla_decoders[] = {
  310. [IFLA_BR_UNSPEC] = NULL,
  311. [IFLA_BR_FORWARD_DELAY] = decode_nla_u32,
  312. [IFLA_BR_HELLO_TIME] = decode_nla_u32,
  313. [IFLA_BR_MAX_AGE] = decode_nla_u32,
  314. [IFLA_BR_AGEING_TIME] = decode_nla_u32,
  315. [IFLA_BR_STP_STATE] = decode_nla_u32,
  316. [IFLA_BR_PRIORITY] = decode_nla_u16,
  317. [IFLA_BR_VLAN_FILTERING] = decode_nla_u8,
  318. [IFLA_BR_VLAN_PROTOCOL] = decode_nla_ether_proto,
  319. [IFLA_BR_GROUP_FWD_MASK] = decode_nla_x16,
  320. [IFLA_BR_ROOT_ID] = decode_ifla_bridge_id,
  321. [IFLA_BR_BRIDGE_ID] = decode_ifla_bridge_id,
  322. [IFLA_BR_ROOT_PORT] = decode_nla_u16,
  323. [IFLA_BR_ROOT_PATH_COST] = decode_nla_u32,
  324. [IFLA_BR_TOPOLOGY_CHANGE] = decode_nla_u8,
  325. [IFLA_BR_TOPOLOGY_CHANGE_DETECTED] = decode_nla_u8,
  326. [IFLA_BR_HELLO_TIMER] = decode_nla_u64,
  327. [IFLA_BR_TCN_TIMER] = decode_nla_u64,
  328. [IFLA_BR_TOPOLOGY_CHANGE_TIMER] = decode_nla_u64,
  329. [IFLA_BR_GC_TIMER] = decode_nla_u64,
  330. [IFLA_BR_GROUP_ADDR] = NULL, /* MAC address */
  331. [IFLA_BR_FDB_FLUSH] = NULL, /* unspecified */
  332. [IFLA_BR_MCAST_ROUTER] = decode_nla_u8,
  333. [IFLA_BR_MCAST_SNOOPING] = decode_nla_u8,
  334. [IFLA_BR_MCAST_QUERY_USE_IFADDR] = decode_nla_u8,
  335. [IFLA_BR_MCAST_QUERIER] = decode_nla_u8,
  336. [IFLA_BR_MCAST_HASH_ELASTICITY] = decode_nla_u32,
  337. [IFLA_BR_MCAST_HASH_MAX] = decode_nla_u32,
  338. [IFLA_BR_MCAST_LAST_MEMBER_CNT] = decode_nla_u32,
  339. [IFLA_BR_MCAST_STARTUP_QUERY_CNT] = decode_nla_u32,
  340. [IFLA_BR_MCAST_LAST_MEMBER_INTVL] = decode_nla_u64,
  341. [IFLA_BR_MCAST_MEMBERSHIP_INTVL] = decode_nla_u64,
  342. [IFLA_BR_MCAST_QUERIER_INTVL] = decode_nla_u64,
  343. [IFLA_BR_MCAST_QUERY_INTVL] = decode_nla_u64,
  344. [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = decode_nla_u64,
  345. [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = decode_nla_u64,
  346. [IFLA_BR_NF_CALL_IPTABLES] = decode_nla_u8,
  347. [IFLA_BR_NF_CALL_IP6TABLES] = decode_nla_u8,
  348. [IFLA_BR_NF_CALL_ARPTABLES] = decode_nla_u8,
  349. [IFLA_BR_VLAN_DEFAULT_PVID] = decode_nla_u16,
  350. [IFLA_BR_PAD] = NULL,
  351. [IFLA_BR_VLAN_STATS_ENABLED] = decode_nla_u8,
  352. [IFLA_BR_MCAST_STATS_ENABLED] = decode_nla_u8,
  353. [IFLA_BR_MCAST_IGMP_VERSION] = decode_nla_u8,
  354. [IFLA_BR_MCAST_MLD_VERSION] = decode_nla_u8,
  355. [IFLA_BR_VLAN_STATS_PER_PORT] = decode_nla_u8,
  356. };
  357. bool
  358. decode_nla_linkinfo_data_bridge(struct tcb *const tcp,
  359. const kernel_ulong_t addr,
  360. const unsigned int len,
  361. const void *const opaque_data)
  362. {
  363. decode_nlattr(tcp, addr, len, rtnl_ifla_info_data_bridge_attrs,
  364. "IFLA_BR_???",
  365. ARRSZ_PAIR(ifla_info_data_bridge_nla_decoders),
  366. opaque_data);
  367. return true;
  368. }
  369. static bool
  370. decode_nla_tun_type(struct tcb *const tcp,
  371. const kernel_ulong_t addr,
  372. const unsigned int len,
  373. const void *const opaque_data)
  374. {
  375. static const struct decode_nla_xlat_opts opts = {
  376. .xlat = tun_device_types,
  377. .dflt = "IFF_???",
  378. .size = 1,
  379. };
  380. return decode_nla_xval(tcp, addr, len, &opts);
  381. }
  382. static const nla_decoder_t ifla_info_data_tun_nla_decoders[] = {
  383. [IFLA_TUN_UNSPEC] = NULL,
  384. [IFLA_TUN_OWNER] = decode_nla_uid,
  385. [IFLA_TUN_GROUP] = decode_nla_gid,
  386. [IFLA_TUN_TYPE] = decode_nla_tun_type,
  387. [IFLA_TUN_PI] = decode_nla_u8,
  388. [IFLA_TUN_VNET_HDR] = decode_nla_u8,
  389. [IFLA_TUN_PERSIST] = decode_nla_u8,
  390. [IFLA_TUN_MULTI_QUEUE] = decode_nla_u8,
  391. [IFLA_TUN_NUM_QUEUES] = decode_nla_u32,
  392. [IFLA_TUN_NUM_DISABLED_QUEUES] = decode_nla_u32,
  393. };
  394. bool
  395. decode_nla_linkinfo_data_tun(struct tcb *const tcp,
  396. const kernel_ulong_t addr,
  397. const unsigned int len,
  398. const void *const opaque_data)
  399. {
  400. decode_nlattr(tcp, addr, len, rtnl_ifla_info_data_tun_attrs,
  401. "IFLA_TUN_???",
  402. ARRSZ_PAIR(ifla_info_data_tun_nla_decoders),
  403. opaque_data);
  404. return true;
  405. }
  406. bool
  407. decode_nla_linkinfo_data(struct tcb *const tcp,
  408. const kernel_ulong_t addr,
  409. const unsigned int len,
  410. const void *const opaque_data)
  411. {
  412. struct ifla_linkinfo_ctx *ctx = (void *) opaque_data;
  413. nla_decoder_t func = NULL;
  414. if (!strcmp(ctx->kind, "bridge"))
  415. func = decode_nla_linkinfo_data_bridge;
  416. else if (!strcmp(ctx->kind, "tun"))
  417. func = decode_nla_linkinfo_data_tun;
  418. if (func)
  419. return func(tcp, addr, len, opaque_data);
  420. return false;
  421. }
  422. static const nla_decoder_t ifla_linkinfo_nla_decoders[] = {
  423. [IFLA_INFO_KIND] = decode_nla_linkinfo_kind,
  424. [IFLA_INFO_DATA] = decode_nla_linkinfo_data,
  425. [IFLA_INFO_XSTATS] = decode_nla_linkinfo_xstats,
  426. [IFLA_INFO_SLAVE_KIND] = decode_nla_str,
  427. [IFLA_INFO_SLAVE_DATA] = NULL, /* unimplemented */
  428. };
  429. static bool
  430. decode_ifla_linkinfo(struct tcb *const tcp,
  431. const kernel_ulong_t addr,
  432. const unsigned int len,
  433. const void *const opaque_data)
  434. {
  435. struct ifla_linkinfo_ctx ctx = { .kind = "", };
  436. decode_nlattr(tcp, addr, len, rtnl_ifla_info_attrs,
  437. "IFLA_INFO_???", ARRSZ_PAIR(ifla_linkinfo_nla_decoders),
  438. &ctx);
  439. return true;
  440. }
  441. static bool
  442. decode_rtnl_link_stats64(struct tcb *const tcp,
  443. const kernel_ulong_t addr,
  444. const unsigned int len,
  445. const void *const opaque_data)
  446. {
  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);
  454. if (!size)
  455. return false;
  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);
  467. PRINT_FIELD_U(", ", st, rx_length_errors);
  468. PRINT_FIELD_U(", ", st, rx_over_errors);
  469. PRINT_FIELD_U(", ", st, rx_crc_errors);
  470. PRINT_FIELD_U(", ", st, rx_frame_errors);
  471. PRINT_FIELD_U(", ", st, rx_fifo_errors);
  472. PRINT_FIELD_U(", ", st, rx_missed_errors);
  473. PRINT_FIELD_U(", ", st, tx_aborted_errors);
  474. PRINT_FIELD_U(", ", st, tx_carrier_errors);
  475. PRINT_FIELD_U(", ", st, tx_fifo_errors);
  476. PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
  477. PRINT_FIELD_U(", ", st, tx_window_errors);
  478. PRINT_FIELD_U(", ", st, rx_compressed);
  479. PRINT_FIELD_U(", ", st, tx_compressed);
  480. if (len >= def_size)
  481. PRINT_FIELD_U(", ", st, rx_nohandler);
  482. tprints("}");
  483. }
  484. return true;
  485. }
  486. static bool
  487. decode_ifla_port_vsi(struct tcb *const tcp,
  488. const kernel_ulong_t addr,
  489. const unsigned int len,
  490. const void *const opaque_data)
  491. {
  492. struct_ifla_port_vsi vsi;
  493. if (len < sizeof(vsi))
  494. return false;
  495. if (umove_or_printaddr(tcp, addr, &vsi))
  496. return true;
  497. PRINT_FIELD_U("{", vsi, vsi_mgr_id);
  498. PRINT_FIELD_STRING(", ", vsi, vsi_type_id,
  499. sizeof(vsi.vsi_type_id), QUOTE_FORCE_HEX);
  500. PRINT_FIELD_U(", ", vsi, vsi_type_version);
  501. if (!IS_ARRAY_ZERO(vsi.pad))
  502. PRINT_FIELD_HEX_ARRAY(", ", vsi, pad);
  503. tprints("}");
  504. return true;
  505. }
  506. static const nla_decoder_t ifla_port_nla_decoders[] = {
  507. [IFLA_PORT_VF] = decode_nla_u32,
  508. [IFLA_PORT_PROFILE] = decode_nla_str,
  509. [IFLA_PORT_VSI_TYPE] = decode_ifla_port_vsi,
  510. [IFLA_PORT_INSTANCE_UUID] = NULL, /* default parser */
  511. [IFLA_PORT_HOST_UUID] = NULL, /* default parser */
  512. [IFLA_PORT_REQUEST] = decode_nla_u8,
  513. [IFLA_PORT_RESPONSE] = decode_nla_u16
  514. };
  515. static bool
  516. decode_ifla_port(struct tcb *const tcp,
  517. const kernel_ulong_t addr,
  518. const unsigned int len,
  519. const void *const opaque_data)
  520. {
  521. decode_nlattr(tcp, addr, len, rtnl_ifla_port_attrs,
  522. "IFLA_VF_PORT_???", ARRSZ_PAIR(ifla_port_nla_decoders),
  523. opaque_data);
  524. return true;
  525. }
  526. static const nla_decoder_t ifla_vf_port_nla_decoders[] = {
  527. [IFLA_VF_PORT] = decode_ifla_port
  528. };
  529. static bool
  530. decode_ifla_vf_ports(struct tcb *const tcp,
  531. const kernel_ulong_t addr,
  532. const unsigned int len,
  533. const void *const opaque_data)
  534. {
  535. decode_nlattr(tcp, addr, len, rtnl_ifla_vf_port_attrs,
  536. "IFLA_VF_PORT_???", ARRSZ_PAIR(ifla_vf_port_nla_decoders),
  537. opaque_data);
  538. return true;
  539. }
  540. static bool
  541. decode_ifla_xdp_flags(struct tcb *const tcp,
  542. const kernel_ulong_t addr,
  543. const unsigned int len,
  544. const void *const opaque_data)
  545. {
  546. uint32_t flags;
  547. if (len < sizeof(flags))
  548. return false;
  549. else if (!umove_or_printaddr(tcp, addr, &flags))
  550. printflags(xdp_flags, flags, "XDP_FLAGS_???");
  551. return true;
  552. }
  553. bool
  554. decode_ifla_xdp_attached(struct tcb *const tcp,
  555. const kernel_ulong_t addr,
  556. const unsigned int len,
  557. const void *const opaque_data)
  558. {
  559. static const struct decode_nla_xlat_opts opts = {
  560. .xlat = rtnl_ifla_xdp_attached_mode,
  561. .dflt = "XDP_ATTACHED_???",
  562. .size = 1,
  563. };
  564. return decode_nla_xval(tcp, addr, len, &opts);
  565. }
  566. static const nla_decoder_t ifla_xdp_nla_decoders[] = {
  567. [IFLA_XDP_FD] = decode_nla_fd,
  568. [IFLA_XDP_ATTACHED] = decode_ifla_xdp_attached,
  569. [IFLA_XDP_FLAGS] = decode_ifla_xdp_flags,
  570. [IFLA_XDP_PROG_ID] = decode_nla_u32,
  571. [IFLA_XDP_DRV_PROG_ID] = decode_nla_u32,
  572. [IFLA_XDP_SKB_PROG_ID] = decode_nla_u32,
  573. [IFLA_XDP_HW_PROG_ID] = decode_nla_u32,
  574. };
  575. static bool
  576. decode_ifla_xdp(struct tcb *const tcp,
  577. const kernel_ulong_t addr,
  578. const unsigned int len,
  579. const void *const opaque_data)
  580. {
  581. decode_nlattr(tcp, addr, len, rtnl_ifla_xdp_attrs,
  582. "IFLA_XDP_???", ARRSZ_PAIR(ifla_xdp_nla_decoders),
  583. opaque_data);
  584. return true;
  585. }
  586. static bool
  587. decode_ifla_event(struct tcb *const tcp,
  588. const kernel_ulong_t addr,
  589. const unsigned int len,
  590. const void *const opaque_data)
  591. {
  592. uint32_t ev;
  593. if (len < sizeof(ev))
  594. return false;
  595. else if (!umove_or_printaddr(tcp, addr, &ev))
  596. printxval(rtnl_ifla_events, ev, "IFLA_EVENT_???");
  597. return true;
  598. }
  599. static bool
  600. decode_ifla_inet_conf(struct tcb *const tcp,
  601. const kernel_ulong_t addr,
  602. const unsigned int len,
  603. const void *const opaque_data)
  604. {
  605. int elem;
  606. size_t cnt = len / sizeof(elem);
  607. if (!cnt)
  608. return false;
  609. print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
  610. tfetch_mem, print_int32_array_member, NULL,
  611. PAF_PRINT_INDICES | XLAT_STYLE_FMT_D,
  612. inet_devconf_indices, "IPV4_DEVCONF_???");
  613. return true;
  614. }
  615. static const nla_decoder_t ifla_inet_nla_decoders[] = {
  616. [IFLA_INET_CONF] = decode_ifla_inet_conf,
  617. };
  618. static bool
  619. decode_ifla_inet6_flags(struct tcb *const tcp,
  620. const kernel_ulong_t addr,
  621. const unsigned int len,
  622. const void *const opaque_data)
  623. {
  624. static const struct decode_nla_xlat_opts opts = {
  625. inet6_if_flags, "IF_???",
  626. .size = 4,
  627. };
  628. return decode_nla_flags(tcp, addr, len, &opts);
  629. }
  630. static bool
  631. decode_ifla_inet6_conf(struct tcb *const tcp,
  632. const kernel_ulong_t addr,
  633. const unsigned int len,
  634. const void *const opaque_data)
  635. {
  636. int elem;
  637. size_t cnt = len / sizeof(elem);
  638. if (!cnt)
  639. return false;
  640. print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
  641. tfetch_mem, print_int32_array_member, NULL,
  642. PAF_PRINT_INDICES | XLAT_STYLE_FMT_D,
  643. inet6_devconf_indices, "DEVCONF_???");
  644. return true;
  645. }
  646. static bool
  647. decode_ifla_inet6_stats(struct tcb *const tcp,
  648. const kernel_ulong_t addr,
  649. const unsigned int len,
  650. const void *const opaque_data)
  651. {
  652. uint64_t elem;
  653. size_t cnt = len / sizeof(elem);
  654. if (!cnt)
  655. return false;
  656. print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
  657. tfetch_mem, print_uint64_array_member, NULL,
  658. PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
  659. snmp_ip_stats, "IPSTATS_MIB_???");
  660. return true;
  661. }
  662. static bool
  663. decode_ifla_inet6_cacheinfo(struct tcb *const tcp,
  664. const kernel_ulong_t addr,
  665. const unsigned int len,
  666. const void *const opaque_data)
  667. {
  668. struct {
  669. uint32_t max_reasm_len;
  670. uint32_t tstamp;
  671. uint32_t reachable_time;
  672. uint32_t retrans_time;
  673. } ci;
  674. if (len < sizeof(ci))
  675. return false;
  676. else if (!umove_or_printaddr(tcp, addr, &ci)) {
  677. PRINT_FIELD_U("{", ci, max_reasm_len);
  678. PRINT_FIELD_U(", ", ci, tstamp);
  679. PRINT_FIELD_U(", ", ci, reachable_time);
  680. PRINT_FIELD_U(", ", ci, retrans_time);
  681. tprints("}");
  682. }
  683. return true;
  684. }
  685. static bool
  686. decode_ifla_inet6_icmp6_stats(struct tcb *const tcp,
  687. const kernel_ulong_t addr,
  688. const unsigned int len,
  689. const void *const opaque_data)
  690. {
  691. uint64_t elem;
  692. size_t cnt = len / sizeof(elem);
  693. if (!cnt)
  694. return false;
  695. print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
  696. tfetch_mem, print_uint64_array_member, NULL,
  697. PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
  698. snmp_icmp6_stats, "ICMP6_MIB_???");
  699. return true;
  700. }
  701. static bool
  702. decode_ifla_inet6_agm(struct tcb *const tcp,
  703. const kernel_ulong_t addr,
  704. const unsigned int len,
  705. const void *const opaque_data)
  706. {
  707. static const struct decode_nla_xlat_opts opts = {
  708. in6_addr_gen_mode, "IN6_ADDR_GEN_MODE_???",
  709. .size = 1,
  710. };
  711. return decode_nla_xval(tcp, addr, len, &opts);
  712. }
  713. static const nla_decoder_t ifla_inet6_nla_decoders[] = {
  714. [IFLA_INET6_FLAGS] = decode_ifla_inet6_flags,
  715. [IFLA_INET6_CONF] = decode_ifla_inet6_conf,
  716. [IFLA_INET6_STATS] = decode_ifla_inet6_stats,
  717. [IFLA_INET6_MCAST] = NULL, /* unused */
  718. [IFLA_INET6_CACHEINFO] = decode_ifla_inet6_cacheinfo,
  719. [IFLA_INET6_ICMP6STATS] = decode_ifla_inet6_icmp6_stats,
  720. [IFLA_INET6_TOKEN] = decode_nla_in6_addr,
  721. [IFLA_INET6_ADDR_GEN_MODE] = decode_ifla_inet6_agm,
  722. };
  723. static const struct nla_decoder_table_desc {
  724. const struct xlat *xlat;
  725. const char *dflt;
  726. const nla_decoder_t *table;
  727. size_t size;
  728. } ifla_af_spec_protos[] = {
  729. [AF_INET] = {
  730. rtnl_ifla_af_spec_inet_attrs, "IFLA_INET_???",
  731. ARRSZ_PAIR(ifla_inet_nla_decoders),
  732. },
  733. [AF_INET6] = {
  734. rtnl_ifla_af_spec_inet6_attrs, "IFLA_INET6_???",
  735. ARRSZ_PAIR(ifla_inet6_nla_decoders),
  736. },
  737. };
  738. static bool
  739. decode_ifla_af(struct tcb *const tcp,
  740. const kernel_ulong_t addr,
  741. const unsigned int len,
  742. const void *const opaque_data)
  743. {
  744. uintptr_t proto = (uintptr_t) opaque_data;
  745. const struct nla_decoder_table_desc *desc
  746. = proto < ARRAY_SIZE(ifla_af_spec_protos)
  747. ? ifla_af_spec_protos + proto : NULL;
  748. if (!desc || !desc->table)
  749. return false;
  750. decode_nlattr(tcp, addr, len,
  751. desc->xlat, desc->dflt, desc->table, desc->size, NULL);
  752. return true;
  753. }
  754. static bool
  755. decode_ifla_af_spec(struct tcb *const tcp,
  756. const kernel_ulong_t addr,
  757. const unsigned int len,
  758. const void *const opaque_data)
  759. {
  760. nla_decoder_t af_spec_decoder = &decode_ifla_af;
  761. decode_nlattr(tcp, addr, len, addrfams, "AF_???",
  762. &af_spec_decoder, 0, opaque_data);
  763. return true;
  764. }
  765. static const nla_decoder_t ifinfomsg_nla_decoders[] = {
  766. [IFLA_ADDRESS] = NULL, /* unimplemented */
  767. [IFLA_BROADCAST] = NULL, /* unimplemented */
  768. [IFLA_IFNAME] = decode_nla_str,
  769. [IFLA_MTU] = decode_nla_u32,
  770. [IFLA_LINK] = decode_nla_u32,
  771. [IFLA_QDISC] = decode_nla_str,
  772. [IFLA_STATS] = decode_rtnl_link_stats,
  773. [IFLA_COST] = NULL, /* unused */
  774. [IFLA_PRIORITY] = NULL, /* unused */
  775. [IFLA_MASTER] = decode_nla_u32,
  776. [IFLA_WIRELESS] = NULL, /* unimplemented */
  777. [IFLA_PROTINFO] = decode_ifla_protinfo,
  778. [IFLA_TXQLEN] = decode_nla_u32,
  779. [IFLA_MAP] = decode_rtnl_link_ifmap,
  780. [IFLA_WEIGHT] = decode_nla_u32,
  781. [IFLA_OPERSTATE] = decode_nla_u8,
  782. [IFLA_LINKMODE] = decode_nla_u8,
  783. [IFLA_LINKINFO] = decode_ifla_linkinfo,
  784. [IFLA_NET_NS_PID] = decode_nla_u32,
  785. [IFLA_IFALIAS] = decode_nla_str,
  786. [IFLA_NUM_VF] = decode_nla_u32,
  787. [IFLA_VFINFO_LIST] = NULL, /* unimplemented */
  788. [IFLA_STATS64] = decode_rtnl_link_stats64,
  789. [IFLA_VF_PORTS] = decode_ifla_vf_ports,
  790. [IFLA_PORT_SELF] = decode_ifla_port,
  791. [IFLA_AF_SPEC] = decode_ifla_af_spec,
  792. [IFLA_GROUP] = decode_nla_u32,
  793. [IFLA_NET_NS_FD] = decode_nla_fd,
  794. [IFLA_EXT_MASK] = decode_nla_u32,
  795. [IFLA_PROMISCUITY] = decode_nla_u32,
  796. [IFLA_NUM_TX_QUEUES] = decode_nla_u32,
  797. [IFLA_NUM_RX_QUEUES] = decode_nla_u32,
  798. [IFLA_CARRIER] = decode_nla_u8,
  799. [IFLA_PHYS_PORT_ID] = NULL, /* default parser */
  800. [IFLA_CARRIER_CHANGES] = decode_nla_u32,
  801. [IFLA_PHYS_SWITCH_ID] = NULL, /* default parser */
  802. [IFLA_LINK_NETNSID] = decode_nla_s32,
  803. [IFLA_PHYS_PORT_NAME] = decode_nla_str,
  804. [IFLA_PROTO_DOWN] = decode_nla_u8,
  805. [IFLA_GSO_MAX_SEGS] = decode_nla_u32,
  806. [IFLA_GSO_MAX_SIZE] = decode_nla_u32,
  807. [IFLA_PAD] = NULL,
  808. [IFLA_XDP] = decode_ifla_xdp,
  809. [IFLA_EVENT] = decode_ifla_event,
  810. [IFLA_NEW_NETNSID] = decode_nla_s32,
  811. [IFLA_IF_NETNSID] = decode_nla_s32,
  812. [IFLA_CARRIER_UP_COUNT] = decode_nla_u32,
  813. [IFLA_CARRIER_DOWN_COUNT] = decode_nla_u32,
  814. [IFLA_NEW_IFINDEX] = decode_nla_ifindex,
  815. [IFLA_MIN_MTU] = decode_nla_u32,
  816. [IFLA_MAX_MTU] = decode_nla_u32,
  817. };
  818. DECL_NETLINK_ROUTE_DECODER(decode_ifinfomsg)
  819. {
  820. struct ifinfomsg ifinfo = { .ifi_family = family };
  821. size_t offset = sizeof(ifinfo.ifi_family);
  822. bool decode_nla = false;
  823. PRINT_FIELD_XVAL("{", ifinfo, ifi_family, addrfams, "AF_???");
  824. tprints(", ");
  825. if (len >= sizeof(ifinfo)) {
  826. if (!umoven_or_printaddr(tcp, addr + offset,
  827. sizeof(ifinfo) - offset,
  828. (char *) &ifinfo + offset)) {
  829. PRINT_FIELD_XVAL("", ifinfo, ifi_type,
  830. arp_hardware_types, "ARPHRD_???");
  831. PRINT_FIELD_IFINDEX(", ", ifinfo, ifi_index);
  832. PRINT_FIELD_FLAGS(", ", ifinfo, ifi_flags,
  833. iffflags, "IFF_???");
  834. PRINT_FIELD_X(", ", ifinfo, ifi_change);
  835. decode_nla = true;
  836. }
  837. } else
  838. tprints("...");
  839. tprints("}");
  840. offset = NLMSG_ALIGN(sizeof(ifinfo));
  841. if (decode_nla && len > offset) {
  842. tprints(", ");
  843. decode_nlattr(tcp, addr + offset, len - offset,
  844. rtnl_link_attrs, "IFLA_???",
  845. ARRSZ_PAIR(ifinfomsg_nla_decoders), NULL);
  846. }
  847. }