@@ -75,6 +75,7 @@ static int ipvlan_port_create(struct net_device *dev)
7575 for (idx = 0 ; idx < IPVLAN_HASH_SIZE ; idx ++ )
7676 INIT_HLIST_HEAD (& port -> hlhead [idx ]);
7777
78+ spin_lock_init (& port -> addrs_lock );
7879 skb_queue_head_init (& port -> backlog );
7980 INIT_WORK (& port -> wq , ipvlan_process_multicast );
8081 ida_init (& port -> ida );
@@ -181,6 +182,7 @@ static void ipvlan_uninit(struct net_device *dev)
181182static int ipvlan_open (struct net_device * dev )
182183{
183184 struct ipvl_dev * ipvlan = netdev_priv (dev );
185+ struct ipvl_port * port = ipvlan -> port ;
184186 struct ipvl_addr * addr ;
185187
186188 if (ipvlan -> port -> mode == IPVLAN_MODE_L3 ||
@@ -189,10 +191,10 @@ static int ipvlan_open(struct net_device *dev)
189191 else
190192 dev -> flags &= ~IFF_NOARP ;
191193
192- rcu_read_lock ( );
193- list_for_each_entry_rcu (addr , & ipvlan -> addrs , anode )
194+ spin_lock_bh ( & port -> addrs_lock );
195+ list_for_each_entry (addr , & ipvlan -> addrs , anode )
194196 ipvlan_ht_addr_add (ipvlan , addr );
195- rcu_read_unlock ( );
197+ spin_unlock_bh ( & port -> addrs_lock );
196198
197199 return 0 ;
198200}
@@ -206,10 +208,10 @@ static int ipvlan_stop(struct net_device *dev)
206208 dev_uc_unsync (phy_dev , dev );
207209 dev_mc_unsync (phy_dev , dev );
208210
209- rcu_read_lock ( );
210- list_for_each_entry_rcu (addr , & ipvlan -> addrs , anode )
211+ spin_lock_bh ( & ipvlan -> port -> addrs_lock );
212+ list_for_each_entry (addr , & ipvlan -> addrs , anode )
211213 ipvlan_ht_addr_del (addr );
212- rcu_read_unlock ( );
214+ spin_unlock_bh ( & ipvlan -> port -> addrs_lock );
213215
214216 return 0 ;
215217}
@@ -579,7 +581,6 @@ int ipvlan_link_new(struct net_device *dev, struct rtnl_newlink_params *params,
579581 if (!tb [IFLA_MTU ])
580582 ipvlan_adjust_mtu (ipvlan , phy_dev );
581583 INIT_LIST_HEAD (& ipvlan -> addrs );
582- spin_lock_init (& ipvlan -> addrs_lock );
583584
584585 /* TODO Probably put random address here to be presented to the
585586 * world but keep using the physical-dev address for the outgoing
@@ -657,13 +658,13 @@ void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
657658 struct ipvl_dev * ipvlan = netdev_priv (dev );
658659 struct ipvl_addr * addr , * next ;
659660
660- spin_lock_bh (& ipvlan -> addrs_lock );
661+ spin_lock_bh (& ipvlan -> port -> addrs_lock );
661662 list_for_each_entry_safe (addr , next , & ipvlan -> addrs , anode ) {
662663 ipvlan_ht_addr_del (addr );
663664 list_del_rcu (& addr -> anode );
664665 kfree_rcu (addr , rcu );
665666 }
666- spin_unlock_bh (& ipvlan -> addrs_lock );
667+ spin_unlock_bh (& ipvlan -> port -> addrs_lock );
667668
668669 ida_free (& ipvlan -> port -> ida , dev -> dev_id );
669670 list_del_rcu (& ipvlan -> pnode );
@@ -817,6 +818,8 @@ static int ipvlan_add_addr(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6)
817818{
818819 struct ipvl_addr * addr ;
819820
821+ assert_spin_locked (& ipvlan -> port -> addrs_lock );
822+
820823 addr = kzalloc (sizeof (struct ipvl_addr ), GFP_ATOMIC );
821824 if (!addr )
822825 return - ENOMEM ;
@@ -847,16 +850,16 @@ static void ipvlan_del_addr(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6)
847850{
848851 struct ipvl_addr * addr ;
849852
850- spin_lock_bh (& ipvlan -> addrs_lock );
853+ spin_lock_bh (& ipvlan -> port -> addrs_lock );
851854 addr = ipvlan_find_addr (ipvlan , iaddr , is_v6 );
852855 if (!addr ) {
853- spin_unlock_bh (& ipvlan -> addrs_lock );
856+ spin_unlock_bh (& ipvlan -> port -> addrs_lock );
854857 return ;
855858 }
856859
857860 ipvlan_ht_addr_del (addr );
858861 list_del_rcu (& addr -> anode );
859- spin_unlock_bh (& ipvlan -> addrs_lock );
862+ spin_unlock_bh (& ipvlan -> port -> addrs_lock );
860863 kfree_rcu (addr , rcu );
861864}
862865
@@ -878,14 +881,14 @@ static int ipvlan_add_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr)
878881{
879882 int ret = - EINVAL ;
880883
881- spin_lock_bh (& ipvlan -> addrs_lock );
884+ spin_lock_bh (& ipvlan -> port -> addrs_lock );
882885 if (ipvlan_addr_busy (ipvlan -> port , ip6_addr , true))
883886 netif_err (ipvlan , ifup , ipvlan -> dev ,
884887 "Failed to add IPv6=%pI6c addr for %s intf\n" ,
885888 ip6_addr , ipvlan -> dev -> name );
886889 else
887890 ret = ipvlan_add_addr (ipvlan , ip6_addr , true);
888- spin_unlock_bh (& ipvlan -> addrs_lock );
891+ spin_unlock_bh (& ipvlan -> port -> addrs_lock );
889892 return ret ;
890893}
891894
@@ -924,36 +927,39 @@ static int ipvlan_addr6_validator_event(struct notifier_block *unused,
924927 struct in6_validator_info * i6vi = (struct in6_validator_info * )ptr ;
925928 struct net_device * dev = (struct net_device * )i6vi -> i6vi_dev -> dev ;
926929 struct ipvl_dev * ipvlan = netdev_priv (dev );
930+ int ret = NOTIFY_OK ;
927931
928932 if (!ipvlan_is_valid_dev (dev ))
929933 return NOTIFY_DONE ;
930934
931935 switch (event ) {
932936 case NETDEV_UP :
937+ spin_lock_bh (& ipvlan -> port -> addrs_lock );
933938 if (ipvlan_addr_busy (ipvlan -> port , & i6vi -> i6vi_addr , true)) {
934939 NL_SET_ERR_MSG (i6vi -> extack ,
935940 "Address already assigned to an ipvlan device" );
936- return notifier_from_errno (- EADDRINUSE );
941+ ret = notifier_from_errno (- EADDRINUSE );
937942 }
943+ spin_unlock_bh (& ipvlan -> port -> addrs_lock );
938944 break ;
939945 }
940946
941- return NOTIFY_OK ;
947+ return ret ;
942948}
943949#endif
944950
945951static int ipvlan_add_addr4 (struct ipvl_dev * ipvlan , struct in_addr * ip4_addr )
946952{
947953 int ret = - EINVAL ;
948954
949- spin_lock_bh (& ipvlan -> addrs_lock );
955+ spin_lock_bh (& ipvlan -> port -> addrs_lock );
950956 if (ipvlan_addr_busy (ipvlan -> port , ip4_addr , false))
951957 netif_err (ipvlan , ifup , ipvlan -> dev ,
952958 "Failed to add IPv4=%pI4 on %s intf.\n" ,
953959 ip4_addr , ipvlan -> dev -> name );
954960 else
955961 ret = ipvlan_add_addr (ipvlan , ip4_addr , false);
956- spin_unlock_bh (& ipvlan -> addrs_lock );
962+ spin_unlock_bh (& ipvlan -> port -> addrs_lock );
957963 return ret ;
958964}
959965
@@ -995,21 +1001,24 @@ static int ipvlan_addr4_validator_event(struct notifier_block *unused,
9951001 struct in_validator_info * ivi = (struct in_validator_info * )ptr ;
9961002 struct net_device * dev = (struct net_device * )ivi -> ivi_dev -> dev ;
9971003 struct ipvl_dev * ipvlan = netdev_priv (dev );
1004+ int ret = NOTIFY_OK ;
9981005
9991006 if (!ipvlan_is_valid_dev (dev ))
10001007 return NOTIFY_DONE ;
10011008
10021009 switch (event ) {
10031010 case NETDEV_UP :
1011+ spin_lock_bh (& ipvlan -> port -> addrs_lock );
10041012 if (ipvlan_addr_busy (ipvlan -> port , & ivi -> ivi_addr , false)) {
10051013 NL_SET_ERR_MSG (ivi -> extack ,
10061014 "Address already assigned to an ipvlan device" );
1007- return notifier_from_errno (- EADDRINUSE );
1015+ ret = notifier_from_errno (- EADDRINUSE );
10081016 }
1017+ spin_unlock_bh (& ipvlan -> port -> addrs_lock );
10091018 break ;
10101019 }
10111020
1012- return NOTIFY_OK ;
1021+ return ret ;
10131022}
10141023
10151024static struct notifier_block ipvlan_addr4_notifier_block __read_mostly = {
0 commit comments