aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c16
-rw-r--r--net/packet/af_packet.c9
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
1645static 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
1276bool 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
1276static int fanout_add(struct sock *sk, u16 id, u16 type_flags) 1284static 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 }