[VLAN]: Move protocol determination to seperate function
I think, that we can make this code flow easier to understand by introducing the vlan_set_encap_proto() function (I hope the name is good) to setup the skb proto and merge the paths calling netif_rx() together. [Patrick: Modified to apply on top of my previous patches] Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
31ffdbcb59
commit
91b4f95475
1 changed files with 35 additions and 28 deletions
|
@ -89,6 +89,40 @@ static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
|
|||
return skb;
|
||||
}
|
||||
|
||||
static inline void vlan_set_encap_proto(struct sk_buff *skb,
|
||||
struct vlan_hdr *vhdr)
|
||||
{
|
||||
__be16 proto;
|
||||
unsigned char *rawp;
|
||||
|
||||
/*
|
||||
* Was a VLAN packet, grab the encapsulated protocol, which the layer
|
||||
* three protocols care about.
|
||||
*/
|
||||
|
||||
proto = vhdr->h_vlan_encapsulated_proto;
|
||||
if (ntohs(proto) >= 1536) {
|
||||
skb->protocol = proto;
|
||||
return;
|
||||
}
|
||||
|
||||
rawp = skb->data;
|
||||
if (*(unsigned short *)rawp == 0xFFFF)
|
||||
/*
|
||||
* This is a magic hack to spot IPX packets. Older Novell
|
||||
* breaks the protocol design and runs IPX over 802.3 without
|
||||
* an 802.2 LLC layer. We look for FFFF which isn't a used
|
||||
* 802.2 SSAP/DSAP. This won't work for fault tolerant netware
|
||||
* but does for the rest.
|
||||
*/
|
||||
skb->protocol = htons(ETH_P_802_3);
|
||||
else
|
||||
/*
|
||||
* Real 802.2 LLC
|
||||
*/
|
||||
skb->protocol = htons(ETH_P_802_2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the packet's protocol ID. The rule here is that we
|
||||
* assume 802.3 if the type field is short enough to be a length.
|
||||
|
@ -114,12 +148,10 @@ static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
|
|||
int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
|
||||
struct packet_type *ptype, struct net_device *orig_dev)
|
||||
{
|
||||
unsigned char *rawp;
|
||||
struct vlan_hdr *vhdr;
|
||||
unsigned short vid;
|
||||
struct net_device_stats *stats;
|
||||
unsigned short vlan_TCI;
|
||||
__be16 proto;
|
||||
|
||||
if (dev->nd_net != &init_net)
|
||||
goto err_free;
|
||||
|
@ -179,33 +211,8 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
|
|||
break;
|
||||
}
|
||||
|
||||
/* Was a VLAN packet, grab the encapsulated protocol, which the layer
|
||||
* three protocols care about.
|
||||
*/
|
||||
proto = vhdr->h_vlan_encapsulated_proto;
|
||||
if (ntohs(proto) >= 1536) {
|
||||
skb->protocol = proto;
|
||||
goto recv;
|
||||
}
|
||||
vlan_set_encap_proto(skb, vhdr);
|
||||
|
||||
/*
|
||||
* This is a magic hack to spot IPX packets. Older Novell breaks
|
||||
* the protocol design and runs IPX over 802.3 without an 802.2 LLC
|
||||
* layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
|
||||
* won't work for fault tolerant netware but does for the rest.
|
||||
*/
|
||||
rawp = skb->data;
|
||||
if (*(unsigned short *)rawp == 0xFFFF) {
|
||||
skb->protocol = htons(ETH_P_802_3);
|
||||
goto recv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Real 802.2 LLC
|
||||
*/
|
||||
skb->protocol = htons(ETH_P_802_2);
|
||||
|
||||
recv:
|
||||
skb = vlan_check_reorder_header(skb);
|
||||
if (!skb) {
|
||||
stats->rx_errors++;
|
||||
|
|
Loading…
Reference in a new issue