aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c2
-rw-r--r--net/ipv6/datagram.c9
-rw-r--r--net/ipv6/fib6_rules.c6
-rw-r--r--net/ipv6/ip6_output.c40
-rw-r--r--net/ipv6/ndisc.c3
-rw-r--r--net/ipv6/netfilter/ip6t_SYNPROXY.c1
-rw-r--r--net/ipv6/ping.c3
-rw-r--r--net/ipv6/protocol.c4
-rw-r--r--net/ipv6/raw.c5
-rw-r--r--net/ipv6/route.c34
-rw-r--r--net/ipv6/sit.c56
-rw-r--r--net/ipv6/tcp_ipv6.c1
-rw-r--r--net/ipv6/tcpv6_offload.c32
-rw-r--r--net/ipv6/udp.c5
14 files changed, 125 insertions, 76 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 12c97d8aa6bb..d5fa5b8c443e 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2613,7 +2613,7 @@ static void init_loopback(struct net_device *dev)
2613 if (sp_ifa->rt) 2613 if (sp_ifa->rt)
2614 continue; 2614 continue;
2615 2615
2616 sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); 2616 sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, false);
2617 2617
2618 /* Failure cases are ignored */ 2618 /* Failure cases are ignored */
2619 if (!IS_ERR(sp_rt)) { 2619 if (!IS_ERR(sp_rt)) {
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index a454b0ff57c7..93b1aa34c432 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -73,7 +73,6 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
73 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); 73 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
74 if (flowlabel == NULL) 74 if (flowlabel == NULL)
75 return -EINVAL; 75 return -EINVAL;
76 usin->sin6_addr = flowlabel->dst;
77 } 76 }
78 } 77 }
79 78
@@ -318,7 +317,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu)
318/* 317/*
319 * Handle MSG_ERRQUEUE 318 * Handle MSG_ERRQUEUE
320 */ 319 */
321int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) 320int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
322{ 321{
323 struct ipv6_pinfo *np = inet6_sk(sk); 322 struct ipv6_pinfo *np = inet6_sk(sk);
324 struct sock_exterr_skb *serr; 323 struct sock_exterr_skb *serr;
@@ -369,6 +368,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
369 &sin->sin6_addr); 368 &sin->sin6_addr);
370 sin->sin6_scope_id = 0; 369 sin->sin6_scope_id = 0;
371 } 370 }
371 *addr_len = sizeof(*sin);
372 } 372 }
373 373
374 memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); 374 memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
@@ -377,6 +377,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
377 if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) { 377 if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {
378 sin->sin6_family = AF_INET6; 378 sin->sin6_family = AF_INET6;
379 sin->sin6_flowinfo = 0; 379 sin->sin6_flowinfo = 0;
380 sin->sin6_port = 0;
380 if (skb->protocol == htons(ETH_P_IPV6)) { 381 if (skb->protocol == htons(ETH_P_IPV6)) {
381 sin->sin6_addr = ipv6_hdr(skb)->saddr; 382 sin->sin6_addr = ipv6_hdr(skb)->saddr;
382 if (np->rxopt.all) 383 if (np->rxopt.all)
@@ -423,7 +424,8 @@ EXPORT_SYMBOL_GPL(ipv6_recv_error);
423/* 424/*
424 * Handle IPV6_RECVPATHMTU 425 * Handle IPV6_RECVPATHMTU
425 */ 426 */
426int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len) 427int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
428 int *addr_len)
427{ 429{
428 struct ipv6_pinfo *np = inet6_sk(sk); 430 struct ipv6_pinfo *np = inet6_sk(sk);
429 struct sk_buff *skb; 431 struct sk_buff *skb;
@@ -457,6 +459,7 @@ int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len)
457 sin->sin6_port = 0; 459 sin->sin6_port = 0;
458 sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id; 460 sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id;
459 sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr; 461 sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr;
462 *addr_len = sizeof(*sin);
460 } 463 }
461 464
462 put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info); 465 put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info);
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index e27591635f92..3fd0a578329e 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -122,7 +122,11 @@ out:
122static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) 122static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg)
123{ 123{
124 struct rt6_info *rt = (struct rt6_info *) arg->result; 124 struct rt6_info *rt = (struct rt6_info *) arg->result;
125 struct net_device *dev = rt->rt6i_idev->dev; 125 struct net_device *dev = NULL;
126
127 if (rt->rt6i_idev)
128 dev = rt->rt6i_idev->dev;
129
126 /* do not accept result if the route does 130 /* do not accept result if the route does
127 * not meet the required prefix length 131 * not meet the required prefix length
128 */ 132 */
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 59df872e2f4d..e6f931997996 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -116,8 +116,8 @@ static int ip6_finish_output2(struct sk_buff *skb)
116 } 116 }
117 rcu_read_unlock_bh(); 117 rcu_read_unlock_bh();
118 118
119 IP6_INC_STATS_BH(dev_net(dst->dev), 119 IP6_INC_STATS(dev_net(dst->dev),
120 ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); 120 ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
121 kfree_skb(skb); 121 kfree_skb(skb);
122 return -EINVAL; 122 return -EINVAL;
123} 123}
@@ -1193,11 +1193,35 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1193 1193
1194 fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len + 1194 fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len +
1195 (opt ? opt->opt_nflen : 0); 1195 (opt ? opt->opt_nflen : 0);
1196 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr); 1196 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen -
1197 sizeof(struct frag_hdr);
1197 1198
1198 if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { 1199 if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
1199 if (cork->length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) { 1200 unsigned int maxnonfragsize, headersize;
1200 ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen); 1201
1202 headersize = sizeof(struct ipv6hdr) +
1203 (opt ? opt->tot_len : 0) +
1204 (dst_allfrag(&rt->dst) ?
1205 sizeof(struct frag_hdr) : 0) +
1206 rt->rt6i_nfheader_len;
1207
1208 maxnonfragsize = (np->pmtudisc >= IPV6_PMTUDISC_DO) ?
1209 mtu : sizeof(struct ipv6hdr) + IPV6_MAXPLEN;
1210
1211 /* dontfrag active */
1212 if ((cork->length + length > mtu - headersize) && dontfrag &&
1213 (sk->sk_protocol == IPPROTO_UDP ||
1214 sk->sk_protocol == IPPROTO_RAW)) {
1215 ipv6_local_rxpmtu(sk, fl6, mtu - headersize +
1216 sizeof(struct ipv6hdr));
1217 goto emsgsize;
1218 }
1219
1220 if (cork->length + length > maxnonfragsize - headersize) {
1221emsgsize:
1222 ipv6_local_error(sk, EMSGSIZE, fl6,
1223 mtu - headersize +
1224 sizeof(struct ipv6hdr));
1201 return -EMSGSIZE; 1225 return -EMSGSIZE;
1202 } 1226 }
1203 } 1227 }
@@ -1222,12 +1246,6 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1222 * --yoshfuji 1246 * --yoshfuji
1223 */ 1247 */
1224 1248
1225 if ((length > mtu) && dontfrag && (sk->sk_protocol == IPPROTO_UDP ||
1226 sk->sk_protocol == IPPROTO_RAW)) {
1227 ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen);
1228 return -EMSGSIZE;
1229 }
1230
1231 skb = skb_peek_tail(&sk->sk_write_queue); 1249 skb = skb_peek_tail(&sk->sk_write_queue);
1232 cork->length += length; 1250 cork->length += length;
1233 if (((length > mtu) || 1251 if (((length > mtu) ||
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 3512177deb4d..300865171394 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1277,6 +1277,9 @@ skip_linkparms:
1277 ri->prefix_len == 0) 1277 ri->prefix_len == 0)
1278 continue; 1278 continue;
1279#endif 1279#endif
1280 if (ri->prefix_len == 0 &&
1281 !in6_dev->cnf.accept_ra_defrtr)
1282 continue;
1280 if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) 1283 if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen)
1281 continue; 1284 continue;
1282 rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3, 1285 rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3,
diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c
index f78f41aca8e9..a0d17270117c 100644
--- a/net/ipv6/netfilter/ip6t_SYNPROXY.c
+++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c
@@ -446,6 +446,7 @@ static void synproxy_tg6_destroy(const struct xt_tgdtor_param *par)
446static struct xt_target synproxy_tg6_reg __read_mostly = { 446static struct xt_target synproxy_tg6_reg __read_mostly = {
447 .name = "SYNPROXY", 447 .name = "SYNPROXY",
448 .family = NFPROTO_IPV6, 448 .family = NFPROTO_IPV6,
449 .hooks = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD),
449 .target = synproxy_tg6, 450 .target = synproxy_tg6,
450 .targetsize = sizeof(struct xt_synproxy_info), 451 .targetsize = sizeof(struct xt_synproxy_info),
451 .checkentry = synproxy_tg6_check, 452 .checkentry = synproxy_tg6_check,
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index 8815e31a87fe..a83243c3d656 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -57,7 +57,8 @@ static struct inet_protosw pingv6_protosw = {
57 57
58 58
59/* Compatibility glue so we can support IPv6 when it's compiled as a module */ 59/* Compatibility glue so we can support IPv6 when it's compiled as a module */
60static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) 60static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
61 int *addr_len)
61{ 62{
62 return -EAFNOSUPPORT; 63 return -EAFNOSUPPORT;
63} 64}
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index 22d1bd4670da..e048cf1bb6a2 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -36,10 +36,6 @@ int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol
36} 36}
37EXPORT_SYMBOL(inet6_add_protocol); 37EXPORT_SYMBOL(inet6_add_protocol);
38 38
39/*
40 * Remove a protocol from the hash tables.
41 */
42
43int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol) 39int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol)
44{ 40{
45 int ret; 41 int ret;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index e24ff1df0401..b6bb87e55805 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -466,10 +466,10 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
466 return -EOPNOTSUPP; 466 return -EOPNOTSUPP;
467 467
468 if (flags & MSG_ERRQUEUE) 468 if (flags & MSG_ERRQUEUE)
469 return ipv6_recv_error(sk, msg, len); 469 return ipv6_recv_error(sk, msg, len, addr_len);
470 470
471 if (np->rxpmtu && np->rxopt.bits.rxpmtu) 471 if (np->rxpmtu && np->rxopt.bits.rxpmtu)
472 return ipv6_recv_rxpmtu(sk, msg, len); 472 return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
473 473
474 skb = skb_recv_datagram(sk, flags, noblock, &err); 474 skb = skb_recv_datagram(sk, flags, noblock, &err);
475 if (!skb) 475 if (!skb)
@@ -792,7 +792,6 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
792 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); 792 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
793 if (flowlabel == NULL) 793 if (flowlabel == NULL)
794 return -EINVAL; 794 return -EINVAL;
795 daddr = &flowlabel->dst;
796 } 795 }
797 } 796 }
798 797
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 7faa9d5e1503..4b4944c3e4c4 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -84,6 +84,8 @@ static int ip6_dst_gc(struct dst_ops *ops);
84 84
85static int ip6_pkt_discard(struct sk_buff *skb); 85static int ip6_pkt_discard(struct sk_buff *skb);
86static int ip6_pkt_discard_out(struct sk_buff *skb); 86static int ip6_pkt_discard_out(struct sk_buff *skb);
87static int ip6_pkt_prohibit(struct sk_buff *skb);
88static int ip6_pkt_prohibit_out(struct sk_buff *skb);
87static void ip6_link_failure(struct sk_buff *skb); 89static void ip6_link_failure(struct sk_buff *skb);
88static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, 90static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
89 struct sk_buff *skb, u32 mtu); 91 struct sk_buff *skb, u32 mtu);
@@ -234,9 +236,6 @@ static const struct rt6_info ip6_null_entry_template = {
234 236
235#ifdef CONFIG_IPV6_MULTIPLE_TABLES 237#ifdef CONFIG_IPV6_MULTIPLE_TABLES
236 238
237static int ip6_pkt_prohibit(struct sk_buff *skb);
238static int ip6_pkt_prohibit_out(struct sk_buff *skb);
239
240static const struct rt6_info ip6_prohibit_entry_template = { 239static const struct rt6_info ip6_prohibit_entry_template = {
241 .dst = { 240 .dst = {
242 .__refcnt = ATOMIC_INIT(1), 241 .__refcnt = ATOMIC_INIT(1),
@@ -1565,21 +1564,24 @@ int ip6_route_add(struct fib6_config *cfg)
1565 goto out; 1564 goto out;
1566 } 1565 }
1567 } 1566 }
1568 rt->dst.output = ip6_pkt_discard_out;
1569 rt->dst.input = ip6_pkt_discard;
1570 rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; 1567 rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP;
1571 switch (cfg->fc_type) { 1568 switch (cfg->fc_type) {
1572 case RTN_BLACKHOLE: 1569 case RTN_BLACKHOLE:
1573 rt->dst.error = -EINVAL; 1570 rt->dst.error = -EINVAL;
1571 rt->dst.output = dst_discard;
1572 rt->dst.input = dst_discard;
1574 break; 1573 break;
1575 case RTN_PROHIBIT: 1574 case RTN_PROHIBIT:
1576 rt->dst.error = -EACCES; 1575 rt->dst.error = -EACCES;
1576 rt->dst.output = ip6_pkt_prohibit_out;
1577 rt->dst.input = ip6_pkt_prohibit;
1577 break; 1578 break;
1578 case RTN_THROW: 1579 case RTN_THROW:
1579 rt->dst.error = -EAGAIN;
1580 break;
1581 default: 1580 default:
1582 rt->dst.error = -ENETUNREACH; 1581 rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN
1582 : -ENETUNREACH;
1583 rt->dst.output = ip6_pkt_discard_out;
1584 rt->dst.input = ip6_pkt_discard;
1583 break; 1585 break;
1584 } 1586 }
1585 goto install_route; 1587 goto install_route;
@@ -1903,9 +1905,7 @@ static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,
1903 else 1905 else
1904 rt->rt6i_gateway = *dest; 1906 rt->rt6i_gateway = *dest;
1905 rt->rt6i_flags = ort->rt6i_flags; 1907 rt->rt6i_flags = ort->rt6i_flags;
1906 if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) == 1908 rt6_set_from(rt, ort);
1907 (RTF_DEFAULT | RTF_ADDRCONF))
1908 rt6_set_from(rt, ort);
1909 rt->rt6i_metric = 0; 1909 rt->rt6i_metric = 0;
1910 1910
1911#ifdef CONFIG_IPV6_SUBTREES 1911#ifdef CONFIG_IPV6_SUBTREES
@@ -2144,8 +2144,6 @@ static int ip6_pkt_discard_out(struct sk_buff *skb)
2144 return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); 2144 return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES);
2145} 2145}
2146 2146
2147#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2148
2149static int ip6_pkt_prohibit(struct sk_buff *skb) 2147static int ip6_pkt_prohibit(struct sk_buff *skb)
2150{ 2148{
2151 return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); 2149 return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES);
@@ -2157,8 +2155,6 @@ static int ip6_pkt_prohibit_out(struct sk_buff *skb)
2157 return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); 2155 return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
2158} 2156}
2159 2157
2160#endif
2161
2162/* 2158/*
2163 * Allocate a dst for local (unicast / anycast) address. 2159 * Allocate a dst for local (unicast / anycast) address.
2164 */ 2160 */
@@ -2168,12 +2164,10 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
2168 bool anycast) 2164 bool anycast)
2169{ 2165{
2170 struct net *net = dev_net(idev->dev); 2166 struct net *net = dev_net(idev->dev);
2171 struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL); 2167 struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev,
2172 2168 DST_NOCOUNT, NULL);
2173 if (!rt) { 2169 if (!rt)
2174 net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n");
2175 return ERR_PTR(-ENOMEM); 2170 return ERR_PTR(-ENOMEM);
2176 }
2177 2171
2178 in6_dev_hold(idev); 2172 in6_dev_hold(idev);
2179 2173
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 1b4a4a953675..c87482252577 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -478,14 +478,44 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
478 dev_put(dev); 478 dev_put(dev);
479} 479}
480 480
481/* Generate icmpv6 with type/code ICMPV6_DEST_UNREACH/ICMPV6_ADDR_UNREACH
482 * if sufficient data bytes are available
483 */
484static int ipip6_err_gen_icmpv6_unreach(struct sk_buff *skb)
485{
486 const struct iphdr *iph = (const struct iphdr *) skb->data;
487 struct rt6_info *rt;
488 struct sk_buff *skb2;
489
490 if (!pskb_may_pull(skb, iph->ihl * 4 + sizeof(struct ipv6hdr) + 8))
491 return 1;
492
493 skb2 = skb_clone(skb, GFP_ATOMIC);
494
495 if (!skb2)
496 return 1;
497
498 skb_dst_drop(skb2);
499 skb_pull(skb2, iph->ihl * 4);
500 skb_reset_network_header(skb2);
501
502 rt = rt6_lookup(dev_net(skb->dev), &ipv6_hdr(skb2)->saddr, NULL, 0, 0);
503
504 if (rt && rt->dst.dev)
505 skb2->dev = rt->dst.dev;
506
507 icmpv6_send(skb2, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0);
508
509 if (rt)
510 ip6_rt_put(rt);
511
512 kfree_skb(skb2);
513
514 return 0;
515}
481 516
482static int ipip6_err(struct sk_buff *skb, u32 info) 517static int ipip6_err(struct sk_buff *skb, u32 info)
483{ 518{
484
485/* All the routers (except for Linux) return only
486 8 bytes of packet payload. It means, that precise relaying of
487 ICMP in the real Internet is absolutely infeasible.
488 */
489 const struct iphdr *iph = (const struct iphdr *)skb->data; 519 const struct iphdr *iph = (const struct iphdr *)skb->data;
490 const int type = icmp_hdr(skb)->type; 520 const int type = icmp_hdr(skb)->type;
491 const int code = icmp_hdr(skb)->code; 521 const int code = icmp_hdr(skb)->code;
@@ -500,7 +530,6 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
500 case ICMP_DEST_UNREACH: 530 case ICMP_DEST_UNREACH:
501 switch (code) { 531 switch (code) {
502 case ICMP_SR_FAILED: 532 case ICMP_SR_FAILED:
503 case ICMP_PORT_UNREACH:
504 /* Impossible event. */ 533 /* Impossible event. */
505 return 0; 534 return 0;
506 default: 535 default:
@@ -545,6 +574,9 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
545 goto out; 574 goto out;
546 575
547 err = 0; 576 err = 0;
577 if (!ipip6_err_gen_icmpv6_unreach(skb))
578 goto out;
579
548 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) 580 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
549 goto out; 581 goto out;
550 582
@@ -892,7 +924,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
892 if (tunnel->parms.iph.daddr && skb_dst(skb)) 924 if (tunnel->parms.iph.daddr && skb_dst(skb))
893 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); 925 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
894 926
895 if (skb->len > mtu) { 927 if (skb->len > mtu && !skb_is_gso(skb)) {
896 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); 928 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
897 ip_rt_put(rt); 929 ip_rt_put(rt);
898 goto tx_error; 930 goto tx_error;
@@ -919,7 +951,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
919 if (!new_skb) { 951 if (!new_skb) {
920 ip_rt_put(rt); 952 ip_rt_put(rt);
921 dev->stats.tx_dropped++; 953 dev->stats.tx_dropped++;
922 dev_kfree_skb(skb); 954 kfree_skb(skb);
923 return NETDEV_TX_OK; 955 return NETDEV_TX_OK;
924 } 956 }
925 if (skb->sk) 957 if (skb->sk)
@@ -934,8 +966,10 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
934 tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6)); 966 tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
935 967
936 skb = iptunnel_handle_offloads(skb, false, SKB_GSO_SIT); 968 skb = iptunnel_handle_offloads(skb, false, SKB_GSO_SIT);
937 if (IS_ERR(skb)) 969 if (IS_ERR(skb)) {
970 ip_rt_put(rt);
938 goto out; 971 goto out;
972 }
939 973
940 err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos, 974 err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos,
941 ttl, df, !net_eq(tunnel->net, dev_net(dev))); 975 ttl, df, !net_eq(tunnel->net, dev_net(dev)));
@@ -945,7 +979,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
945tx_error_icmp: 979tx_error_icmp:
946 dst_link_failure(skb); 980 dst_link_failure(skb);
947tx_error: 981tx_error:
948 dev_kfree_skb(skb); 982 kfree_skb(skb);
949out: 983out:
950 dev->stats.tx_errors++; 984 dev->stats.tx_errors++;
951 return NETDEV_TX_OK; 985 return NETDEV_TX_OK;
@@ -985,7 +1019,7 @@ static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb,
985 1019
986tx_err: 1020tx_err:
987 dev->stats.tx_errors++; 1021 dev->stats.tx_errors++;
988 dev_kfree_skb(skb); 1022 kfree_skb(skb);
989 return NETDEV_TX_OK; 1023 return NETDEV_TX_OK;
990 1024
991} 1025}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 0740f93a114a..f67033b4bb66 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -156,7 +156,6 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
156 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); 156 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
157 if (flowlabel == NULL) 157 if (flowlabel == NULL)
158 return -EINVAL; 158 return -EINVAL;
159 usin->sin6_addr = flowlabel->dst;
160 fl6_sock_release(flowlabel); 159 fl6_sock_release(flowlabel);
161 } 160 }
162 } 161 }
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c
index c1097c798900..6d18157dc32c 100644
--- a/net/ipv6/tcpv6_offload.c
+++ b/net/ipv6/tcpv6_offload.c
@@ -37,34 +37,32 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
37{ 37{
38 const struct ipv6hdr *iph = skb_gro_network_header(skb); 38 const struct ipv6hdr *iph = skb_gro_network_header(skb);
39 __wsum wsum; 39 __wsum wsum;
40 __sum16 sum; 40
41 /* Don't bother verifying checksum if we're going to flush anyway. */
42 if (NAPI_GRO_CB(skb)->flush)
43 goto skip_csum;
44
45 wsum = skb->csum;
41 46
42 switch (skb->ip_summed) { 47 switch (skb->ip_summed) {
48 case CHECKSUM_NONE:
49 wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
50 wsum);
51
52 /* fall through */
53
43 case CHECKSUM_COMPLETE: 54 case CHECKSUM_COMPLETE:
44 if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr, 55 if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr,
45 skb->csum)) { 56 wsum)) {
46 skb->ip_summed = CHECKSUM_UNNECESSARY; 57 skb->ip_summed = CHECKSUM_UNNECESSARY;
47 break; 58 break;
48 } 59 }
49flush: 60
50 NAPI_GRO_CB(skb)->flush = 1; 61 NAPI_GRO_CB(skb)->flush = 1;
51 return NULL; 62 return NULL;
52
53 case CHECKSUM_NONE:
54 wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr,
55 skb_gro_len(skb),
56 IPPROTO_TCP, 0));
57 sum = csum_fold(skb_checksum(skb,
58 skb_gro_offset(skb),
59 skb_gro_len(skb),
60 wsum));
61 if (sum)
62 goto flush;
63
64 skb->ip_summed = CHECKSUM_UNNECESSARY;
65 break;
66 } 63 }
67 64
65skip_csum:
68 return tcp_gro_receive(head, skb); 66 return tcp_gro_receive(head, skb);
69} 67}
70 68
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 81eb8cf8389b..089c741a3992 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -393,10 +393,10 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
393 bool slow; 393 bool slow;
394 394
395 if (flags & MSG_ERRQUEUE) 395 if (flags & MSG_ERRQUEUE)
396 return ipv6_recv_error(sk, msg, len); 396 return ipv6_recv_error(sk, msg, len, addr_len);
397 397
398 if (np->rxpmtu && np->rxopt.bits.rxpmtu) 398 if (np->rxpmtu && np->rxopt.bits.rxpmtu)
399 return ipv6_recv_rxpmtu(sk, msg, len); 399 return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
400 400
401try_again: 401try_again:
402 skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), 402 skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
@@ -1140,7 +1140,6 @@ do_udp_sendmsg:
1140 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); 1140 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
1141 if (flowlabel == NULL) 1141 if (flowlabel == NULL)
1142 return -EINVAL; 1142 return -EINVAL;
1143 daddr = &flowlabel->dst;
1144 } 1143 }
1145 } 1144 }
1146 1145