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_mdb.c 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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 <netinet/in.h>
  14. #include <linux/if_bridge.h>
  15. #include "netlink.h"
  16. #include "xlat/mdb_flags.h"
  17. #include "xlat/mdb_states.h"
  18. #include "xlat/multicast_router_types.h"
  19. #include "xlat/rtnl_mdb_attrs.h"
  20. #include "xlat/rtnl_mdba_mdb_attrs.h"
  21. #include "xlat/rtnl_mdba_mdb_eattr_attrs.h"
  22. #include "xlat/rtnl_mdba_mdb_entry_attrs.h"
  23. #include "xlat/rtnl_mdba_router_attrs.h"
  24. #include "xlat/rtnl_mdba_router_pattr_attrs.h"
  25. typedef struct {
  26. uint8_t family;
  27. uint32_t ifindex;
  28. } struct_br_port_msg;
  29. typedef struct {
  30. uint32_t ifindex;
  31. uint8_t state;
  32. uint8_t flags;
  33. uint16_t vid;
  34. struct {
  35. union {
  36. uint32_t /* __be32 */ ip4;
  37. struct in6_addr ip6;
  38. } u;
  39. uint16_t /* __be16 */ proto;
  40. } addr;
  41. } struct_br_mdb_entry;
  42. #ifdef HAVE_STRUCT_BR_PORT_MSG
  43. static_assert(sizeof(struct br_port_msg) <= sizeof(struct_br_port_msg),
  44. "Unexpected struct br_port_msg size, please update the decoder");
  45. #endif
  46. #ifdef HAVE_STRUCT_BR_NDB_ENTRY
  47. static_assert(sizeof(struct br_mdb_entry) <= sizeof(struct_br_mdb_entry),
  48. "Unexpected struct br_mdb_entry size, please update the decoder");
  49. #endif
  50. static const nla_decoder_t mdba_mdb_eattr_nla_decoders[] = {
  51. [MDBA_MDB_EATTR_TIMER] = decode_nla_u32
  52. };
  53. static bool
  54. decode_mdba_mdb_entry_info(struct tcb *const tcp,
  55. const kernel_ulong_t addr,
  56. const unsigned int len,
  57. const void *const opaque_data)
  58. {
  59. struct_br_mdb_entry entry;
  60. if (len < sizeof(entry))
  61. return false;
  62. else if (!umove_or_printaddr(tcp, addr, &entry)) {
  63. PRINT_FIELD_IFINDEX("{", entry, ifindex);
  64. PRINT_FIELD_XVAL(", ", entry, state, mdb_states, "MDB_???");
  65. /*
  66. * Note that it's impossible to derive if flags/vid fields
  67. * are present on all architectures except m68k; as a side note,
  68. * v4.3-rc1~96^2~365 has introduced an ABI breakage on m68k.
  69. */
  70. PRINT_FIELD_FLAGS(", ", entry, flags,
  71. mdb_flags, "MDB_FLAGS_???");
  72. PRINT_FIELD_U(", ", entry, vid);
  73. const int proto = ntohs(entry.addr.proto);
  74. tprints(", addr={");
  75. print_inet_addr(proto, &entry.addr.u,
  76. sizeof(entry.addr.u), "u");
  77. tprints(", proto=htons(");
  78. printxval(addrfams, proto, "AF_???");
  79. tprints(")}}");
  80. }
  81. const size_t offset = NLMSG_ALIGN(sizeof(entry));
  82. if (len > offset) {
  83. tprints(", ");
  84. decode_nlattr(tcp, addr + offset, len - offset,
  85. rtnl_mdba_mdb_eattr_attrs, "MDBA_MDB_EATTR_???",
  86. mdba_mdb_eattr_nla_decoders,
  87. ARRAY_SIZE(mdba_mdb_eattr_nla_decoders), NULL);
  88. }
  89. return true;
  90. }
  91. static const nla_decoder_t mdba_mdb_entry_nla_decoders[] = {
  92. [MDBA_MDB_ENTRY_INFO] = decode_mdba_mdb_entry_info
  93. };
  94. static bool
  95. decode_mdba_mdb_entry(struct tcb *const tcp,
  96. const kernel_ulong_t addr,
  97. const unsigned int len,
  98. const void *const opaque_data)
  99. {
  100. decode_nlattr(tcp, addr, len, rtnl_mdba_mdb_entry_attrs,
  101. "MDBA_MDB_ENTRY_???", mdba_mdb_entry_nla_decoders,
  102. ARRAY_SIZE(mdba_mdb_entry_nla_decoders), NULL);
  103. return true;
  104. }
  105. static const nla_decoder_t mdba_mdb_nla_decoders[] = {
  106. [MDBA_MDB_ENTRY] = decode_mdba_mdb_entry
  107. };
  108. static bool
  109. decode_mdba_mdb(struct tcb *const tcp,
  110. const kernel_ulong_t addr,
  111. const unsigned int len,
  112. const void *const opaque_data)
  113. {
  114. decode_nlattr(tcp, addr, len, rtnl_mdba_mdb_attrs, "MDBA_MDB_???",
  115. mdba_mdb_nla_decoders,
  116. ARRAY_SIZE(mdba_mdb_nla_decoders), NULL);
  117. return true;
  118. }
  119. static bool
  120. decode_multicast_router_type(struct tcb *const tcp,
  121. const kernel_ulong_t addr,
  122. const unsigned int len,
  123. const void *const opaque_data)
  124. {
  125. uint8_t type;
  126. if (!umove_or_printaddr(tcp, addr, &type))
  127. printxval(multicast_router_types, type, "MDB_RTR_TYPE_???");
  128. return true;
  129. }
  130. static const nla_decoder_t mdba_router_pattr_nla_decoders[] = {
  131. [MDBA_ROUTER_PATTR_TIMER] = decode_nla_u32,
  132. [MDBA_ROUTER_PATTR_TYPE] = decode_multicast_router_type
  133. };
  134. static bool
  135. decode_mdba_router_port(struct tcb *const tcp,
  136. const kernel_ulong_t addr,
  137. const unsigned int len,
  138. const void *const opaque_data)
  139. {
  140. uint32_t ifindex;
  141. if (len < sizeof(ifindex))
  142. return false;
  143. else if (!umove_or_printaddr(tcp, addr, &ifindex))
  144. print_ifindex(ifindex);
  145. const size_t offset = NLMSG_ALIGN(sizeof(ifindex));
  146. if (len > offset) {
  147. tprints(", ");
  148. decode_nlattr(tcp, addr + offset, len - offset,
  149. rtnl_mdba_router_pattr_attrs,
  150. "MDBA_ROUTER_PATTR_???",
  151. mdba_router_pattr_nla_decoders,
  152. ARRAY_SIZE(mdba_router_pattr_nla_decoders), NULL);
  153. }
  154. return true;
  155. }
  156. static const nla_decoder_t mdba_router_nla_decoders[] = {
  157. [MDBA_ROUTER_PORT] = decode_mdba_router_port
  158. };
  159. static bool
  160. decode_mdba_router(struct tcb *const tcp,
  161. const kernel_ulong_t addr,
  162. const unsigned int len,
  163. const void *const opaque_data)
  164. {
  165. decode_nlattr(tcp, addr, len, rtnl_mdba_router_attrs, "MDBA_ROUTER_???",
  166. mdba_router_nla_decoders,
  167. ARRAY_SIZE(mdba_router_nla_decoders), NULL);
  168. return true;
  169. }
  170. static const nla_decoder_t br_port_msg_nla_decoders[] = {
  171. [MDBA_MDB] = decode_mdba_mdb,
  172. [MDBA_ROUTER] = decode_mdba_router
  173. };
  174. DECL_NETLINK_ROUTE_DECODER(decode_br_port_msg)
  175. {
  176. struct_br_port_msg bpm = { .family = family };
  177. size_t offset = sizeof(bpm.family);
  178. bool decode_nla = false;
  179. PRINT_FIELD_XVAL("{", bpm, family, addrfams, "AF_???");
  180. tprints(", ");
  181. if (len >= sizeof(bpm)) {
  182. if (!umoven_or_printaddr(tcp, addr + offset,
  183. sizeof(bpm) - offset,
  184. (char *) &bpm + offset)) {
  185. PRINT_FIELD_IFINDEX("", bpm, ifindex);
  186. decode_nla = true;
  187. }
  188. } else
  189. tprints("...");
  190. tprints("}");
  191. offset = NLMSG_ALIGN(sizeof(bpm));
  192. if (decode_nla && len > offset) {
  193. tprints(", ");
  194. decode_nlattr(tcp, addr + offset, len - offset,
  195. rtnl_mdb_attrs, "MDBA_???",
  196. br_port_msg_nla_decoders,
  197. ARRAY_SIZE(br_port_msg_nla_decoders), NULL);
  198. }
  199. }