Commit | Line | Data |
---|---|---|
243a2e63 VY |
1 | #include <linux/kernel.h> |
2 | #include <linux/netdevice.h> | |
3 | #include <linux/rtnetlink.h> | |
4 | #include <linux/slab.h> | |
5 | ||
6 | #include "br_private.h" | |
7 | ||
552406c4 VY |
8 | static void __vlan_add_pvid(struct net_port_vlans *v, u16 vid) |
9 | { | |
10 | if (v->pvid == vid) | |
11 | return; | |
12 | ||
13 | smp_wmb(); | |
14 | v->pvid = vid; | |
15 | } | |
16 | ||
17 | static void __vlan_delete_pvid(struct net_port_vlans *v, u16 vid) | |
18 | { | |
19 | if (v->pvid != vid) | |
20 | return; | |
21 | ||
22 | smp_wmb(); | |
23 | v->pvid = 0; | |
24 | } | |
25 | ||
35e03f3a VY |
26 | static void __vlan_add_flags(struct net_port_vlans *v, u16 vid, u16 flags) |
27 | { | |
28 | if (flags & BRIDGE_VLAN_INFO_PVID) | |
29 | __vlan_add_pvid(v, vid); | |
30 | ||
31 | if (flags & BRIDGE_VLAN_INFO_UNTAGGED) | |
32 | set_bit(vid, v->untagged_bitmap); | |
33 | } | |
34 | ||
552406c4 | 35 | static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) |
243a2e63 | 36 | { |
80d5c368 | 37 | const struct net_device_ops *ops; |
bc9a25d2 VY |
38 | struct net_bridge_port *p = NULL; |
39 | struct net_bridge *br; | |
40 | struct net_device *dev; | |
243a2e63 VY |
41 | int err; |
42 | ||
552406c4 | 43 | if (test_bit(vid, v->vlan_bitmap)) { |
35e03f3a | 44 | __vlan_add_flags(v, vid, flags); |
552406c4 VY |
45 | return 0; |
46 | } | |
243a2e63 | 47 | |
bc9a25d2 VY |
48 | if (vid) { |
49 | if (v->port_idx) { | |
50 | p = v->parent.port; | |
51 | br = p->br; | |
52 | dev = p->dev; | |
53 | } else { | |
54 | br = v->parent.br; | |
55 | dev = br->dev; | |
56 | } | |
80d5c368 | 57 | ops = dev->netdev_ops; |
243a2e63 | 58 | |
f646968f | 59 | if (p && (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) { |
bc9a25d2 VY |
60 | /* Add VLAN to the device filter if it is supported. |
61 | * Stricly speaking, this is not necessary now, since | |
62 | * devices are made promiscuous by the bridge, but if | |
63 | * that ever changes this code will allow tagged | |
64 | * traffic to enter the bridge. | |
65 | */ | |
80d5c368 PM |
66 | err = ops->ndo_vlan_rx_add_vid(dev, htons(ETH_P_8021Q), |
67 | vid); | |
243a2e63 VY |
68 | if (err) |
69 | return err; | |
70 | } | |
bc9a25d2 VY |
71 | |
72 | err = br_fdb_insert(br, p, dev->dev_addr, vid); | |
73 | if (err) { | |
74 | br_err(br, "failed insert local address into bridge " | |
75 | "forwarding table\n"); | |
76 | goto out_filt; | |
77 | } | |
78 | ||
243a2e63 VY |
79 | } |
80 | ||
81 | set_bit(vid, v->vlan_bitmap); | |
6cbdceeb | 82 | v->num_vlans++; |
35e03f3a | 83 | __vlan_add_flags(v, vid, flags); |
552406c4 | 84 | |
243a2e63 | 85 | return 0; |
bc9a25d2 VY |
86 | |
87 | out_filt: | |
f646968f | 88 | if (p && (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) |
80d5c368 | 89 | ops->ndo_vlan_rx_kill_vid(dev, htons(ETH_P_8021Q), vid); |
bc9a25d2 | 90 | return err; |
243a2e63 VY |
91 | } |
92 | ||
93 | static int __vlan_del(struct net_port_vlans *v, u16 vid) | |
94 | { | |
95 | if (!test_bit(vid, v->vlan_bitmap)) | |
96 | return -EINVAL; | |
97 | ||
552406c4 | 98 | __vlan_delete_pvid(v, vid); |
35e03f3a | 99 | clear_bit(vid, v->untagged_bitmap); |
552406c4 | 100 | |
243a2e63 VY |
101 | if (v->port_idx && vid) { |
102 | struct net_device *dev = v->parent.port->dev; | |
80d5c368 | 103 | const struct net_device_ops *ops = dev->netdev_ops; |
243a2e63 | 104 | |
f646968f | 105 | if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) |
80d5c368 | 106 | ops->ndo_vlan_rx_kill_vid(dev, htons(ETH_P_8021Q), vid); |
243a2e63 VY |
107 | } |
108 | ||
109 | clear_bit(vid, v->vlan_bitmap); | |
6cbdceeb | 110 | v->num_vlans--; |
243a2e63 VY |
111 | if (bitmap_empty(v->vlan_bitmap, BR_VLAN_BITMAP_LEN)) { |
112 | if (v->port_idx) | |
113 | rcu_assign_pointer(v->parent.port->vlan_info, NULL); | |
114 | else | |
115 | rcu_assign_pointer(v->parent.br->vlan_info, NULL); | |
116 | kfree_rcu(v, rcu); | |
117 | } | |
118 | return 0; | |
119 | } | |
120 | ||
121 | static void __vlan_flush(struct net_port_vlans *v) | |
122 | { | |
552406c4 VY |
123 | smp_wmb(); |
124 | v->pvid = 0; | |
243a2e63 VY |
125 | bitmap_zero(v->vlan_bitmap, BR_VLAN_BITMAP_LEN); |
126 | if (v->port_idx) | |
127 | rcu_assign_pointer(v->parent.port->vlan_info, NULL); | |
128 | else | |
129 | rcu_assign_pointer(v->parent.br->vlan_info, NULL); | |
130 | kfree_rcu(v, rcu); | |
131 | } | |
132 | ||
78851988 VY |
133 | /* Strip the tag from the packet. Will return skb with tci set 0. */ |
134 | static struct sk_buff *br_vlan_untag(struct sk_buff *skb) | |
135 | { | |
136 | if (skb->protocol != htons(ETH_P_8021Q)) { | |
137 | skb->vlan_tci = 0; | |
138 | return skb; | |
139 | } | |
140 | ||
141 | skb->vlan_tci = 0; | |
142 | skb = vlan_untag(skb); | |
143 | if (skb) | |
144 | skb->vlan_tci = 0; | |
145 | ||
146 | return skb; | |
147 | } | |
148 | ||
149 | struct sk_buff *br_handle_vlan(struct net_bridge *br, | |
150 | const struct net_port_vlans *pv, | |
151 | struct sk_buff *skb) | |
a37b85c9 VY |
152 | { |
153 | u16 vid; | |
154 | ||
78851988 VY |
155 | if (!br->vlan_enabled) |
156 | goto out; | |
157 | ||
158 | /* At this point, we know that the frame was filtered and contains | |
35e03f3a | 159 | * a valid vlan id. If the vlan id is set in the untagged bitmap, |
78851988 VY |
160 | * send untagged; otherwise, send taged. |
161 | */ | |
162 | br_vlan_get_tag(skb, &vid); | |
35e03f3a | 163 | if (test_bit(vid, pv->untagged_bitmap)) |
78851988 VY |
164 | skb = br_vlan_untag(skb); |
165 | else { | |
166 | /* Egress policy says "send tagged". If output device | |
167 | * is the bridge, we need to add the VLAN header | |
168 | * ourselves since we'll be going through the RX path. | |
169 | * Sending to ports puts the frame on the TX path and | |
170 | * we let dev_hard_start_xmit() add the header. | |
171 | */ | |
172 | if (skb->protocol != htons(ETH_P_8021Q) && | |
173 | pv->port_idx == 0) { | |
174 | /* vlan_put_tag expects skb->data to point to | |
175 | * mac header. | |
176 | */ | |
177 | skb_push(skb, ETH_HLEN); | |
86a9bad3 | 178 | skb = __vlan_put_tag(skb, skb->vlan_proto, skb->vlan_tci); |
78851988 VY |
179 | if (!skb) |
180 | goto out; | |
181 | /* put skb->data back to where it was */ | |
182 | skb_pull(skb, ETH_HLEN); | |
183 | skb->vlan_tci = 0; | |
184 | } | |
185 | } | |
186 | ||
187 | out: | |
188 | return skb; | |
189 | } | |
190 | ||
191 | /* Called under RCU */ | |
192 | bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | |
193 | struct sk_buff *skb, u16 *vid) | |
194 | { | |
a37b85c9 VY |
195 | /* If VLAN filtering is disabled on the bridge, all packets are |
196 | * permitted. | |
197 | */ | |
198 | if (!br->vlan_enabled) | |
199 | return true; | |
200 | ||
201 | /* If there are no vlan in the permitted list, all packets are | |
202 | * rejected. | |
203 | */ | |
204 | if (!v) | |
205 | return false; | |
206 | ||
78851988 VY |
207 | if (br_vlan_get_tag(skb, vid)) { |
208 | u16 pvid = br_get_pvid(v); | |
209 | ||
210 | /* Frame did not have a tag. See if pvid is set | |
211 | * on this port. That tells us which vlan untagged | |
212 | * traffic belongs to. | |
213 | */ | |
214 | if (pvid == VLAN_N_VID) | |
215 | return false; | |
216 | ||
217 | /* PVID is set on this port. Any untagged ingress | |
218 | * frame is considered to belong to this vlan. | |
219 | */ | |
86a9bad3 | 220 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), pvid); |
78851988 VY |
221 | return true; |
222 | } | |
223 | ||
224 | /* Frame had a valid vlan tag. See if vlan is allowed */ | |
225 | if (test_bit(*vid, v->vlan_bitmap)) | |
a37b85c9 VY |
226 | return true; |
227 | ||
228 | return false; | |
229 | } | |
230 | ||
85f46c6b VY |
231 | /* Called under RCU. */ |
232 | bool br_allowed_egress(struct net_bridge *br, | |
233 | const struct net_port_vlans *v, | |
234 | const struct sk_buff *skb) | |
235 | { | |
236 | u16 vid; | |
237 | ||
238 | if (!br->vlan_enabled) | |
239 | return true; | |
240 | ||
241 | if (!v) | |
242 | return false; | |
243 | ||
244 | br_vlan_get_tag(skb, &vid); | |
245 | if (test_bit(vid, v->vlan_bitmap)) | |
246 | return true; | |
247 | ||
248 | return false; | |
249 | } | |
250 | ||
243a2e63 | 251 | /* Must be protected by RTNL */ |
552406c4 | 252 | int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags) |
243a2e63 VY |
253 | { |
254 | struct net_port_vlans *pv = NULL; | |
255 | int err; | |
256 | ||
257 | ASSERT_RTNL(); | |
258 | ||
259 | pv = rtnl_dereference(br->vlan_info); | |
260 | if (pv) | |
552406c4 | 261 | return __vlan_add(pv, vid, flags); |
243a2e63 VY |
262 | |
263 | /* Create port vlan infomration | |
264 | */ | |
265 | pv = kzalloc(sizeof(*pv), GFP_KERNEL); | |
266 | if (!pv) | |
267 | return -ENOMEM; | |
268 | ||
269 | pv->parent.br = br; | |
552406c4 | 270 | err = __vlan_add(pv, vid, flags); |
243a2e63 VY |
271 | if (err) |
272 | goto out; | |
273 | ||
274 | rcu_assign_pointer(br->vlan_info, pv); | |
275 | return 0; | |
276 | out: | |
277 | kfree(pv); | |
278 | return err; | |
279 | } | |
280 | ||
281 | /* Must be protected by RTNL */ | |
282 | int br_vlan_delete(struct net_bridge *br, u16 vid) | |
283 | { | |
284 | struct net_port_vlans *pv; | |
285 | ||
286 | ASSERT_RTNL(); | |
287 | ||
288 | pv = rtnl_dereference(br->vlan_info); | |
289 | if (!pv) | |
290 | return -EINVAL; | |
291 | ||
bc9a25d2 VY |
292 | if (vid) { |
293 | /* If the VID !=0 remove fdb for this vid. VID 0 is special | |
294 | * in that it's the default and is always there in the fdb. | |
295 | */ | |
296 | spin_lock_bh(&br->hash_lock); | |
297 | fdb_delete_by_addr(br, br->dev->dev_addr, vid); | |
298 | spin_unlock_bh(&br->hash_lock); | |
299 | } | |
300 | ||
243a2e63 VY |
301 | __vlan_del(pv, vid); |
302 | return 0; | |
303 | } | |
304 | ||
305 | void br_vlan_flush(struct net_bridge *br) | |
306 | { | |
307 | struct net_port_vlans *pv; | |
308 | ||
309 | ASSERT_RTNL(); | |
243a2e63 VY |
310 | pv = rtnl_dereference(br->vlan_info); |
311 | if (!pv) | |
312 | return; | |
313 | ||
314 | __vlan_flush(pv); | |
315 | } | |
316 | ||
317 | int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) | |
318 | { | |
319 | if (!rtnl_trylock()) | |
320 | return restart_syscall(); | |
321 | ||
322 | if (br->vlan_enabled == val) | |
323 | goto unlock; | |
324 | ||
325 | br->vlan_enabled = val; | |
326 | ||
327 | unlock: | |
328 | rtnl_unlock(); | |
329 | return 0; | |
330 | } | |
331 | ||
332 | /* Must be protected by RTNL */ | |
552406c4 | 333 | int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) |
243a2e63 VY |
334 | { |
335 | struct net_port_vlans *pv = NULL; | |
336 | int err; | |
337 | ||
338 | ASSERT_RTNL(); | |
339 | ||
340 | pv = rtnl_dereference(port->vlan_info); | |
341 | if (pv) | |
552406c4 | 342 | return __vlan_add(pv, vid, flags); |
243a2e63 VY |
343 | |
344 | /* Create port vlan infomration | |
345 | */ | |
346 | pv = kzalloc(sizeof(*pv), GFP_KERNEL); | |
347 | if (!pv) { | |
348 | err = -ENOMEM; | |
349 | goto clean_up; | |
350 | } | |
351 | ||
352 | pv->port_idx = port->port_no; | |
353 | pv->parent.port = port; | |
552406c4 | 354 | err = __vlan_add(pv, vid, flags); |
243a2e63 VY |
355 | if (err) |
356 | goto clean_up; | |
357 | ||
358 | rcu_assign_pointer(port->vlan_info, pv); | |
359 | return 0; | |
360 | ||
361 | clean_up: | |
362 | kfree(pv); | |
363 | return err; | |
364 | } | |
365 | ||
366 | /* Must be protected by RTNL */ | |
367 | int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) | |
368 | { | |
369 | struct net_port_vlans *pv; | |
370 | ||
371 | ASSERT_RTNL(); | |
372 | ||
373 | pv = rtnl_dereference(port->vlan_info); | |
374 | if (!pv) | |
375 | return -EINVAL; | |
376 | ||
bc9a25d2 VY |
377 | if (vid) { |
378 | /* If the VID !=0 remove fdb for this vid. VID 0 is special | |
379 | * in that it's the default and is always there in the fdb. | |
380 | */ | |
381 | spin_lock_bh(&port->br->hash_lock); | |
382 | fdb_delete_by_addr(port->br, port->dev->dev_addr, vid); | |
383 | spin_unlock_bh(&port->br->hash_lock); | |
384 | } | |
385 | ||
243a2e63 VY |
386 | return __vlan_del(pv, vid); |
387 | } | |
388 | ||
389 | void nbp_vlan_flush(struct net_bridge_port *port) | |
390 | { | |
391 | struct net_port_vlans *pv; | |
392 | ||
393 | ASSERT_RTNL(); | |
394 | ||
395 | pv = rtnl_dereference(port->vlan_info); | |
396 | if (!pv) | |
397 | return; | |
398 | ||
399 | __vlan_flush(pv); | |
400 | } | |
bc9a25d2 VY |
401 | |
402 | bool nbp_vlan_find(struct net_bridge_port *port, u16 vid) | |
403 | { | |
404 | struct net_port_vlans *pv; | |
405 | bool found = false; | |
406 | ||
407 | rcu_read_lock(); | |
408 | pv = rcu_dereference(port->vlan_info); | |
409 | ||
410 | if (!pv) | |
411 | goto out; | |
412 | ||
413 | if (test_bit(vid, pv->vlan_bitmap)) | |
414 | found = true; | |
415 | ||
416 | out: | |
417 | rcu_read_unlock(); | |
418 | return found; | |
419 | } |