@@ -855,92 +855,128 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f,
855855 call_rcu (& f -> rcu , vxlan_fdb_free );
856856}
857857
858- /* Add new entry to forwarding table -- assumes lock held */
859- static int vxlan_fdb_update ( struct vxlan_dev * vxlan ,
860- const u8 * mac , union vxlan_addr * ip ,
861- __u16 state , __u16 flags ,
862- __be16 port , __be32 src_vni , __be32 vni ,
863- __u32 ifindex , __u16 ndm_flags ,
864- bool swdev_notify )
858+ static int vxlan_fdb_update_existing ( struct vxlan_dev * vxlan ,
859+ union vxlan_addr * ip ,
860+ __u16 state , __u16 flags ,
861+ __be16 port , __be32 vni ,
862+ __u32 ifindex , __u16 ndm_flags ,
863+ struct vxlan_fdb * f ,
864+ bool swdev_notify )
865865{
866866 __u16 fdb_flags = (ndm_flags & ~NTF_USE );
867867 struct vxlan_rdst * rd = NULL ;
868- struct vxlan_fdb * f ;
869868 int notify = 0 ;
870869 int rc ;
871870
872- f = __vxlan_find_mac (vxlan , mac , src_vni );
873- if (f ) {
874- if (flags & NLM_F_EXCL ) {
875- netdev_dbg (vxlan -> dev ,
876- "lost race to create %pM\n" , mac );
877- return - EEXIST ;
878- }
879-
880- /* Do not allow an externally learned entry to take over an
881- * entry added by the user.
882- */
883- if (!(fdb_flags & NTF_EXT_LEARNED ) ||
884- !(f -> flags & NTF_VXLAN_ADDED_BY_USER )) {
885- if (f -> state != state ) {
886- f -> state = state ;
887- f -> updated = jiffies ;
888- notify = 1 ;
889- }
890- if (f -> flags != fdb_flags ) {
891- f -> flags = fdb_flags ;
892- f -> updated = jiffies ;
893- notify = 1 ;
894- }
871+ /* Do not allow an externally learned entry to take over an entry added
872+ * by the user.
873+ */
874+ if (!(fdb_flags & NTF_EXT_LEARNED ) ||
875+ !(f -> flags & NTF_VXLAN_ADDED_BY_USER )) {
876+ if (f -> state != state ) {
877+ f -> state = state ;
878+ f -> updated = jiffies ;
879+ notify = 1 ;
895880 }
896-
897- if ((flags & NLM_F_REPLACE )) {
898- /* Only change unicasts */
899- if (!(is_multicast_ether_addr (f -> eth_addr ) ||
900- is_zero_ether_addr (f -> eth_addr ))) {
901- notify |= vxlan_fdb_replace (f , ip , port , vni ,
902- ifindex );
903- } else
904- return - EOPNOTSUPP ;
881+ if (f -> flags != fdb_flags ) {
882+ f -> flags = fdb_flags ;
883+ f -> updated = jiffies ;
884+ notify = 1 ;
905885 }
906- if ((flags & NLM_F_APPEND ) &&
907- (is_multicast_ether_addr (f -> eth_addr ) ||
908- is_zero_ether_addr (f -> eth_addr ))) {
909- rc = vxlan_fdb_append (f , ip , port , vni , ifindex , & rd );
886+ }
910887
911- if (rc < 0 )
912- return rc ;
888+ if ((flags & NLM_F_REPLACE )) {
889+ /* Only change unicasts */
890+ if (!(is_multicast_ether_addr (f -> eth_addr ) ||
891+ is_zero_ether_addr (f -> eth_addr ))) {
892+ rc = vxlan_fdb_replace (f , ip , port , vni ,
893+ ifindex );
913894 notify |= rc ;
914- }
915-
916- if (ndm_flags & NTF_USE )
917- f -> used = jiffies ;
918- } else {
919- if (!(flags & NLM_F_CREATE ))
920- return - ENOENT ;
921-
922- /* Disallow replace to add a multicast entry */
923- if ((flags & NLM_F_REPLACE ) &&
924- (is_multicast_ether_addr (mac ) || is_zero_ether_addr (mac )))
895+ } else {
925896 return - EOPNOTSUPP ;
897+ }
898+ }
899+ if ((flags & NLM_F_APPEND ) &&
900+ (is_multicast_ether_addr (f -> eth_addr ) ||
901+ is_zero_ether_addr (f -> eth_addr ))) {
902+ rc = vxlan_fdb_append (f , ip , port , vni , ifindex , & rd );
926903
927- netdev_dbg (vxlan -> dev , "add %pM -> %pIS\n" , mac , ip );
928- rc = vxlan_fdb_create (vxlan , mac , ip , state , port , src_vni ,
929- vni , ifindex , fdb_flags , & f );
930904 if (rc < 0 )
931905 return rc ;
932- notify = 1 ;
906+ notify |= rc ;
933907 }
934908
909+ if (ndm_flags & NTF_USE )
910+ f -> used = jiffies ;
911+
935912 if (notify ) {
936913 if (rd == NULL )
937914 rd = first_remote_rtnl (f );
915+
938916 vxlan_fdb_notify (vxlan , f , rd , RTM_NEWNEIGH , swdev_notify );
939917 }
940918
941919 return 0 ;
942920}
943921
922+ static int vxlan_fdb_update_create (struct vxlan_dev * vxlan ,
923+ const u8 * mac , union vxlan_addr * ip ,
924+ __u16 state , __u16 flags ,
925+ __be16 port , __be32 src_vni , __be32 vni ,
926+ __u32 ifindex , __u16 ndm_flags ,
927+ bool swdev_notify )
928+ {
929+ __u16 fdb_flags = (ndm_flags & ~NTF_USE );
930+ struct vxlan_fdb * f ;
931+ int rc ;
932+
933+ /* Disallow replace to add a multicast entry */
934+ if ((flags & NLM_F_REPLACE ) &&
935+ (is_multicast_ether_addr (mac ) || is_zero_ether_addr (mac )))
936+ return - EOPNOTSUPP ;
937+
938+ netdev_dbg (vxlan -> dev , "add %pM -> %pIS\n" , mac , ip );
939+ rc = vxlan_fdb_create (vxlan , mac , ip , state , port , src_vni ,
940+ vni , ifindex , fdb_flags , & f );
941+ if (rc < 0 )
942+ return rc ;
943+
944+ vxlan_fdb_notify (vxlan , f , first_remote_rtnl (f ), RTM_NEWNEIGH ,
945+ swdev_notify );
946+ return 0 ;
947+ }
948+
949+ /* Add new entry to forwarding table -- assumes lock held */
950+ static int vxlan_fdb_update (struct vxlan_dev * vxlan ,
951+ const u8 * mac , union vxlan_addr * ip ,
952+ __u16 state , __u16 flags ,
953+ __be16 port , __be32 src_vni , __be32 vni ,
954+ __u32 ifindex , __u16 ndm_flags ,
955+ bool swdev_notify )
956+ {
957+ struct vxlan_fdb * f ;
958+
959+ f = __vxlan_find_mac (vxlan , mac , src_vni );
960+ if (f ) {
961+ if (flags & NLM_F_EXCL ) {
962+ netdev_dbg (vxlan -> dev ,
963+ "lost race to create %pM\n" , mac );
964+ return - EEXIST ;
965+ }
966+
967+ return vxlan_fdb_update_existing (vxlan , ip , state , flags , port ,
968+ vni , ifindex , ndm_flags , f ,
969+ swdev_notify );
970+ } else {
971+ if (!(flags & NLM_F_CREATE ))
972+ return - ENOENT ;
973+
974+ return vxlan_fdb_update_create (vxlan , mac , ip , state , flags ,
975+ port , src_vni , vni , ifindex ,
976+ ndm_flags , swdev_notify );
977+ }
978+ }
979+
944980static void vxlan_dst_free (struct rcu_head * head )
945981{
946982 struct vxlan_rdst * rd = container_of (head , struct vxlan_rdst , rcu );
0 commit comments