diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ah6.c | 3 | ||||
-rw-r--r-- | net/ipv6/esp6.c | 3 | ||||
-rw-r--r-- | net/ipv6/ip6_gre.c | 3 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 29 | ||||
-rw-r--r-- | net/ipv6/ipcomp6.c | 3 | ||||
-rw-r--r-- | net/ipv6/route.c | 46 | ||||
-rw-r--r-- | net/ipv6/udp.c | 5 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 1 |
8 files changed, 60 insertions, 33 deletions
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 73784c3d4642..82e1da3a40b9 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -618,8 +618,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
618 | struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset); | 618 | struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset); |
619 | struct xfrm_state *x; | 619 | struct xfrm_state *x; |
620 | 620 | ||
621 | if (type != ICMPV6_DEST_UNREACH && | 621 | if (type != ICMPV6_PKT_TOOBIG && |
622 | type != ICMPV6_PKT_TOOBIG && | ||
623 | type != NDISC_REDIRECT) | 622 | type != NDISC_REDIRECT) |
624 | return; | 623 | return; |
625 | 624 | ||
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index d3618a78fcac..e67e63f9858d 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -436,8 +436,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
436 | struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset); | 436 | struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data + offset); |
437 | struct xfrm_state *x; | 437 | struct xfrm_state *x; |
438 | 438 | ||
439 | if (type != ICMPV6_DEST_UNREACH && | 439 | if (type != ICMPV6_PKT_TOOBIG && |
440 | type != ICMPV6_PKT_TOOBIG && | ||
441 | type != NDISC_REDIRECT) | 440 | type != NDISC_REDIRECT) |
442 | return; | 441 | return; |
443 | 442 | ||
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 1ef1fa2b22a6..bf4a9a084de5 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -976,6 +976,7 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu) | |||
976 | if (t->parms.o_flags&GRE_SEQ) | 976 | if (t->parms.o_flags&GRE_SEQ) |
977 | addend += 4; | 977 | addend += 4; |
978 | } | 978 | } |
979 | t->hlen = addend; | ||
979 | 980 | ||
980 | if (p->flags & IP6_TNL_F_CAP_XMIT) { | 981 | if (p->flags & IP6_TNL_F_CAP_XMIT) { |
981 | int strict = (ipv6_addr_type(&p->raddr) & | 982 | int strict = (ipv6_addr_type(&p->raddr) & |
@@ -1002,8 +1003,6 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu) | |||
1002 | } | 1003 | } |
1003 | ip6_rt_put(rt); | 1004 | ip6_rt_put(rt); |
1004 | } | 1005 | } |
1005 | |||
1006 | t->hlen = addend; | ||
1007 | } | 1006 | } |
1008 | 1007 | ||
1009 | static int ip6gre_tnl_change(struct ip6_tnl *t, | 1008 | static int ip6gre_tnl_change(struct ip6_tnl *t, |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index a54c45ce4a48..91fb4e8212f5 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -105,7 +105,7 @@ static int ip6_finish_output2(struct sk_buff *skb) | |||
105 | } | 105 | } |
106 | 106 | ||
107 | rcu_read_lock_bh(); | 107 | rcu_read_lock_bh(); |
108 | nexthop = rt6_nexthop((struct rt6_info *)dst, &ipv6_hdr(skb)->daddr); | 108 | nexthop = rt6_nexthop((struct rt6_info *)dst); |
109 | neigh = __ipv6_neigh_lookup_noref(dst->dev, nexthop); | 109 | neigh = __ipv6_neigh_lookup_noref(dst->dev, nexthop); |
110 | if (unlikely(!neigh)) | 110 | if (unlikely(!neigh)) |
111 | neigh = __neigh_create(&nd_tbl, nexthop, dst->dev, false); | 111 | neigh = __neigh_create(&nd_tbl, nexthop, dst->dev, false); |
@@ -874,7 +874,7 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
874 | */ | 874 | */ |
875 | rt = (struct rt6_info *) *dst; | 875 | rt = (struct rt6_info *) *dst; |
876 | rcu_read_lock_bh(); | 876 | rcu_read_lock_bh(); |
877 | n = __ipv6_neigh_lookup_noref(rt->dst.dev, rt6_nexthop(rt, &fl6->daddr)); | 877 | n = __ipv6_neigh_lookup_noref(rt->dst.dev, rt6_nexthop(rt)); |
878 | err = n && !(n->nud_state & NUD_VALID) ? -EINVAL : 0; | 878 | err = n && !(n->nud_state & NUD_VALID) ? -EINVAL : 0; |
879 | rcu_read_unlock_bh(); | 879 | rcu_read_unlock_bh(); |
880 | 880 | ||
@@ -1008,6 +1008,7 @@ static inline int ip6_ufo_append_data(struct sock *sk, | |||
1008 | 1008 | ||
1009 | { | 1009 | { |
1010 | struct sk_buff *skb; | 1010 | struct sk_buff *skb; |
1011 | struct frag_hdr fhdr; | ||
1011 | int err; | 1012 | int err; |
1012 | 1013 | ||
1013 | /* There is support for UDP large send offload by network | 1014 | /* There is support for UDP large send offload by network |
@@ -1015,8 +1016,6 @@ static inline int ip6_ufo_append_data(struct sock *sk, | |||
1015 | * udp datagram | 1016 | * udp datagram |
1016 | */ | 1017 | */ |
1017 | if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) { | 1018 | if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) { |
1018 | struct frag_hdr fhdr; | ||
1019 | |||
1020 | skb = sock_alloc_send_skb(sk, | 1019 | skb = sock_alloc_send_skb(sk, |
1021 | hh_len + fragheaderlen + transhdrlen + 20, | 1020 | hh_len + fragheaderlen + transhdrlen + 20, |
1022 | (flags & MSG_DONTWAIT), &err); | 1021 | (flags & MSG_DONTWAIT), &err); |
@@ -1036,20 +1035,24 @@ static inline int ip6_ufo_append_data(struct sock *sk, | |||
1036 | skb->transport_header = skb->network_header + fragheaderlen; | 1035 | skb->transport_header = skb->network_header + fragheaderlen; |
1037 | 1036 | ||
1038 | skb->protocol = htons(ETH_P_IPV6); | 1037 | skb->protocol = htons(ETH_P_IPV6); |
1039 | skb->ip_summed = CHECKSUM_PARTIAL; | ||
1040 | skb->csum = 0; | 1038 | skb->csum = 0; |
1041 | 1039 | ||
1042 | /* Specify the length of each IPv6 datagram fragment. | ||
1043 | * It has to be a multiple of 8. | ||
1044 | */ | ||
1045 | skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - | ||
1046 | sizeof(struct frag_hdr)) & ~7; | ||
1047 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP; | ||
1048 | ipv6_select_ident(&fhdr, rt); | ||
1049 | skb_shinfo(skb)->ip6_frag_id = fhdr.identification; | ||
1050 | __skb_queue_tail(&sk->sk_write_queue, skb); | 1040 | __skb_queue_tail(&sk->sk_write_queue, skb); |
1041 | } else if (skb_is_gso(skb)) { | ||
1042 | goto append; | ||
1051 | } | 1043 | } |
1052 | 1044 | ||
1045 | skb->ip_summed = CHECKSUM_PARTIAL; | ||
1046 | /* Specify the length of each IPv6 datagram fragment. | ||
1047 | * It has to be a multiple of 8. | ||
1048 | */ | ||
1049 | skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - | ||
1050 | sizeof(struct frag_hdr)) & ~7; | ||
1051 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP; | ||
1052 | ipv6_select_ident(&fhdr, rt); | ||
1053 | skb_shinfo(skb)->ip6_frag_id = fhdr.identification; | ||
1054 | |||
1055 | append: | ||
1053 | return skb_append_datato_frags(sk, skb, getfrag, from, | 1056 | return skb_append_datato_frags(sk, skb, getfrag, from, |
1054 | (length - transhdrlen)); | 1057 | (length - transhdrlen)); |
1055 | } | 1058 | } |
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 5636a912074a..ce507d9e1c90 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c | |||
@@ -64,8 +64,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
64 | (struct ip_comp_hdr *)(skb->data + offset); | 64 | (struct ip_comp_hdr *)(skb->data + offset); |
65 | struct xfrm_state *x; | 65 | struct xfrm_state *x; |
66 | 66 | ||
67 | if (type != ICMPV6_DEST_UNREACH && | 67 | if (type != ICMPV6_PKT_TOOBIG && |
68 | type != ICMPV6_PKT_TOOBIG && | ||
69 | type != NDISC_REDIRECT) | 68 | type != NDISC_REDIRECT) |
70 | return; | 69 | return; |
71 | 70 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c3130ffc3bca..5dc6ca6b6686 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -476,6 +476,24 @@ out: | |||
476 | } | 476 | } |
477 | 477 | ||
478 | #ifdef CONFIG_IPV6_ROUTER_PREF | 478 | #ifdef CONFIG_IPV6_ROUTER_PREF |
479 | struct __rt6_probe_work { | ||
480 | struct work_struct work; | ||
481 | struct in6_addr target; | ||
482 | struct net_device *dev; | ||
483 | }; | ||
484 | |||
485 | static void rt6_probe_deferred(struct work_struct *w) | ||
486 | { | ||
487 | struct in6_addr mcaddr; | ||
488 | struct __rt6_probe_work *work = | ||
489 | container_of(w, struct __rt6_probe_work, work); | ||
490 | |||
491 | addrconf_addr_solict_mult(&work->target, &mcaddr); | ||
492 | ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL); | ||
493 | dev_put(work->dev); | ||
494 | kfree(w); | ||
495 | } | ||
496 | |||
479 | static void rt6_probe(struct rt6_info *rt) | 497 | static void rt6_probe(struct rt6_info *rt) |
480 | { | 498 | { |
481 | struct neighbour *neigh; | 499 | struct neighbour *neigh; |
@@ -499,17 +517,23 @@ static void rt6_probe(struct rt6_info *rt) | |||
499 | 517 | ||
500 | if (!neigh || | 518 | if (!neigh || |
501 | time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { | 519 | time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { |
502 | struct in6_addr mcaddr; | 520 | struct __rt6_probe_work *work; |
503 | struct in6_addr *target; | ||
504 | 521 | ||
505 | if (neigh) { | 522 | work = kmalloc(sizeof(*work), GFP_ATOMIC); |
523 | |||
524 | if (neigh && work) | ||
506 | neigh->updated = jiffies; | 525 | neigh->updated = jiffies; |
526 | |||
527 | if (neigh) | ||
507 | write_unlock(&neigh->lock); | 528 | write_unlock(&neigh->lock); |
508 | } | ||
509 | 529 | ||
510 | target = (struct in6_addr *)&rt->rt6i_gateway; | 530 | if (work) { |
511 | addrconf_addr_solict_mult(target, &mcaddr); | 531 | INIT_WORK(&work->work, rt6_probe_deferred); |
512 | ndisc_send_ns(rt->dst.dev, NULL, target, &mcaddr, NULL); | 532 | work->target = rt->rt6i_gateway; |
533 | dev_hold(rt->dst.dev); | ||
534 | work->dev = rt->dst.dev; | ||
535 | schedule_work(&work->work); | ||
536 | } | ||
513 | } else { | 537 | } else { |
514 | out: | 538 | out: |
515 | write_unlock(&neigh->lock); | 539 | write_unlock(&neigh->lock); |
@@ -851,7 +875,6 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, | |||
851 | if (ort->rt6i_dst.plen != 128 && | 875 | if (ort->rt6i_dst.plen != 128 && |
852 | ipv6_addr_equal(&ort->rt6i_dst.addr, daddr)) | 876 | ipv6_addr_equal(&ort->rt6i_dst.addr, daddr)) |
853 | rt->rt6i_flags |= RTF_ANYCAST; | 877 | rt->rt6i_flags |= RTF_ANYCAST; |
854 | rt->rt6i_gateway = *daddr; | ||
855 | } | 878 | } |
856 | 879 | ||
857 | rt->rt6i_flags |= RTF_CACHE; | 880 | rt->rt6i_flags |= RTF_CACHE; |
@@ -1335,6 +1358,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
1335 | rt->dst.flags |= DST_HOST; | 1358 | rt->dst.flags |= DST_HOST; |
1336 | rt->dst.output = ip6_output; | 1359 | rt->dst.output = ip6_output; |
1337 | atomic_set(&rt->dst.__refcnt, 1); | 1360 | atomic_set(&rt->dst.__refcnt, 1); |
1361 | rt->rt6i_gateway = fl6->daddr; | ||
1338 | rt->rt6i_dst.addr = fl6->daddr; | 1362 | rt->rt6i_dst.addr = fl6->daddr; |
1339 | rt->rt6i_dst.plen = 128; | 1363 | rt->rt6i_dst.plen = 128; |
1340 | rt->rt6i_idev = idev; | 1364 | rt->rt6i_idev = idev; |
@@ -1870,7 +1894,10 @@ static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, | |||
1870 | in6_dev_hold(rt->rt6i_idev); | 1894 | in6_dev_hold(rt->rt6i_idev); |
1871 | rt->dst.lastuse = jiffies; | 1895 | rt->dst.lastuse = jiffies; |
1872 | 1896 | ||
1873 | rt->rt6i_gateway = ort->rt6i_gateway; | 1897 | if (ort->rt6i_flags & RTF_GATEWAY) |
1898 | rt->rt6i_gateway = ort->rt6i_gateway; | ||
1899 | else | ||
1900 | rt->rt6i_gateway = *dest; | ||
1874 | rt->rt6i_flags = ort->rt6i_flags; | 1901 | rt->rt6i_flags = ort->rt6i_flags; |
1875 | if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) == | 1902 | if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) == |
1876 | (RTF_DEFAULT | RTF_ADDRCONF)) | 1903 | (RTF_DEFAULT | RTF_ADDRCONF)) |
@@ -2157,6 +2184,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
2157 | else | 2184 | else |
2158 | rt->rt6i_flags |= RTF_LOCAL; | 2185 | rt->rt6i_flags |= RTF_LOCAL; |
2159 | 2186 | ||
2187 | rt->rt6i_gateway = *addr; | ||
2160 | rt->rt6i_dst.addr = *addr; | 2188 | rt->rt6i_dst.addr = *addr; |
2161 | rt->rt6i_dst.plen = 128; | 2189 | rt->rt6i_dst.plen = 128; |
2162 | rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL); | 2190 | rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL); |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 44fc4e3d661f..f3893e897f72 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -1243,9 +1243,6 @@ do_udp_sendmsg: | |||
1243 | if (tclass < 0) | 1243 | if (tclass < 0) |
1244 | tclass = np->tclass; | 1244 | tclass = np->tclass; |
1245 | 1245 | ||
1246 | if (dontfrag < 0) | ||
1247 | dontfrag = np->dontfrag; | ||
1248 | |||
1249 | if (msg->msg_flags&MSG_CONFIRM) | 1246 | if (msg->msg_flags&MSG_CONFIRM) |
1250 | goto do_confirm; | 1247 | goto do_confirm; |
1251 | back_from_confirm: | 1248 | back_from_confirm: |
@@ -1264,6 +1261,8 @@ back_from_confirm: | |||
1264 | up->pending = AF_INET6; | 1261 | up->pending = AF_INET6; |
1265 | 1262 | ||
1266 | do_append_data: | 1263 | do_append_data: |
1264 | if (dontfrag < 0) | ||
1265 | dontfrag = np->dontfrag; | ||
1267 | up->len += ulen; | 1266 | up->len += ulen; |
1268 | getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; | 1267 | getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; |
1269 | err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen, | 1268 | err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen, |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 23ed03d786c8..08ed2772b7aa 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -138,6 +138,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
138 | 138 | ||
139 | memset(fl6, 0, sizeof(struct flowi6)); | 139 | memset(fl6, 0, sizeof(struct flowi6)); |
140 | fl6->flowi6_mark = skb->mark; | 140 | fl6->flowi6_mark = skb->mark; |
141 | fl6->flowi6_oif = skb_dst(skb)->dev->ifindex; | ||
141 | 142 | ||
142 | fl6->daddr = reverse ? hdr->saddr : hdr->daddr; | 143 | fl6->daddr = reverse ? hdr->saddr : hdr->daddr; |
143 | fl6->saddr = reverse ? hdr->daddr : hdr->saddr; | 144 | fl6->saddr = reverse ? hdr->daddr : hdr->saddr; |