diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ah6.c | 11 | ||||
-rw-r--r-- | net/ipv6/esp6.c | 5 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 12 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 4 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 3 |
5 files changed, 30 insertions, 5 deletions
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index ecc35b93314b..384233188ac1 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -472,7 +472,10 @@ static void ah6_input_done(struct crypto_async_request *base, int err) | |||
472 | skb->network_header += ah_hlen; | 472 | skb->network_header += ah_hlen; |
473 | memcpy(skb_network_header(skb), work_iph, hdr_len); | 473 | memcpy(skb_network_header(skb), work_iph, hdr_len); |
474 | __skb_pull(skb, ah_hlen + hdr_len); | 474 | __skb_pull(skb, ah_hlen + hdr_len); |
475 | skb_set_transport_header(skb, -hdr_len); | 475 | if (x->props.mode == XFRM_MODE_TUNNEL) |
476 | skb_reset_transport_header(skb); | ||
477 | else | ||
478 | skb_set_transport_header(skb, -hdr_len); | ||
476 | out: | 479 | out: |
477 | kfree(AH_SKB_CB(skb)->tmp); | 480 | kfree(AH_SKB_CB(skb)->tmp); |
478 | xfrm_input_resume(skb, err); | 481 | xfrm_input_resume(skb, err); |
@@ -593,9 +596,13 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
593 | 596 | ||
594 | skb->network_header += ah_hlen; | 597 | skb->network_header += ah_hlen; |
595 | memcpy(skb_network_header(skb), work_iph, hdr_len); | 598 | memcpy(skb_network_header(skb), work_iph, hdr_len); |
596 | skb->transport_header = skb->network_header; | ||
597 | __skb_pull(skb, ah_hlen + hdr_len); | 599 | __skb_pull(skb, ah_hlen + hdr_len); |
598 | 600 | ||
601 | if (x->props.mode == XFRM_MODE_TUNNEL) | ||
602 | skb_reset_transport_header(skb); | ||
603 | else | ||
604 | skb_set_transport_header(skb, -hdr_len); | ||
605 | |||
599 | err = nexthdr; | 606 | err = nexthdr; |
600 | 607 | ||
601 | out_free: | 608 | out_free: |
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 282f3723ee19..40ffd72243a4 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -300,7 +300,10 @@ static int esp_input_done2(struct sk_buff *skb, int err) | |||
300 | 300 | ||
301 | pskb_trim(skb, skb->len - alen - padlen - 2); | 301 | pskb_trim(skb, skb->len - alen - padlen - 2); |
302 | __skb_pull(skb, hlen); | 302 | __skb_pull(skb, hlen); |
303 | skb_set_transport_header(skb, -hdr_len); | 303 | if (x->props.mode == XFRM_MODE_TUNNEL) |
304 | skb_reset_transport_header(skb); | ||
305 | else | ||
306 | skb_set_transport_header(skb, -hdr_len); | ||
304 | 307 | ||
305 | err = nexthdr[1]; | 308 | err = nexthdr[1]; |
306 | 309 | ||
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index b4a9fd51dae7..fff5bdd8b680 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -81,10 +81,22 @@ static inline struct sock *icmpv6_sk(struct net *net) | |||
81 | return net->ipv6.icmp_sk[smp_processor_id()]; | 81 | return net->ipv6.icmp_sk[smp_processor_id()]; |
82 | } | 82 | } |
83 | 83 | ||
84 | static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | ||
85 | u8 type, u8 code, int offset, __be32 info) | ||
86 | { | ||
87 | struct net *net = dev_net(skb->dev); | ||
88 | |||
89 | if (type == ICMPV6_PKT_TOOBIG) | ||
90 | ip6_update_pmtu(skb, net, info, 0, 0); | ||
91 | else if (type == NDISC_REDIRECT) | ||
92 | ip6_redirect(skb, net, 0, 0); | ||
93 | } | ||
94 | |||
84 | static int icmpv6_rcv(struct sk_buff *skb); | 95 | static int icmpv6_rcv(struct sk_buff *skb); |
85 | 96 | ||
86 | static const struct inet6_protocol icmpv6_protocol = { | 97 | static const struct inet6_protocol icmpv6_protocol = { |
87 | .handler = icmpv6_rcv, | 98 | .handler = icmpv6_rcv, |
99 | .err_handler = icmpv6_err, | ||
88 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, | 100 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |
89 | }; | 101 | }; |
90 | 102 | ||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 5552d13ae92f..0c7c03d50dc0 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1213,10 +1213,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1213 | if (dst_allfrag(rt->dst.path)) | 1213 | if (dst_allfrag(rt->dst.path)) |
1214 | cork->flags |= IPCORK_ALLFRAG; | 1214 | cork->flags |= IPCORK_ALLFRAG; |
1215 | cork->length = 0; | 1215 | cork->length = 0; |
1216 | exthdrlen = (opt ? opt->opt_flen : 0) - rt->rt6i_nfheader_len; | 1216 | exthdrlen = (opt ? opt->opt_flen : 0); |
1217 | length += exthdrlen; | 1217 | length += exthdrlen; |
1218 | transhdrlen += exthdrlen; | 1218 | transhdrlen += exthdrlen; |
1219 | dst_exthdrlen = rt->dst.header_len; | 1219 | dst_exthdrlen = rt->dst.header_len - rt->rt6i_nfheader_len; |
1220 | } else { | 1220 | } else { |
1221 | rt = (struct rt6_info *)cork->dst; | 1221 | rt = (struct rt6_info *)cork->dst; |
1222 | fl6 = &inet->cork.fl.u.ip6; | 1222 | fl6 = &inet->cork.fl.u.ip6; |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 26dcdec9e3a5..8fd154e5f079 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -1710,6 +1710,9 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns | |||
1710 | return -EINVAL; | 1710 | return -EINVAL; |
1711 | if (get_user(v, (u32 __user *)optval)) | 1711 | if (get_user(v, (u32 __user *)optval)) |
1712 | return -EFAULT; | 1712 | return -EFAULT; |
1713 | /* "pim6reg%u" should not exceed 16 bytes (IFNAMSIZ) */ | ||
1714 | if (v != RT_TABLE_DEFAULT && v >= 100000000) | ||
1715 | return -EINVAL; | ||
1713 | if (sk == mrt->mroute6_sk) | 1716 | if (sk == mrt->mroute6_sk) |
1714 | return -EBUSY; | 1717 | return -EBUSY; |
1715 | 1718 | ||