aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q/vlan_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/8021q/vlan_dev.c')
-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++;