Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'ipvs-for-v4.10' of https://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-next

Simon Horman says:

====================
IPVS Updates for v4.10

please consider these enhancements to the IPVS for v4.10.

* Decrement the IP ttl in all the modes in order to prevent infinite
route loops. Thanks to Dwip Banerjee.
* Use IS_ERR_OR_NULL macro. Clean-up from Gao Feng.
====================

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

+55 -1
+1 -1
net/netfilter/ipvs/ip_vs_ctl.c
··· 3260 3260 3261 3261 3262 3262 svc = ip_vs_genl_find_service(ipvs, attrs[IPVS_CMD_ATTR_SERVICE]); 3263 - if (IS_ERR(svc) || svc == NULL) 3263 + if (IS_ERR_OR_NULL(svc)) 3264 3264 goto out_err; 3265 3265 3266 3266 /* Dump the destinations */
+54
net/netfilter/ipvs/ip_vs_xmit.c
··· 254 254 return true; 255 255 } 256 256 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 + 257 305 /* Get route to destination or remote server */ 258 306 static int 259 307 __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, ··· 373 325 ip_rt_put(rt); 374 326 return local; 375 327 } 328 + 329 + if (!decrement_ttl(ipvs, skb_af, skb)) 330 + goto err_put; 376 331 377 332 if (likely(!(rt_mode & IP_VS_RT_MODE_TUNNEL))) { 378 333 mtu = dst_mtu(&rt->dst); ··· 523 472 dst_release(&rt->dst); 524 473 return local; 525 474 } 475 + 476 + if (!decrement_ttl(ipvs, skb_af, skb)) 477 + goto err_put; 526 478 527 479 /* MTU checking */ 528 480 if (likely(!(rt_mode & IP_VS_RT_MODE_TUNNEL)))