diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 16 | ||||
-rw-r--r-- | net/packet/af_packet.c | 9 |
2 files changed, 23 insertions, 2 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index a39354ee1432..debd9372472f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1642,6 +1642,19 @@ static inline int deliver_skb(struct sk_buff *skb, | |||
1642 | return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); | 1642 | return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); |
1643 | } | 1643 | } |
1644 | 1644 | ||
1645 | static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) | ||
1646 | { | ||
1647 | if (ptype->af_packet_priv == NULL) | ||
1648 | return false; | ||
1649 | |||
1650 | if (ptype->id_match) | ||
1651 | return ptype->id_match(ptype, skb->sk); | ||
1652 | else if ((struct sock *)ptype->af_packet_priv == skb->sk) | ||
1653 | return true; | ||
1654 | |||
1655 | return false; | ||
1656 | } | ||
1657 | |||
1645 | /* | 1658 | /* |
1646 | * Support routine. Sends outgoing frames to any network | 1659 | * Support routine. Sends outgoing frames to any network |
1647 | * taps currently in use. | 1660 | * taps currently in use. |
@@ -1659,8 +1672,7 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) | |||
1659 | * they originated from - MvS (miquels@drinkel.ow.org) | 1672 | * they originated from - MvS (miquels@drinkel.ow.org) |
1660 | */ | 1673 | */ |
1661 | if ((ptype->dev == dev || !ptype->dev) && | 1674 | if ((ptype->dev == dev || !ptype->dev) && |
1662 | (ptype->af_packet_priv == NULL || | 1675 | (!skb_loop_sk(ptype, skb))) { |
1663 | (struct sock *)ptype->af_packet_priv != skb->sk)) { | ||
1664 | if (pt_prev) { | 1676 | if (pt_prev) { |
1665 | deliver_skb(skb2, pt_prev, skb->dev); | 1677 | deliver_skb(skb2, pt_prev, skb->dev); |
1666 | pt_prev = ptype; | 1678 | pt_prev = ptype; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 8ac890a1a4c0..aee7196aac36 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1273,6 +1273,14 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po) | |||
1273 | spin_unlock(&f->lock); | 1273 | spin_unlock(&f->lock); |
1274 | } | 1274 | } |
1275 | 1275 | ||
1276 | bool match_fanout_group(struct packet_type *ptype, struct sock * sk) | ||
1277 | { | ||
1278 | if (ptype->af_packet_priv == (void*)((struct packet_sock *)sk)->fanout) | ||
1279 | return true; | ||
1280 | |||
1281 | return false; | ||
1282 | } | ||
1283 | |||
1276 | static int fanout_add(struct sock *sk, u16 id, u16 type_flags) | 1284 | static int fanout_add(struct sock *sk, u16 id, u16 type_flags) |
1277 | { | 1285 | { |
1278 | struct packet_sock *po = pkt_sk(sk); | 1286 | struct packet_sock *po = pkt_sk(sk); |
@@ -1325,6 +1333,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) | |||
1325 | match->prot_hook.dev = po->prot_hook.dev; | 1333 | match->prot_hook.dev = po->prot_hook.dev; |
1326 | match->prot_hook.func = packet_rcv_fanout; | 1334 | match->prot_hook.func = packet_rcv_fanout; |
1327 | match->prot_hook.af_packet_priv = match; | 1335 | match->prot_hook.af_packet_priv = match; |
1336 | match->prot_hook.id_match = match_fanout_group; | ||
1328 | dev_add_pack(&match->prot_hook); | 1337 | dev_add_pack(&match->prot_hook); |
1329 | list_add(&match->list, &fanout_list); | 1338 | list_add(&match->list, &fanout_list); |
1330 | } | 1339 | } |