diff options
| author | David S. Miller <davem@davemloft.net> | 2014-03-05 20:32:02 -0500 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-03-05 20:32:02 -0500 | 
| commit | 67ddc87f162e2d0e29db2b6b21c5a3fbcb8be206 (patch) | |
| tree | c83ac73e3d569156d4b7f3dab3e7e27e0054cd0d /net/ipv6 | |
| parent | 6092c79fd00ce48ee8698955ea6419cc5cd65641 (diff) | |
| parent | c3bebc71c4bcdafa24b506adf0c1de3c1f77e2e0 (diff) | |
| download | linux-67ddc87f162e2d0e29db2b6b21c5a3fbcb8be206.tar.bz2 | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
	drivers/net/wireless/ath/ath9k/recv.c
	drivers/net/wireless/mwifiex/pcie.c
	net/ipv6/sit.c
The SIT driver conflict consists of a bug fix being done by hand
in 'net' (missing u64_stats_init()) whilst in 'net-next' a helper
was created (netdev_alloc_pcpu_stats()) which takes care of this.
The two wireless conflicts were overlapping changes.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/Kconfig | 1 | ||||
| -rw-r--r-- | net/ipv6/exthdrs_core.c | 2 | ||||
| -rw-r--r-- | net/ipv6/ip6_offload.c | 20 | ||||
| -rw-r--r-- | net/ipv6/ip6_output.c | 3 | ||||
| -rw-r--r-- | net/ipv6/ping.c | 1 | ||||
| -rw-r--r-- | net/ipv6/sit.c | 19 | ||||
| -rw-r--r-- | net/ipv6/udp_offload.c | 2 | 
7 files changed, 35 insertions, 13 deletions
| diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index d92e5586783e..438a73aa777c 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -138,6 +138,7 @@ config INET6_XFRM_MODE_ROUTEOPTIMIZATION  config IPV6_VTI  tristate "Virtual (secure) IPv6: tunneling"  	select IPV6_TUNNEL +	select NET_IP_TUNNEL  	depends on INET6_XFRM_MODE_TUNNEL  	---help---  	Tunneling means encapsulating data of one protocol type within diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c index 140748debc4a..8af3eb57f438 100644 --- a/net/ipv6/exthdrs_core.c +++ b/net/ipv6/exthdrs_core.c @@ -212,7 +212,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,  		found = (nexthdr == target);  		if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { -			if (target < 0) +			if (target < 0 || found)  				break;  			return -ENOENT;  		} diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index 1e8683b135bb..59f95affceb0 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c @@ -89,7 +89,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,  	unsigned int unfrag_ip6hlen;  	u8 *prevhdr;  	int offset = 0; -	bool tunnel; +	bool encap, udpfrag;  	int nhoff;  	if (unlikely(skb_shinfo(skb)->gso_type & @@ -110,8 +110,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,  	if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))  		goto out; -	tunnel = SKB_GSO_CB(skb)->encap_level > 0; -	if (tunnel) +	encap = SKB_GSO_CB(skb)->encap_level > 0; +	if (encap)  		features = skb->dev->hw_enc_features & netif_skb_features(skb);  	SKB_GSO_CB(skb)->encap_level += sizeof(*ipv6h); @@ -121,6 +121,12 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,  	proto = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr); +	if (skb->encapsulation && +	    skb_shinfo(skb)->gso_type & (SKB_GSO_SIT|SKB_GSO_IPIP)) +		udpfrag = proto == IPPROTO_UDP && encap; +	else +		udpfrag = proto == IPPROTO_UDP && !skb->encapsulation; +  	ops = rcu_dereference(inet6_offloads[proto]);  	if (likely(ops && ops->callbacks.gso_segment)) {  		skb_reset_transport_header(skb); @@ -133,13 +139,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,  	for (skb = segs; skb; skb = skb->next) {  		ipv6h = (struct ipv6hdr *)(skb_mac_header(skb) + nhoff);  		ipv6h->payload_len = htons(skb->len - nhoff - sizeof(*ipv6h)); -		if (tunnel) { -			skb_reset_inner_headers(skb); -			skb->encapsulation = 1; -		}  		skb->network_header = (u8 *)ipv6h - skb->head; -		if (!tunnel && proto == IPPROTO_UDP) { +		if (udpfrag) {  			unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);  			fptr = (struct frag_hdr *)((u8 *)ipv6h + unfrag_ip6hlen);  			fptr->frag_off = htons(offset); @@ -148,6 +150,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,  			offset += (ntohs(ipv6h->payload_len) -  				   sizeof(struct frag_hdr));  		} +		if (encap) +			skb_reset_inner_headers(skb);  	}  out: diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index be1b7f5a3a54..2bc10701182b 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -530,9 +530,6 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)  	to->tc_index = from->tc_index;  #endif  	nf_copy(to, from); -#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) -	to->nf_trace = from->nf_trace; -#endif  	skb_copy_secmark(to, from);  } diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index fb9beb78f00b..587bbdcb22b4 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c @@ -135,6 +135,7 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,  	fl6.flowi6_proto = IPPROTO_ICMPV6;  	fl6.saddr = np->saddr;  	fl6.daddr = *daddr; +	fl6.flowi6_mark = sk->sk_mark;  	fl6.fl6_icmp_type = user_icmph.icmp6_type;  	fl6.fl6_icmp_code = user_icmph.icmp6_code;  	security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 958027be0e94..1693c8d885f0 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -475,6 +475,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev)  		ipip6_tunnel_unlink(sitn, tunnel);  		ipip6_tunnel_del_prl(tunnel, NULL);  	} +	ip_tunnel_dst_reset_all(tunnel);  	dev_put(dev);  } @@ -1082,6 +1083,7 @@ static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p)  		t->parms.link = p->link;  		ipip6_tunnel_bind_dev(t->dev);  	} +	ip_tunnel_dst_reset_all(t);  	netdev_state_change(t->dev);  } @@ -1112,6 +1114,7 @@ static int ipip6_tunnel_update_6rd(struct ip_tunnel *t,  	t->ip6rd.relay_prefix = relay_prefix;  	t->ip6rd.prefixlen = ip6rd->prefixlen;  	t->ip6rd.relay_prefixlen = ip6rd->relay_prefixlen; +	ip_tunnel_dst_reset_all(t);  	netdev_state_change(t->dev);  	return 0;  } @@ -1271,6 +1274,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)  			err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL);  			break;  		} +		ip_tunnel_dst_reset_all(t);  		netdev_state_change(dev);  		break; @@ -1326,6 +1330,9 @@ static const struct net_device_ops ipip6_netdev_ops = {  static void ipip6_dev_free(struct net_device *dev)  { +	struct ip_tunnel *tunnel = netdev_priv(dev); + +	free_percpu(tunnel->dst_cache);  	free_percpu(dev->tstats);  	free_netdev(dev);  } @@ -1368,6 +1375,12 @@ static int ipip6_tunnel_init(struct net_device *dev)  	if (!dev->tstats)  		return -ENOMEM; +	tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst); +	if (!tunnel->dst_cache) { +		free_percpu(dev->tstats); +		return -ENOMEM; +	} +  	return 0;  } @@ -1391,6 +1404,12 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)  	if (!dev->tstats)  		return -ENOMEM; +	tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst); +	if (!tunnel->dst_cache) { +		free_percpu(dev->tstats); +		return -ENOMEM; +	} +  	dev_hold(dev);  	rcu_assign_pointer(sitn->tunnels_wc[0], tunnel);  	return 0; diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index e7359f9eaa8d..b261ee8b83fc 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c @@ -113,7 +113,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,  		fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen);  		fptr->nexthdr = nexthdr;  		fptr->reserved = 0; -		ipv6_select_ident(fptr, (struct rt6_info *)skb_dst(skb)); +		fptr->identification = skb_shinfo(skb)->ip6_frag_id;  		/* Fragment the skb. ipv6 header and the remaining fields of the  		 * fragment header are updated in ipv6_gso_segment() |