aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-07-15 03:13:44 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-15 03:13:44 -0400
commite308a5d806c852f56590ffdd3834d0df0cbed8d7 (patch)
tree294ff654e90950f5162737c26f4799b0b710b748 /net/core/dev.c
parentf1f28aa3510ddb84c966bac65611bb866c77a092 (diff)
netdev: Add netdev->addr_list_lock protection.
Add netif_addr_{lock,unlock}{,_bh}() helpers. Use them to protect operations that operate on or read the network device unicast and multicast address lists. Also use them in cases where the code simply wants to block calls into the driver's ->set_rx_mode() and ->set_multicast_list() methods. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index d933d1bfa6f..ef1502d71f2 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2982,7 +2982,9 @@ void __dev_set_rx_mode(struct net_device *dev)
2982void dev_set_rx_mode(struct net_device *dev) 2982void dev_set_rx_mode(struct net_device *dev)
2983{ 2983{
2984 netif_tx_lock_bh(dev); 2984 netif_tx_lock_bh(dev);
2985 netif_addr_lock(dev);
2985 __dev_set_rx_mode(dev); 2986 __dev_set_rx_mode(dev);
2987 netif_addr_unlock(dev);
2986 netif_tx_unlock_bh(dev); 2988 netif_tx_unlock_bh(dev);
2987} 2989}
2988 2990
@@ -3062,9 +3064,11 @@ int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
3062 ASSERT_RTNL(); 3064 ASSERT_RTNL();
3063 3065
3064 netif_tx_lock_bh(dev); 3066 netif_tx_lock_bh(dev);
3067 netif_addr_lock(dev);
3065 err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0); 3068 err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
3066 if (!err) 3069 if (!err)
3067 __dev_set_rx_mode(dev); 3070 __dev_set_rx_mode(dev);
3071 netif_addr_unlock(dev);
3068 netif_tx_unlock_bh(dev); 3072 netif_tx_unlock_bh(dev);
3069 return err; 3073 return err;
3070} 3074}
@@ -3088,9 +3092,11 @@ int dev_unicast_add(struct net_device *dev, void *addr, int alen)
3088 ASSERT_RTNL(); 3092 ASSERT_RTNL();
3089 3093
3090 netif_tx_lock_bh(dev); 3094 netif_tx_lock_bh(dev);
3095 netif_addr_lock(dev);
3091 err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0); 3096 err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
3092 if (!err) 3097 if (!err)
3093 __dev_set_rx_mode(dev); 3098 __dev_set_rx_mode(dev);
3099 netif_addr_unlock(dev);
3094 netif_tx_unlock_bh(dev); 3100 netif_tx_unlock_bh(dev);
3095 return err; 3101 return err;
3096} 3102}
@@ -3159,10 +3165,12 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from)
3159 int err = 0; 3165 int err = 0;
3160 3166
3161 netif_tx_lock_bh(to); 3167 netif_tx_lock_bh(to);
3168 netif_addr_lock(to);
3162 err = __dev_addr_sync(&to->uc_list, &to->uc_count, 3169 err = __dev_addr_sync(&to->uc_list, &to->uc_count,
3163 &from->uc_list, &from->uc_count); 3170 &from->uc_list, &from->uc_count);
3164 if (!err) 3171 if (!err)
3165 __dev_set_rx_mode(to); 3172 __dev_set_rx_mode(to);
3173 netif_addr_unlock(to);
3166 netif_tx_unlock_bh(to); 3174 netif_tx_unlock_bh(to);
3167 return err; 3175 return err;
3168} 3176}
@@ -3180,13 +3188,17 @@ EXPORT_SYMBOL(dev_unicast_sync);
3180void dev_unicast_unsync(struct net_device *to, struct net_device *from) 3188void dev_unicast_unsync(struct net_device *to, struct net_device *from)
3181{ 3189{
3182 netif_tx_lock_bh(from); 3190 netif_tx_lock_bh(from);
3191 netif_addr_lock(from);
3183 netif_tx_lock_bh(to); 3192 netif_tx_lock_bh(to);
3193 netif_addr_lock(to);
3184 3194
3185 __dev_addr_unsync(&to->uc_list, &to->uc_count, 3195 __dev_addr_unsync(&to->uc_list, &to->uc_count,
3186 &from->uc_list, &from->uc_count); 3196 &from->uc_list, &from->uc_count);
3187 __dev_set_rx_mode(to); 3197 __dev_set_rx_mode(to);
3188 3198
3199 netif_addr_unlock(to);
3189 netif_tx_unlock_bh(to); 3200 netif_tx_unlock_bh(to);
3201 netif_addr_unlock(from);
3190 netif_tx_unlock_bh(from); 3202 netif_tx_unlock_bh(from);
3191} 3203}
3192EXPORT_SYMBOL(dev_unicast_unsync); 3204EXPORT_SYMBOL(dev_unicast_unsync);
@@ -3208,6 +3220,7 @@ static void __dev_addr_discard(struct dev_addr_list **list)
3208static void dev_addr_discard(struct net_device *dev) 3220static void dev_addr_discard(struct net_device *dev)
3209{ 3221{
3210 netif_tx_lock_bh(dev); 3222 netif_tx_lock_bh(dev);
3223 netif_addr_lock(dev);
3211 3224
3212 __dev_addr_discard(&dev->uc_list); 3225 __dev_addr_discard(&dev->uc_list);
3213 dev->uc_count = 0; 3226 dev->uc_count = 0;
@@ -3215,6 +3228,7 @@ static void dev_addr_discard(struct net_device *dev)
3215 __dev_addr_discard(&dev->mc_list); 3228 __dev_addr_discard(&dev->mc_list);
3216 dev->mc_count = 0; 3229 dev->mc_count = 0;
3217 3230
3231 netif_addr_unlock(dev);
3218 netif_tx_unlock_bh(dev); 3232 netif_tx_unlock_bh(dev);
3219} 3233}
3220 3234