aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasahide NAKAMURA <nakam@linux-ipv6.org>2006-08-23 22:27:25 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:06:55 -0400
commit793832361fe7e9c3fcae2edd1d293c583a0a095c (patch)
tree43ee73c5f5cd329089c3fbcf71594036974d6be3
parent8dd7368dd97def967bbb3aec67b882e8dfd1a528 (diff)
[IPV6] MIP6: Revert address to send ICMPv6 error.
IPv6 source address is replaced in receiving packet with home address option carried by destination options header. To send ICMPv6 error back, original address which is received one on wire should be used. This function checks such header is included and reverts them. Based on MIPL2 kernel patch. This patch was also written by: Ville Nuorvala <vnuorval@tcs.hut.fi> Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv6/icmp.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index e3a8e27af950..4ec876066b3f 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -273,6 +273,29 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st
273 return 0; 273 return 0;
274} 274}
275 275
276#ifdef CONFIG_IPV6_MIP6
277static void mip6_addr_swap(struct sk_buff *skb)
278{
279 struct ipv6hdr *iph = skb->nh.ipv6h;
280 struct inet6_skb_parm *opt = IP6CB(skb);
281 struct ipv6_destopt_hao *hao;
282 struct in6_addr tmp;
283 int off;
284
285 if (opt->dsthao) {
286 off = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
287 if (likely(off >= 0)) {
288 hao = (struct ipv6_destopt_hao *)(skb->nh.raw + off);
289 ipv6_addr_copy(&tmp, &iph->saddr);
290 ipv6_addr_copy(&iph->saddr, &hao->addr);
291 ipv6_addr_copy(&hao->addr, &tmp);
292 }
293 }
294}
295#else
296static inline void mip6_addr_swap(struct sk_buff *skb) {}
297#endif
298
276/* 299/*
277 * Send an ICMP message in response to a packet in error 300 * Send an ICMP message in response to a packet in error
278 */ 301 */
@@ -350,6 +373,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
350 return; 373 return;
351 } 374 }
352 375
376 mip6_addr_swap(skb);
377
353 memset(&fl, 0, sizeof(fl)); 378 memset(&fl, 0, sizeof(fl));
354 fl.proto = IPPROTO_ICMPV6; 379 fl.proto = IPPROTO_ICMPV6;
355 ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr); 380 ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);