aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-01-21 03:28:03 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:08:35 -0500
commit91b4f954759653272504c55b715b757207ed1700 (patch)
treed494866443c2e2d1faf263e0f184b0d6410f3d3d /net/8021q
parent31ffdbcb5989c121f2f81a6b5b20c1c4bb21e5fd (diff)
[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/8021q')
-rw-r--r--net/8021q/vlan_dev.c63
1 files changed, 35 insertions, 28 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 57799af51088..8059fa42b085 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)
89 return skb; 89 return skb;
90} 90}
91 91
92static inline void vlan_set_encap_proto(struct sk_buff *skb,
93 struct vlan_hdr *vhdr)
94{
95 __be16 proto;
96 unsigned char *rawp;
97
98 /*
99 * Was a VLAN packet, grab the encapsulated protocol, which the layer
100 * three protocols care about.
101 */
102
103 proto = vhdr->h_vlan_encapsulated_proto;
104 if (ntohs(proto) >= 1536) {
105 skb->protocol = proto;
106 return;
107 }
108
109 rawp = skb->data;
110 if (*(unsigned short *)rawp == 0xFFFF)
111 /*
112 * This is a magic hack to spot IPX packets. Older Novell
113 * breaks the protocol design and runs IPX over 802.3 without
114 * an 802.2 LLC layer. We look for FFFF which isn't a used
115 * 802.2 SSAP/DSAP. This won't work for fault tolerant netware
116 * but does for the rest.
117 */
118 skb->protocol = htons(ETH_P_802_3);
119 else
120 /*
121 * Real 802.2 LLC
122 */
123 skb->protocol = htons(ETH_P_802_2);
124}
125
92/* 126/*
93 * Determine the packet's protocol ID. The rule here is that we 127 * Determine the packet's protocol ID. The rule here is that we
94 * assume 802.3 if the type field is short enough to be a length. 128 * 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)
114int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, 148int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
115 struct packet_type *ptype, struct net_device *orig_dev) 149 struct packet_type *ptype, struct net_device *orig_dev)
116{ 150{
117 unsigned char *rawp;
118 struct vlan_hdr *vhdr; 151 struct vlan_hdr *vhdr;
119 unsigned short vid; 152 unsigned short vid;
120 struct net_device_stats *stats; 153 struct net_device_stats *stats;
121 unsigned short vlan_TCI; 154 unsigned short vlan_TCI;
122 __be16 proto;
123 155
124 if (dev->nd_net != &init_net) 156 if (dev->nd_net != &init_net)
125 goto err_free; 157 goto err_free;
@@ -179,33 +211,8 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
179 break; 211 break;
180 } 212 }
181 213
182 /* Was a VLAN packet, grab the encapsulated protocol, which the layer 214 vlan_set_encap_proto(skb, vhdr);
183 * three protocols care about.
184 */
185 proto = vhdr->h_vlan_encapsulated_proto;
186 if (ntohs(proto) >= 1536) {
187 skb->protocol = proto;
188 goto recv;
189 }
190
191 /*
192 * This is a magic hack to spot IPX packets. Older Novell breaks
193 * the protocol design and runs IPX over 802.3 without an 802.2 LLC
194 * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
195 * won't work for fault tolerant netware but does for the rest.
196 */
197 rawp = skb->data;
198 if (*(unsigned short *)rawp == 0xFFFF) {
199 skb->protocol = htons(ETH_P_802_3);
200 goto recv;
201 }
202
203 /*
204 * Real 802.2 LLC
205 */
206 skb->protocol = htons(ETH_P_802_2);
207 215
208recv:
209 skb = vlan_check_reorder_header(skb); 216 skb = vlan_check_reorder_header(skb);
210 if (!skb) { 217 if (!skb) {
211 stats->rx_errors++; 218 stats->rx_errors++;