sit: strictly restrict incoming traffic to tunnel link device
Check link device when looking up a tunnel. When a tunnel is linked to a interface, traffic from a different interface must not reach the tunnel. This also allows creating of multiple tunnels with the same endpoints, if the link device differs. Signed-off-by: Sascha Hlusiak <contact@saschahlusiak.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
					parent
					
						
							
								8db99e5717
							
						
					
				
			
			
				commit
				
					
						4fddbf5d78
					
				
			
		
					 1 changed files with 21 additions and 9 deletions
				
			
		|  | @ -80,7 +80,7 @@ struct sit_net { | |||
| static DEFINE_RWLOCK(ipip6_lock); | ||||
| 
 | ||||
| static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net, | ||||
| 		__be32 remote, __be32 local) | ||||
| 		struct net_device *dev, __be32 remote, __be32 local) | ||||
| { | ||||
| 	unsigned h0 = HASH(remote); | ||||
| 	unsigned h1 = HASH(local); | ||||
|  | @ -89,18 +89,25 @@ static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net, | |||
| 
 | ||||
| 	for (t = sitn->tunnels_r_l[h0^h1]; t; t = t->next) { | ||||
| 		if (local == t->parms.iph.saddr && | ||||
| 		    remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP)) | ||||
| 		    remote == t->parms.iph.daddr && | ||||
| 		    (!dev || !t->parms.link || dev->iflink == t->parms.link) && | ||||
| 		    (t->dev->flags & IFF_UP)) | ||||
| 			return t; | ||||
| 	} | ||||
| 	for (t = sitn->tunnels_r[h0]; t; t = t->next) { | ||||
| 		if (remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP)) | ||||
| 		if (remote == t->parms.iph.daddr && | ||||
| 		    (!dev || !t->parms.link || dev->iflink == t->parms.link) && | ||||
| 		    (t->dev->flags & IFF_UP)) | ||||
| 			return t; | ||||
| 	} | ||||
| 	for (t = sitn->tunnels_l[h1]; t; t = t->next) { | ||||
| 		if (local == t->parms.iph.saddr && (t->dev->flags&IFF_UP)) | ||||
| 		if (local == t->parms.iph.saddr && | ||||
| 		    (!dev || !t->parms.link || dev->iflink == t->parms.link) && | ||||
| 		    (t->dev->flags & IFF_UP)) | ||||
| 			return t; | ||||
| 	} | ||||
| 	if ((t = sitn->tunnels_wc[0]) != NULL && (t->dev->flags&IFF_UP)) | ||||
| 	t = sitn->tunnels_wc[0]; | ||||
| 	if ((t != NULL) && (t->dev->flags & IFF_UP)) | ||||
| 		return t; | ||||
| 	return NULL; | ||||
| } | ||||
|  | @ -166,7 +173,8 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, | |||
| 
 | ||||
| 	for (tp = __ipip6_bucket(sitn, parms); (t = *tp) != NULL; tp = &t->next) { | ||||
| 		if (local == t->parms.iph.saddr && | ||||
| 		    remote == t->parms.iph.daddr) { | ||||
| 		    remote == t->parms.iph.daddr && | ||||
| 		    parms->link == t->parms.link) { | ||||
| 			if (create) | ||||
| 				return NULL; | ||||
| 			else | ||||
|  | @ -451,7 +459,10 @@ static int ipip6_err(struct sk_buff *skb, u32 info) | |||
| 	err = -ENOENT; | ||||
| 
 | ||||
| 	read_lock(&ipip6_lock); | ||||
| 	t = ipip6_tunnel_lookup(dev_net(skb->dev), iph->daddr, iph->saddr); | ||||
| 	t = ipip6_tunnel_lookup(dev_net(skb->dev), | ||||
| 				skb->dev, | ||||
| 				iph->daddr, | ||||
| 				iph->saddr); | ||||
| 	if (t == NULL || t->parms.iph.daddr == 0) | ||||
| 		goto out; | ||||
| 
 | ||||
|  | @ -486,8 +497,9 @@ static int ipip6_rcv(struct sk_buff *skb) | |||
| 	iph = ip_hdr(skb); | ||||
| 
 | ||||
| 	read_lock(&ipip6_lock); | ||||
| 	if ((tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), | ||||
| 					iph->saddr, iph->daddr)) != NULL) { | ||||
| 	tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, | ||||
| 				     iph->saddr, iph->daddr); | ||||
| 	if (tunnel != NULL) { | ||||
| 		secpath_reset(skb); | ||||
| 		skb->mac_header = skb->network_header; | ||||
| 		skb_reset_network_header(skb); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Sascha Hlusiak
				Sascha Hlusiak