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

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: Alex Gartrell <agartrell@fb.com>
Signed-off-by: Simon Horman <horms@verge.net.au>

authored by

Alex Gartrell and committed by
Simon Horman
4e478098 5e26b1b3

+37 -1
+10
Documentation/networking/ipvs-sysctl.txt
··· 157 157 persistence template if it is to be used to schedule a new 158 158 connection and the destination server is quiescent. 159 159 160 + ignore_tunneled - BOOLEAN 161 + 0 - disabled (default) 162 + not 0 - enabled 163 + 164 + If set, ipvs will set the ipvs_property on all packets which are of 165 + unrecognized protocols. This prevents us from routing tunneled 166 + protocols like ipip, which is useful to prevent rescheduling 167 + packets that have been tunneled to the ipvs host (i.e. to prevent 168 + ipvs routing loops when ipvs is also acting as a real server). 169 + 160 170 nat_icmp_send - BOOLEAN 161 171 0 - disabled (default) 162 172 not 0 - enabled
+11
include/net/ip_vs.h
··· 998 998 int sysctl_backup_only; 999 999 int sysctl_conn_reuse_mode; 1000 1000 int sysctl_schedule_icmp; 1001 + int sysctl_ignore_tunneled; 1001 1002 1002 1003 /* ip_vs_lblc */ 1003 1004 int sysctl_lblc_expiration; ··· 1122 1121 return ipvs->sysctl_schedule_icmp; 1123 1122 } 1124 1123 1124 + static inline int sysctl_ignore_tunneled(struct netns_ipvs *ipvs) 1125 + { 1126 + return ipvs->sysctl_ignore_tunneled; 1127 + } 1128 + 1125 1129 #else 1126 1130 1127 1131 static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs) ··· 1200 1194 } 1201 1195 1202 1196 static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs) 1197 + { 1198 + return 0; 1199 + } 1200 + 1201 + static inline int sysctl_ignore_tunneled(struct netns_ipvs *ipvs) 1203 1202 { 1204 1203 return 0; 1205 1204 }
+9 -1
net/netfilter/ipvs/ip_vs_core.c
··· 1760 1760 1761 1761 /* Protocol supported? */ 1762 1762 pd = ip_vs_proto_data_get(net, iph.protocol); 1763 - if (unlikely(!pd)) 1763 + if (unlikely(!pd)) { 1764 + /* The only way we'll see this packet again is if it's 1765 + * encapsulated, so mark it with ipvs_property=1 so we 1766 + * skip it if we're ignoring tunneled packets 1767 + */ 1768 + if (sysctl_ignore_tunneled(ipvs)) 1769 + skb->ipvs_property = 1; 1770 + 1764 1771 return NF_ACCEPT; 1772 + } 1765 1773 pp = pd->pp; 1766 1774 /* 1767 1775 * Check if the packet belongs to an existing connection entry
+7
net/netfilter/ipvs/ip_vs_ctl.c
··· 1850 1850 .mode = 0644, 1851 1851 .proc_handler = proc_dointvec, 1852 1852 }, 1853 + { 1854 + .procname = "ignore_tunneled", 1855 + .maxlen = sizeof(int), 1856 + .mode = 0644, 1857 + .proc_handler = proc_dointvec, 1858 + }, 1853 1859 #ifdef CONFIG_IP_VS_DEBUG 1854 1860 { 1855 1861 .procname = "debug_level", ··· 3908 3902 ipvs->sysctl_conn_reuse_mode = 1; 3909 3903 tbl[idx++].data = &ipvs->sysctl_conn_reuse_mode; 3910 3904 tbl[idx++].data = &ipvs->sysctl_schedule_icmp; 3905 + tbl[idx++].data = &ipvs->sysctl_ignore_tunneled; 3911 3906 3912 3907 ipvs->sysctl_hdr = register_net_sysctl(net, "net/ipv4/vs", tbl); 3913 3908 if (ipvs->sysctl_hdr == NULL) {