diff options
-rw-r--r-- | net/packet/af_packet.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 279467b74eb7..85bb38cb56fd 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -2567,9 +2567,12 @@ static int packet_release(struct socket *sock) | |||
2567 | * Attach a packet hook. | 2567 | * Attach a packet hook. |
2568 | */ | 2568 | */ |
2569 | 2569 | ||
2570 | static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protocol) | 2570 | static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 proto) |
2571 | { | 2571 | { |
2572 | struct packet_sock *po = pkt_sk(sk); | 2572 | struct packet_sock *po = pkt_sk(sk); |
2573 | const struct net_device *dev_curr; | ||
2574 | __be16 proto_curr; | ||
2575 | bool need_rehook; | ||
2573 | 2576 | ||
2574 | if (po->fanout) { | 2577 | if (po->fanout) { |
2575 | if (dev) | 2578 | if (dev) |
@@ -2579,21 +2582,29 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc | |||
2579 | } | 2582 | } |
2580 | 2583 | ||
2581 | lock_sock(sk); | 2584 | lock_sock(sk); |
2582 | |||
2583 | spin_lock(&po->bind_lock); | 2585 | spin_lock(&po->bind_lock); |
2584 | unregister_prot_hook(sk, true); | ||
2585 | 2586 | ||
2586 | po->num = protocol; | 2587 | proto_curr = po->prot_hook.type; |
2587 | po->prot_hook.type = protocol; | 2588 | dev_curr = po->prot_hook.dev; |
2588 | if (po->prot_hook.dev) | 2589 | |
2589 | dev_put(po->prot_hook.dev); | 2590 | need_rehook = proto_curr != proto || dev_curr != dev; |
2591 | |||
2592 | if (need_rehook) { | ||
2593 | unregister_prot_hook(sk, true); | ||
2590 | 2594 | ||
2591 | po->prot_hook.dev = dev; | 2595 | po->num = proto; |
2592 | po->ifindex = dev ? dev->ifindex : 0; | 2596 | po->prot_hook.type = proto; |
2597 | |||
2598 | if (po->prot_hook.dev) | ||
2599 | dev_put(po->prot_hook.dev); | ||
2593 | 2600 | ||
2594 | packet_cached_dev_assign(po, dev); | 2601 | po->prot_hook.dev = dev; |
2602 | |||
2603 | po->ifindex = dev ? dev->ifindex : 0; | ||
2604 | packet_cached_dev_assign(po, dev); | ||
2605 | } | ||
2595 | 2606 | ||
2596 | if (protocol == 0) | 2607 | if (proto == 0 || !need_rehook) |
2597 | goto out_unlock; | 2608 | goto out_unlock; |
2598 | 2609 | ||
2599 | if (!dev || (dev->flags & IFF_UP)) { | 2610 | if (!dev || (dev->flags & IFF_UP)) { |