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