Commit 4e478098 authored by Alex Gartrell's avatar Alex Gartrell Committed by Simon Horman
Browse files

ipvs: add sysctl to ignore tunneled packets



This is a way to avoid nasty routing loops when multiple ipvs instances can
forward to eachother.

Signed-off-by: default avatarAlex Gartrell <agartrell@fb.com>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
parent 5e26b1b3
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -157,6 +157,16 @@ expire_quiescent_template - BOOLEAN
	persistence template if it is to be used to schedule a new
	persistence template if it is to be used to schedule a new
	connection and the destination server is quiescent.
	connection and the destination server is quiescent.


ignore_tunneled - BOOLEAN
	0 - disabled (default)
	not 0 - enabled

	If set, ipvs will set the ipvs_property on all packets which are of
	unrecognized protocols.  This prevents us from routing tunneled
	protocols like ipip, which is useful to prevent rescheduling
	packets that have been tunneled to the ipvs host (i.e. to prevent
	ipvs routing loops when ipvs is also acting as a real server).

nat_icmp_send - BOOLEAN
nat_icmp_send - BOOLEAN
        0 - disabled (default)
        0 - disabled (default)
        not 0 - enabled
        not 0 - enabled
+11 −0
Original line number Original line Diff line number Diff line
@@ -998,6 +998,7 @@ struct netns_ipvs {
	int			sysctl_backup_only;
	int			sysctl_backup_only;
	int			sysctl_conn_reuse_mode;
	int			sysctl_conn_reuse_mode;
	int			sysctl_schedule_icmp;
	int			sysctl_schedule_icmp;
	int			sysctl_ignore_tunneled;


	/* ip_vs_lblc */
	/* ip_vs_lblc */
	int			sysctl_lblc_expiration;
	int			sysctl_lblc_expiration;
@@ -1121,6 +1122,11 @@ static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs)
	return ipvs->sysctl_schedule_icmp;
	return ipvs->sysctl_schedule_icmp;
}
}


static inline int sysctl_ignore_tunneled(struct netns_ipvs *ipvs)
{
	return ipvs->sysctl_ignore_tunneled;
}

#else
#else


static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs)
static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs)
@@ -1198,6 +1204,11 @@ static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs)
	return 0;
	return 0;
}
}


static inline int sysctl_ignore_tunneled(struct netns_ipvs *ipvs)
{
	return 0;
}

#endif
#endif


/* IPVS core functions
/* IPVS core functions
+9 −1
Original line number Original line Diff line number Diff line
@@ -1760,8 +1760,16 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)


	/* Protocol supported? */
	/* Protocol supported? */
	pd = ip_vs_proto_data_get(net, iph.protocol);
	pd = ip_vs_proto_data_get(net, iph.protocol);
	if (unlikely(!pd))
	if (unlikely(!pd)) {
		/* The only way we'll see this packet again is if it's
		 * encapsulated, so mark it with ipvs_property=1 so we
		 * skip it if we're ignoring tunneled packets
		 */
		if (sysctl_ignore_tunneled(ipvs))
			skb->ipvs_property = 1;

		return NF_ACCEPT;
		return NF_ACCEPT;
	}
	pp = pd->pp;
	pp = pd->pp;
	/*
	/*
	 * Check if the packet belongs to an existing connection entry
	 * Check if the packet belongs to an existing connection entry
+7 −0
Original line number Original line Diff line number Diff line
@@ -1850,6 +1850,12 @@ static struct ctl_table vs_vars[] = {
		.mode		= 0644,
		.mode		= 0644,
		.proc_handler	= proc_dointvec,
		.proc_handler	= proc_dointvec,
	},
	},
	{
		.procname	= "ignore_tunneled",
		.maxlen		= sizeof(int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec,
	},
#ifdef CONFIG_IP_VS_DEBUG
#ifdef CONFIG_IP_VS_DEBUG
	{
	{
		.procname	= "debug_level",
		.procname	= "debug_level",
@@ -3902,6 +3908,7 @@ static int __net_init ip_vs_control_net_init_sysctl(struct net *net)
	ipvs->sysctl_conn_reuse_mode = 1;
	ipvs->sysctl_conn_reuse_mode = 1;
	tbl[idx++].data = &ipvs->sysctl_conn_reuse_mode;
	tbl[idx++].data = &ipvs->sysctl_conn_reuse_mode;
	tbl[idx++].data = &ipvs->sysctl_schedule_icmp;
	tbl[idx++].data = &ipvs->sysctl_schedule_icmp;
	tbl[idx++].data = &ipvs->sysctl_ignore_tunneled;


	ipvs->sysctl_hdr = register_net_sysctl(net, "net/ipv4/vs", tbl);
	ipvs->sysctl_hdr = register_net_sysctl(net, "net/ipv4/vs", tbl);
	if (ipvs->sysctl_hdr == NULL) {
	if (ipvs->sysctl_hdr == NULL) {