Loading net/packet/af_packet.c +24 −8 Original line number Diff line number Diff line Loading @@ -1380,6 +1380,8 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po) f->arr[f->num_members] = sk; smp_wmb(); f->num_members++; if (f->num_members == 1) dev_add_pack(&f->prot_hook); spin_unlock(&f->lock); } Loading @@ -1396,6 +1398,8 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po) BUG_ON(i >= f->num_members); f->arr[i] = f->arr[f->num_members - 1]; f->num_members--; if (f->num_members == 0) __dev_remove_pack(&f->prot_hook); spin_unlock(&f->lock); } Loading Loading @@ -1468,7 +1472,6 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) match->prot_hook.func = packet_rcv_fanout; match->prot_hook.af_packet_priv = match; match->prot_hook.id_match = match_fanout_group; dev_add_pack(&match->prot_hook); list_add(&match->list, &fanout_list); } err = -EINVAL; Loading @@ -1489,7 +1492,14 @@ out: return err; } static void fanout_release(struct sock *sk) /* If pkt_sk(sk)->fanout->sk_ref is zero, this function removes * pkt_sk(sk)->fanout from fanout_list and returns pkt_sk(sk)->fanout. * It is the responsibility of the caller to free the returned packet_fanout * (after synchronize_net()) * This Branch still does not have support classic BPF fanout mode. * upstream commit 47dceb8ecdc: packet: add classic BPF fanout mode */ static struct packet_fanout *fanout_release(struct sock *sk) { struct packet_sock *po = pkt_sk(sk); struct packet_fanout *f; Loading @@ -1499,13 +1509,15 @@ static void fanout_release(struct sock *sk) if (f) { po->fanout = NULL; if (atomic_dec_and_test(&f->sk_ref)) { if (atomic_dec_and_test(&f->sk_ref)) list_del(&f->list); dev_remove_pack(&f->prot_hook); kfree(f); } else f = NULL; } mutex_unlock(&fanout_mutex); return f; } static bool packet_extra_vlan_len_allowed(const struct net_device *dev, Loading Loading @@ -2587,6 +2599,7 @@ static int packet_release(struct socket *sock) { struct sock *sk = sock->sk; struct packet_sock *po; struct packet_fanout *f; struct net *net; union tpacket_req_u req_u; Loading Loading @@ -2626,9 +2639,13 @@ static int packet_release(struct socket *sock) packet_set_ring(sk, &req_u, 1, 1); } fanout_release(sk); f = fanout_release(sk); synchronize_net(); if (f) kfree(f); /* * Now the socket is dead. No more input will appear. */ Loading Loading @@ -3567,7 +3584,6 @@ static int packet_notifier(struct notifier_block *this, } if (msg == NETDEV_UNREGISTER) { packet_cached_dev_reset(po); fanout_release(sk); po->ifindex = -1; if (po->prot_hook.dev) dev_put(po->prot_hook.dev); Loading Loading
net/packet/af_packet.c +24 −8 Original line number Diff line number Diff line Loading @@ -1380,6 +1380,8 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po) f->arr[f->num_members] = sk; smp_wmb(); f->num_members++; if (f->num_members == 1) dev_add_pack(&f->prot_hook); spin_unlock(&f->lock); } Loading @@ -1396,6 +1398,8 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po) BUG_ON(i >= f->num_members); f->arr[i] = f->arr[f->num_members - 1]; f->num_members--; if (f->num_members == 0) __dev_remove_pack(&f->prot_hook); spin_unlock(&f->lock); } Loading Loading @@ -1468,7 +1472,6 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) match->prot_hook.func = packet_rcv_fanout; match->prot_hook.af_packet_priv = match; match->prot_hook.id_match = match_fanout_group; dev_add_pack(&match->prot_hook); list_add(&match->list, &fanout_list); } err = -EINVAL; Loading @@ -1489,7 +1492,14 @@ out: return err; } static void fanout_release(struct sock *sk) /* If pkt_sk(sk)->fanout->sk_ref is zero, this function removes * pkt_sk(sk)->fanout from fanout_list and returns pkt_sk(sk)->fanout. * It is the responsibility of the caller to free the returned packet_fanout * (after synchronize_net()) * This Branch still does not have support classic BPF fanout mode. * upstream commit 47dceb8ecdc: packet: add classic BPF fanout mode */ static struct packet_fanout *fanout_release(struct sock *sk) { struct packet_sock *po = pkt_sk(sk); struct packet_fanout *f; Loading @@ -1499,13 +1509,15 @@ static void fanout_release(struct sock *sk) if (f) { po->fanout = NULL; if (atomic_dec_and_test(&f->sk_ref)) { if (atomic_dec_and_test(&f->sk_ref)) list_del(&f->list); dev_remove_pack(&f->prot_hook); kfree(f); } else f = NULL; } mutex_unlock(&fanout_mutex); return f; } static bool packet_extra_vlan_len_allowed(const struct net_device *dev, Loading Loading @@ -2587,6 +2599,7 @@ static int packet_release(struct socket *sock) { struct sock *sk = sock->sk; struct packet_sock *po; struct packet_fanout *f; struct net *net; union tpacket_req_u req_u; Loading Loading @@ -2626,9 +2639,13 @@ static int packet_release(struct socket *sock) packet_set_ring(sk, &req_u, 1, 1); } fanout_release(sk); f = fanout_release(sk); synchronize_net(); if (f) kfree(f); /* * Now the socket is dead. No more input will appear. */ Loading Loading @@ -3567,7 +3584,6 @@ static int packet_notifier(struct notifier_block *this, } if (msg == NETDEV_UNREGISTER) { packet_cached_dev_reset(po); fanout_release(sk); po->ifindex = -1; if (po->prot_hook.dev) dev_put(po->prot_hook.dev); Loading