Skip to content

Commit 8d8e20e

Browse files
dwipbanerjeehorms
authored andcommitted
ipvs: Decrement ttl
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]>
1 parent fe24a0c commit 8d8e20e

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

net/netfilter/ipvs/ip_vs_xmit.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,54 @@ static inline bool ensure_mtu_is_adequate(struct netns_ipvs *ipvs, int skb_af,
254254
return true;
255255
}
256256

257+
static inline bool decrement_ttl(struct netns_ipvs *ipvs,
258+
int skb_af,
259+
struct sk_buff *skb)
260+
{
261+
struct net *net = ipvs->net;
262+
263+
#ifdef CONFIG_IP_VS_IPV6
264+
if (skb_af == AF_INET6) {
265+
struct dst_entry *dst = skb_dst(skb);
266+
267+
/* check and decrement ttl */
268+
if (ipv6_hdr(skb)->hop_limit <= 1) {
269+
/* Force OUTPUT device used as source address */
270+
skb->dev = dst->dev;
271+
icmpv6_send(skb, ICMPV6_TIME_EXCEED,
272+
ICMPV6_EXC_HOPLIMIT, 0);
273+
__IP6_INC_STATS(net, ip6_dst_idev(dst),
274+
IPSTATS_MIB_INHDRERRORS);
275+
276+
return false;
277+
}
278+
279+
/* don't propagate ttl change to cloned packets */
280+
if (!skb_make_writable(skb, sizeof(struct ipv6hdr)))
281+
return false;
282+
283+
ipv6_hdr(skb)->hop_limit--;
284+
} else
285+
#endif
286+
{
287+
if (ip_hdr(skb)->ttl <= 1) {
288+
/* Tell the sender its packet died... */
289+
__IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
290+
icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
291+
return false;
292+
}
293+
294+
/* don't propagate ttl change to cloned packets */
295+
if (!skb_make_writable(skb, sizeof(struct iphdr)))
296+
return false;
297+
298+
/* Decrease ttl */
299+
ip_decrease_ttl(ip_hdr(skb));
300+
}
301+
302+
return true;
303+
}
304+
257305
/* Get route to destination or remote server */
258306
static int
259307
__ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
@@ -326,6 +374,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
326374
return local;
327375
}
328376

377+
if (!decrement_ttl(ipvs, skb_af, skb))
378+
goto err_put;
379+
329380
if (likely(!(rt_mode & IP_VS_RT_MODE_TUNNEL))) {
330381
mtu = dst_mtu(&rt->dst);
331382
} else {
@@ -473,6 +524,9 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
473524
return local;
474525
}
475526

527+
if (!decrement_ttl(ipvs, skb_af, skb))
528+
goto err_put;
529+
476530
/* MTU checking */
477531
if (likely(!(rt_mode & IP_VS_RT_MODE_TUNNEL)))
478532
mtu = dst_mtu(&rt->dst);

0 commit comments

Comments
 (0)