diff options
Diffstat (limited to 'net/ipv6/icmp.c')
| -rw-r--r-- | net/ipv6/icmp.c | 23 |
1 files changed, 9 insertions, 14 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 091a2971c7b7..24d69dbca4d6 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
| @@ -188,14 +188,16 @@ static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type, | |||
| 188 | } else { | 188 | } else { |
| 189 | struct rt6_info *rt = (struct rt6_info *)dst; | 189 | struct rt6_info *rt = (struct rt6_info *)dst; |
| 190 | int tmo = net->ipv6.sysctl.icmpv6_time; | 190 | int tmo = net->ipv6.sysctl.icmpv6_time; |
| 191 | struct inet_peer *peer; | ||
| 191 | 192 | ||
| 192 | /* Give more bandwidth to wider prefixes. */ | 193 | /* Give more bandwidth to wider prefixes. */ |
| 193 | if (rt->rt6i_dst.plen < 128) | 194 | if (rt->rt6i_dst.plen < 128) |
| 194 | tmo >>= ((128 - rt->rt6i_dst.plen)>>5); | 195 | tmo >>= ((128 - rt->rt6i_dst.plen)>>5); |
| 195 | 196 | ||
| 196 | if (!rt->rt6i_peer) | 197 | peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1); |
| 197 | rt6_bind_peer(rt, 1); | 198 | res = inet_peer_xrlim_allow(peer, tmo); |
| 198 | res = inet_peer_xrlim_allow(rt->rt6i_peer, tmo); | 199 | if (peer) |
| 200 | inet_putpeer(peer); | ||
| 199 | } | 201 | } |
| 200 | dst_release(dst); | 202 | dst_release(dst); |
| 201 | return res; | 203 | return res; |
| @@ -596,13 +598,12 @@ out: | |||
| 596 | icmpv6_xmit_unlock(sk); | 598 | icmpv6_xmit_unlock(sk); |
| 597 | } | 599 | } |
| 598 | 600 | ||
| 599 | static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) | 601 | void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) |
| 600 | { | 602 | { |
| 601 | const struct inet6_protocol *ipprot; | 603 | const struct inet6_protocol *ipprot; |
| 602 | int inner_offset; | 604 | int inner_offset; |
| 603 | int hash; | ||
| 604 | u8 nexthdr; | ||
| 605 | __be16 frag_off; | 605 | __be16 frag_off; |
| 606 | u8 nexthdr; | ||
| 606 | 607 | ||
| 607 | if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) | 608 | if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) |
| 608 | return; | 609 | return; |
| @@ -629,10 +630,8 @@ static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) | |||
| 629 | --ANK (980726) | 630 | --ANK (980726) |
| 630 | */ | 631 | */ |
| 631 | 632 | ||
| 632 | hash = nexthdr & (MAX_INET_PROTOS - 1); | ||
| 633 | |||
| 634 | rcu_read_lock(); | 633 | rcu_read_lock(); |
| 635 | ipprot = rcu_dereference(inet6_protos[hash]); | 634 | ipprot = rcu_dereference(inet6_protos[nexthdr]); |
| 636 | if (ipprot && ipprot->err_handler) | 635 | if (ipprot && ipprot->err_handler) |
| 637 | ipprot->err_handler(skb, NULL, type, code, inner_offset, info); | 636 | ipprot->err_handler(skb, NULL, type, code, inner_offset, info); |
| 638 | rcu_read_unlock(); | 637 | rcu_read_unlock(); |
| @@ -649,7 +648,6 @@ static int icmpv6_rcv(struct sk_buff *skb) | |||
| 649 | struct net_device *dev = skb->dev; | 648 | struct net_device *dev = skb->dev; |
| 650 | struct inet6_dev *idev = __in6_dev_get(dev); | 649 | struct inet6_dev *idev = __in6_dev_get(dev); |
| 651 | const struct in6_addr *saddr, *daddr; | 650 | const struct in6_addr *saddr, *daddr; |
| 652 | const struct ipv6hdr *orig_hdr; | ||
| 653 | struct icmp6hdr *hdr; | 651 | struct icmp6hdr *hdr; |
| 654 | u8 type; | 652 | u8 type; |
| 655 | 653 | ||
| @@ -661,7 +659,7 @@ static int icmpv6_rcv(struct sk_buff *skb) | |||
| 661 | XFRM_STATE_ICMP)) | 659 | XFRM_STATE_ICMP)) |
| 662 | goto drop_no_count; | 660 | goto drop_no_count; |
| 663 | 661 | ||
| 664 | if (!pskb_may_pull(skb, sizeof(*hdr) + sizeof(*orig_hdr))) | 662 | if (!pskb_may_pull(skb, sizeof(*hdr) + sizeof(struct ipv6hdr))) |
| 665 | goto drop_no_count; | 663 | goto drop_no_count; |
| 666 | 664 | ||
| 667 | nh = skb_network_offset(skb); | 665 | nh = skb_network_offset(skb); |
| @@ -722,9 +720,6 @@ static int icmpv6_rcv(struct sk_buff *skb) | |||
| 722 | if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) | 720 | if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) |
| 723 | goto discard_it; | 721 | goto discard_it; |
| 724 | hdr = icmp6_hdr(skb); | 722 | hdr = icmp6_hdr(skb); |
| 725 | orig_hdr = (struct ipv6hdr *) (hdr + 1); | ||
| 726 | rt6_pmtu_discovery(&orig_hdr->daddr, &orig_hdr->saddr, dev, | ||
| 727 | ntohl(hdr->icmp6_mtu)); | ||
| 728 | 723 | ||
| 729 | /* | 724 | /* |
| 730 | * Drop through to notify | 725 | * Drop through to notify |
