diff options
Diffstat (limited to 'net/8021q/vlan_core.c')
| -rw-r--r-- | net/8021q/vlan_core.c | 21 | 
1 files changed, 15 insertions, 6 deletions
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 6ee48aac776..75d42776399 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -22,11 +22,11 @@ bool vlan_do_receive(struct sk_buff **skbp)  		return false;  	skb->dev = vlan_dev; -	if (skb->pkt_type == PACKET_OTHERHOST) { +	if (unlikely(skb->pkt_type == PACKET_OTHERHOST)) {  		/* Our lower layer thinks this is not local, let's make sure.  		 * This allows the VLAN to have a different MAC than the  		 * underlying device, and still route correctly. */ -		if (ether_addr_equal(eth_hdr(skb)->h_dest, vlan_dev->dev_addr)) +		if (ether_addr_equal_64bits(eth_hdr(skb)->h_dest, vlan_dev->dev_addr))  			skb->pkt_type = PACKET_HOST;  	} @@ -63,7 +63,7 @@ bool vlan_do_receive(struct sk_buff **skbp)  }  /* Must be invoked with rcu_read_lock. */ -struct net_device *__vlan_find_dev_deep(struct net_device *dev, +struct net_device *__vlan_find_dev_deep_rcu(struct net_device *dev,  					__be16 vlan_proto, u16 vlan_id)  {  	struct vlan_info *vlan_info = rcu_dereference(dev->vlan_info); @@ -81,13 +81,13 @@ struct net_device *__vlan_find_dev_deep(struct net_device *dev,  		upper_dev = netdev_master_upper_dev_get_rcu(dev);  		if (upper_dev) -			return __vlan_find_dev_deep(upper_dev, +			return __vlan_find_dev_deep_rcu(upper_dev,  						    vlan_proto, vlan_id);  	}  	return NULL;  } -EXPORT_SYMBOL(__vlan_find_dev_deep); +EXPORT_SYMBOL(__vlan_find_dev_deep_rcu);  struct net_device *vlan_dev_real_dev(const struct net_device *dev)  { @@ -106,10 +106,19 @@ u16 vlan_dev_vlan_id(const struct net_device *dev)  }  EXPORT_SYMBOL(vlan_dev_vlan_id); +__be16 vlan_dev_vlan_proto(const struct net_device *dev) +{ +	return vlan_dev_priv(dev)->vlan_proto; +} +EXPORT_SYMBOL(vlan_dev_vlan_proto); +  static struct sk_buff *vlan_reorder_header(struct sk_buff *skb)  { -	if (skb_cow(skb, skb_headroom(skb)) < 0) +	if (skb_cow(skb, skb_headroom(skb)) < 0) { +		kfree_skb(skb);  		return NULL; +	} +  	memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN);  	skb->mac_header += VLAN_HLEN;  	return skb;  | 
