diff options
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/mcast.c | 13 | ||||
| -rw-r--r-- | net/ipv6/tcpv6_offload.c | 2 | ||||
| -rw-r--r-- | net/ipv6/udp.c | 6 | 
3 files changed, 17 insertions, 4 deletions
| diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 08b367c6b9cf..617f0958e164 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1301,8 +1301,17 @@ int igmp6_event_query(struct sk_buff *skb)  	len = ntohs(ipv6_hdr(skb)->payload_len) + sizeof(struct ipv6hdr);  	len -= skb_network_header_len(skb); -	/* Drop queries with not link local source */ -	if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) +	/* RFC3810 6.2 +	 * Upon reception of an MLD message that contains a Query, the node +	 * checks if the source address of the message is a valid link-local +	 * address, if the Hop Limit is set to 1, and if the Router Alert +	 * option is present in the Hop-By-Hop Options header of the IPv6 +	 * packet.  If any of these checks fails, the packet is dropped. +	 */ +	if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL) || +	    ipv6_hdr(skb)->hop_limit != 1 || +	    !(IP6CB(skb)->flags & IP6SKB_ROUTERALERT) || +	    IP6CB(skb)->ra != htons(IPV6_OPT_ROUTERALERT_MLD))  		return -EINVAL;  	idev = __in6_dev_get(skb->dev); diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c index 8517d3cd1aed..01b0ff9a0c2c 100644 --- a/net/ipv6/tcpv6_offload.c +++ b/net/ipv6/tcpv6_offload.c @@ -73,7 +73,7 @@ static int tcp6_gro_complete(struct sk_buff *skb, int thoff)  	th->check = ~tcp_v6_check(skb->len - thoff, &iph->saddr,  				  &iph->daddr, 0); -	skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; +	skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6;  	return tcp_gro_complete(skb);  } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 95c834799288..7092ff78fd84 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -674,8 +674,11 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)  			goto csum_error;  	} -	if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf)) +	if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf)) { +		UDP6_INC_STATS_BH(sock_net(sk), +				  UDP_MIB_RCVBUFERRORS, is_udplite);  		goto drop; +	}  	skb_dst_drop(skb); @@ -690,6 +693,7 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)  	bh_unlock_sock(sk);  	return rc; +  csum_error:  	UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);  drop: |