aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet/af_packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/packet/af_packet.c')
-rw-r--r--net/packet/af_packet.c69
1 files changed, 42 insertions, 27 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index ac27c86ef6d1..88cfbc189558 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
@@ -439,9 +460,9 @@ static void prb_shutdown_retire_blk_timer(struct packet_sock *po,
439 460
440 pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc; 461 pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc;
441 462
442 spin_lock(&rb_queue->lock); 463 spin_lock_bh(&rb_queue->lock);
443 pkc->delete_blk_timer = 1; 464 pkc->delete_blk_timer = 1;
444 spin_unlock(&rb_queue->lock); 465 spin_unlock_bh(&rb_queue->lock);
445 466
446 prb_del_retire_blk_timer(pkc); 467 prb_del_retire_blk_timer(pkc);
447} 468}
@@ -2059,19 +2080,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
2059 return tp_len; 2080 return tp_len;
2060} 2081}
2061 2082
2062static struct net_device *packet_cached_dev_get(struct packet_sock *po)
2063{
2064 struct net_device *dev;
2065
2066 rcu_read_lock();
2067 dev = rcu_dereference(po->cached_dev);
2068 if (dev)
2069 dev_hold(dev);
2070 rcu_read_unlock();
2071
2072 return dev;
2073}
2074
2075static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) 2083static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2076{ 2084{
2077 struct sk_buff *skb; 2085 struct sk_buff *skb;
@@ -2088,7 +2096,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
2088 2096
2089 mutex_lock(&po->pg_vec_lock); 2097 mutex_lock(&po->pg_vec_lock);
2090 2098
2091 if (saddr == NULL) { 2099 if (likely(saddr == NULL)) {
2092 dev = packet_cached_dev_get(po); 2100 dev = packet_cached_dev_get(po);
2093 proto = po->num; 2101 proto = po->num;
2094 addr = NULL; 2102 addr = NULL;
@@ -2242,7 +2250,7 @@ static int packet_snd(struct socket *sock,
2242 * Get and verify the address. 2250 * Get and verify the address.
2243 */ 2251 */
2244 2252
2245 if (saddr == NULL) { 2253 if (likely(saddr == NULL)) {
2246 dev = packet_cached_dev_get(po); 2254 dev = packet_cached_dev_get(po);
2247 proto = po->num; 2255 proto = po->num;
2248 addr = NULL; 2256 addr = NULL;
@@ -2451,6 +2459,8 @@ static int packet_release(struct socket *sock)
2451 2459
2452 spin_lock(&po->bind_lock); 2460 spin_lock(&po->bind_lock);
2453 unregister_prot_hook(sk, false); 2461 unregister_prot_hook(sk, false);
2462 packet_cached_dev_reset(po);
2463
2454 if (po->prot_hook.dev) { 2464 if (po->prot_hook.dev) {
2455 dev_put(po->prot_hook.dev); 2465 dev_put(po->prot_hook.dev);
2456 po->prot_hook.dev = NULL; 2466 po->prot_hook.dev = NULL;
@@ -2506,14 +2516,17 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc
2506 2516
2507 spin_lock(&po->bind_lock); 2517 spin_lock(&po->bind_lock);
2508 unregister_prot_hook(sk, true); 2518 unregister_prot_hook(sk, true);
2519
2509 po->num = protocol; 2520 po->num = protocol;
2510 po->prot_hook.type = protocol; 2521 po->prot_hook.type = protocol;
2511 if (po->prot_hook.dev) 2522 if (po->prot_hook.dev)
2512 dev_put(po->prot_hook.dev); 2523 dev_put(po->prot_hook.dev);
2513 po->prot_hook.dev = dev;
2514 2524
2525 po->prot_hook.dev = dev;
2515 po->ifindex = dev ? dev->ifindex : 0; 2526 po->ifindex = dev ? dev->ifindex : 0;
2516 2527
2528 packet_cached_dev_assign(po, dev);
2529
2517 if (protocol == 0) 2530 if (protocol == 0)
2518 goto out_unlock; 2531 goto out_unlock;
2519 2532
@@ -2626,7 +2639,8 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
2626 po = pkt_sk(sk); 2639 po = pkt_sk(sk);
2627 sk->sk_family = PF_PACKET; 2640 sk->sk_family = PF_PACKET;
2628 po->num = proto; 2641 po->num = proto;
2629 RCU_INIT_POINTER(po->cached_dev, NULL); 2642
2643 packet_cached_dev_reset(po);
2630 2644
2631 sk->sk_destruct = packet_sock_destruct; 2645 sk->sk_destruct = packet_sock_destruct;
2632 sk_refcnt_debug_inc(sk); 2646 sk_refcnt_debug_inc(sk);
@@ -3337,6 +3351,7 @@ static int packet_notifier(struct notifier_block *this,
3337 sk->sk_error_report(sk); 3351 sk->sk_error_report(sk);
3338 } 3352 }
3339 if (msg == NETDEV_UNREGISTER) { 3353 if (msg == NETDEV_UNREGISTER) {
3354 packet_cached_dev_reset(po);
3340 po->ifindex = -1; 3355 po->ifindex = -1;
3341 if (po->prot_hook.dev) 3356 if (po->prot_hook.dev)
3342 dev_put(po->prot_hook.dev); 3357 dev_put(po->prot_hook.dev);