|
@@ -1642,6 +1642,19 @@ static inline int deliver_skb(struct sk_buff *skb,
|
|
|
return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
|
|
|
}
|
|
|
|
|
|
+static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb)
|
|
|
+{
|
|
|
+ if (ptype->af_packet_priv == NULL)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (ptype->id_match)
|
|
|
+ return ptype->id_match(ptype, skb->sk);
|
|
|
+ else if ((struct sock *)ptype->af_packet_priv == skb->sk)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Support routine. Sends outgoing frames to any network
|
|
|
* taps currently in use.
|
|
@@ -1659,8 +1672,7 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
|
|
|
* they originated from - MvS (miquels@drinkel.ow.org)
|
|
|
*/
|
|
|
if ((ptype->dev == dev || !ptype->dev) &&
|
|
|
- (ptype->af_packet_priv == NULL ||
|
|
|
- (struct sock *)ptype->af_packet_priv != skb->sk)) {
|
|
|
+ (!skb_loop_sk(ptype, skb))) {
|
|
|
if (pt_prev) {
|
|
|
deliver_skb(skb2, pt_prev, skb->dev);
|
|
|
pt_prev = ptype;
|