diff options
Diffstat (limited to 'net/ipv6/icmp.c')
-rw-r--r-- | net/ipv6/icmp.c | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index fff5bdd8b680..b4ff0a42b8c7 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -124,15 +124,6 @@ static __inline__ void icmpv6_xmit_unlock(struct sock *sk) | |||
124 | } | 124 | } |
125 | 125 | ||
126 | /* | 126 | /* |
127 | * Slightly more convenient version of icmpv6_send. | ||
128 | */ | ||
129 | void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos) | ||
130 | { | ||
131 | icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos); | ||
132 | kfree_skb(skb); | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * Figure out, may we reply to this packet with icmp error. | 127 | * Figure out, may we reply to this packet with icmp error. |
137 | * | 128 | * |
138 | * We do not reply, if: | 129 | * We do not reply, if: |
@@ -332,7 +323,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *sk | |||
332 | * anycast. | 323 | * anycast. |
333 | */ | 324 | */ |
334 | if (((struct rt6_info *)dst)->rt6i_flags & RTF_ANYCAST) { | 325 | if (((struct rt6_info *)dst)->rt6i_flags & RTF_ANYCAST) { |
335 | LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: acast source\n"); | 326 | LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: acast source\n"); |
336 | dst_release(dst); | 327 | dst_release(dst); |
337 | return ERR_PTR(-EINVAL); | 328 | return ERR_PTR(-EINVAL); |
338 | } | 329 | } |
@@ -381,7 +372,7 @@ relookup_failed: | |||
381 | /* | 372 | /* |
382 | * Send an ICMP message in response to a packet in error | 373 | * Send an ICMP message in response to a packet in error |
383 | */ | 374 | */ |
384 | void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | 375 | static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) |
385 | { | 376 | { |
386 | struct net *net = dev_net(skb->dev); | 377 | struct net *net = dev_net(skb->dev); |
387 | struct inet6_dev *idev = NULL; | 378 | struct inet6_dev *idev = NULL; |
@@ -406,7 +397,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
406 | /* | 397 | /* |
407 | * Make sure we respect the rules | 398 | * Make sure we respect the rules |
408 | * i.e. RFC 1885 2.4(e) | 399 | * i.e. RFC 1885 2.4(e) |
409 | * Rule (e.1) is enforced by not using icmpv6_send | 400 | * Rule (e.1) is enforced by not using icmp6_send |
410 | * in any code that processes icmp errors. | 401 | * in any code that processes icmp errors. |
411 | */ | 402 | */ |
412 | addr_type = ipv6_addr_type(&hdr->daddr); | 403 | addr_type = ipv6_addr_type(&hdr->daddr); |
@@ -434,7 +425,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
434 | * Source addr check | 425 | * Source addr check |
435 | */ | 426 | */ |
436 | 427 | ||
437 | if (addr_type & IPV6_ADDR_LINKLOCAL) | 428 | if (__ipv6_addr_needs_scope_id(addr_type)) |
438 | iif = skb->dev->ifindex; | 429 | iif = skb->dev->ifindex; |
439 | 430 | ||
440 | /* | 431 | /* |
@@ -444,7 +435,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
444 | * and anycast addresses will be checked later. | 435 | * and anycast addresses will be checked later. |
445 | */ | 436 | */ |
446 | if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) { | 437 | if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) { |
447 | LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n"); | 438 | LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: addr_any/mcast source\n"); |
448 | return; | 439 | return; |
449 | } | 440 | } |
450 | 441 | ||
@@ -452,7 +443,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info) | |||
452 | * Never answer to a ICMP packet. | 443 | * Never answer to a ICMP packet. |
453 | */ | 444 | */ |
454 | if (is_ineligible(skb)) { | 445 | if (is_ineligible(skb)) { |
455 | LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: no reply to icmp error\n"); | 446 | LIMIT_NETDEBUG(KERN_DEBUG "icmp6_send: no reply to icmp error\n"); |
456 | return; | 447 | return; |
457 | } | 448 | } |
458 | 449 | ||
@@ -529,7 +520,14 @@ out_dst_release: | |||
529 | out: | 520 | out: |
530 | icmpv6_xmit_unlock(sk); | 521 | icmpv6_xmit_unlock(sk); |
531 | } | 522 | } |
532 | EXPORT_SYMBOL(icmpv6_send); | 523 | |
524 | /* Slightly more convenient version of icmp6_send. | ||
525 | */ | ||
526 | void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos) | ||
527 | { | ||
528 | icmp6_send(skb, ICMPV6_PARAMPROB, code, pos); | ||
529 | kfree_skb(skb); | ||
530 | } | ||
533 | 531 | ||
534 | static void icmpv6_echo_reply(struct sk_buff *skb) | 532 | static void icmpv6_echo_reply(struct sk_buff *skb) |
535 | { | 533 | { |
@@ -701,7 +699,7 @@ static int icmpv6_rcv(struct sk_buff *skb) | |||
701 | if (__skb_checksum_complete(skb)) { | 699 | if (__skb_checksum_complete(skb)) { |
702 | LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%pI6 > %pI6]\n", | 700 | LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%pI6 > %pI6]\n", |
703 | saddr, daddr); | 701 | saddr, daddr); |
704 | goto discard_it; | 702 | goto csum_error; |
705 | } | 703 | } |
706 | } | 704 | } |
707 | 705 | ||
@@ -787,6 +785,8 @@ static int icmpv6_rcv(struct sk_buff *skb) | |||
787 | kfree_skb(skb); | 785 | kfree_skb(skb); |
788 | return 0; | 786 | return 0; |
789 | 787 | ||
788 | csum_error: | ||
789 | ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_CSUMERRORS); | ||
790 | discard_it: | 790 | discard_it: |
791 | ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INERRORS); | 791 | ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INERRORS); |
792 | drop_no_count: | 792 | drop_no_count: |
@@ -885,8 +885,14 @@ int __init icmpv6_init(void) | |||
885 | err = -EAGAIN; | 885 | err = -EAGAIN; |
886 | if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0) | 886 | if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0) |
887 | goto fail; | 887 | goto fail; |
888 | |||
889 | err = inet6_register_icmp_sender(icmp6_send); | ||
890 | if (err) | ||
891 | goto sender_reg_err; | ||
888 | return 0; | 892 | return 0; |
889 | 893 | ||
894 | sender_reg_err: | ||
895 | inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); | ||
890 | fail: | 896 | fail: |
891 | pr_err("Failed to register ICMP6 protocol\n"); | 897 | pr_err("Failed to register ICMP6 protocol\n"); |
892 | unregister_pernet_subsys(&icmpv6_sk_ops); | 898 | unregister_pernet_subsys(&icmpv6_sk_ops); |
@@ -895,6 +901,7 @@ fail: | |||
895 | 901 | ||
896 | void icmpv6_cleanup(void) | 902 | void icmpv6_cleanup(void) |
897 | { | 903 | { |
904 | inet6_unregister_icmp_sender(icmp6_send); | ||
898 | unregister_pernet_subsys(&icmpv6_sk_ops); | 905 | unregister_pernet_subsys(&icmpv6_sk_ops); |
899 | inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); | 906 | inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); |
900 | } | 907 | } |