aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2010-10-17 09:27:31 -0400
committerSimon Horman <horms@verge.net.au>2010-10-21 04:50:57 -0400
commit489fdedaed5ddb437dd2840eb93df37a6dd8c7de (patch)
treea70ba093165e4592a582dc4b692b3270f239d7d9
parent190ecd27cd7294105e3b26ca71663c7d940acbbb (diff)
ipvs: stop ICMP from FORWARD to local
Delivering locally ICMP from FORWARD hook is not supported. Signed-off-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 0090d6d25e95..27ecb258ea70 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -48,6 +48,7 @@
48#ifdef CONFIG_IP_VS_IPV6 48#ifdef CONFIG_IP_VS_IPV6
49#include <net/ipv6.h> 49#include <net/ipv6.h>
50#include <linux/netfilter_ipv6.h> 50#include <linux/netfilter_ipv6.h>
51#include <net/ip6_route.h>
51#endif 52#endif
52 53
53#include <net/ip_vs.h> 54#include <net/ip_vs.h>
@@ -1191,7 +1192,14 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
1191 if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol) 1192 if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol)
1192 offset += 2 * sizeof(__u16); 1193 offset += 2 * sizeof(__u16);
1193 verdict = ip_vs_icmp_xmit(skb, cp, pp, offset); 1194 verdict = ip_vs_icmp_xmit(skb, cp, pp, offset);
1194 /* do not touch skb anymore */ 1195 /* LOCALNODE from FORWARD hook is not supported */
1196 if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD &&
1197 skb_rtable(skb)->rt_flags & RTCF_LOCAL) {
1198 IP_VS_DBG(1, "%s(): "
1199 "local delivery to %pI4 but in FORWARD\n",
1200 __func__, &skb_rtable(skb)->rt_dst);
1201 verdict = NF_DROP;
1202 }
1195 1203
1196 out: 1204 out:
1197 __ip_vs_conn_put(cp); 1205 __ip_vs_conn_put(cp);
@@ -1212,6 +1220,7 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
1212 struct ip_vs_protocol *pp; 1220 struct ip_vs_protocol *pp;
1213 unsigned int offset, verdict; 1221 unsigned int offset, verdict;
1214 union nf_inet_addr snet; 1222 union nf_inet_addr snet;
1223 struct rt6_info *rt;
1215 1224
1216 *related = 1; 1225 *related = 1;
1217 1226
@@ -1290,7 +1299,15 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
1290 IPPROTO_SCTP == cih->nexthdr) 1299 IPPROTO_SCTP == cih->nexthdr)
1291 offset += 2 * sizeof(__u16); 1300 offset += 2 * sizeof(__u16);
1292 verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset); 1301 verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset);
1293 /* do not touch skb anymore */ 1302 /* LOCALNODE from FORWARD hook is not supported */
1303 if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD &&
1304 (rt = (struct rt6_info *) skb_dst(skb)) &&
1305 rt->rt6i_dev && rt->rt6i_dev->flags & IFF_LOOPBACK) {
1306 IP_VS_DBG(1, "%s(): "
1307 "local delivery to %pI6 but in FORWARD\n",
1308 __func__, &rt->rt6i_dst);
1309 verdict = NF_DROP;
1310 }
1294 1311
1295 __ip_vs_conn_put(cp); 1312 __ip_vs_conn_put(cp);
1296 1313