aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/icmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/icmp.c')
-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);