Skip to content

Commit

Permalink
ipvs: Decrement ttl
Browse files Browse the repository at this point in the history
We decrement the IP ttl in all the modes in order to prevent infinite
route loops. The changes were done based on Julian Anastasov's
suggestions in a prior thread.

The ttl based check/discard and the actual decrement are done in
__ip_vs_get_out_rt() and in __ip_vs_get_out_rt_v6(), for the IPv6
case. decrement_ttl() implements the actual functionality for the
two cases.

Signed-off-by: Dwip Banerjee <[email protected]>
Acked-by: Julian Anastasov <[email protected]>
Signed-off-by: Simon Horman <[email protected]>
  • Loading branch information
dwipbanerjee authored and horms committed Nov 15, 2016
1 parent fe24a0c commit 8d8e20e
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions net/netfilter/ipvs/ip_vs_xmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,54 @@ static inline bool ensure_mtu_is_adequate(struct netns_ipvs *ipvs, int skb_af,
return true;
}

static inline bool decrement_ttl(struct netns_ipvs *ipvs,
int skb_af,
struct sk_buff *skb)
{
struct net *net = ipvs->net;

#ifdef CONFIG_IP_VS_IPV6
if (skb_af == AF_INET6) {
struct dst_entry *dst = skb_dst(skb);

/* check and decrement ttl */
if (ipv6_hdr(skb)->hop_limit <= 1) {
/* Force OUTPUT device used as source address */
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_TIME_EXCEED,
ICMPV6_EXC_HOPLIMIT, 0);
__IP6_INC_STATS(net, ip6_dst_idev(dst),
IPSTATS_MIB_INHDRERRORS);

return false;
}

/* don't propagate ttl change to cloned packets */
if (!skb_make_writable(skb, sizeof(struct ipv6hdr)))
return false;

ipv6_hdr(skb)->hop_limit--;
} else
#endif
{
if (ip_hdr(skb)->ttl <= 1) {
/* Tell the sender its packet died... */
__IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
return false;
}

/* don't propagate ttl change to cloned packets */
if (!skb_make_writable(skb, sizeof(struct iphdr)))
return false;

/* Decrease ttl */
ip_decrease_ttl(ip_hdr(skb));
}

return true;
}

/* Get route to destination or remote server */
static int
__ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
Expand Down Expand Up @@ -326,6 +374,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
return local;
}

if (!decrement_ttl(ipvs, skb_af, skb))
goto err_put;

if (likely(!(rt_mode & IP_VS_RT_MODE_TUNNEL))) {
mtu = dst_mtu(&rt->dst);
} else {
Expand Down Expand Up @@ -473,6 +524,9 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
return local;
}

if (!decrement_ttl(ipvs, skb_af, skb))
goto err_put;

/* MTU checking */
if (likely(!(rt_mode & IP_VS_RT_MODE_TUNNEL)))
mtu = dst_mtu(&rt->dst);
Expand Down

0 comments on commit 8d8e20e

Please sign in to comment.