diff options
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/addrconf.c | 6 | ||||
| -rw-r--r-- | net/ipv6/netfilter.c | 7 | ||||
| -rw-r--r-- | net/ipv6/proc.c | 2 | ||||
| -rw-r--r-- | net/ipv6/udp_offload.c | 20 | 
4 files changed, 24 insertions, 11 deletions
| diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d1ab6ab29a55..1bbf744c2cc3 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1487,7 +1487,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev)  }  int ipv6_chk_addr(struct net *net, const struct in6_addr *addr, -		  struct net_device *dev, int strict) +		  const struct net_device *dev, int strict)  {  	struct inet6_ifaddr *ifp;  	unsigned int hash = inet6_addr_hash(addr); @@ -2658,8 +2658,10 @@ static void init_loopback(struct net_device *dev)  			sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0);  			/* Failure cases are ignored */ -			if (!IS_ERR(sp_rt)) +			if (!IS_ERR(sp_rt)) { +				sp_ifa->rt = sp_rt;  				ip6_ins_rt(sp_rt); +			}  		}  		read_unlock_bh(&idev->lock);  	} diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 72836f40b730..95f3f1da0d7f 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -10,6 +10,7 @@  #include <linux/netfilter.h>  #include <linux/netfilter_ipv6.h>  #include <linux/export.h> +#include <net/addrconf.h>  #include <net/dst.h>  #include <net/ipv6.h>  #include <net/ip6_route.h> @@ -186,6 +187,10 @@ static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook,  	return csum;  }; +static const struct nf_ipv6_ops ipv6ops = { +	.chk_addr	= ipv6_chk_addr, +}; +  static const struct nf_afinfo nf_ip6_afinfo = {  	.family			= AF_INET6,  	.checksum		= nf_ip6_checksum, @@ -198,6 +203,7 @@ static const struct nf_afinfo nf_ip6_afinfo = {  int __init ipv6_netfilter_init(void)  { +	RCU_INIT_POINTER(nf_ipv6_ops, &ipv6ops);  	return nf_register_afinfo(&nf_ip6_afinfo);  } @@ -206,5 +212,6 @@ int __init ipv6_netfilter_init(void)   */  void ipv6_netfilter_fini(void)  { +	RCU_INIT_POINTER(nf_ipv6_ops, NULL);  	nf_unregister_afinfo(&nf_ip6_afinfo);  } diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index f3c1ff4357ff..51c3285b5d9b 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -90,7 +90,7 @@ static const struct snmp_mib snmp6_ipstats_list[] = {  	SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),  	SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),  	SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS), -	SNMP_MIB_ITEM("InCsumErrors", IPSTATS_MIB_CSUMERRORS), +	/* IPSTATS_MIB_CSUMERRORS is not relevant in IPv6 (no checksum) */  	SNMP_MIB_SENTINEL  }; diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index 3bb3a891a424..d3cfaf9c7a08 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c @@ -46,11 +46,12 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,  	unsigned int mss;  	unsigned int unfrag_ip6hlen, unfrag_len;  	struct frag_hdr *fptr; -	u8 *mac_start, *prevhdr; +	u8 *packet_start, *prevhdr;  	u8 nexthdr;  	u8 frag_hdr_sz = sizeof(struct frag_hdr);  	int offset;  	__wsum csum; +	int tnl_hlen;  	mss = skb_shinfo(skb)->gso_size;  	if (unlikely(skb->len <= mss)) @@ -83,9 +84,11 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,  	skb->ip_summed = CHECKSUM_NONE;  	/* Check if there is enough headroom to insert fragment header. */ -	if ((skb_mac_header(skb) < skb->head + frag_hdr_sz) && -	    pskb_expand_head(skb, frag_hdr_sz, 0, GFP_ATOMIC)) -		goto out; +	tnl_hlen = skb_tnl_header_len(skb); +	if (skb_headroom(skb) < (tnl_hlen + frag_hdr_sz)) { +		if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz)) +			goto out; +	}  	/* Find the unfragmentable header and shift it left by frag_hdr_sz  	 * bytes to insert fragment header. @@ -93,11 +96,12 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,  	unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);  	nexthdr = *prevhdr;  	*prevhdr = NEXTHDR_FRAGMENT; -	unfrag_len = skb_network_header(skb) - skb_mac_header(skb) + -		     unfrag_ip6hlen; -	mac_start = skb_mac_header(skb); -	memmove(mac_start-frag_hdr_sz, mac_start, unfrag_len); +	unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) + +		     unfrag_ip6hlen + tnl_hlen; +	packet_start = (u8 *) skb->head + SKB_GSO_CB(skb)->mac_offset; +	memmove(packet_start-frag_hdr_sz, packet_start, unfrag_len); +	SKB_GSO_CB(skb)->mac_offset -= frag_hdr_sz;  	skb->mac_header -= frag_hdr_sz;  	skb->network_header -= frag_hdr_sz; |