diff options
author | David S. Miller <davem@davemloft.net> | 2008-07-15 03:13:44 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-15 03:13:44 -0400 |
commit | e308a5d806c852f56590ffdd3834d0df0cbed8d7 (patch) | |
tree | 294ff654e90950f5162737c26f4799b0b710b748 /net/core | |
parent | f1f28aa3510ddb84c966bac65611bb866c77a092 (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.c | 14 | ||||
-rw-r--r-- | net/core/dev_mcast.c | 12 |
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) | |||
2982 | void dev_set_rx_mode(struct net_device *dev) | 2982 | void 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); | |||
3180 | void dev_unicast_unsync(struct net_device *to, struct net_device *from) | 3188 | void 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 | } |
3192 | EXPORT_SYMBOL(dev_unicast_unsync); | 3204 | EXPORT_SYMBOL(dev_unicast_unsync); |
@@ -3208,6 +3220,7 @@ static void __dev_addr_discard(struct dev_addr_list **list) | |||
3208 | static void dev_addr_discard(struct net_device *dev) | 3220 | static 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); | |||
144 | void dev_mc_unsync(struct net_device *to, struct net_device *from) | 150 | void 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 | } |
156 | EXPORT_SYMBOL(dev_mc_unsync); | 166 | EXPORT_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 | } |