summaryrefslogtreecommitdiff
path: root/include/net/ip6_tunnel.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/ip6_tunnel.h')
-rw-r--r--include/net/ip6_tunnel.h14
1 files changed, 14 insertions, 0 deletions
diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
index 120db2865811..359b595f1df9 100644
--- a/include/net/ip6_tunnel.h
+++ b/include/net/ip6_tunnel.h
@@ -156,6 +156,18 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
{
int pkt_len, err;
+ if (unlikely(dev_recursion_level() > IP_TUNNEL_RECURSION_LIMIT)) {
+ if (dev) {
+ net_crit_ratelimited("Dead loop on virtual device %s, fix it urgently!\n",
+ dev->name);
+ DEV_STATS_INC(dev, tx_errors);
+ }
+ kfree_skb(skb);
+ return;
+ }
+
+ dev_xmit_recursion_inc();
+
memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
IP6CB(skb)->flags = ip6cb_flags;
pkt_len = skb->len - skb_inner_network_offset(skb);
@@ -166,6 +178,8 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
pkt_len = -1;
iptunnel_xmit_stats(dev, pkt_len);
}
+
+ dev_xmit_recursion_dec();
}
#endif
#endif