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 24KB

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