aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
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
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')
-rw-r--r--net/core/dev.c14
-rw-r--r--net/core/dev_mcast.c12
2 files changed, 26 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index d933d1bfa6fa..ef1502d71f25 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
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index f8a3455f4493..b6b2a129971a 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -73,6 +73,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
73 int err; 73 int err;
74 74
75 netif_tx_lock_bh(dev); 75 netif_tx_lock_bh(dev);
76 netif_addr_lock(dev);
76 err = __dev_addr_delete(&dev->mc_list, &dev->mc_count, 77 err = __dev_addr_delete(&dev->mc_list, &dev->mc_count,
77 addr, alen, glbl); 78 addr, alen, glbl);
78 if (!err) { 79 if (!err) {
@@ -83,6 +84,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
83 84
84 __dev_set_rx_mode(dev); 85 __dev_set_rx_mode(dev);
85 } 86 }
87 netif_addr_unlock(dev);
86 netif_tx_unlock_bh(dev); 88 netif_tx_unlock_bh(dev);
87 return err; 89 return err;
88} 90}
@@ -96,9 +98,11 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
96 int err; 98 int err;
97 99
98 netif_tx_lock_bh(dev); 100 netif_tx_lock_bh(dev);
101 netif_addr_lock(dev);
99 err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); 102 err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
100 if (!err) 103 if (!err)
101 __dev_set_rx_mode(dev); 104 __dev_set_rx_mode(dev);
105 netif_addr_unlock(dev);
102 netif_tx_unlock_bh(dev); 106 netif_tx_unlock_bh(dev);
103 return err; 107 return err;
104} 108}
@@ -120,10 +124,12 @@ int dev_mc_sync(struct net_device *to, struct net_device *from)
120 int err = 0; 124 int err = 0;
121 125
122 netif_tx_lock_bh(to); 126 netif_tx_lock_bh(to);
127 netif_addr_lock(to);
123 err = __dev_addr_sync(&to->mc_list, &to->mc_count, 128 err = __dev_addr_sync(&to->mc_list, &to->mc_count,
124 &from->mc_list, &from->mc_count); 129 &from->mc_list, &from->mc_count);
125 if (!err) 130 if (!err)
126 __dev_set_rx_mode(to); 131 __dev_set_rx_mode(to);
132 netif_addr_unlock(to);
127 netif_tx_unlock_bh(to); 133 netif_tx_unlock_bh(to);
128 134
129 return err; 135 return err;
@@ -144,13 +150,17 @@ EXPORT_SYMBOL(dev_mc_sync);
144void dev_mc_unsync(struct net_device *to, struct net_device *from) 150void dev_mc_unsync(struct net_device *to, struct net_device *from)
145{ 151{
146 netif_tx_lock_bh(from); 152 netif_tx_lock_bh(from);
153 netif_addr_lock(from);
147 netif_tx_lock_bh(to); 154 netif_tx_lock_bh(to);
155 netif_addr_lock(to);
148 156
149 __dev_addr_unsync(&to->mc_list, &to->mc_count, 157 __dev_addr_unsync(&to->mc_list, &to->mc_count,
150 &from->mc_list, &from->mc_count); 158 &from->mc_list, &from->mc_count);
151 __dev_set_rx_mode(to); 159 __dev_set_rx_mode(to);
152 160
161 netif_addr_unlock(to);
153 netif_tx_unlock_bh(to); 162 netif_tx_unlock_bh(to);
163 netif_addr_unlock(from);
154 netif_tx_unlock_bh(from); 164 netif_tx_unlock_bh(from);
155} 165}
156EXPORT_SYMBOL(dev_mc_unsync); 166EXPORT_SYMBOL(dev_mc_unsync);
@@ -165,6 +175,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
165 return 0; 175 return 0;
166 176
167 netif_tx_lock_bh(dev); 177 netif_tx_lock_bh(dev);
178 netif_addr_lock(dev);
168 for (m = dev->mc_list; m; m = m->next) { 179 for (m = dev->mc_list; m; m = m->next) {
169 int i; 180 int i;
170 181
@@ -176,6 +187,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
176 187
177 seq_putc(seq, '\n'); 188 seq_putc(seq, '\n');
178 } 189 }
190 netif_addr_unlock(dev);
179 netif_tx_unlock_bh(dev); 191 netif_tx_unlock_bh(dev);
180 return 0; 192 return 0;
181} 193}