Browse Source

rtnl_mdb: decode messages regardless of availability of kernel headers

* netlink_route.c [!HAVE_STRUCT_BR_PORT_MSG]: Do not skip decoding of
RTM_DELMDB, RTM_GETMDB, and RTM_NEWMDB messages.
* rtnl_mdb.c: Remove #ifdef HAVE_STRUCT_BR_PORT_MSG guard.
(struct_br_port_msg, struct_br_mdb_entry): New typedefs.
[HAVE_STRUCT_BR_PORT_MSG]: Static assert check for struct br_port_msg
size.
[HAVE_STRUCT_BR_NDB_ENTRY]: Static assert check for strucr br_mdb_entry
size.
(decode_mdba_mdb_entry_info) [!HAVE_STRUCT_BR_MDB_ENTRY]: Remove.
(decode_mdba_mdb_entry_info): Change entry type to struct_br_mdb_entry.
(decode_mdba_mdb_entry_info) [HAVE_STRUCT_BR_MDB_ENTRY_FLAGS,
HAVE_STRUCT_BR_MDB_ENTRY_VID]: Remove guards.
(decode_br_port_msg): Change bpm type to struct_br_port_msg.
* tests/nlattr_ifinfomsg.c: Use TEST_NLATTR_OBJECT_MINSZ to test
struct rtnl_link_stats printing.
* tests/nlattr_mdba_mdb_entry.c: Update expected output.

References: https://bugzilla.redhat.com/show_bug.cgi?id=1758201
Eugene Syromyatnikov 1 month ago
parent
commit
e1a9e0f35d
4 changed files with 89 additions and 64 deletions
  1. 0
    2
      netlink_route.c
  2. 52
    31
      rtnl_mdb.c
  3. 29
    31
      tests/nlattr_ifinfomsg.c
  4. 8
    0
      tests/nlattr_mdba_mdb_entry.c

+ 0
- 2
netlink_route.c View File

@@ -90,11 +90,9 @@ static const netlink_route_decoder_t route_decoders[] = {
90 90
 	[RTM_NEWNETCONF - RTM_BASE] = decode_netconfmsg,
91 91
 #endif
92 92
 
93
-#ifdef HAVE_STRUCT_BR_PORT_MSG
94 93
 	[RTM_DELMDB - RTM_BASE] = decode_br_port_msg,
95 94
 	[RTM_GETMDB - RTM_BASE] = decode_br_port_msg,
96 95
 	[RTM_NEWMDB - RTM_BASE] = decode_br_port_msg,
97
-#endif
98 96
 
99 97
 	[RTM_DELNSID - RTM_BASE] = decode_rtgenmsg,
100 98
 	[RTM_GETNSID - RTM_BASE] = decode_rtgenmsg,

+ 52
- 31
rtnl_mdb.c View File

@@ -9,27 +9,52 @@
9 9
 
10 10
 #include "defs.h"
11 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
+
12 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
13 53
 
14
-# include "netlink_route.h"
15
-# include "nlattr.h"
16
-# include "print_fields.h"
17
-
18
-# include <netinet/in.h>
19
-# include <linux/if_bridge.h>
20
-# include "netlink.h"
21
-
22
-# ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
23
-#  include "xlat/mdb_flags.h"
24
-# endif
25
-# include "xlat/mdb_states.h"
26
-# include "xlat/multicast_router_types.h"
27
-# include "xlat/rtnl_mdb_attrs.h"
28
-# include "xlat/rtnl_mdba_mdb_attrs.h"
29
-# include "xlat/rtnl_mdba_mdb_eattr_attrs.h"
30
-# include "xlat/rtnl_mdba_mdb_entry_attrs.h"
31
-# include "xlat/rtnl_mdba_router_attrs.h"
32
-# include "xlat/rtnl_mdba_router_pattr_attrs.h"
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
33 58
 
34 59
 static const nla_decoder_t mdba_mdb_eattr_nla_decoders[] = {
35 60
 	[MDBA_MDB_EATTR_TIMER]	= decode_nla_u32
@@ -41,21 +66,22 @@ decode_mdba_mdb_entry_info(struct tcb *const tcp,
41 66
 			   const unsigned int len,
42 67
 			   const void *const opaque_data)
43 68
 {
44
-# ifdef HAVE_STRUCT_BR_MDB_ENTRY
45
-	struct br_mdb_entry entry;
69
+	struct_br_mdb_entry entry;
46 70
 
47 71
 	if (len < sizeof(entry))
48 72
 		return false;
49 73
 	else if (!umove_or_printaddr(tcp, addr, &entry)) {
50 74
 		PRINT_FIELD_IFINDEX("{", entry, ifindex);
51 75
 		PRINT_FIELD_XVAL(", ", entry, state, mdb_states, "MDB_???");
52
-#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
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
+		 */
53 82
 		PRINT_FIELD_FLAGS(", ", entry, flags,
54 83
 				  mdb_flags, "MDB_FLAGS_???");
55
-#  endif
56
-#  ifdef HAVE_STRUCT_BR_MDB_ENTRY_VID
57 84
 		PRINT_FIELD_U(", ", entry, vid);
58
-#  endif
59 85
 
60 86
 		const int proto = ntohs(entry.addr.proto);
61 87
 
@@ -77,9 +103,6 @@ decode_mdba_mdb_entry_info(struct tcb *const tcp,
77 103
 	}
78 104
 
79 105
 	return true;
80
-# else
81
-	return false;
82
-# endif /* HAVE_STRUCT_BR_MDB_ENTRY */
83 106
 }
84 107
 
85 108
 static const nla_decoder_t mdba_mdb_entry_nla_decoders[] = {
@@ -185,7 +208,7 @@ static const nla_decoder_t br_port_msg_nla_decoders[] = {
185 208
 
186 209
 DECL_NETLINK_ROUTE_DECODER(decode_br_port_msg)
187 210
 {
188
-	struct br_port_msg bpm = { .family = family };
211
+	struct_br_port_msg bpm = { .family = family };
189 212
 	size_t offset = sizeof(bpm.family);
190 213
 	bool decode_nla = false;
191 214
 
@@ -212,5 +235,3 @@ DECL_NETLINK_ROUTE_DECODER(decode_br_port_msg)
212 235
 			      ARRAY_SIZE(br_port_msg_nla_decoders), NULL);
213 236
 	}
214 237
 }
215
-
216
-#endif

+ 29
- 31
tests/nlattr_ifinfomsg.c View File

@@ -118,40 +118,39 @@ main(void)
118 118
 			   IFLA_LINK_NETNSID, pattern, netnsid,
119 119
 			   printf("%d", netnsid));
120 120
 
121
-	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
122
-			   init_ifinfomsg, print_ifinfomsg,
123
-			   IFLA_STATS, pattern, st,
124
-			   PRINT_FIELD_U("{", st, rx_packets);
125
-			   PRINT_FIELD_U(", ", st, tx_packets);
126
-			   PRINT_FIELD_U(", ", st, rx_bytes);
127
-			   PRINT_FIELD_U(", ", st, tx_bytes);
128
-			   PRINT_FIELD_U(", ", st, rx_errors);
129
-			   PRINT_FIELD_U(", ", st, tx_errors);
130
-			   PRINT_FIELD_U(", ", st, rx_dropped);
131
-			   PRINT_FIELD_U(", ", st, tx_dropped);
132
-			   PRINT_FIELD_U(", ", st, multicast);
133
-			   PRINT_FIELD_U(", ", st, collisions);
134
-			   PRINT_FIELD_U(", ", st, rx_length_errors);
135
-			   PRINT_FIELD_U(", ", st, rx_over_errors);
136
-			   PRINT_FIELD_U(", ", st, rx_crc_errors);
137
-			   PRINT_FIELD_U(", ", st, rx_frame_errors);
138
-			   PRINT_FIELD_U(", ", st, rx_fifo_errors);
139
-			   PRINT_FIELD_U(", ", st, rx_missed_errors);
140
-			   PRINT_FIELD_U(", ", st, tx_aborted_errors);
141
-			   PRINT_FIELD_U(", ", st, tx_carrier_errors);
142
-			   PRINT_FIELD_U(", ", st, tx_fifo_errors);
143
-			   PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
144
-			   PRINT_FIELD_U(", ", st, tx_window_errors);
145
-			   PRINT_FIELD_U(", ", st, rx_compressed);
146
-			   PRINT_FIELD_U(", ", st, tx_compressed);
121
+	const unsigned int sizeof_stats =
122
+		offsetofend(struct rtnl_link_stats, tx_compressed);
123
+	TEST_NLATTR_OBJECT_MINSZ(fd, nlh0, hdrlen,
124
+				 init_ifinfomsg, print_ifinfomsg,
125
+				 IFLA_STATS, pattern, st, sizeof_stats,
126
+				 PRINT_FIELD_U("{", st, rx_packets);
127
+				 PRINT_FIELD_U(", ", st, tx_packets);
128
+				 PRINT_FIELD_U(", ", st, rx_bytes);
129
+				 PRINT_FIELD_U(", ", st, tx_bytes);
130
+				 PRINT_FIELD_U(", ", st, rx_errors);
131
+				 PRINT_FIELD_U(", ", st, tx_errors);
132
+				 PRINT_FIELD_U(", ", st, rx_dropped);
133
+				 PRINT_FIELD_U(", ", st, tx_dropped);
134
+				 PRINT_FIELD_U(", ", st, multicast);
135
+				 PRINT_FIELD_U(", ", st, collisions);
136
+				 PRINT_FIELD_U(", ", st, rx_length_errors);
137
+				 PRINT_FIELD_U(", ", st, rx_over_errors);
138
+				 PRINT_FIELD_U(", ", st, rx_crc_errors);
139
+				 PRINT_FIELD_U(", ", st, rx_frame_errors);
140
+				 PRINT_FIELD_U(", ", st, rx_fifo_errors);
141
+				 PRINT_FIELD_U(", ", st, rx_missed_errors);
142
+				 PRINT_FIELD_U(", ", st, tx_aborted_errors);
143
+				 PRINT_FIELD_U(", ", st, tx_carrier_errors);
144
+				 PRINT_FIELD_U(", ", st, tx_fifo_errors);
145
+				 PRINT_FIELD_U(", ", st, tx_heartbeat_errors);
146
+				 PRINT_FIELD_U(", ", st, tx_window_errors);
147
+				 PRINT_FIELD_U(", ", st, rx_compressed);
148
+				 PRINT_FIELD_U(", ", st, tx_compressed);
147 149
 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
148
-			   PRINT_FIELD_U(", ", st, rx_nohandler);
150
+				 PRINT_FIELD_U(", ", st, rx_nohandler);
149 151
 #endif
150 152
 			   printf("}"));
151 153
 
152
-#ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER
153
-	const unsigned int sizeof_stats =
154
-		offsetofend(struct rtnl_link_stats, tx_compressed);
155 154
 	TEST_NLATTR(fd, nlh0, hdrlen,
156 155
 		    init_ifinfomsg, print_ifinfomsg,
157 156
 		    IFLA_STATS, sizeof_stats, &st, sizeof_stats,
@@ -179,7 +178,6 @@ main(void)
179 178
 		    PRINT_FIELD_U(", ", st, rx_compressed);
180 179
 		    PRINT_FIELD_U(", ", st, tx_compressed);
181 180
 		    printf("}"));
182
-#endif /* HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER */
183 181
 
184 182
 	static const struct rtnl_link_ifmap map = {
185 183
 		.mem_start = 0xadcbefedefbcdedb,

+ 8
- 0
tests/nlattr_mdba_mdb_entry.c View File

@@ -122,9 +122,13 @@ main(void)
122 122
 				     printf(", state=MDB_TEMPORARY");
123 123
 #  ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
124 124
 				     printf(", flags=MDB_FLAGS_OFFLOAD");
125
+#  else
126
+				     printf(", flags=0");
125 127
 #  endif
126 128
 #  ifdef HAVE_STRUCT_BR_MDB_ENTRY_VID
127 129
 				     PRINT_FIELD_U(", ", entry, vid);
130
+#  else
131
+				     printf(", vid=0");
128 132
 #  endif
129 133
 				     printf(", addr={u=");
130 134
 				     print_quoted_hex(&entry.addr.u,
@@ -145,9 +149,13 @@ main(void)
145 149
 		    printf(", state=MDB_TEMPORARY");
146 150
 #  ifdef HAVE_STRUCT_BR_MDB_ENTRY_FLAGS
147 151
 		    printf(", flags=MDB_FLAGS_OFFLOAD");
152
+#  else
153
+		    printf(", flags=0");
148 154
 #  endif
149 155
 #  ifdef HAVE_STRUCT_BR_MDB_ENTRY_VID
150 156
 		    PRINT_FIELD_U(", ", entry, vid);
157
+#  else
158
+		    printf(", vid=0");
151 159
 #  endif
152 160
 		    printf(", addr={u=");
153 161
 		    print_quoted_hex(&entry.addr.u, sizeof(entry.addr.u));

Loading…
Cancel
Save