@@ -75,8 +75,9 @@ static inline unsigned long hold_time(const struct net_bridge *br)
7575static inline int has_expired (const struct net_bridge * br ,
7676 const struct net_bridge_fdb_entry * fdb )
7777{
78- return !fdb -> is_static && !fdb -> added_by_external_learn &&
79- time_before_eq (fdb -> updated + hold_time (br ), jiffies );
78+ return !test_bit (BR_FDB_STATIC , & fdb -> flags ) &&
79+ !test_bit (BR_FDB_ADDED_BY_EXT_LEARN , & fdb -> flags ) &&
80+ time_before_eq (fdb -> updated + hold_time (br ), jiffies );
8081}
8182
8283static void fdb_rcu_free (struct rcu_head * head )
@@ -197,7 +198,7 @@ static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f,
197198{
198199 trace_fdb_delete (br , f );
199200
200- if (f -> is_static )
201+ if (test_bit ( BR_FDB_STATIC , & f -> flags ) )
201202 fdb_del_hw_addr (br , f -> key .addr .addr );
202203
203204 hlist_del_init_rcu (& f -> fdb_node );
@@ -224,7 +225,7 @@ static void fdb_delete_local(struct net_bridge *br,
224225 if (op != p && ether_addr_equal (op -> dev -> dev_addr , addr ) &&
225226 (!vid || br_vlan_find (vg , vid ))) {
226227 f -> dst = op ;
227- f -> added_by_user = 0 ;
228+ clear_bit ( BR_FDB_ADDED_BY_USER , & f -> flags ) ;
228229 return ;
229230 }
230231 }
@@ -235,7 +236,7 @@ static void fdb_delete_local(struct net_bridge *br,
235236 if (p && ether_addr_equal (br -> dev -> dev_addr , addr ) &&
236237 (!vid || (v && br_vlan_should_use (v )))) {
237238 f -> dst = NULL ;
238- f -> added_by_user = 0 ;
239+ clear_bit ( BR_FDB_ADDED_BY_USER , & f -> flags ) ;
239240 return ;
240241 }
241242
@@ -250,7 +251,8 @@ void br_fdb_find_delete_local(struct net_bridge *br,
250251
251252 spin_lock_bh (& br -> hash_lock );
252253 f = br_fdb_find (br , addr , vid );
253- if (f && f -> is_local && !f -> added_by_user && f -> dst == p )
254+ if (f && test_bit (BR_FDB_LOCAL , & f -> flags ) &&
255+ !test_bit (BR_FDB_ADDED_BY_USER , & f -> flags ) && f -> dst == p )
254256 fdb_delete_local (br , p , f );
255257 spin_unlock_bh (& br -> hash_lock );
256258}
@@ -265,7 +267,8 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr)
265267 spin_lock_bh (& br -> hash_lock );
266268 vg = nbp_vlan_group (p );
267269 hlist_for_each_entry (f , & br -> fdb_list , fdb_node ) {
268- if (f -> dst == p && f -> is_local && !f -> added_by_user ) {
270+ if (f -> dst == p && test_bit (BR_FDB_LOCAL , & f -> flags ) &&
271+ !test_bit (BR_FDB_ADDED_BY_USER , & f -> flags )) {
269272 /* delete old one */
270273 fdb_delete_local (br , p , f );
271274
@@ -306,7 +309,8 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
306309
307310 /* If old entry was unassociated with any port, then delete it. */
308311 f = br_fdb_find (br , br -> dev -> dev_addr , 0 );
309- if (f && f -> is_local && !f -> dst && !f -> added_by_user )
312+ if (f && test_bit (BR_FDB_LOCAL , & f -> flags ) &&
313+ !f -> dst && !test_bit (BR_FDB_ADDED_BY_USER , & f -> flags ))
310314 fdb_delete_local (br , NULL , f );
311315
312316 fdb_insert (br , NULL , newaddr , 0 );
@@ -321,7 +325,8 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
321325 if (!br_vlan_should_use (v ))
322326 continue ;
323327 f = br_fdb_find (br , br -> dev -> dev_addr , v -> vid );
324- if (f && f -> is_local && !f -> dst && !f -> added_by_user )
328+ if (f && test_bit (BR_FDB_LOCAL , & f -> flags ) &&
329+ !f -> dst && !test_bit (BR_FDB_ADDED_BY_USER , & f -> flags ))
325330 fdb_delete_local (br , NULL , f );
326331 fdb_insert (br , NULL , newaddr , v -> vid );
327332 }
@@ -346,7 +351,8 @@ void br_fdb_cleanup(struct work_struct *work)
346351 hlist_for_each_entry_rcu (f , & br -> fdb_list , fdb_node ) {
347352 unsigned long this_timer ;
348353
349- if (f -> is_static || f -> added_by_external_learn )
354+ if (test_bit (BR_FDB_STATIC , & f -> flags ) ||
355+ test_bit (BR_FDB_ADDED_BY_EXT_LEARN , & f -> flags ))
350356 continue ;
351357 this_timer = f -> updated + delay ;
352358 if (time_after (this_timer , now )) {
@@ -373,7 +379,7 @@ void br_fdb_flush(struct net_bridge *br)
373379
374380 spin_lock_bh (& br -> hash_lock );
375381 hlist_for_each_entry_safe (f , tmp , & br -> fdb_list , fdb_node ) {
376- if (!f -> is_static )
382+ if (!test_bit ( BR_FDB_STATIC , & f -> flags ) )
377383 fdb_delete (br , f , true);
378384 }
379385 spin_unlock_bh (& br -> hash_lock );
@@ -397,10 +403,11 @@ void br_fdb_delete_by_port(struct net_bridge *br,
397403 continue ;
398404
399405 if (!do_all )
400- if (f -> is_static || (vid && f -> key .vlan_id != vid ))
406+ if (test_bit (BR_FDB_STATIC , & f -> flags ) ||
407+ (vid && f -> key .vlan_id != vid ))
401408 continue ;
402409
403- if (f -> is_local )
410+ if (test_bit ( BR_FDB_LOCAL , & f -> flags ) )
404411 fdb_delete_local (br , p , f );
405412 else
406413 fdb_delete (br , f , true);
@@ -469,8 +476,8 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf,
469476 fe -> port_no = f -> dst -> port_no ;
470477 fe -> port_hi = f -> dst -> port_no >> 8 ;
471478
472- fe -> is_local = f -> is_local ;
473- if (!f -> is_static )
479+ fe -> is_local = test_bit ( BR_FDB_LOCAL , & f -> flags ) ;
480+ if (!test_bit ( BR_FDB_STATIC , & f -> flags ) )
474481 fe -> ageing_timer_value = jiffies_delta_to_clock_t (jiffies - f -> updated );
475482 ++ fe ;
476483 ++ num ;
@@ -484,8 +491,7 @@ static struct net_bridge_fdb_entry *fdb_create(struct net_bridge *br,
484491 struct net_bridge_port * source ,
485492 const unsigned char * addr ,
486493 __u16 vid ,
487- unsigned char is_local ,
488- unsigned char is_static )
494+ unsigned long flags )
489495{
490496 struct net_bridge_fdb_entry * fdb ;
491497
@@ -494,12 +500,7 @@ static struct net_bridge_fdb_entry *fdb_create(struct net_bridge *br,
494500 memcpy (fdb -> key .addr .addr , addr , ETH_ALEN );
495501 fdb -> dst = source ;
496502 fdb -> key .vlan_id = vid ;
497- fdb -> is_local = is_local ;
498- fdb -> is_static = is_static ;
499- fdb -> added_by_user = 0 ;
500- fdb -> added_by_external_learn = 0 ;
501- fdb -> offloaded = 0 ;
502- fdb -> is_sticky = 0 ;
503+ fdb -> flags = flags ;
503504 fdb -> updated = fdb -> used = jiffies ;
504505 if (rhashtable_lookup_insert_fast (& br -> fdb_hash_tbl ,
505506 & fdb -> rhnode ,
@@ -526,14 +527,15 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
526527 /* it is okay to have multiple ports with same
527528 * address, just use the first one.
528529 */
529- if (fdb -> is_local )
530+ if (test_bit ( BR_FDB_LOCAL , & fdb -> flags ) )
530531 return 0 ;
531532 br_warn (br , "adding interface %s with same address as a received packet (addr:%pM, vlan:%u)\n" ,
532533 source ? source -> dev -> name : br -> dev -> name , addr , vid );
533534 fdb_delete (br , fdb , true);
534535 }
535536
536- fdb = fdb_create (br , source , addr , vid , 1 , 1 );
537+ fdb = fdb_create (br , source , addr , vid ,
538+ BIT (BR_FDB_LOCAL ) | BIT (BR_FDB_STATIC ));
537539 if (!fdb )
538540 return - ENOMEM ;
539541
@@ -572,36 +574,37 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
572574 fdb = fdb_find_rcu (& br -> fdb_hash_tbl , addr , vid );
573575 if (likely (fdb )) {
574576 /* attempt to update an entry for a local interface */
575- if (unlikely (fdb -> is_local )) {
577+ if (unlikely (test_bit ( BR_FDB_LOCAL , & fdb -> flags ) )) {
576578 if (net_ratelimit ())
577579 br_warn (br , "received packet on %s with own address as source address (addr:%pM, vlan:%u)\n" ,
578580 source -> dev -> name , addr , vid );
579581 } else {
580582 unsigned long now = jiffies ;
581583
582584 /* fastpath: update of existing entry */
583- if (unlikely (source != fdb -> dst && !fdb -> is_sticky )) {
585+ if (unlikely (source != fdb -> dst &&
586+ !test_bit (BR_FDB_STICKY , & fdb -> flags ))) {
584587 fdb -> dst = source ;
585588 fdb_modified = true;
586589 /* Take over HW learned entry */
587- if ( unlikely ( fdb -> added_by_external_learn ))
588- fdb -> added_by_external_learn = 0 ;
590+ test_and_clear_bit ( BR_FDB_ADDED_BY_EXT_LEARN ,
591+ & fdb -> flags ) ;
589592 }
590593 if (now != fdb -> updated )
591594 fdb -> updated = now ;
592595 if (unlikely (added_by_user ))
593- fdb -> added_by_user = 1 ;
596+ set_bit ( BR_FDB_ADDED_BY_USER , & fdb -> flags ) ;
594597 if (unlikely (fdb_modified )) {
595598 trace_br_fdb_update (br , source , addr , vid , added_by_user );
596599 fdb_notify (br , fdb , RTM_NEWNEIGH , true);
597600 }
598601 }
599602 } else {
600603 spin_lock (& br -> hash_lock );
601- fdb = fdb_create (br , source , addr , vid , 0 , 0 );
604+ fdb = fdb_create (br , source , addr , vid , 0 );
602605 if (fdb ) {
603606 if (unlikely (added_by_user ))
604- fdb -> added_by_user = 1 ;
607+ set_bit ( BR_FDB_ADDED_BY_USER , & fdb -> flags ) ;
605608 trace_br_fdb_update (br , source , addr , vid ,
606609 added_by_user );
607610 fdb_notify (br , fdb , RTM_NEWNEIGH , true);
@@ -616,9 +619,9 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
616619static int fdb_to_nud (const struct net_bridge * br ,
617620 const struct net_bridge_fdb_entry * fdb )
618621{
619- if (fdb -> is_local )
622+ if (test_bit ( BR_FDB_LOCAL , & fdb -> flags ) )
620623 return NUD_PERMANENT ;
621- else if (fdb -> is_static )
624+ else if (test_bit ( BR_FDB_STATIC , & fdb -> flags ) )
622625 return NUD_NOARP ;
623626 else if (has_expired (br , fdb ))
624627 return NUD_STALE ;
@@ -648,11 +651,11 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
648651 ndm -> ndm_ifindex = fdb -> dst ? fdb -> dst -> dev -> ifindex : br -> dev -> ifindex ;
649652 ndm -> ndm_state = fdb_to_nud (br , fdb );
650653
651- if (fdb -> offloaded )
654+ if (test_bit ( BR_FDB_OFFLOADED , & fdb -> flags ) )
652655 ndm -> ndm_flags |= NTF_OFFLOADED ;
653- if (fdb -> added_by_external_learn )
656+ if (test_bit ( BR_FDB_ADDED_BY_EXT_LEARN , & fdb -> flags ) )
654657 ndm -> ndm_flags |= NTF_EXT_LEARNED ;
655- if (fdb -> is_sticky )
658+ if (test_bit ( BR_FDB_STICKY , & fdb -> flags ) )
656659 ndm -> ndm_flags |= NTF_STICKY ;
657660
658661 if (nla_put (skb , NDA_LLADDR , ETH_ALEN , & fdb -> key .addr ))
@@ -799,7 +802,7 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
799802 const u8 * addr , u16 state , u16 flags , u16 vid ,
800803 u8 ndm_flags )
801804{
802- u8 is_sticky = !!(ndm_flags & NTF_STICKY );
805+ bool is_sticky = !!(ndm_flags & NTF_STICKY );
803806 struct net_bridge_fdb_entry * fdb ;
804807 bool modified = false;
805808
@@ -823,7 +826,7 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
823826 if (!(flags & NLM_F_CREATE ))
824827 return - ENOENT ;
825828
826- fdb = fdb_create (br , source , addr , vid , 0 , 0 );
829+ fdb = fdb_create (br , source , addr , vid , 0 );
827830 if (!fdb )
828831 return - ENOMEM ;
829832
@@ -840,34 +843,28 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
840843
841844 if (fdb_to_nud (br , fdb ) != state ) {
842845 if (state & NUD_PERMANENT ) {
843- fdb -> is_local = 1 ;
844- if (!fdb -> is_static ) {
845- fdb -> is_static = 1 ;
846+ set_bit (BR_FDB_LOCAL , & fdb -> flags );
847+ if (!test_and_set_bit (BR_FDB_STATIC , & fdb -> flags ))
846848 fdb_add_hw_addr (br , addr );
847- }
848849 } else if (state & NUD_NOARP ) {
849- fdb -> is_local = 0 ;
850- if (!fdb -> is_static ) {
851- fdb -> is_static = 1 ;
850+ clear_bit (BR_FDB_LOCAL , & fdb -> flags );
851+ if (!test_and_set_bit (BR_FDB_STATIC , & fdb -> flags ))
852852 fdb_add_hw_addr (br , addr );
853- }
854853 } else {
855- fdb -> is_local = 0 ;
856- if (fdb -> is_static ) {
857- fdb -> is_static = 0 ;
854+ clear_bit (BR_FDB_LOCAL , & fdb -> flags );
855+ if (test_and_clear_bit (BR_FDB_STATIC , & fdb -> flags ))
858856 fdb_del_hw_addr (br , addr );
859- }
860857 }
861858
862859 modified = true;
863860 }
864861
865- if (is_sticky != fdb -> is_sticky ) {
866- fdb -> is_sticky = is_sticky ;
862+ if (is_sticky != test_bit ( BR_FDB_STICKY , & fdb -> flags ) ) {
863+ change_bit ( BR_FDB_STICKY , & fdb -> flags ) ;
867864 modified = true;
868865 }
869866
870- fdb -> added_by_user = 1 ;
867+ set_bit ( BR_FDB_ADDED_BY_USER , & fdb -> flags ) ;
871868
872869 fdb -> used = jiffies ;
873870 if (modified ) {
@@ -1064,7 +1061,7 @@ int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p)
10641061 rcu_read_lock ();
10651062 hlist_for_each_entry_rcu (f , & br -> fdb_list , fdb_node ) {
10661063 /* We only care for static entries */
1067- if (!f -> is_static )
1064+ if (!test_bit ( BR_FDB_STATIC , & f -> flags ) )
10681065 continue ;
10691066 err = dev_uc_add (p -> dev , f -> key .addr .addr );
10701067 if (err )
@@ -1078,7 +1075,7 @@ int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p)
10781075rollback :
10791076 hlist_for_each_entry_rcu (tmp , & br -> fdb_list , fdb_node ) {
10801077 /* We only care for static entries */
1081- if (!tmp -> is_static )
1078+ if (!test_bit ( BR_FDB_STATIC , & tmp -> flags ) )
10821079 continue ;
10831080 if (tmp == f )
10841081 break ;
@@ -1097,7 +1094,7 @@ void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p)
10971094 rcu_read_lock ();
10981095 hlist_for_each_entry_rcu (f , & br -> fdb_list , fdb_node ) {
10991096 /* We only care for static entries */
1100- if (!f -> is_static )
1097+ if (!test_bit ( BR_FDB_STATIC , & f -> flags ) )
11011098 continue ;
11021099
11031100 dev_uc_del (p -> dev , f -> key .addr .addr );
@@ -1119,14 +1116,14 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
11191116
11201117 fdb = br_fdb_find (br , addr , vid );
11211118 if (!fdb ) {
1122- fdb = fdb_create (br , p , addr , vid , 0 , 0 );
1119+ fdb = fdb_create (br , p , addr , vid , 0 );
11231120 if (!fdb ) {
11241121 err = - ENOMEM ;
11251122 goto err_unlock ;
11261123 }
11271124 if (swdev_notify )
1128- fdb -> added_by_user = 1 ;
1129- fdb -> added_by_external_learn = 1 ;
1125+ set_bit ( BR_FDB_ADDED_BY_USER , & fdb -> flags ) ;
1126+ set_bit ( BR_FDB_ADDED_BY_EXT_LEARN , & fdb -> flags ) ;
11301127 fdb_notify (br , fdb , RTM_NEWNEIGH , swdev_notify );
11311128 } else {
11321129 fdb -> updated = jiffies ;
@@ -1136,17 +1133,17 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
11361133 modified = true;
11371134 }
11381135
1139- if (fdb -> added_by_external_learn ) {
1136+ if (test_bit ( BR_FDB_ADDED_BY_EXT_LEARN , & fdb -> flags ) ) {
11401137 /* Refresh entry */
11411138 fdb -> used = jiffies ;
1142- } else if (!fdb -> added_by_user ) {
1139+ } else if (!test_bit ( BR_FDB_ADDED_BY_USER , & fdb -> flags ) ) {
11431140 /* Take over SW learned entry */
1144- fdb -> added_by_external_learn = 1 ;
1141+ set_bit ( BR_FDB_ADDED_BY_EXT_LEARN , & fdb -> flags ) ;
11451142 modified = true;
11461143 }
11471144
11481145 if (swdev_notify )
1149- fdb -> added_by_user = 1 ;
1146+ set_bit ( BR_FDB_ADDED_BY_USER , & fdb -> flags ) ;
11501147
11511148 if (modified )
11521149 fdb_notify (br , fdb , RTM_NEWNEIGH , swdev_notify );
@@ -1168,7 +1165,7 @@ int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
11681165 spin_lock_bh (& br -> hash_lock );
11691166
11701167 fdb = br_fdb_find (br , addr , vid );
1171- if (fdb && fdb -> added_by_external_learn )
1168+ if (fdb && test_bit ( BR_FDB_ADDED_BY_EXT_LEARN , & fdb -> flags ) )
11721169 fdb_delete (br , fdb , swdev_notify );
11731170 else
11741171 err = - ENOENT ;
@@ -1186,8 +1183,8 @@ void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p,
11861183 spin_lock_bh (& br -> hash_lock );
11871184
11881185 fdb = br_fdb_find (br , addr , vid );
1189- if (fdb )
1190- fdb -> offloaded = offloaded ;
1186+ if (fdb && offloaded != test_bit ( BR_FDB_OFFLOADED , & fdb -> flags ) )
1187+ change_bit ( BR_FDB_OFFLOADED , & fdb -> flags ) ;
11911188
11921189 spin_unlock_bh (& br -> hash_lock );
11931190}
@@ -1206,7 +1203,7 @@ void br_fdb_clear_offload(const struct net_device *dev, u16 vid)
12061203 spin_lock_bh (& p -> br -> hash_lock );
12071204 hlist_for_each_entry (f , & p -> br -> fdb_list , fdb_node ) {
12081205 if (f -> dst == p && f -> key .vlan_id == vid )
1209- f -> offloaded = 0 ;
1206+ clear_bit ( BR_FDB_OFFLOADED , & f -> flags ) ;
12101207 }
12111208 spin_unlock_bh (& p -> br -> hash_lock );
12121209}
0 commit comments