@@ -804,6 +804,14 @@ static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan,
804
804
return f ;
805
805
}
806
806
807
+ static void vxlan_fdb_link (struct vxlan_dev * vxlan , const u8 * mac ,
808
+ __be32 src_vni , struct vxlan_fdb * f )
809
+ {
810
+ ++ vxlan -> addrcnt ;
811
+ hlist_add_head_rcu (& f -> hlist ,
812
+ vxlan_fdb_head (vxlan , mac , src_vni ));
813
+ }
814
+
807
815
static int vxlan_fdb_create (struct vxlan_dev * vxlan ,
808
816
const u8 * mac , union vxlan_addr * ip ,
809
817
__u16 state , __be16 port , __be32 src_vni ,
@@ -829,10 +837,6 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
829
837
return rc ;
830
838
}
831
839
832
- ++ vxlan -> addrcnt ;
833
- hlist_add_head_rcu (& f -> hlist ,
834
- vxlan_fdb_head (vxlan , mac , src_vni ));
835
-
836
840
* fdb = f ;
837
841
838
842
return 0 ;
@@ -977,6 +981,7 @@ static int vxlan_fdb_update_create(struct vxlan_dev *vxlan,
977
981
if (rc < 0 )
978
982
return rc ;
979
983
984
+ vxlan_fdb_link (vxlan , mac , src_vni , f );
980
985
rc = vxlan_fdb_notify (vxlan , f , first_remote_rtnl (f ), RTM_NEWNEIGH ,
981
986
swdev_notify , extack );
982
987
if (rc )
@@ -3571,12 +3576,17 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev,
3571
3576
if (err )
3572
3577
goto errout ;
3573
3578
3574
- /* notify default fdb entry */
3575
3579
if (f ) {
3580
+ vxlan_fdb_link (vxlan , all_zeros_mac ,
3581
+ vxlan -> default_dst .remote_vni , f );
3582
+
3583
+ /* notify default fdb entry */
3576
3584
err = vxlan_fdb_notify (vxlan , f , first_remote_rtnl (f ),
3577
3585
RTM_NEWNEIGH , true, extack );
3578
- if (err )
3579
- goto errout ;
3586
+ if (err ) {
3587
+ vxlan_fdb_destroy (vxlan , f , false, false);
3588
+ goto unregister ;
3589
+ }
3580
3590
}
3581
3591
3582
3592
list_add (& vxlan -> next , & vn -> vxlan_list );
@@ -3588,7 +3598,8 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev,
3588
3598
* destroy the entry by hand here.
3589
3599
*/
3590
3600
if (f )
3591
- vxlan_fdb_destroy (vxlan , f , false, false);
3601
+ call_rcu (& f -> rcu , vxlan_fdb_free );
3602
+ unregister :
3592
3603
if (unregister )
3593
3604
unregister_netdevice (dev );
3594
3605
return err ;
0 commit comments