diff options
Diffstat (limited to 'net/ipv6/ip6_input.c')
| -rw-r--r-- | net/ipv6/ip6_input.c | 15 | 
1 files changed, 14 insertions, 1 deletions
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index b1876e52091..2bab2aa5974 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -118,6 +118,18 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt  	    ipv6_addr_loopback(&hdr->daddr))  		goto err; +	/* RFC4291 Errata ID: 3480 +	 * Interface-Local scope spans only a single interface on a +	 * node and is useful only for loopback transmission of +	 * multicast.  Packets with interface-local scope received +	 * from another node must be discarded. +	 */ +	if (!(skb->pkt_type == PACKET_LOOPBACK || +	      dev->flags & IFF_LOOPBACK) && +	    ipv6_addr_is_multicast(&hdr->daddr) && +	    IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 1) +		goto err; +  	/* RFC4291 2.7  	 * Nodes must not originate a packet to a multicast address whose scope  	 * field contains the reserved value 0; if such a packet is received, it @@ -281,7 +293,8 @@ int ip6_mc_input(struct sk_buff *skb)  	 *      IPv6 multicast router mode is now supported ;)  	 */  	if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding && -	    !(ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL) && +	    !(ipv6_addr_type(&hdr->daddr) & +	      (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)) &&  	    likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) {  		/*  		 * Okay, we try to forward - split and duplicate  |