diff options
| author | Ingo Molnar <mingo@kernel.org> | 2013-12-17 09:27:08 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2013-12-17 09:27:08 -0500 |
| commit | bb799d3b980eb803ca2da4a4eefbd9308f8d988a (patch) | |
| tree | 69fbe0cd6d47b23a50f5e1d87bf7489532fae149 /net/ipv6 | |
| parent | 919fc6e34831d1c2b58bfb5ae261dc3facc9b269 (diff) | |
| parent | 319e2e3f63c348a9b66db4667efa73178e18b17d (diff) | |
Merge tag 'v3.13-rc4' into core/locking
Merge Linux 3.13-rc4, to refresh this rather old tree with the latest fixes.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/addrconf.c | 2 | ||||
| -rw-r--r-- | net/ipv6/datagram.c | 9 | ||||
| -rw-r--r-- | net/ipv6/fib6_rules.c | 6 | ||||
| -rw-r--r-- | net/ipv6/ip6_output.c | 4 | ||||
| -rw-r--r-- | net/ipv6/ndisc.c | 3 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_SYNPROXY.c | 1 | ||||
| -rw-r--r-- | net/ipv6/ping.c | 3 | ||||
| -rw-r--r-- | net/ipv6/protocol.c | 4 | ||||
| -rw-r--r-- | net/ipv6/raw.c | 5 | ||||
| -rw-r--r-- | net/ipv6/route.c | 30 | ||||
| -rw-r--r-- | net/ipv6/sit.c | 50 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 1 | ||||
| -rw-r--r-- | net/ipv6/tcpv6_offload.c | 32 | ||||
| -rw-r--r-- | net/ipv6/udp.c | 5 |
14 files changed, 93 insertions, 62 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 | */ |
| 321 | int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) | 320 | int 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 | */ |
| 426 | int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len) | 427 | int 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: | |||
| 122 | static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) | 122 | static 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..4acdb63495db 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 | } |
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 bf9f612c1bc2..f78f41aca8e9 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c | |||
| @@ -259,6 +259,7 @@ synproxy_recv_client_ack(const struct synproxy_net *snet, | |||
| 259 | 259 | ||
| 260 | this_cpu_inc(snet->stats->cookie_valid); | 260 | this_cpu_inc(snet->stats->cookie_valid); |
| 261 | opts->mss = mss; | 261 | opts->mss = mss; |
| 262 | opts->options |= XT_SYNPROXY_OPT_MSS; | ||
| 262 | 263 | ||
| 263 | if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) | 264 | if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) |
| 264 | synproxy_check_timestamp_cookie(opts); | 265 | synproxy_check_timestamp_cookie(opts); |
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 */ |
| 60 | static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len) | 60 | static 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 | } |
| 37 | EXPORT_SYMBOL(inet6_add_protocol); | 37 | EXPORT_SYMBOL(inet6_add_protocol); |
| 38 | 38 | ||
| 39 | /* | ||
| 40 | * Remove a protocol from the hash tables. | ||
| 41 | */ | ||
| 42 | |||
| 43 | int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol) | 39 | int 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..a0a48ac3403f 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 | ||
| 85 | static int ip6_pkt_discard(struct sk_buff *skb); | 85 | static int ip6_pkt_discard(struct sk_buff *skb); |
| 86 | static int ip6_pkt_discard_out(struct sk_buff *skb); | 86 | static int ip6_pkt_discard_out(struct sk_buff *skb); |
| 87 | static int ip6_pkt_prohibit(struct sk_buff *skb); | ||
| 88 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); | ||
| 87 | static void ip6_link_failure(struct sk_buff *skb); | 89 | static void ip6_link_failure(struct sk_buff *skb); |
| 88 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | 90 | static 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 | ||
| 237 | static int ip6_pkt_prohibit(struct sk_buff *skb); | ||
| 238 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); | ||
| 239 | |||
| 240 | static const struct rt6_info ip6_prohibit_entry_template = { | 239 | static 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; |
| @@ -2144,8 +2146,6 @@ static int ip6_pkt_discard_out(struct sk_buff *skb) | |||
| 2144 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); | 2146 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); |
| 2145 | } | 2147 | } |
| 2146 | 2148 | ||
| 2147 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
| 2148 | |||
| 2149 | static int ip6_pkt_prohibit(struct sk_buff *skb) | 2149 | static int ip6_pkt_prohibit(struct sk_buff *skb) |
| 2150 | { | 2150 | { |
| 2151 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); | 2151 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); |
| @@ -2157,8 +2157,6 @@ static int ip6_pkt_prohibit_out(struct sk_buff *skb) | |||
| 2157 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); | 2157 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); |
| 2158 | } | 2158 | } |
| 2159 | 2159 | ||
| 2160 | #endif | ||
| 2161 | |||
| 2162 | /* | 2160 | /* |
| 2163 | * Allocate a dst for local (unicast / anycast) address. | 2161 | * Allocate a dst for local (unicast / anycast) address. |
| 2164 | */ | 2162 | */ |
| @@ -2168,12 +2166,10 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
| 2168 | bool anycast) | 2166 | bool anycast) |
| 2169 | { | 2167 | { |
| 2170 | struct net *net = dev_net(idev->dev); | 2168 | struct net *net = dev_net(idev->dev); |
| 2171 | struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL); | 2169 | struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, |
| 2172 | 2170 | DST_NOCOUNT, NULL); | |
| 2173 | if (!rt) { | 2171 | if (!rt) |
| 2174 | net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n"); | ||
| 2175 | return ERR_PTR(-ENOMEM); | 2172 | return ERR_PTR(-ENOMEM); |
| 2176 | } | ||
| 2177 | 2173 | ||
| 2178 | in6_dev_hold(idev); | 2174 | in6_dev_hold(idev); |
| 2179 | 2175 | ||
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 1b4a4a953675..366fbba3359a 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 | */ | ||
| 484 | static 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 | ||
| 482 | static int ipip6_err(struct sk_buff *skb, u32 info) | 517 | static 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 | ||
| @@ -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) |
| @@ -945,7 +977,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
| 945 | tx_error_icmp: | 977 | tx_error_icmp: |
| 946 | dst_link_failure(skb); | 978 | dst_link_failure(skb); |
| 947 | tx_error: | 979 | tx_error: |
| 948 | dev_kfree_skb(skb); | 980 | kfree_skb(skb); |
| 949 | out: | 981 | out: |
| 950 | dev->stats.tx_errors++; | 982 | dev->stats.tx_errors++; |
| 951 | return NETDEV_TX_OK; | 983 | return NETDEV_TX_OK; |
| @@ -985,7 +1017,7 @@ static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb, | |||
| 985 | 1017 | ||
| 986 | tx_err: | 1018 | tx_err: |
| 987 | dev->stats.tx_errors++; | 1019 | dev->stats.tx_errors++; |
| 988 | dev_kfree_skb(skb); | 1020 | kfree_skb(skb); |
| 989 | return NETDEV_TX_OK; | 1021 | return NETDEV_TX_OK; |
| 990 | 1022 | ||
| 991 | } | 1023 | } |
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 | } |
| 49 | flush: | 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 | ||
| 65 | skip_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 | ||
| 401 | try_again: | 401 | try_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 | ||
