diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-01-21 00:28:03 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 15:08:35 -0800 |
commit | 91b4f954759653272504c55b715b757207ed1700 (patch) | |
tree | d494866443c2e2d1faf263e0f184b0d6410f3d3d /net | |
parent | 31ffdbcb5989c121f2f81a6b5b20c1c4bb21e5fd (diff) | |
download | linux-3.10-91b4f954759653272504c55b715b757207ed1700.tar.gz linux-3.10-91b4f954759653272504c55b715b757207ed1700.tar.bz2 linux-3.10-91b4f954759653272504c55b715b757207ed1700.zip |
[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>
Diffstat (limited to 'net')
-rw-r--r-- | net/8021q/vlan_dev.c | 63 |
1 files changed, 35 insertions, 28 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 57799af5108..8059fa42b08 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -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; - } - - /* - * 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); + vlan_set_encap_proto(skb, vhdr); -recv: skb = vlan_check_reorder_header(skb); if (!skb) { stats->rx_errors++; |