diff options
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/ip6_input.c | 9 | ||||
| -rw-r--r-- | net/ipv6/ipcomp6.c | 2 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 7 | ||||
| -rw-r--r-- | net/ipv6/raw.c | 2 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 9 | 
5 files changed, 22 insertions, 7 deletions
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 866f10726c5..10fbb50daea 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -198,12 +198,13 @@ resubmit:  		if (!raw_sk) {  			if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {  				IP6_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS); -				icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff); +				icmpv6_send(skb, ICMPV6_PARAMPROB, +				            ICMPV6_UNK_NEXTHDR, nhoff, +				            skb->dev);  			} -		} else { +		} else  			IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); -			kfree_skb(skb); -		} +		kfree_skb(skb);  	}  	rcu_read_unlock();  	return 0; diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 423feb46ccc..135383ef538 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -354,7 +354,7 @@ static struct crypto_tfm **ipcomp6_alloc_tfms(const char *alg_name)  	int cpu;  	/* This can be any valid CPU ID so we don't need locking. */ -	cpu = smp_processor_id(); +	cpu = raw_smp_processor_id();  	list_for_each_entry(pos, &ipcomp6_tfms_list, list) {  		struct crypto_tfm *tfm; diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 5493180f0d4..a16df5b27c8 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -211,6 +211,12 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)  		break;  	case IPQ_COPY_PACKET: +		if (entry->skb->ip_summed == CHECKSUM_HW && +		    (*errp = skb_checksum_help(entry->skb, +		                               entry->info->outdev == NULL))) { +			read_unlock_bh(&queue_lock); +			return NULL; +		}  		if (copy_range == 0 || copy_range > entry->skb->len)  			data_len = entry->skb->len;  		else @@ -381,6 +387,7 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)  	if (!skb_ip_make_writable(&e->skb, v->data_len))  		return -ENOMEM;  	memcpy(e->skb->data, v->payload, v->data_len); +	e->skb->ip_summed = CHECKSUM_NONE;  	e->skb->nfcache |= NFC_ALTERED;  	/* diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index e2b848ec985..1d4d75b34d3 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -328,6 +328,8 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)  	if (skb->ip_summed != CHECKSUM_UNNECESSARY) {  		if (skb->ip_summed == CHECKSUM_HW) { +			skb_postpull_rcsum(skb, skb->nh.raw, +			                   skb->h.raw - skb->nh.raw);  			skb->ip_summed = CHECKSUM_UNNECESSARY;  			if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,  					    &skb->nh.ipv6h->daddr, diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index f6e288dc116..ef29cfd936d 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -158,9 +158,14 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)  		tcp_port_rover = rover;  		spin_unlock(&tcp_portalloc_lock); -		/* Exhausted local port range during search? */ +		/* Exhausted local port range during search?  It is not +		 * possible for us to be holding one of the bind hash +		 * locks if this test triggers, because if 'remaining' +		 * drops to zero, we broke out of the do/while loop at +		 * the top level, not from the 'break;' statement. +		 */  		ret = 1; -		if (remaining <= 0) +		if (unlikely(remaining <= 0))  			goto fail;  		/* OK, here is the one we will use. */  | 
