aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJulius Volz <julius.volz@gmail.com>2009-08-31 10:22:23 -0400
committerPatrick McHardy <kaber@trash.net>2009-08-31 10:22:23 -0400
commit94b265514a8398ba3cfecb5a821a027b68a5c38e (patch)
tree275d3317053f1dc1643ace438915f33d29ef9690 /net
parent488908696971c5ea1dcc5d13f29c158ba4f6ae7d (diff)
IPVS: Add handling of incoming ICMPV6 messages
Add handling of incoming ICMPv6 messages. This follows the handling of IPv4 ICMP messages. Amongst ther things this problem allows IPVS to behave sensibly when an ICMPV6_PKT_TOOBIG message is received: This message is received when a realserver sends a packet >PMTU to the client. The hop on this path with insufficient MTU will generate an ICMPv6 Packet Too Big message back to the VIP. The LVS server receives this message, but the call to the function handling this has been missing. Thus, IPVS fails to forward the message to the real server, which then does not adjust the path MTU. This patch adds the missing call to ip_vs_in_icmp_v6() in ip_vs_in() to handle this situation. Thanks to Rob Gallagher from HEAnet for reporting this issue and for testing this patch in production (with direct routing mode). [horms@verge.net.au: tweaked changelog] Signed-off-by: Julius Volz <julius.volz@gmail.com> Tested-by: Rob Gallagher <robert.gallagher@heanet.ie> Signed-off-by: Simon Horman <horms@verge.net.au> Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index a986ee20e128..b95699f00545 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1277,13 +1277,24 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
1277 return NF_ACCEPT; 1277 return NF_ACCEPT;
1278 } 1278 }
1279 1279
1280 if (unlikely(iph.protocol == IPPROTO_ICMP)) { 1280#ifdef CONFIG_IP_VS_IPV6
1281 int related, verdict = ip_vs_in_icmp(skb, &related, hooknum); 1281 if (af == AF_INET6) {
1282 if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
1283 int related, verdict = ip_vs_in_icmp_v6(skb, &related, hooknum);
1282 1284
1283 if (related) 1285 if (related)
1284 return verdict; 1286 return verdict;
1285 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); 1287 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1286 } 1288 }
1289 } else
1290#endif
1291 if (unlikely(iph.protocol == IPPROTO_ICMP)) {
1292 int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
1293
1294 if (related)
1295 return verdict;
1296 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1297 }
1287 1298
1288 /* Protocol supported? */ 1299 /* Protocol supported? */
1289 pp = ip_vs_proto_get(iph.protocol); 1300 pp = ip_vs_proto_get(iph.protocol);