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.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 1044b6fce0d5..4ec876066b3f 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -151,7 +151,7 @@ static int is_ineligible(struct sk_buff *skb)
151 return 0; 151 return 0;
152} 152}
153 153
154static int sysctl_icmpv6_time = 1*HZ; 154static int sysctl_icmpv6_time __read_mostly = 1*HZ;
155 155
156/* 156/*
157 * Check the ICMP output rate limit 157 * Check the ICMP output rate limit
@@ -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);
@@ -358,6 +383,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
358 fl.oif = iif; 383 fl.oif = iif;
359 fl.fl_icmp_type = type; 384 fl.fl_icmp_type = type;
360 fl.fl_icmp_code = code; 385 fl.fl_icmp_code = code;
386 security_skb_classify_flow(skb, &fl);
361 387
362 if (icmpv6_xmit_lock()) 388 if (icmpv6_xmit_lock())
363 return; 389 return;
@@ -401,7 +427,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
401 if (hlimit < 0) 427 if (hlimit < 0)
402 hlimit = ipv6_get_hoplimit(dst->dev); 428 hlimit = ipv6_get_hoplimit(dst->dev);
403 429
404 tclass = np->cork.tclass; 430 tclass = np->tclass;
405 if (tclass < 0) 431 if (tclass < 0)
406 tclass = 0; 432 tclass = 0;
407 433
@@ -472,6 +498,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
472 ipv6_addr_copy(&fl.fl6_src, saddr); 498 ipv6_addr_copy(&fl.fl6_src, saddr);
473 fl.oif = skb->dev->ifindex; 499 fl.oif = skb->dev->ifindex;
474 fl.fl_icmp_type = ICMPV6_ECHO_REPLY; 500 fl.fl_icmp_type = ICMPV6_ECHO_REPLY;
501 security_skb_classify_flow(skb, &fl);
475 502
476 if (icmpv6_xmit_lock()) 503 if (icmpv6_xmit_lock())
477 return; 504 return;
@@ -497,7 +524,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
497 if (hlimit < 0) 524 if (hlimit < 0)
498 hlimit = ipv6_get_hoplimit(dst->dev); 525 hlimit = ipv6_get_hoplimit(dst->dev);
499 526
500 tclass = np->cork.tclass; 527 tclass = np->tclass;
501 if (tclass < 0) 528 if (tclass < 0)
502 tclass = 0; 529 tclass = 0;
503 530
@@ -604,7 +631,7 @@ static int icmpv6_rcv(struct sk_buff **pskb)
604 631
605 /* Perform checksum. */ 632 /* Perform checksum. */
606 switch (skb->ip_summed) { 633 switch (skb->ip_summed) {
607 case CHECKSUM_HW: 634 case CHECKSUM_COMPLETE:
608 if (!csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6, 635 if (!csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
609 skb->csum)) 636 skb->csum))
610 break; 637 break;
@@ -712,6 +739,11 @@ discard_it:
712 return 0; 739 return 0;
713} 740}
714 741
742/*
743 * Special lock-class for __icmpv6_socket:
744 */
745static struct lock_class_key icmpv6_socket_sk_dst_lock_key;
746
715int __init icmpv6_init(struct net_proto_family *ops) 747int __init icmpv6_init(struct net_proto_family *ops)
716{ 748{
717 struct sock *sk; 749 struct sock *sk;
@@ -730,6 +762,14 @@ int __init icmpv6_init(struct net_proto_family *ops)
730 762
731 sk = per_cpu(__icmpv6_socket, i)->sk; 763 sk = per_cpu(__icmpv6_socket, i)->sk;
732 sk->sk_allocation = GFP_ATOMIC; 764 sk->sk_allocation = GFP_ATOMIC;
765 /*
766 * Split off their lock-class, because sk->sk_dst_lock
767 * gets used from softirqs, which is safe for
768 * __icmpv6_socket (because those never get directly used
769 * via userspace syscalls), but unsafe for normal sockets.
770 */
771 lockdep_set_class(&sk->sk_dst_lock,
772 &icmpv6_socket_sk_dst_lock_key);
733 773
734 /* Enough space for 2 64K ICMP packets, including 774 /* Enough space for 2 64K ICMP packets, including
735 * sk_buff struct overhead. 775 * sk_buff struct overhead.