hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/bridge/br_mdb.c
....@@ -26,14 +26,14 @@
2626 if (!br->multicast_router || hlist_empty(&br->router_list))
2727 return 0;
2828
29
- nest = nla_nest_start(skb, MDBA_ROUTER);
29
+ nest = nla_nest_start_noflag(skb, MDBA_ROUTER);
3030 if (nest == NULL)
3131 return -EMSGSIZE;
3232
3333 hlist_for_each_entry_rcu(p, &br->router_list, rlist) {
3434 if (!p)
3535 continue;
36
- port_nest = nla_nest_start(skb, MDBA_ROUTER_PORT);
36
+ port_nest = nla_nest_start_noflag(skb, MDBA_ROUTER_PORT);
3737 if (!port_nest)
3838 goto fail;
3939 if (nla_put_nohdr(skb, sizeof(u32), &p->dev->ifindex) ||
....@@ -60,106 +60,261 @@
6060 e->flags = 0;
6161 if (flags & MDB_PG_FLAGS_OFFLOAD)
6262 e->flags |= MDB_FLAGS_OFFLOAD;
63
+ if (flags & MDB_PG_FLAGS_FAST_LEAVE)
64
+ e->flags |= MDB_FLAGS_FAST_LEAVE;
65
+ if (flags & MDB_PG_FLAGS_STAR_EXCL)
66
+ e->flags |= MDB_FLAGS_STAR_EXCL;
67
+ if (flags & MDB_PG_FLAGS_BLOCKED)
68
+ e->flags |= MDB_FLAGS_BLOCKED;
6369 }
6470
65
-static void __mdb_entry_to_br_ip(struct br_mdb_entry *entry, struct br_ip *ip)
71
+static void __mdb_entry_to_br_ip(struct br_mdb_entry *entry, struct br_ip *ip,
72
+ struct nlattr **mdb_attrs)
6673 {
6774 memset(ip, 0, sizeof(struct br_ip));
6875 ip->vid = entry->vid;
6976 ip->proto = entry->addr.proto;
70
- if (ip->proto == htons(ETH_P_IP))
71
- ip->u.ip4 = entry->addr.u.ip4;
77
+ switch (ip->proto) {
78
+ case htons(ETH_P_IP):
79
+ ip->dst.ip4 = entry->addr.u.ip4;
80
+ if (mdb_attrs && mdb_attrs[MDBE_ATTR_SOURCE])
81
+ ip->src.ip4 = nla_get_in_addr(mdb_attrs[MDBE_ATTR_SOURCE]);
82
+ break;
7283 #if IS_ENABLED(CONFIG_IPV6)
73
- else
74
- ip->u.ip6 = entry->addr.u.ip6;
84
+ case htons(ETH_P_IPV6):
85
+ ip->dst.ip6 = entry->addr.u.ip6;
86
+ if (mdb_attrs && mdb_attrs[MDBE_ATTR_SOURCE])
87
+ ip->src.ip6 = nla_get_in6_addr(mdb_attrs[MDBE_ATTR_SOURCE]);
88
+ break;
7589 #endif
90
+ }
91
+
92
+}
93
+
94
+static int __mdb_fill_srcs(struct sk_buff *skb,
95
+ struct net_bridge_port_group *p)
96
+{
97
+ struct net_bridge_group_src *ent;
98
+ struct nlattr *nest, *nest_ent;
99
+
100
+ if (hlist_empty(&p->src_list))
101
+ return 0;
102
+
103
+ nest = nla_nest_start(skb, MDBA_MDB_EATTR_SRC_LIST);
104
+ if (!nest)
105
+ return -EMSGSIZE;
106
+
107
+ hlist_for_each_entry_rcu(ent, &p->src_list, node,
108
+ lockdep_is_held(&p->key.port->br->multicast_lock)) {
109
+ nest_ent = nla_nest_start(skb, MDBA_MDB_SRCLIST_ENTRY);
110
+ if (!nest_ent)
111
+ goto out_cancel_err;
112
+ switch (ent->addr.proto) {
113
+ case htons(ETH_P_IP):
114
+ if (nla_put_in_addr(skb, MDBA_MDB_SRCATTR_ADDRESS,
115
+ ent->addr.src.ip4)) {
116
+ nla_nest_cancel(skb, nest_ent);
117
+ goto out_cancel_err;
118
+ }
119
+ break;
120
+#if IS_ENABLED(CONFIG_IPV6)
121
+ case htons(ETH_P_IPV6):
122
+ if (nla_put_in6_addr(skb, MDBA_MDB_SRCATTR_ADDRESS,
123
+ &ent->addr.src.ip6)) {
124
+ nla_nest_cancel(skb, nest_ent);
125
+ goto out_cancel_err;
126
+ }
127
+ break;
128
+#endif
129
+ default:
130
+ nla_nest_cancel(skb, nest_ent);
131
+ continue;
132
+ }
133
+ if (nla_put_u32(skb, MDBA_MDB_SRCATTR_TIMER,
134
+ br_timer_value(&ent->timer))) {
135
+ nla_nest_cancel(skb, nest_ent);
136
+ goto out_cancel_err;
137
+ }
138
+ nla_nest_end(skb, nest_ent);
139
+ }
140
+
141
+ nla_nest_end(skb, nest);
142
+
143
+ return 0;
144
+
145
+out_cancel_err:
146
+ nla_nest_cancel(skb, nest);
147
+ return -EMSGSIZE;
148
+}
149
+
150
+static int __mdb_fill_info(struct sk_buff *skb,
151
+ struct net_bridge_mdb_entry *mp,
152
+ struct net_bridge_port_group *p)
153
+{
154
+ bool dump_srcs_mode = false;
155
+ struct timer_list *mtimer;
156
+ struct nlattr *nest_ent;
157
+ struct br_mdb_entry e;
158
+ u8 flags = 0;
159
+ int ifindex;
160
+
161
+ memset(&e, 0, sizeof(e));
162
+ if (p) {
163
+ ifindex = p->key.port->dev->ifindex;
164
+ mtimer = &p->timer;
165
+ flags = p->flags;
166
+ } else {
167
+ ifindex = mp->br->dev->ifindex;
168
+ mtimer = &mp->timer;
169
+ }
170
+
171
+ __mdb_entry_fill_flags(&e, flags);
172
+ e.ifindex = ifindex;
173
+ e.vid = mp->addr.vid;
174
+ if (mp->addr.proto == htons(ETH_P_IP))
175
+ e.addr.u.ip4 = mp->addr.dst.ip4;
176
+#if IS_ENABLED(CONFIG_IPV6)
177
+ if (mp->addr.proto == htons(ETH_P_IPV6))
178
+ e.addr.u.ip6 = mp->addr.dst.ip6;
179
+#endif
180
+ e.addr.proto = mp->addr.proto;
181
+ nest_ent = nla_nest_start_noflag(skb,
182
+ MDBA_MDB_ENTRY_INFO);
183
+ if (!nest_ent)
184
+ return -EMSGSIZE;
185
+
186
+ if (nla_put_nohdr(skb, sizeof(e), &e) ||
187
+ nla_put_u32(skb,
188
+ MDBA_MDB_EATTR_TIMER,
189
+ br_timer_value(mtimer)))
190
+ goto nest_err;
191
+
192
+ switch (mp->addr.proto) {
193
+ case htons(ETH_P_IP):
194
+ dump_srcs_mode = !!(mp->br->multicast_igmp_version == 3);
195
+ if (mp->addr.src.ip4) {
196
+ if (nla_put_in_addr(skb, MDBA_MDB_EATTR_SOURCE,
197
+ mp->addr.src.ip4))
198
+ goto nest_err;
199
+ break;
200
+ }
201
+ break;
202
+#if IS_ENABLED(CONFIG_IPV6)
203
+ case htons(ETH_P_IPV6):
204
+ dump_srcs_mode = !!(mp->br->multicast_mld_version == 2);
205
+ if (!ipv6_addr_any(&mp->addr.src.ip6)) {
206
+ if (nla_put_in6_addr(skb, MDBA_MDB_EATTR_SOURCE,
207
+ &mp->addr.src.ip6))
208
+ goto nest_err;
209
+ break;
210
+ }
211
+ break;
212
+#endif
213
+ }
214
+ if (p) {
215
+ if (nla_put_u8(skb, MDBA_MDB_EATTR_RTPROT, p->rt_protocol))
216
+ goto nest_err;
217
+ if (dump_srcs_mode &&
218
+ (__mdb_fill_srcs(skb, p) ||
219
+ nla_put_u8(skb, MDBA_MDB_EATTR_GROUP_MODE,
220
+ p->filter_mode)))
221
+ goto nest_err;
222
+ }
223
+ nla_nest_end(skb, nest_ent);
224
+
225
+ return 0;
226
+
227
+nest_err:
228
+ nla_nest_cancel(skb, nest_ent);
229
+ return -EMSGSIZE;
76230 }
77231
78232 static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
79233 struct net_device *dev)
80234 {
235
+ int idx = 0, s_idx = cb->args[1], err = 0, pidx = 0, s_pidx = cb->args[2];
81236 struct net_bridge *br = netdev_priv(dev);
82
- struct net_bridge_mdb_htable *mdb;
237
+ struct net_bridge_mdb_entry *mp;
83238 struct nlattr *nest, *nest2;
84
- int i, err = 0;
85
- int idx = 0, s_idx = cb->args[1];
86239
87
- if (br->multicast_disabled)
240
+ if (!br_opt_get(br, BROPT_MULTICAST_ENABLED))
88241 return 0;
89242
90
- mdb = rcu_dereference(br->mdb);
91
- if (!mdb)
92
- return 0;
93
-
94
- nest = nla_nest_start(skb, MDBA_MDB);
243
+ nest = nla_nest_start_noflag(skb, MDBA_MDB);
95244 if (nest == NULL)
96245 return -EMSGSIZE;
97246
98
- for (i = 0; i < mdb->max; i++) {
99
- struct net_bridge_mdb_entry *mp;
247
+ hlist_for_each_entry_rcu(mp, &br->mdb_list, mdb_node) {
100248 struct net_bridge_port_group *p;
101249 struct net_bridge_port_group __rcu **pp;
102
- struct net_bridge_port *port;
103250
104
- hlist_for_each_entry_rcu(mp, &mdb->mhash[i], hlist[mdb->ver]) {
105
- if (idx < s_idx)
106
- goto skip;
251
+ if (idx < s_idx)
252
+ goto skip;
107253
108
- nest2 = nla_nest_start(skb, MDBA_MDB_ENTRY);
109
- if (nest2 == NULL) {
110
- err = -EMSGSIZE;
254
+ nest2 = nla_nest_start_noflag(skb, MDBA_MDB_ENTRY);
255
+ if (!nest2) {
256
+ err = -EMSGSIZE;
257
+ break;
258
+ }
259
+
260
+ if (!s_pidx && mp->host_joined) {
261
+ err = __mdb_fill_info(skb, mp, NULL);
262
+ if (err) {
263
+ nla_nest_cancel(skb, nest2);
264
+ break;
265
+ }
266
+ }
267
+
268
+ for (pp = &mp->ports; (p = rcu_dereference(*pp)) != NULL;
269
+ pp = &p->next) {
270
+ if (!p->key.port)
271
+ continue;
272
+ if (pidx < s_pidx)
273
+ goto skip_pg;
274
+
275
+ err = __mdb_fill_info(skb, mp, p);
276
+ if (err) {
277
+ nla_nest_end(skb, nest2);
111278 goto out;
112279 }
113
-
114
- for (pp = &mp->ports;
115
- (p = rcu_dereference(*pp)) != NULL;
116
- pp = &p->next) {
117
- struct nlattr *nest_ent;
118
- struct br_mdb_entry e;
119
-
120
- port = p->port;
121
- if (!port)
122
- continue;
123
-
124
- memset(&e, 0, sizeof(e));
125
- e.ifindex = port->dev->ifindex;
126
- e.vid = p->addr.vid;
127
- __mdb_entry_fill_flags(&e, p->flags);
128
- if (p->addr.proto == htons(ETH_P_IP))
129
- e.addr.u.ip4 = p->addr.u.ip4;
130
-#if IS_ENABLED(CONFIG_IPV6)
131
- if (p->addr.proto == htons(ETH_P_IPV6))
132
- e.addr.u.ip6 = p->addr.u.ip6;
133
-#endif
134
- e.addr.proto = p->addr.proto;
135
- nest_ent = nla_nest_start(skb,
136
- MDBA_MDB_ENTRY_INFO);
137
- if (!nest_ent) {
138
- nla_nest_cancel(skb, nest2);
139
- err = -EMSGSIZE;
140
- goto out;
141
- }
142
- if (nla_put_nohdr(skb, sizeof(e), &e) ||
143
- nla_put_u32(skb,
144
- MDBA_MDB_EATTR_TIMER,
145
- br_timer_value(&p->timer))) {
146
- nla_nest_cancel(skb, nest_ent);
147
- nla_nest_cancel(skb, nest2);
148
- err = -EMSGSIZE;
149
- goto out;
150
- }
151
- nla_nest_end(skb, nest_ent);
152
- }
153
- nla_nest_end(skb, nest2);
154
- skip:
155
- idx++;
280
+skip_pg:
281
+ pidx++;
156282 }
283
+ pidx = 0;
284
+ s_pidx = 0;
285
+ nla_nest_end(skb, nest2);
286
+skip:
287
+ idx++;
157288 }
158289
159290 out:
160291 cb->args[1] = idx;
292
+ cb->args[2] = pidx;
161293 nla_nest_end(skb, nest);
162294 return err;
295
+}
296
+
297
+static int br_mdb_valid_dump_req(const struct nlmsghdr *nlh,
298
+ struct netlink_ext_ack *extack)
299
+{
300
+ struct br_port_msg *bpm;
301
+
302
+ if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*bpm))) {
303
+ NL_SET_ERR_MSG_MOD(extack, "Invalid header for mdb dump request");
304
+ return -EINVAL;
305
+ }
306
+
307
+ bpm = nlmsg_data(nlh);
308
+ if (bpm->ifindex) {
309
+ NL_SET_ERR_MSG_MOD(extack, "Filtering by device index is not supported for mdb dump request");
310
+ return -EINVAL;
311
+ }
312
+ if (nlmsg_attrlen(nlh, sizeof(*bpm))) {
313
+ NL_SET_ERR_MSG(extack, "Invalid data after header in mdb dump request");
314
+ return -EINVAL;
315
+ }
316
+
317
+ return 0;
163318 }
164319
165320 static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
....@@ -169,12 +324,18 @@
169324 struct nlmsghdr *nlh = NULL;
170325 int idx = 0, s_idx;
171326
327
+ if (cb->strict_check) {
328
+ int err = br_mdb_valid_dump_req(cb->nlh, cb->extack);
329
+
330
+ if (err < 0)
331
+ return err;
332
+ }
333
+
172334 s_idx = cb->args[0];
173335
174336 rcu_read_lock();
175337
176
- /* In theory this could be wrapped to 0... */
177
- cb->seq = net->dev_base_seq + br_mdb_rehash_seq;
338
+ cb->seq = net->dev_base_seq;
178339
179340 for_each_netdev_rcu(net, dev) {
180341 if (dev->priv_flags & IFF_EBRIDGE) {
....@@ -214,14 +375,15 @@
214375
215376 static int nlmsg_populate_mdb_fill(struct sk_buff *skb,
216377 struct net_device *dev,
217
- struct br_mdb_entry *entry, u32 pid,
218
- u32 seq, int type, unsigned int flags)
378
+ struct net_bridge_mdb_entry *mp,
379
+ struct net_bridge_port_group *pg,
380
+ int type)
219381 {
220382 struct nlmsghdr *nlh;
221383 struct br_port_msg *bpm;
222384 struct nlattr *nest, *nest2;
223385
224
- nlh = nlmsg_put(skb, pid, seq, type, sizeof(*bpm), 0);
386
+ nlh = nlmsg_put(skb, 0, 0, type, sizeof(*bpm), 0);
225387 if (!nlh)
226388 return -EMSGSIZE;
227389
....@@ -229,14 +391,14 @@
229391 memset(bpm, 0, sizeof(*bpm));
230392 bpm->family = AF_BRIDGE;
231393 bpm->ifindex = dev->ifindex;
232
- nest = nla_nest_start(skb, MDBA_MDB);
394
+ nest = nla_nest_start_noflag(skb, MDBA_MDB);
233395 if (nest == NULL)
234396 goto cancel;
235
- nest2 = nla_nest_start(skb, MDBA_MDB_ENTRY);
397
+ nest2 = nla_nest_start_noflag(skb, MDBA_MDB_ENTRY);
236398 if (nest2 == NULL)
237399 goto end;
238400
239
- if (nla_put(skb, MDBA_MDB_ENTRY_INFO, sizeof(*entry), entry))
401
+ if (__mdb_fill_info(skb, mp, pg))
240402 goto end;
241403
242404 nla_nest_end(skb, nest2);
....@@ -251,10 +413,58 @@
251413 return -EMSGSIZE;
252414 }
253415
254
-static inline size_t rtnl_mdb_nlmsg_size(void)
416
+static size_t rtnl_mdb_nlmsg_size(struct net_bridge_port_group *pg)
255417 {
256
- return NLMSG_ALIGN(sizeof(struct br_port_msg))
257
- + nla_total_size(sizeof(struct br_mdb_entry));
418
+ size_t nlmsg_size = NLMSG_ALIGN(sizeof(struct br_port_msg)) +
419
+ nla_total_size(sizeof(struct br_mdb_entry)) +
420
+ nla_total_size(sizeof(u32));
421
+ struct net_bridge_group_src *ent;
422
+ size_t addr_size = 0;
423
+
424
+ if (!pg)
425
+ goto out;
426
+
427
+ /* MDBA_MDB_EATTR_RTPROT */
428
+ nlmsg_size += nla_total_size(sizeof(u8));
429
+
430
+ switch (pg->key.addr.proto) {
431
+ case htons(ETH_P_IP):
432
+ /* MDBA_MDB_EATTR_SOURCE */
433
+ if (pg->key.addr.src.ip4)
434
+ nlmsg_size += nla_total_size(sizeof(__be32));
435
+ if (pg->key.port->br->multicast_igmp_version == 2)
436
+ goto out;
437
+ addr_size = sizeof(__be32);
438
+ break;
439
+#if IS_ENABLED(CONFIG_IPV6)
440
+ case htons(ETH_P_IPV6):
441
+ /* MDBA_MDB_EATTR_SOURCE */
442
+ if (!ipv6_addr_any(&pg->key.addr.src.ip6))
443
+ nlmsg_size += nla_total_size(sizeof(struct in6_addr));
444
+ if (pg->key.port->br->multicast_mld_version == 1)
445
+ goto out;
446
+ addr_size = sizeof(struct in6_addr);
447
+ break;
448
+#endif
449
+ }
450
+
451
+ /* MDBA_MDB_EATTR_GROUP_MODE */
452
+ nlmsg_size += nla_total_size(sizeof(u8));
453
+
454
+ /* MDBA_MDB_EATTR_SRC_LIST nested attr */
455
+ if (!hlist_empty(&pg->src_list))
456
+ nlmsg_size += nla_total_size(0);
457
+
458
+ hlist_for_each_entry(ent, &pg->src_list, node) {
459
+ /* MDBA_MDB_SRCLIST_ENTRY nested attr +
460
+ * MDBA_MDB_SRCATTR_ADDRESS + MDBA_MDB_SRCATTR_TIMER
461
+ */
462
+ nlmsg_size += nla_total_size(0) +
463
+ nla_total_size(addr_size) +
464
+ nla_total_size(sizeof(u32));
465
+ }
466
+out:
467
+ return nlmsg_size;
258468 }
259469
260470 struct br_mdb_complete_info {
....@@ -267,7 +477,6 @@
267477 struct br_mdb_complete_info *data = priv;
268478 struct net_bridge_port_group __rcu **pp;
269479 struct net_bridge_port_group *p;
270
- struct net_bridge_mdb_htable *mdb;
271480 struct net_bridge_mdb_entry *mp;
272481 struct net_bridge_port *port = data->port;
273482 struct net_bridge *br = port->br;
....@@ -276,13 +485,12 @@
276485 goto err;
277486
278487 spin_lock_bh(&br->multicast_lock);
279
- mdb = mlock_dereference(br->mdb, br);
280
- mp = br_mdb_ip_get(mdb, &data->ip);
488
+ mp = br_mdb_ip_get(br, &data->ip);
281489 if (!mp)
282490 goto out;
283491 for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL;
284492 pp = &p->next) {
285
- if (p->port != port)
493
+ if (p->key.port != port)
286494 continue;
287495 p->flags |= MDB_PG_FLAGS_OFFLOAD;
288496 }
....@@ -294,27 +502,28 @@
294502
295503 static void br_mdb_switchdev_host_port(struct net_device *dev,
296504 struct net_device *lower_dev,
297
- struct br_mdb_entry *entry, int type)
505
+ struct net_bridge_mdb_entry *mp,
506
+ int type)
298507 {
299508 struct switchdev_obj_port_mdb mdb = {
300509 .obj = {
301510 .id = SWITCHDEV_OBJ_ID_HOST_MDB,
302511 .flags = SWITCHDEV_F_DEFER,
303512 },
304
- .vid = entry->vid,
513
+ .vid = mp->addr.vid,
305514 };
306515
307
- if (entry->addr.proto == htons(ETH_P_IP))
308
- ip_eth_mc_map(entry->addr.u.ip4, mdb.addr);
516
+ if (mp->addr.proto == htons(ETH_P_IP))
517
+ ip_eth_mc_map(mp->addr.dst.ip4, mdb.addr);
309518 #if IS_ENABLED(CONFIG_IPV6)
310519 else
311
- ipv6_eth_mc_map(&entry->addr.u.ip6, mdb.addr);
520
+ ipv6_eth_mc_map(&mp->addr.dst.ip6, mdb.addr);
312521 #endif
313522
314523 mdb.obj.orig_dev = dev;
315524 switch (type) {
316525 case RTM_NEWMDB:
317
- switchdev_port_obj_add(lower_dev, &mdb.obj);
526
+ switchdev_port_obj_add(lower_dev, &mdb.obj, NULL);
318527 break;
319528 case RTM_DELMDB:
320529 switchdev_port_obj_del(lower_dev, &mdb.obj);
....@@ -323,17 +532,19 @@
323532 }
324533
325534 static void br_mdb_switchdev_host(struct net_device *dev,
326
- struct br_mdb_entry *entry, int type)
535
+ struct net_bridge_mdb_entry *mp, int type)
327536 {
328537 struct net_device *lower_dev;
329538 struct list_head *iter;
330539
331540 netdev_for_each_lower_dev(dev, lower_dev, iter)
332
- br_mdb_switchdev_host_port(dev, lower_dev, entry, type);
541
+ br_mdb_switchdev_host_port(dev, lower_dev, mp, type);
333542 }
334543
335
-static void __br_mdb_notify(struct net_device *dev, struct net_bridge_port *p,
336
- struct br_mdb_entry *entry, int type)
544
+void br_mdb_notify(struct net_device *dev,
545
+ struct net_bridge_mdb_entry *mp,
546
+ struct net_bridge_port_group *pg,
547
+ int type)
337548 {
338549 struct br_mdb_complete_info *complete_info;
339550 struct switchdev_obj_port_mdb mdb = {
....@@ -341,44 +552,45 @@
341552 .id = SWITCHDEV_OBJ_ID_PORT_MDB,
342553 .flags = SWITCHDEV_F_DEFER,
343554 },
344
- .vid = entry->vid,
555
+ .vid = mp->addr.vid,
345556 };
346
- struct net_device *port_dev;
347557 struct net *net = dev_net(dev);
348558 struct sk_buff *skb;
349559 int err = -ENOBUFS;
350560
351
- port_dev = __dev_get_by_index(net, entry->ifindex);
352
- if (entry->addr.proto == htons(ETH_P_IP))
353
- ip_eth_mc_map(entry->addr.u.ip4, mdb.addr);
561
+ if (pg) {
562
+ if (mp->addr.proto == htons(ETH_P_IP))
563
+ ip_eth_mc_map(mp->addr.dst.ip4, mdb.addr);
354564 #if IS_ENABLED(CONFIG_IPV6)
355
- else
356
- ipv6_eth_mc_map(&entry->addr.u.ip6, mdb.addr);
565
+ else
566
+ ipv6_eth_mc_map(&mp->addr.dst.ip6, mdb.addr);
357567 #endif
358
-
359
- mdb.obj.orig_dev = port_dev;
360
- if (p && port_dev && type == RTM_NEWMDB) {
361
- complete_info = kmalloc(sizeof(*complete_info), GFP_ATOMIC);
362
- if (complete_info) {
363
- complete_info->port = p;
364
- __mdb_entry_to_br_ip(entry, &complete_info->ip);
568
+ mdb.obj.orig_dev = pg->key.port->dev;
569
+ switch (type) {
570
+ case RTM_NEWMDB:
571
+ complete_info = kmalloc(sizeof(*complete_info), GFP_ATOMIC);
572
+ if (!complete_info)
573
+ break;
574
+ complete_info->port = pg->key.port;
575
+ complete_info->ip = mp->addr;
365576 mdb.obj.complete_priv = complete_info;
366577 mdb.obj.complete = br_mdb_complete;
367
- if (switchdev_port_obj_add(port_dev, &mdb.obj))
578
+ if (switchdev_port_obj_add(pg->key.port->dev, &mdb.obj, NULL))
368579 kfree(complete_info);
580
+ break;
581
+ case RTM_DELMDB:
582
+ switchdev_port_obj_del(pg->key.port->dev, &mdb.obj);
583
+ break;
369584 }
370
- } else if (p && port_dev && type == RTM_DELMDB) {
371
- switchdev_port_obj_del(port_dev, &mdb.obj);
585
+ } else {
586
+ br_mdb_switchdev_host(dev, mp, type);
372587 }
373588
374
- if (!p)
375
- br_mdb_switchdev_host(dev, entry, type);
376
-
377
- skb = nlmsg_new(rtnl_mdb_nlmsg_size(), GFP_ATOMIC);
589
+ skb = nlmsg_new(rtnl_mdb_nlmsg_size(pg), GFP_ATOMIC);
378590 if (!skb)
379591 goto errout;
380592
381
- err = nlmsg_populate_mdb_fill(skb, dev, entry, 0, 0, type, NTF_SELF);
593
+ err = nlmsg_populate_mdb_fill(skb, dev, mp, pg, type);
382594 if (err < 0) {
383595 kfree_skb(skb);
384596 goto errout;
....@@ -388,26 +600,6 @@
388600 return;
389601 errout:
390602 rtnl_set_sk_err(net, RTNLGRP_MDB, err);
391
-}
392
-
393
-void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
394
- struct br_ip *group, int type, u8 flags)
395
-{
396
- struct br_mdb_entry entry;
397
-
398
- memset(&entry, 0, sizeof(entry));
399
- if (port)
400
- entry.ifindex = port->dev->ifindex;
401
- else
402
- entry.ifindex = dev->ifindex;
403
- entry.addr.proto = group->proto;
404
- entry.addr.u.ip4 = group->u.ip4;
405
-#if IS_ENABLED(CONFIG_IPV6)
406
- entry.addr.u.ip6 = group->u.ip6;
407
-#endif
408
- entry.vid = group->vid;
409
- __mdb_entry_fill_flags(&entry, flags);
410
- __br_mdb_notify(dev, port, &entry, type);
411603 }
412604
413605 static int nlmsg_populate_rtr_fill(struct sk_buff *skb,
....@@ -427,7 +619,7 @@
427619 memset(bpm, 0, sizeof(*bpm));
428620 bpm->family = AF_BRIDGE;
429621 bpm->ifindex = dev->ifindex;
430
- nest = nla_nest_start(skb, MDBA_ROUTER);
622
+ nest = nla_nest_start_noflag(skb, MDBA_ROUTER);
431623 if (!nest)
432624 goto cancel;
433625
....@@ -477,33 +669,94 @@
477669 rtnl_set_sk_err(net, RTNLGRP_MDB, err);
478670 }
479671
480
-static bool is_valid_mdb_entry(struct br_mdb_entry *entry)
672
+static bool is_valid_mdb_entry(struct br_mdb_entry *entry,
673
+ struct netlink_ext_ack *extack)
481674 {
482
- if (entry->ifindex == 0)
675
+ if (entry->ifindex == 0) {
676
+ NL_SET_ERR_MSG_MOD(extack, "Zero entry ifindex is not allowed");
483677 return false;
678
+ }
484679
485680 if (entry->addr.proto == htons(ETH_P_IP)) {
486
- if (!ipv4_is_multicast(entry->addr.u.ip4))
681
+ if (!ipv4_is_multicast(entry->addr.u.ip4)) {
682
+ NL_SET_ERR_MSG_MOD(extack, "IPv4 entry group address is not multicast");
487683 return false;
488
- if (ipv4_is_local_multicast(entry->addr.u.ip4))
684
+ }
685
+ if (ipv4_is_local_multicast(entry->addr.u.ip4)) {
686
+ NL_SET_ERR_MSG_MOD(extack, "IPv4 entry group address is local multicast");
489687 return false;
688
+ }
490689 #if IS_ENABLED(CONFIG_IPV6)
491690 } else if (entry->addr.proto == htons(ETH_P_IPV6)) {
492
- if (ipv6_addr_is_ll_all_nodes(&entry->addr.u.ip6))
691
+ if (ipv6_addr_is_ll_all_nodes(&entry->addr.u.ip6)) {
692
+ NL_SET_ERR_MSG_MOD(extack, "IPv6 entry group address is link-local all nodes");
493693 return false;
694
+ }
494695 #endif
495
- } else
696
+ } else {
697
+ NL_SET_ERR_MSG_MOD(extack, "Unknown entry protocol");
496698 return false;
497
- if (entry->state != MDB_PERMANENT && entry->state != MDB_TEMPORARY)
699
+ }
700
+
701
+ if (entry->state != MDB_PERMANENT && entry->state != MDB_TEMPORARY) {
702
+ NL_SET_ERR_MSG_MOD(extack, "Unknown entry state");
498703 return false;
499
- if (entry->vid >= VLAN_VID_MASK)
704
+ }
705
+ if (entry->vid >= VLAN_VID_MASK) {
706
+ NL_SET_ERR_MSG_MOD(extack, "Invalid entry VLAN id");
500707 return false;
708
+ }
501709
502710 return true;
503711 }
504712
713
+static bool is_valid_mdb_source(struct nlattr *attr, __be16 proto,
714
+ struct netlink_ext_ack *extack)
715
+{
716
+ switch (proto) {
717
+ case htons(ETH_P_IP):
718
+ if (nla_len(attr) != sizeof(struct in_addr)) {
719
+ NL_SET_ERR_MSG_MOD(extack, "IPv4 invalid source address length");
720
+ return false;
721
+ }
722
+ if (ipv4_is_multicast(nla_get_in_addr(attr))) {
723
+ NL_SET_ERR_MSG_MOD(extack, "IPv4 multicast source address is not allowed");
724
+ return false;
725
+ }
726
+ break;
727
+#if IS_ENABLED(CONFIG_IPV6)
728
+ case htons(ETH_P_IPV6): {
729
+ struct in6_addr src;
730
+
731
+ if (nla_len(attr) != sizeof(struct in6_addr)) {
732
+ NL_SET_ERR_MSG_MOD(extack, "IPv6 invalid source address length");
733
+ return false;
734
+ }
735
+ src = nla_get_in6_addr(attr);
736
+ if (ipv6_addr_is_multicast(&src)) {
737
+ NL_SET_ERR_MSG_MOD(extack, "IPv6 multicast source address is not allowed");
738
+ return false;
739
+ }
740
+ break;
741
+ }
742
+#endif
743
+ default:
744
+ NL_SET_ERR_MSG_MOD(extack, "Invalid protocol used with source address");
745
+ return false;
746
+ }
747
+
748
+ return true;
749
+}
750
+
751
+static const struct nla_policy br_mdbe_attrs_pol[MDBE_ATTR_MAX + 1] = {
752
+ [MDBE_ATTR_SOURCE] = NLA_POLICY_RANGE(NLA_BINARY,
753
+ sizeof(struct in_addr),
754
+ sizeof(struct in6_addr)),
755
+};
756
+
505757 static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh,
506
- struct net_device **pdev, struct br_mdb_entry **pentry)
758
+ struct net_device **pdev, struct br_mdb_entry **pentry,
759
+ struct nlattr **mdb_attrs, struct netlink_ext_ack *extack)
507760 {
508761 struct net *net = sock_net(skb->sk);
509762 struct br_mdb_entry *entry;
....@@ -512,198 +765,285 @@
512765 struct net_device *dev;
513766 int err;
514767
515
- err = nlmsg_parse(nlh, sizeof(*bpm), tb, MDBA_SET_ENTRY_MAX, NULL,
516
- NULL);
768
+ err = nlmsg_parse_deprecated(nlh, sizeof(*bpm), tb,
769
+ MDBA_SET_ENTRY_MAX, NULL, NULL);
517770 if (err < 0)
518771 return err;
519772
520773 bpm = nlmsg_data(nlh);
521774 if (bpm->ifindex == 0) {
522
- pr_info("PF_BRIDGE: br_mdb_parse() with invalid ifindex\n");
775
+ NL_SET_ERR_MSG_MOD(extack, "Invalid bridge ifindex");
523776 return -EINVAL;
524777 }
525778
526779 dev = __dev_get_by_index(net, bpm->ifindex);
527780 if (dev == NULL) {
528
- pr_info("PF_BRIDGE: br_mdb_parse() with unknown ifindex\n");
781
+ NL_SET_ERR_MSG_MOD(extack, "Bridge device doesn't exist");
529782 return -ENODEV;
530783 }
531784
532785 if (!(dev->priv_flags & IFF_EBRIDGE)) {
533
- pr_info("PF_BRIDGE: br_mdb_parse() with non-bridge\n");
786
+ NL_SET_ERR_MSG_MOD(extack, "Device is not a bridge");
534787 return -EOPNOTSUPP;
535788 }
536789
537790 *pdev = dev;
538791
539
- if (!tb[MDBA_SET_ENTRY] ||
540
- nla_len(tb[MDBA_SET_ENTRY]) != sizeof(struct br_mdb_entry)) {
541
- pr_info("PF_BRIDGE: br_mdb_parse() with invalid attr\n");
792
+ if (!tb[MDBA_SET_ENTRY]) {
793
+ NL_SET_ERR_MSG_MOD(extack, "Missing MDBA_SET_ENTRY attribute");
794
+ return -EINVAL;
795
+ }
796
+ if (nla_len(tb[MDBA_SET_ENTRY]) != sizeof(struct br_mdb_entry)) {
797
+ NL_SET_ERR_MSG_MOD(extack, "Invalid MDBA_SET_ENTRY attribute length");
542798 return -EINVAL;
543799 }
544800
545801 entry = nla_data(tb[MDBA_SET_ENTRY]);
546
- if (!is_valid_mdb_entry(entry)) {
547
- pr_info("PF_BRIDGE: br_mdb_parse() with invalid entry\n");
802
+ if (!is_valid_mdb_entry(entry, extack))
548803 return -EINVAL;
804
+ *pentry = entry;
805
+
806
+ if (tb[MDBA_SET_ENTRY_ATTRS]) {
807
+ err = nla_parse_nested(mdb_attrs, MDBE_ATTR_MAX,
808
+ tb[MDBA_SET_ENTRY_ATTRS],
809
+ br_mdbe_attrs_pol, extack);
810
+ if (err)
811
+ return err;
812
+ if (mdb_attrs[MDBE_ATTR_SOURCE] &&
813
+ !is_valid_mdb_source(mdb_attrs[MDBE_ATTR_SOURCE],
814
+ entry->addr.proto, extack))
815
+ return -EINVAL;
816
+ } else {
817
+ memset(mdb_attrs, 0,
818
+ sizeof(struct nlattr *) * (MDBE_ATTR_MAX + 1));
549819 }
550820
551
- *pentry = entry;
552821 return 0;
553822 }
554823
555824 static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
556
- struct br_ip *group, unsigned char state)
825
+ struct br_mdb_entry *entry,
826
+ struct nlattr **mdb_attrs,
827
+ struct netlink_ext_ack *extack)
557828 {
558
- struct net_bridge_mdb_entry *mp;
829
+ struct net_bridge_mdb_entry *mp, *star_mp;
559830 struct net_bridge_port_group *p;
560831 struct net_bridge_port_group __rcu **pp;
561
- struct net_bridge_mdb_htable *mdb;
832
+ struct br_ip group, star_group;
562833 unsigned long now = jiffies;
834
+ u8 filter_mode;
563835 int err;
564836
565
- mdb = mlock_dereference(br->mdb, br);
566
- mp = br_mdb_ip_get(mdb, group);
837
+ __mdb_entry_to_br_ip(entry, &group, mdb_attrs);
838
+
839
+ /* host join errors which can happen before creating the group */
840
+ if (!port) {
841
+ /* don't allow any flags for host-joined groups */
842
+ if (entry->state) {
843
+ NL_SET_ERR_MSG_MOD(extack, "Flags are not allowed for host groups");
844
+ return -EINVAL;
845
+ }
846
+ if (!br_multicast_is_star_g(&group)) {
847
+ NL_SET_ERR_MSG_MOD(extack, "Groups with sources cannot be manually host joined");
848
+ return -EINVAL;
849
+ }
850
+ }
851
+
852
+ mp = br_mdb_ip_get(br, &group);
567853 if (!mp) {
568
- mp = br_multicast_new_group(br, port, group);
854
+ mp = br_multicast_new_group(br, &group);
569855 err = PTR_ERR_OR_ZERO(mp);
570856 if (err)
571857 return err;
572858 }
573859
860
+ /* host join */
861
+ if (!port) {
862
+ if (mp->host_joined) {
863
+ NL_SET_ERR_MSG_MOD(extack, "Group is already joined by host");
864
+ return -EEXIST;
865
+ }
866
+
867
+ br_multicast_host_join(mp, false);
868
+ br_mdb_notify(br->dev, mp, NULL, RTM_NEWMDB);
869
+
870
+ return 0;
871
+ }
872
+
574873 for (pp = &mp->ports;
575874 (p = mlock_dereference(*pp, br)) != NULL;
576875 pp = &p->next) {
577
- if (p->port == port)
876
+ if (p->key.port == port) {
877
+ NL_SET_ERR_MSG_MOD(extack, "Group is already joined by port");
578878 return -EEXIST;
579
- if ((unsigned long)p->port < (unsigned long)port)
879
+ }
880
+ if ((unsigned long)p->key.port < (unsigned long)port)
580881 break;
581882 }
582883
583
- p = br_multicast_new_port_group(port, group, *pp, state, NULL);
584
- if (unlikely(!p))
884
+ filter_mode = br_multicast_is_star_g(&group) ? MCAST_EXCLUDE :
885
+ MCAST_INCLUDE;
886
+
887
+ p = br_multicast_new_port_group(port, &group, *pp, entry->state, NULL,
888
+ filter_mode, RTPROT_STATIC);
889
+ if (unlikely(!p)) {
890
+ NL_SET_ERR_MSG_MOD(extack, "Couldn't allocate new port group");
585891 return -ENOMEM;
892
+ }
586893 rcu_assign_pointer(*pp, p);
587
- if (state == MDB_TEMPORARY)
894
+ if (entry->state == MDB_TEMPORARY)
588895 mod_timer(&p->timer, now + br->multicast_membership_interval);
896
+ br_mdb_notify(br->dev, mp, p, RTM_NEWMDB);
897
+ /* if we are adding a new EXCLUDE port group (*,G) it needs to be also
898
+ * added to all S,G entries for proper replication, if we are adding
899
+ * a new INCLUDE port (S,G) then all of *,G EXCLUDE ports need to be
900
+ * added to it for proper replication
901
+ */
902
+ if (br_multicast_should_handle_mode(br, group.proto)) {
903
+ switch (filter_mode) {
904
+ case MCAST_EXCLUDE:
905
+ br_multicast_star_g_handle_mode(p, MCAST_EXCLUDE);
906
+ break;
907
+ case MCAST_INCLUDE:
908
+ star_group = p->key.addr;
909
+ memset(&star_group.src, 0, sizeof(star_group.src));
910
+ star_mp = br_mdb_ip_get(br, &star_group);
911
+ if (star_mp)
912
+ br_multicast_sg_add_exclude_ports(star_mp, p);
913
+ break;
914
+ }
915
+ }
589916
590917 return 0;
591918 }
592919
593920 static int __br_mdb_add(struct net *net, struct net_bridge *br,
594
- struct br_mdb_entry *entry)
921
+ struct net_bridge_port *p,
922
+ struct br_mdb_entry *entry,
923
+ struct nlattr **mdb_attrs,
924
+ struct netlink_ext_ack *extack)
595925 {
596
- struct br_ip ip;
597
- struct net_device *dev;
598
- struct net_bridge_port *p;
599926 int ret;
600927
601
- if (!netif_running(br->dev) || br->multicast_disabled)
602
- return -EINVAL;
603
-
604
- dev = __dev_get_by_index(net, entry->ifindex);
605
- if (!dev)
606
- return -ENODEV;
607
-
608
- p = br_port_get_rtnl(dev);
609
- if (!p || p->br != br || p->state == BR_STATE_DISABLED)
610
- return -EINVAL;
611
-
612
- __mdb_entry_to_br_ip(entry, &ip);
613
-
614928 spin_lock_bh(&br->multicast_lock);
615
- ret = br_mdb_add_group(br, p, &ip, entry->state);
929
+ ret = br_mdb_add_group(br, p, entry, mdb_attrs, extack);
616930 spin_unlock_bh(&br->multicast_lock);
931
+
617932 return ret;
618933 }
619934
620935 static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh,
621936 struct netlink_ext_ack *extack)
622937 {
938
+ struct nlattr *mdb_attrs[MDBE_ATTR_MAX + 1];
623939 struct net *net = sock_net(skb->sk);
624940 struct net_bridge_vlan_group *vg;
941
+ struct net_bridge_port *p = NULL;
625942 struct net_device *dev, *pdev;
626943 struct br_mdb_entry *entry;
627
- struct net_bridge_port *p;
628944 struct net_bridge_vlan *v;
629945 struct net_bridge *br;
630946 int err;
631947
632
- err = br_mdb_parse(skb, nlh, &dev, &entry);
948
+ err = br_mdb_parse(skb, nlh, &dev, &entry, mdb_attrs, extack);
633949 if (err < 0)
634950 return err;
635951
636952 br = netdev_priv(dev);
637953
954
+ if (!netif_running(br->dev)) {
955
+ NL_SET_ERR_MSG_MOD(extack, "Bridge device is not running");
956
+ return -EINVAL;
957
+ }
958
+
959
+ if (!br_opt_get(br, BROPT_MULTICAST_ENABLED)) {
960
+ NL_SET_ERR_MSG_MOD(extack, "Bridge's multicast processing is disabled");
961
+ return -EINVAL;
962
+ }
963
+
964
+ if (entry->ifindex != br->dev->ifindex) {
965
+ pdev = __dev_get_by_index(net, entry->ifindex);
966
+ if (!pdev) {
967
+ NL_SET_ERR_MSG_MOD(extack, "Port net device doesn't exist");
968
+ return -ENODEV;
969
+ }
970
+
971
+ p = br_port_get_rtnl(pdev);
972
+ if (!p) {
973
+ NL_SET_ERR_MSG_MOD(extack, "Net device is not a bridge port");
974
+ return -EINVAL;
975
+ }
976
+
977
+ if (p->br != br) {
978
+ NL_SET_ERR_MSG_MOD(extack, "Port belongs to a different bridge device");
979
+ return -EINVAL;
980
+ }
981
+ if (p->state == BR_STATE_DISABLED) {
982
+ NL_SET_ERR_MSG_MOD(extack, "Port is in disabled state");
983
+ return -EINVAL;
984
+ }
985
+ vg = nbp_vlan_group(p);
986
+ } else {
987
+ vg = br_vlan_group(br);
988
+ }
989
+
638990 /* If vlan filtering is enabled and VLAN is not specified
639991 * install mdb entry on all vlans configured on the port.
640992 */
641
- pdev = __dev_get_by_index(net, entry->ifindex);
642
- if (!pdev)
643
- return -ENODEV;
644
-
645
- p = br_port_get_rtnl(pdev);
646
- if (!p || p->br != br || p->state == BR_STATE_DISABLED)
647
- return -EINVAL;
648
-
649
- vg = nbp_vlan_group(p);
650993 if (br_vlan_enabled(br->dev) && vg && entry->vid == 0) {
651994 list_for_each_entry(v, &vg->vlan_list, vlist) {
652995 entry->vid = v->vid;
653
- err = __br_mdb_add(net, br, entry);
996
+ err = __br_mdb_add(net, br, p, entry, mdb_attrs, extack);
654997 if (err)
655998 break;
656
- __br_mdb_notify(dev, p, entry, RTM_NEWMDB);
657999 }
6581000 } else {
659
- err = __br_mdb_add(net, br, entry);
660
- if (!err)
661
- __br_mdb_notify(dev, p, entry, RTM_NEWMDB);
1001
+ err = __br_mdb_add(net, br, p, entry, mdb_attrs, extack);
6621002 }
6631003
6641004 return err;
6651005 }
6661006
667
-static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry)
1007
+static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry,
1008
+ struct nlattr **mdb_attrs)
6681009 {
669
- struct net_bridge_mdb_htable *mdb;
6701010 struct net_bridge_mdb_entry *mp;
6711011 struct net_bridge_port_group *p;
6721012 struct net_bridge_port_group __rcu **pp;
6731013 struct br_ip ip;
6741014 int err = -EINVAL;
6751015
676
- if (!netif_running(br->dev) || br->multicast_disabled)
1016
+ if (!netif_running(br->dev) || !br_opt_get(br, BROPT_MULTICAST_ENABLED))
6771017 return -EINVAL;
6781018
679
- __mdb_entry_to_br_ip(entry, &ip);
1019
+ __mdb_entry_to_br_ip(entry, &ip, mdb_attrs);
6801020
6811021 spin_lock_bh(&br->multicast_lock);
682
- mdb = mlock_dereference(br->mdb, br);
683
-
684
- mp = br_mdb_ip_get(mdb, &ip);
1022
+ mp = br_mdb_ip_get(br, &ip);
6851023 if (!mp)
6861024 goto unlock;
1025
+
1026
+ /* host leave */
1027
+ if (entry->ifindex == mp->br->dev->ifindex && mp->host_joined) {
1028
+ br_multicast_host_leave(mp, false);
1029
+ err = 0;
1030
+ br_mdb_notify(br->dev, mp, NULL, RTM_DELMDB);
1031
+ if (!mp->ports && netif_running(br->dev))
1032
+ mod_timer(&mp->timer, jiffies);
1033
+ goto unlock;
1034
+ }
6871035
6881036 for (pp = &mp->ports;
6891037 (p = mlock_dereference(*pp, br)) != NULL;
6901038 pp = &p->next) {
691
- if (!p->port || p->port->dev->ifindex != entry->ifindex)
1039
+ if (!p->key.port || p->key.port->dev->ifindex != entry->ifindex)
6921040 continue;
6931041
694
- if (p->port->state == BR_STATE_DISABLED)
1042
+ if (p->key.port->state == BR_STATE_DISABLED)
6951043 goto unlock;
6961044
697
- __mdb_entry_fill_flags(entry, p->flags);
698
- rcu_assign_pointer(*pp, p->next);
699
- hlist_del_init(&p->mglist);
700
- del_timer(&p->timer);
701
- call_rcu_bh(&p->rcu, br_multicast_free_pg);
1045
+ br_multicast_del_pg(mp, p, pp);
7021046 err = 0;
703
-
704
- if (!mp->ports && !mp->host_joined &&
705
- netif_running(br->dev))
706
- mod_timer(&mp->timer, jiffies);
7071047 break;
7081048 }
7091049
....@@ -715,44 +1055,45 @@
7151055 static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,
7161056 struct netlink_ext_ack *extack)
7171057 {
1058
+ struct nlattr *mdb_attrs[MDBE_ATTR_MAX + 1];
7181059 struct net *net = sock_net(skb->sk);
7191060 struct net_bridge_vlan_group *vg;
1061
+ struct net_bridge_port *p = NULL;
7201062 struct net_device *dev, *pdev;
7211063 struct br_mdb_entry *entry;
722
- struct net_bridge_port *p;
7231064 struct net_bridge_vlan *v;
7241065 struct net_bridge *br;
7251066 int err;
7261067
727
- err = br_mdb_parse(skb, nlh, &dev, &entry);
1068
+ err = br_mdb_parse(skb, nlh, &dev, &entry, mdb_attrs, extack);
7281069 if (err < 0)
7291070 return err;
7301071
7311072 br = netdev_priv(dev);
7321073
1074
+ if (entry->ifindex != br->dev->ifindex) {
1075
+ pdev = __dev_get_by_index(net, entry->ifindex);
1076
+ if (!pdev)
1077
+ return -ENODEV;
1078
+
1079
+ p = br_port_get_rtnl(pdev);
1080
+ if (!p || p->br != br || p->state == BR_STATE_DISABLED)
1081
+ return -EINVAL;
1082
+ vg = nbp_vlan_group(p);
1083
+ } else {
1084
+ vg = br_vlan_group(br);
1085
+ }
1086
+
7331087 /* If vlan filtering is enabled and VLAN is not specified
7341088 * delete mdb entry on all vlans configured on the port.
7351089 */
736
- pdev = __dev_get_by_index(net, entry->ifindex);
737
- if (!pdev)
738
- return -ENODEV;
739
-
740
- p = br_port_get_rtnl(pdev);
741
- if (!p || p->br != br || p->state == BR_STATE_DISABLED)
742
- return -EINVAL;
743
-
744
- vg = nbp_vlan_group(p);
7451090 if (br_vlan_enabled(br->dev) && vg && entry->vid == 0) {
7461091 list_for_each_entry(v, &vg->vlan_list, vlist) {
7471092 entry->vid = v->vid;
748
- err = __br_mdb_del(br, entry);
749
- if (!err)
750
- __br_mdb_notify(dev, p, entry, RTM_DELMDB);
1093
+ err = __br_mdb_del(br, entry, mdb_attrs);
7511094 }
7521095 } else {
753
- err = __br_mdb_del(br, entry);
754
- if (!err)
755
- __br_mdb_notify(dev, p, entry, RTM_DELMDB);
1096
+ err = __br_mdb_del(br, entry, mdb_attrs);
7561097 }
7571098
7581099 return err;