@@ -41,6 +41,14 @@ static int br_rports_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
41
41
return - EMSGSIZE ;
42
42
}
43
43
44
+ static void __mdb_entry_fill_flags (struct br_mdb_entry * e , unsigned char flags )
45
+ {
46
+ e -> state = flags & MDB_PG_FLAGS_PERMANENT ;
47
+ e -> flags = 0 ;
48
+ if (flags & MDB_PG_FLAGS_OFFLOAD )
49
+ e -> flags |= MDB_FLAGS_OFFLOAD ;
50
+ }
51
+
44
52
static int br_mdb_fill_info (struct sk_buff * skb , struct netlink_callback * cb ,
45
53
struct net_device * dev )
46
54
{
@@ -85,8 +93,8 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
85
93
struct br_mdb_entry e ;
86
94
memset (& e , 0 , sizeof (e ));
87
95
e .ifindex = port -> dev -> ifindex ;
88
- e .state = p -> state ;
89
96
e .vid = p -> addr .vid ;
97
+ __mdb_entry_fill_flags (& e , p -> flags );
90
98
if (p -> addr .proto == htons (ETH_P_IP ))
91
99
e .addr .u .ip4 = p -> addr .u .ip4 ;
92
100
#if IS_ENABLED (CONFIG_IPV6 )
@@ -209,7 +217,7 @@ static inline size_t rtnl_mdb_nlmsg_size(void)
209
217
}
210
218
211
219
static void __br_mdb_notify (struct net_device * dev , struct br_mdb_entry * entry ,
212
- int type )
220
+ int type , struct net_bridge_port_group * pg )
213
221
{
214
222
struct switchdev_obj_port_mdb mdb = {
215
223
.obj = {
@@ -232,10 +240,13 @@ static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry,
232
240
#endif
233
241
234
242
mdb .obj .orig_dev = port_dev ;
235
- if (port_dev && type == RTM_NEWMDB )
236
- switchdev_port_obj_add (port_dev , & mdb .obj );
237
- else if (port_dev && type == RTM_DELMDB )
243
+ if (port_dev && type == RTM_NEWMDB ) {
244
+ err = switchdev_port_obj_add (port_dev , & mdb .obj );
245
+ if (!err && pg )
246
+ pg -> flags |= MDB_PG_FLAGS_OFFLOAD ;
247
+ } else if (port_dev && type == RTM_DELMDB ) {
238
248
switchdev_port_obj_del (port_dev , & mdb .obj );
249
+ }
239
250
240
251
skb = nlmsg_new (rtnl_mdb_nlmsg_size (), GFP_ATOMIC );
241
252
if (!skb )
@@ -253,21 +264,21 @@ static void __br_mdb_notify(struct net_device *dev, struct br_mdb_entry *entry,
253
264
rtnl_set_sk_err (net , RTNLGRP_MDB , err );
254
265
}
255
266
256
- void br_mdb_notify (struct net_device * dev , struct net_bridge_port * port ,
257
- struct br_ip * group , int type , u8 state )
267
+ void br_mdb_notify (struct net_device * dev , struct net_bridge_port_group * pg ,
268
+ int type )
258
269
{
259
270
struct br_mdb_entry entry ;
260
271
261
272
memset (& entry , 0 , sizeof (entry ));
262
- entry .ifindex = port -> dev -> ifindex ;
263
- entry .addr .proto = group -> proto ;
264
- entry .addr .u .ip4 = group -> u .ip4 ;
273
+ entry .ifindex = pg -> port -> dev -> ifindex ;
274
+ entry .addr .proto = pg -> addr . proto ;
275
+ entry .addr .u .ip4 = pg -> addr . u .ip4 ;
265
276
#if IS_ENABLED (CONFIG_IPV6 )
266
- entry .addr .u .ip6 = group -> u .ip6 ;
277
+ entry .addr .u .ip6 = pg -> addr . u .ip6 ;
267
278
#endif
268
- entry .state = state ;
269
- entry . vid = group -> vid ;
270
- __br_mdb_notify (dev , & entry , type );
279
+ entry .vid = pg -> addr . vid ;
280
+ __mdb_entry_fill_flags ( & entry , pg -> flags ) ;
281
+ __br_mdb_notify (dev , & entry , type , pg );
271
282
}
272
283
273
284
static int nlmsg_populate_rtr_fill (struct sk_buff * skb ,
@@ -412,7 +423,8 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh,
412
423
}
413
424
414
425
static int br_mdb_add_group (struct net_bridge * br , struct net_bridge_port * port ,
415
- struct br_ip * group , unsigned char state )
426
+ struct br_ip * group , unsigned char state ,
427
+ struct net_bridge_port_group * * pg )
416
428
{
417
429
struct net_bridge_mdb_entry * mp ;
418
430
struct net_bridge_port_group * p ;
@@ -443,14 +455,16 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
443
455
if (unlikely (!p ))
444
456
return - ENOMEM ;
445
457
rcu_assign_pointer (* pp , p );
458
+ * pg = p ;
446
459
if (state == MDB_TEMPORARY )
447
460
mod_timer (& p -> timer , now + br -> multicast_membership_interval );
448
461
449
462
return 0 ;
450
463
}
451
464
452
465
static int __br_mdb_add (struct net * net , struct net_bridge * br ,
453
- struct br_mdb_entry * entry )
466
+ struct br_mdb_entry * entry ,
467
+ struct net_bridge_port_group * * pg )
454
468
{
455
469
struct br_ip ip ;
456
470
struct net_device * dev ;
@@ -479,14 +493,15 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br,
479
493
#endif
480
494
481
495
spin_lock_bh (& br -> multicast_lock );
482
- ret = br_mdb_add_group (br , p , & ip , entry -> state );
496
+ ret = br_mdb_add_group (br , p , & ip , entry -> state , pg );
483
497
spin_unlock_bh (& br -> multicast_lock );
484
498
return ret ;
485
499
}
486
500
487
501
static int br_mdb_add (struct sk_buff * skb , struct nlmsghdr * nlh )
488
502
{
489
503
struct net * net = sock_net (skb -> sk );
504
+ struct net_bridge_port_group * pg ;
490
505
struct net_bridge_vlan_group * vg ;
491
506
struct net_device * dev , * pdev ;
492
507
struct br_mdb_entry * entry ;
@@ -516,15 +531,15 @@ static int br_mdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
516
531
if (br_vlan_enabled (br ) && vg && entry -> vid == 0 ) {
517
532
list_for_each_entry (v , & vg -> vlan_list , vlist ) {
518
533
entry -> vid = v -> vid ;
519
- err = __br_mdb_add (net , br , entry );
534
+ err = __br_mdb_add (net , br , entry , & pg );
520
535
if (err )
521
536
break ;
522
- __br_mdb_notify (dev , entry , RTM_NEWMDB );
537
+ __br_mdb_notify (dev , entry , RTM_NEWMDB , pg );
523
538
}
524
539
} else {
525
- err = __br_mdb_add (net , br , entry );
540
+ err = __br_mdb_add (net , br , entry , & pg );
526
541
if (!err )
527
- __br_mdb_notify (dev , entry , RTM_NEWMDB );
542
+ __br_mdb_notify (dev , entry , RTM_NEWMDB , pg );
528
543
}
529
544
530
545
return err ;
@@ -568,7 +583,7 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry)
568
583
if (p -> port -> state == BR_STATE_DISABLED )
569
584
goto unlock ;
570
585
571
- entry -> state = p -> state ;
586
+ __mdb_entry_fill_flags ( entry , p -> flags ) ;
572
587
rcu_assign_pointer (* pp , p -> next );
573
588
hlist_del_init (& p -> mglist );
574
589
del_timer (& p -> timer );
@@ -620,12 +635,12 @@ static int br_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
620
635
entry -> vid = v -> vid ;
621
636
err = __br_mdb_del (br , entry );
622
637
if (!err )
623
- __br_mdb_notify (dev , entry , RTM_DELMDB );
638
+ __br_mdb_notify (dev , entry , RTM_DELMDB , NULL );
624
639
}
625
640
} else {
626
641
err = __br_mdb_del (br , entry );
627
642
if (!err )
628
- __br_mdb_notify (dev , entry , RTM_DELMDB );
643
+ __br_mdb_notify (dev , entry , RTM_DELMDB , NULL );
629
644
}
630
645
631
646
return err ;
0 commit comments