Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a803040 authored by Julian Anastasov's avatar Julian Anastasov Committed by Patrick McHardy
Browse files

ipvs: make rerouting optional with snat_reroute



	Add new sysctl flag "snat_reroute". Recent kernels use
ip_route_me_harder() to route LVS-NAT responses properly by
VIP when there are multiple paths to client. But setups
that do not have alternative default routes can skip this
routing lookup by using snat_reroute=0.

Signed-off-by: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent f4bc17cd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -801,6 +801,7 @@ extern int sysctl_ip_vs_expire_quiescent_template;
extern int sysctl_ip_vs_sync_threshold[2];
extern int sysctl_ip_vs_nat_icmp_send;
extern int sysctl_ip_vs_conntrack;
extern int sysctl_ip_vs_snat_reroute;
extern struct ip_vs_stats ip_vs_stats;
extern const struct ctl_path net_vs_ctl_path[];

+29 −8
Original line number Diff line number Diff line
@@ -929,12 +929,22 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
		ip_send_check(ip_hdr(skb));
	}

	/*
	 * nf_iterate does not expect change in the skb->dst->dev.
	 * It looks like it is not fatal to enable this code for hooks
	 * where our handlers are at the end of the chain list and
	 * when all next handlers use skb->dst->dev and not outdev.
	 * It will definitely route properly the inout NAT traffic
	 * when multiple paths are used.
	 */

	/* For policy routing, packets originating from this
	 * machine itself may be routed differently to packets
	 * passing through.  We want this packet to be routed as
	 * if it came from this machine itself.  So re-compute
	 * the routing information.
	 */
	if (sysctl_ip_vs_snat_reroute) {
#ifdef CONFIG_IP_VS_IPV6
		if (af == AF_INET6) {
			if (ip6_route_me_harder(skb) != 0)
@@ -943,6 +953,7 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
#endif
			if (ip_route_me_harder(skb, RTN_LOCAL) != 0)
				goto drop;
	}

	IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");

@@ -991,8 +1002,13 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
		if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
			int related, verdict = ip_vs_out_icmp_v6(skb, &related);

			if (related)
			if (related) {
				if (sysctl_ip_vs_snat_reroute &&
					NF_ACCEPT == verdict &&
					ip6_route_me_harder(skb))
					verdict = NF_DROP;
				return verdict;
			}
			ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
		}
	} else
@@ -1000,8 +1016,13 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
		if (unlikely(iph.protocol == IPPROTO_ICMP)) {
			int related, verdict = ip_vs_out_icmp(skb, &related);

			if (related)
			if (related) {
				if (sysctl_ip_vs_snat_reroute &&
					NF_ACCEPT == verdict &&
					ip_route_me_harder(skb, RTN_LOCAL))
					verdict = NF_DROP;
				return verdict;
			}
			ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
		}

+8 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ int sysctl_ip_vs_nat_icmp_send = 0;
#ifdef CONFIG_IP_VS_NFCT
int sysctl_ip_vs_conntrack;
#endif
int sysctl_ip_vs_snat_reroute = 1;


#ifdef CONFIG_IP_VS_DEBUG
@@ -1599,6 +1600,13 @@ static struct ctl_table vs_vars[] = {
		.mode		= 0644,
		.proc_handler	= proc_do_defense_mode,
	},
	{
		.procname	= "snat_reroute",
		.data		= &sysctl_ip_vs_snat_reroute,
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= &proc_dointvec,
	},
#if 0
	{
		.procname	= "timeout_established",