diff options
Diffstat (limited to 'net/8021q/vlan_dev.c')
-rw-r--r-- | net/8021q/vlan_dev.c | 173 |
1 files changed, 0 insertions, 173 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index b84a46b30c0c..d174c312b7f1 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -65,179 +65,6 @@ static int vlan_dev_rebuild_header(struct sk_buff *skb) | |||
65 | return 0; | 65 | return 0; |
66 | } | 66 | } |
67 | 67 | ||
68 | static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb) | ||
69 | { | ||
70 | if (vlan_dev_info(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) { | ||
71 | if (skb_cow(skb, skb_headroom(skb)) < 0) | ||
72 | skb = NULL; | ||
73 | if (skb) { | ||
74 | /* Lifted from Gleb's VLAN code... */ | ||
75 | memmove(skb->data - ETH_HLEN, | ||
76 | skb->data - VLAN_ETH_HLEN, 12); | ||
77 | skb->mac_header += VLAN_HLEN; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | return skb; | ||
82 | } | ||
83 | |||
84 | static inline void vlan_set_encap_proto(struct sk_buff *skb, | ||
85 | struct vlan_hdr *vhdr) | ||
86 | { | ||
87 | __be16 proto; | ||
88 | unsigned char *rawp; | ||
89 | |||
90 | /* | ||
91 | * Was a VLAN packet, grab the encapsulated protocol, which the layer | ||
92 | * three protocols care about. | ||
93 | */ | ||
94 | |||
95 | proto = vhdr->h_vlan_encapsulated_proto; | ||
96 | if (ntohs(proto) >= 1536) { | ||
97 | skb->protocol = proto; | ||
98 | return; | ||
99 | } | ||
100 | |||
101 | rawp = skb->data; | ||
102 | if (*(unsigned short *)rawp == 0xFFFF) | ||
103 | /* | ||
104 | * This is a magic hack to spot IPX packets. Older Novell | ||
105 | * breaks the protocol design and runs IPX over 802.3 without | ||
106 | * an 802.2 LLC layer. We look for FFFF which isn't a used | ||
107 | * 802.2 SSAP/DSAP. This won't work for fault tolerant netware | ||
108 | * but does for the rest. | ||
109 | */ | ||
110 | skb->protocol = htons(ETH_P_802_3); | ||
111 | else | ||
112 | /* | ||
113 | * Real 802.2 LLC | ||
114 | */ | ||
115 | skb->protocol = htons(ETH_P_802_2); | ||
116 | } | ||
117 | |||
118 | /* | ||
119 | * Determine the packet's protocol ID. The rule here is that we | ||
120 | * assume 802.3 if the type field is short enough to be a length. | ||
121 | * This is normal practice and works for any 'now in use' protocol. | ||
122 | * | ||
123 | * Also, at this point we assume that we ARE dealing exclusively with | ||
124 | * VLAN packets, or packets that should be made into VLAN packets based | ||
125 | * on a default VLAN ID. | ||
126 | * | ||
127 | * NOTE: Should be similar to ethernet/eth.c. | ||
128 | * | ||
129 | * SANITY NOTE: This method is called when a packet is moving up the stack | ||
130 | * towards userland. To get here, it would have already passed | ||
131 | * through the ethernet/eth.c eth_type_trans() method. | ||
132 | * SANITY NOTE 2: We are referencing to the VLAN_HDR frields, which MAY be | ||
133 | * stored UNALIGNED in the memory. RISC systems don't like | ||
134 | * such cases very much... | ||
135 | * SANITY NOTE 2a: According to Dave Miller & Alexey, it will always be | ||
136 | * aligned, so there doesn't need to be any of the unaligned | ||
137 | * stuff. It has been commented out now... --Ben | ||
138 | * | ||
139 | */ | ||
140 | int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, | ||
141 | struct packet_type *ptype, struct net_device *orig_dev) | ||
142 | { | ||
143 | struct vlan_hdr *vhdr; | ||
144 | struct vlan_pcpu_stats *rx_stats; | ||
145 | struct net_device *vlan_dev; | ||
146 | u16 vlan_id; | ||
147 | u16 vlan_tci; | ||
148 | |||
149 | skb = skb_share_check(skb, GFP_ATOMIC); | ||
150 | if (skb == NULL) | ||
151 | goto err_free; | ||
152 | |||
153 | if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) | ||
154 | goto err_free; | ||
155 | |||
156 | vhdr = (struct vlan_hdr *)skb->data; | ||
157 | vlan_tci = ntohs(vhdr->h_vlan_TCI); | ||
158 | vlan_id = vlan_tci & VLAN_VID_MASK; | ||
159 | |||
160 | rcu_read_lock(); | ||
161 | vlan_dev = vlan_find_dev(dev, vlan_id); | ||
162 | |||
163 | /* If the VLAN device is defined, we use it. | ||
164 | * If not, and the VID is 0, it is a 802.1p packet (not | ||
165 | * really a VLAN), so we will just netif_rx it later to the | ||
166 | * original interface, but with the skb->proto set to the | ||
167 | * wrapped proto: we do nothing here. | ||
168 | */ | ||
169 | |||
170 | if (!vlan_dev) { | ||
171 | if (vlan_id) { | ||
172 | pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n", | ||
173 | __func__, vlan_id, dev->name); | ||
174 | goto err_unlock; | ||
175 | } | ||
176 | rx_stats = NULL; | ||
177 | } else { | ||
178 | skb->dev = vlan_dev; | ||
179 | |||
180 | rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_pcpu_stats); | ||
181 | |||
182 | u64_stats_update_begin(&rx_stats->syncp); | ||
183 | rx_stats->rx_packets++; | ||
184 | rx_stats->rx_bytes += skb->len; | ||
185 | |||
186 | skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tci); | ||
187 | |||
188 | pr_debug("%s: priority: %u for TCI: %hu\n", | ||
189 | __func__, skb->priority, vlan_tci); | ||
190 | |||
191 | switch (skb->pkt_type) { | ||
192 | case PACKET_BROADCAST: | ||
193 | /* Yeah, stats collect these together.. */ | ||
194 | /* stats->broadcast ++; // no such counter :-( */ | ||
195 | break; | ||
196 | |||
197 | case PACKET_MULTICAST: | ||
198 | rx_stats->rx_multicast++; | ||
199 | break; | ||
200 | |||
201 | case PACKET_OTHERHOST: | ||
202 | /* Our lower layer thinks this is not local, let's make | ||
203 | * sure. | ||
204 | * This allows the VLAN to have a different MAC than the | ||
205 | * underlying device, and still route correctly. | ||
206 | */ | ||
207 | if (!compare_ether_addr(eth_hdr(skb)->h_dest, | ||
208 | skb->dev->dev_addr)) | ||
209 | skb->pkt_type = PACKET_HOST; | ||
210 | break; | ||
211 | default: | ||
212 | break; | ||
213 | } | ||
214 | u64_stats_update_end(&rx_stats->syncp); | ||
215 | } | ||
216 | |||
217 | skb_pull_rcsum(skb, VLAN_HLEN); | ||
218 | vlan_set_encap_proto(skb, vhdr); | ||
219 | |||
220 | if (vlan_dev) { | ||
221 | skb = vlan_check_reorder_header(skb); | ||
222 | if (!skb) { | ||
223 | rx_stats->rx_errors++; | ||
224 | goto err_unlock; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | netif_rx(skb); | ||
229 | |||
230 | rcu_read_unlock(); | ||
231 | return NET_RX_SUCCESS; | ||
232 | |||
233 | err_unlock: | ||
234 | rcu_read_unlock(); | ||
235 | err_free: | ||
236 | atomic_long_inc(&dev->rx_dropped); | ||
237 | kfree_skb(skb); | ||
238 | return NET_RX_DROP; | ||
239 | } | ||
240 | |||
241 | static inline u16 | 68 | static inline u16 |
242 | vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb) | 69 | vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb) |
243 | { | 70 | { |