Commit 5ca2ef67 authored by Andrea Claudi's avatar Andrea Claudi Committed by Greg Kroah-Hartman

ipvs: fix dependency on nf_defrag_ipv6

[ Upstream commit 098e13f5 ]

ipvs relies on nf_defrag_ipv6 module to manage IPv6 fragmentation,
but lacks proper Kconfig dependencies and does not explicitly
request defrag features.

As a result, if netfilter hooks are not loaded, when IPv6 fragmented
packet are handled by ipvs only the first fragment makes through.

Fix it properly declaring the dependency on Kconfig and registering
netfilter hooks on ip_vs_add_service() and ip_vs_new_dest().
Reported-by: default avatarLi Shuang <shuali@redhat.com>
Signed-off-by: default avatarAndrea Claudi <aclaudi@redhat.com>
Acked-by: default avatarJulian Anastasov <ja@ssi.bg>
Acked-by: default avatarSimon Horman <horms@verge.net.au>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 29452f66
...@@ -29,6 +29,7 @@ config IP_VS_IPV6 ...@@ -29,6 +29,7 @@ config IP_VS_IPV6
bool "IPv6 support for IPVS" bool "IPv6 support for IPVS"
depends on IPV6 = y || IP_VS = IPV6 depends on IPV6 = y || IP_VS = IPV6
select IP6_NF_IPTABLES select IP6_NF_IPTABLES
select NF_DEFRAG_IPV6
---help--- ---help---
Add IPv6 support to IPVS. Add IPv6 support to IPVS.
......
...@@ -1536,14 +1536,12 @@ ip_vs_try_to_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, ...@@ -1536,14 +1536,12 @@ ip_vs_try_to_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb,
/* sorry, all this trouble for a no-hit :) */ /* sorry, all this trouble for a no-hit :) */
IP_VS_DBG_PKT(12, af, pp, skb, iph->off, IP_VS_DBG_PKT(12, af, pp, skb, iph->off,
"ip_vs_in: packet continues traversal as normal"); "ip_vs_in: packet continues traversal as normal");
if (iph->fragoffs) {
/* Fragment that couldn't be mapped to a conn entry /* Fragment couldn't be mapped to a conn entry */
* is missing module nf_defrag_ipv6 if (iph->fragoffs)
*/
IP_VS_DBG_RL("Unhandled frag, load nf_defrag_ipv6\n");
IP_VS_DBG_PKT(7, af, pp, skb, iph->off, IP_VS_DBG_PKT(7, af, pp, skb, iph->off,
"unhandled fragment"); "unhandled fragment");
}
*verdict = NF_ACCEPT; *verdict = NF_ACCEPT;
return 0; return 0;
} }
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#ifdef CONFIG_IP_VS_IPV6 #ifdef CONFIG_IP_VS_IPV6
#include <net/ipv6.h> #include <net/ipv6.h>
#include <net/ip6_route.h> #include <net/ip6_route.h>
#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
#endif #endif
#include <net/route.h> #include <net/route.h>
#include <net/sock.h> #include <net/sock.h>
...@@ -895,6 +896,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest, ...@@ -895,6 +896,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest,
{ {
struct ip_vs_dest *dest; struct ip_vs_dest *dest;
unsigned int atype, i; unsigned int atype, i;
int ret = 0;
EnterFunction(2); EnterFunction(2);
...@@ -905,6 +907,10 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest, ...@@ -905,6 +907,10 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest,
atype & IPV6_ADDR_LINKLOCAL) && atype & IPV6_ADDR_LINKLOCAL) &&
!__ip_vs_addr_is_local_v6(svc->ipvs->net, &udest->addr.in6)) !__ip_vs_addr_is_local_v6(svc->ipvs->net, &udest->addr.in6))
return -EINVAL; return -EINVAL;
ret = nf_defrag_ipv6_enable(svc->ipvs->net);
if (ret)
return ret;
} else } else
#endif #endif
{ {
...@@ -1228,6 +1234,10 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, ...@@ -1228,6 +1234,10 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u,
ret = -EINVAL; ret = -EINVAL;
goto out_err; goto out_err;
} }
ret = nf_defrag_ipv6_enable(ipvs->net);
if (ret)
goto out_err;
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment