aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-12-09 20:20:14 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-09 20:20:14 -0500
commit34f9f437104b86f6ddfa2770e2cd852846385dc3 (patch)
tree6c78386b3db9dd47fd2b79efb4dcf8c1472de99e /net/packet
parent95dc19299f741c986227ec33e23cbf9b3321f812 (diff)
parent66e56cd46b93ef407c60adcac62cf33b06119d50 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Merge 'net' into 'net-next' to get the AF_PACKET bug fix that Daniel's direct transmit changes depend upon. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/packet')
-rw-r--r--net/packet/af_packet.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index c235da940019..e4171dd98590 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -237,6 +237,30 @@ struct packet_skb_cb {
237static void __fanout_unlink(struct sock *sk, struct packet_sock *po); 237static void __fanout_unlink(struct sock *sk, struct packet_sock *po);
238static void __fanout_link(struct sock *sk, struct packet_sock *po); 238static void __fanout_link(struct sock *sk, struct packet_sock *po);
239 239
240static struct net_device *packet_cached_dev_get(struct packet_sock *po)
241{
242 struct net_device *dev;
243
244 rcu_read_lock();
245 dev = rcu_dereference(po->cached_dev);
246 if (likely(dev))
247 dev_hold(dev);
248 rcu_read_unlock();
249
250 return dev;
251}
252
253static void packet_cached_dev_assign(struct packet_sock *po,
254 struct net_device *dev)
255{
256 rcu_assign_pointer(po->cached_dev, dev);
257}
258
259static void packet_cached_dev_reset(struct packet_sock *po)
260{
261 RCU_INIT_POINTER(po->cached_dev, NULL);
262}
263
240/* register_prot_hook must be invoked with the po->bind_lock held, 264/* register_prot_hook must be invoked with the po->bind_lock held,
241 * or from a context in which asynchronous accesses to the packet 265 * or from a context in which asynchronous accesses to the packet
242 * socket is not possible (packet_create()). 266 * socket is not possible (packet_create()).
@@ -246,12 +270,10 @@ static void register_prot_hook(struct sock *sk)
246 struct packet_sock *po = pkt_sk(sk); 270 struct packet_sock *po = pkt_sk(sk);
247 271
248 if (!po->running) { 272 if (!po->running) {
249 if (po->fanout) { 273 if (po->fanout)
250 __fanout_link(sk, po); 274 __fanout_link(sk, po);
251 } else { 275 else
252 dev_add_pack(&po->prot_hook); 276 dev_add_pack(&po->prot_hook);
253 rcu_assign_pointer(po->cached_dev, po->prot_hook.dev);
254 }
255 277
256 sock_hold(sk); 278 sock_hold(sk);
257 po->running = 1; 279 po->running = 1;
@@ -270,12 +292,11 @@ static void __unregister_prot_hook(struct sock *sk, bool sync)
270 struct packet_sock *po = pkt_sk(sk); 292 struct packet_sock *po = pkt_sk(sk);
271 293
272 po->running = 0; 294 po->running = 0;
273 if (po->fanout) { 295
296 if (po->fanout)
274 __fanout_unlink(sk, po); 297 __fanout_unlink(sk, po);
275 } else { 298 else
276 __dev_remove_pack(&po->prot_hook); 299 __dev_remove_pack(&po->prot_hook);
277 RCU_INIT_POINTER(po->cached_dev, NULL);
278 }
279 300
280 __sock_put(sk); 301 __sock_put(sk);
281 302
@@ -2061,19 +2082,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
2061 return tp_len; 2082 return tp_len;
2062} 2083}
2063 2084
2064static struct net_device *packet_cached_dev_get(struct packet_sock *po)
2065{
2066 struct net_device *dev;
2067
2068 rcu_read_lock();
2069 dev = rcu_dereference(po->cached_dev);
2070 if (dev)
2071 dev_hold(dev);
2072 rcu_read_unlock();
2073
2074 return dev;
2075}
2076
2077static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) 2085static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2078{ 2086{
2079 struct sk_buff *skb; 2087 struct sk_buff *skb;
@@ -2090,7 +2098,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2090 2098
2091 mutex_lock(&po->pg_vec_lock); 2099 mutex_lock(&po->pg_vec_lock);
2092 2100
2093 if (saddr == NULL) { 2101 if (likely(saddr == NULL)) {
2094 dev = packet_cached_dev_get(po); 2102 dev = packet_cached_dev_get(po);
2095 proto = po->num; 2103 proto = po->num;
2096 addr = NULL; 2104 addr = NULL;
@@ -2244,7 +2252,7 @@ static int packet_snd(struct socket *sock,
2244 * Get and verify the address. 2252 * Get and verify the address.
2245 */ 2253 */
2246 2254
2247 if (saddr == NULL) { 2255 if (likely(saddr == NULL)) {
2248 dev = packet_cached_dev_get(po); 2256 dev = packet_cached_dev_get(po);
2249 proto = po->num; 2257 proto = po->num;
2250 addr = NULL; 2258 addr = NULL;
@@ -2453,6 +2461,8 @@ static int packet_release(struct socket *sock)
2453 2461
2454 spin_lock(&po->bind_lock); 2462 spin_lock(&po->bind_lock);
2455 unregister_prot_hook(sk, false); 2463 unregister_prot_hook(sk, false);
2464 packet_cached_dev_reset(po);
2465
2456 if (po->prot_hook.dev) { 2466 if (po->prot_hook.dev) {
2457 dev_put(po->prot_hook.dev); 2467 dev_put(po->prot_hook.dev);
2458 po->prot_hook.dev = NULL; 2468 po->prot_hook.dev = NULL;
@@ -2508,14 +2518,17 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc
2508 2518
2509 spin_lock(&po->bind_lock); 2519 spin_lock(&po->bind_lock);
2510 unregister_prot_hook(sk, true); 2520 unregister_prot_hook(sk, true);
2521
2511 po->num = protocol; 2522 po->num = protocol;
2512 po->prot_hook.type = protocol; 2523 po->prot_hook.type = protocol;
2513 if (po->prot_hook.dev) 2524 if (po->prot_hook.dev)
2514 dev_put(po->prot_hook.dev); 2525 dev_put(po->prot_hook.dev);
2515 po->prot_hook.dev = dev;
2516 2526
2527 po->prot_hook.dev = dev;
2517 po->ifindex = dev ? dev->ifindex : 0; 2528 po->ifindex = dev ? dev->ifindex : 0;
2518 2529
2530 packet_cached_dev_assign(po, dev);
2531
2519 if (protocol == 0) 2532 if (protocol == 0)
2520 goto out_unlock; 2533 goto out_unlock;
2521 2534
@@ -2628,7 +2641,8 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
2628 po = pkt_sk(sk); 2641 po = pkt_sk(sk);
2629 sk->sk_family = PF_PACKET; 2642 sk->sk_family = PF_PACKET;
2630 po->num = proto; 2643 po->num = proto;
2631 RCU_INIT_POINTER(po->cached_dev, NULL); 2644
2645 packet_cached_dev_reset(po);
2632 2646
2633 sk->sk_destruct = packet_sock_destruct; 2647 sk->sk_destruct = packet_sock_destruct;
2634 sk_refcnt_debug_inc(sk); 2648 sk_refcnt_debug_inc(sk);
@@ -3339,6 +3353,7 @@ static int packet_notifier(struct notifier_block *this,
3339 sk->sk_error_report(sk); 3353 sk->sk_error_report(sk);
3340 } 3354 }
3341 if (msg == NETDEV_UNREGISTER) { 3355 if (msg == NETDEV_UNREGISTER) {
3356 packet_cached_dev_reset(po);
3342 po->ifindex = -1; 3357 po->ifindex = -1;
3343 if (po->prot_hook.dev) 3358 if (po->prot_hook.dev)
3344 dev_put(po->prot_hook.dev); 3359 dev_put(po->prot_hook.dev);