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> | |
7f109539 | 5 | #include <net/switchdev.h> |
243a2e63 VY |
6 | |
7 | #include "br_private.h" | |
8 | ||
552406c4 VY |
9 | static void __vlan_add_pvid(struct net_port_vlans *v, u16 vid) |
10 | { | |
11 | if (v->pvid == vid) | |
12 | return; | |
13 | ||
14 | smp_wmb(); | |
15 | v->pvid = vid; | |
16 | } | |
17 | ||
18 | static void __vlan_delete_pvid(struct net_port_vlans *v, u16 vid) | |
19 | { | |
20 | if (v->pvid != vid) | |
21 | return; | |
22 | ||
23 | smp_wmb(); | |
24 | v->pvid = 0; | |
25 | } | |
26 | ||
35e03f3a VY |
27 | static void __vlan_add_flags(struct net_port_vlans *v, u16 vid, u16 flags) |
28 | { | |
29 | if (flags & BRIDGE_VLAN_INFO_PVID) | |
30 | __vlan_add_pvid(v, vid); | |
635126b7 VY |
31 | else |
32 | __vlan_delete_pvid(v, vid); | |
35e03f3a VY |
33 | |
34 | if (flags & BRIDGE_VLAN_INFO_UNTAGGED) | |
35 | set_bit(vid, v->untagged_bitmap); | |
635126b7 VY |
36 | else |
37 | clear_bit(vid, v->untagged_bitmap); | |
35e03f3a VY |
38 | } |
39 | ||
7f109539 SF |
40 | static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br, |
41 | u16 vid, u16 flags) | |
42 | { | |
43 | const struct net_device_ops *ops = dev->netdev_ops; | |
44 | int err; | |
45 | ||
46 | /* If driver uses VLAN ndo ops, use 8021q to install vid | |
47 | * on device, otherwise try switchdev ops to install vid. | |
48 | */ | |
49 | ||
50 | if (ops->ndo_vlan_rx_add_vid) { | |
51 | err = vlan_vid_add(dev, br->vlan_proto, vid); | |
52 | } else { | |
53 | struct switchdev_obj vlan_obj = { | |
54 | .id = SWITCHDEV_OBJ_PORT_VLAN, | |
55 | .u.vlan = { | |
56 | .flags = flags, | |
3e3a78b4 | 57 | .vid_begin = vid, |
7f109539 SF |
58 | .vid_end = vid, |
59 | }, | |
60 | }; | |
61 | ||
62 | err = switchdev_port_obj_add(dev, &vlan_obj); | |
63 | if (err == -EOPNOTSUPP) | |
64 | err = 0; | |
65 | } | |
66 | ||
67 | return err; | |
68 | } | |
69 | ||
552406c4 | 70 | static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) |
243a2e63 | 71 | { |
bc9a25d2 VY |
72 | struct net_bridge_port *p = NULL; |
73 | struct net_bridge *br; | |
74 | struct net_device *dev; | |
243a2e63 VY |
75 | int err; |
76 | ||
552406c4 | 77 | if (test_bit(vid, v->vlan_bitmap)) { |
35e03f3a | 78 | __vlan_add_flags(v, vid, flags); |
552406c4 VY |
79 | return 0; |
80 | } | |
243a2e63 | 81 | |
8adff41c TM |
82 | if (v->port_idx) { |
83 | p = v->parent.port; | |
84 | br = p->br; | |
85 | dev = p->dev; | |
86 | } else { | |
87 | br = v->parent.br; | |
88 | dev = br->dev; | |
89 | } | |
8adff41c | 90 | |
19236837 | 91 | if (p) { |
8adff41c | 92 | /* Add VLAN to the device filter if it is supported. |
fdb0a662 TM |
93 | * This ensures tagged traffic enters the bridge when |
94 | * promiscuous mode is disabled by br_manage_promisc(). | |
8adff41c | 95 | */ |
7f109539 | 96 | err = __vlan_vid_add(dev, br, vid, flags); |
8adff41c TM |
97 | if (err) |
98 | return err; | |
99 | } | |
bc9a25d2 | 100 | |
8adff41c TM |
101 | err = br_fdb_insert(br, p, dev->dev_addr, vid); |
102 | if (err) { | |
103 | br_err(br, "failed insert local address into bridge " | |
104 | "forwarding table\n"); | |
105 | goto out_filt; | |
243a2e63 VY |
106 | } |
107 | ||
108 | set_bit(vid, v->vlan_bitmap); | |
6cbdceeb | 109 | v->num_vlans++; |
35e03f3a | 110 | __vlan_add_flags(v, vid, flags); |
552406c4 | 111 | |
243a2e63 | 112 | return 0; |
bc9a25d2 VY |
113 | |
114 | out_filt: | |
19236837 | 115 | if (p) |
8580e211 | 116 | vlan_vid_del(dev, br->vlan_proto, vid); |
bc9a25d2 | 117 | return err; |
243a2e63 VY |
118 | } |
119 | ||
7f109539 SF |
120 | static void __vlan_vid_del(struct net_device *dev, struct net_bridge *br, |
121 | u16 vid) | |
122 | { | |
123 | const struct net_device_ops *ops = dev->netdev_ops; | |
124 | ||
125 | /* If driver uses VLAN ndo ops, use 8021q to delete vid | |
126 | * on device, otherwise try switchdev ops to delete vid. | |
127 | */ | |
128 | ||
129 | if (ops->ndo_vlan_rx_kill_vid) { | |
130 | vlan_vid_del(dev, br->vlan_proto, vid); | |
131 | } else { | |
132 | struct switchdev_obj vlan_obj = { | |
133 | .id = SWITCHDEV_OBJ_PORT_VLAN, | |
134 | .u.vlan = { | |
3e3a78b4 | 135 | .vid_begin = vid, |
7f109539 SF |
136 | .vid_end = vid, |
137 | }, | |
138 | }; | |
139 | ||
140 | switchdev_port_obj_del(dev, &vlan_obj); | |
141 | } | |
142 | } | |
143 | ||
243a2e63 VY |
144 | static int __vlan_del(struct net_port_vlans *v, u16 vid) |
145 | { | |
146 | if (!test_bit(vid, v->vlan_bitmap)) | |
147 | return -EINVAL; | |
148 | ||
552406c4 | 149 | __vlan_delete_pvid(v, vid); |
35e03f3a | 150 | clear_bit(vid, v->untagged_bitmap); |
552406c4 | 151 | |
8580e211 TM |
152 | if (v->port_idx) { |
153 | struct net_bridge_port *p = v->parent.port; | |
7f109539 | 154 | __vlan_vid_del(p->dev, p->br, vid); |
8580e211 | 155 | } |
243a2e63 VY |
156 | |
157 | clear_bit(vid, v->vlan_bitmap); | |
6cbdceeb | 158 | v->num_vlans--; |
ef40b7ef | 159 | if (bitmap_empty(v->vlan_bitmap, VLAN_N_VID)) { |
243a2e63 | 160 | if (v->port_idx) |
cd18721e | 161 | RCU_INIT_POINTER(v->parent.port->vlan_info, NULL); |
243a2e63 | 162 | else |
cd18721e | 163 | RCU_INIT_POINTER(v->parent.br->vlan_info, NULL); |
243a2e63 VY |
164 | kfree_rcu(v, rcu); |
165 | } | |
166 | return 0; | |
167 | } | |
168 | ||
169 | static void __vlan_flush(struct net_port_vlans *v) | |
170 | { | |
552406c4 VY |
171 | smp_wmb(); |
172 | v->pvid = 0; | |
ef40b7ef | 173 | bitmap_zero(v->vlan_bitmap, VLAN_N_VID); |
243a2e63 | 174 | if (v->port_idx) |
cd18721e | 175 | RCU_INIT_POINTER(v->parent.port->vlan_info, NULL); |
243a2e63 | 176 | else |
cd18721e | 177 | RCU_INIT_POINTER(v->parent.br->vlan_info, NULL); |
243a2e63 VY |
178 | kfree_rcu(v, rcu); |
179 | } | |
180 | ||
78851988 VY |
181 | struct sk_buff *br_handle_vlan(struct net_bridge *br, |
182 | const struct net_port_vlans *pv, | |
183 | struct sk_buff *skb) | |
a37b85c9 VY |
184 | { |
185 | u16 vid; | |
186 | ||
20adfa1a VY |
187 | /* If this packet was not filtered at input, let it pass */ |
188 | if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) | |
78851988 VY |
189 | goto out; |
190 | ||
fc92f745 VY |
191 | /* Vlan filter table must be configured at this point. The |
192 | * only exception is the bridge is set in promisc mode and the | |
193 | * packet is destined for the bridge device. In this case | |
194 | * pass the packet as is. | |
195 | */ | |
196 | if (!pv) { | |
197 | if ((br->dev->flags & IFF_PROMISC) && skb->dev == br->dev) { | |
198 | goto out; | |
199 | } else { | |
200 | kfree_skb(skb); | |
201 | return NULL; | |
202 | } | |
203 | } | |
204 | ||
78851988 | 205 | /* At this point, we know that the frame was filtered and contains |
35e03f3a | 206 | * a valid vlan id. If the vlan id is set in the untagged bitmap, |
1a81a2e0 | 207 | * send untagged; otherwise, send tagged. |
78851988 VY |
208 | */ |
209 | br_vlan_get_tag(skb, &vid); | |
35e03f3a | 210 | if (test_bit(vid, pv->untagged_bitmap)) |
99b192da | 211 | skb->vlan_tci = 0; |
78851988 VY |
212 | |
213 | out: | |
214 | return skb; | |
215 | } | |
216 | ||
217 | /* Called under RCU */ | |
218 | bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | |
219 | struct sk_buff *skb, u16 *vid) | |
220 | { | |
8580e211 TM |
221 | bool tagged; |
222 | __be16 proto; | |
b90356ce | 223 | |
a37b85c9 VY |
224 | /* If VLAN filtering is disabled on the bridge, all packets are |
225 | * permitted. | |
226 | */ | |
20adfa1a VY |
227 | if (!br->vlan_enabled) { |
228 | BR_INPUT_SKB_CB(skb)->vlan_filtered = false; | |
a37b85c9 | 229 | return true; |
20adfa1a | 230 | } |
a37b85c9 VY |
231 | |
232 | /* If there are no vlan in the permitted list, all packets are | |
233 | * rejected. | |
234 | */ | |
235 | if (!v) | |
eb707618 | 236 | goto drop; |
a37b85c9 | 237 | |
20adfa1a | 238 | BR_INPUT_SKB_CB(skb)->vlan_filtered = true; |
8580e211 TM |
239 | proto = br->vlan_proto; |
240 | ||
12464bb8 TM |
241 | /* If vlan tx offload is disabled on bridge device and frame was |
242 | * sent from vlan device on the bridge device, it does not have | |
243 | * HW accelerated vlan tag. | |
244 | */ | |
df8a39de | 245 | if (unlikely(!skb_vlan_tag_present(skb) && |
8580e211 | 246 | skb->protocol == proto)) { |
0d5501c1 | 247 | skb = skb_vlan_untag(skb); |
12464bb8 TM |
248 | if (unlikely(!skb)) |
249 | return false; | |
250 | } | |
251 | ||
8580e211 TM |
252 | if (!br_vlan_get_tag(skb, vid)) { |
253 | /* Tagged frame */ | |
254 | if (skb->vlan_proto != proto) { | |
255 | /* Protocol-mismatch, empty out vlan_tci for new tag */ | |
256 | skb_push(skb, ETH_HLEN); | |
62749e2c | 257 | skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, |
df8a39de | 258 | skb_vlan_tag_get(skb)); |
8580e211 TM |
259 | if (unlikely(!skb)) |
260 | return false; | |
261 | ||
262 | skb_pull(skb, ETH_HLEN); | |
263 | skb_reset_mac_len(skb); | |
264 | *vid = 0; | |
265 | tagged = false; | |
266 | } else { | |
267 | tagged = true; | |
268 | } | |
269 | } else { | |
270 | /* Untagged frame */ | |
271 | tagged = false; | |
272 | } | |
273 | ||
b90356ce | 274 | if (!*vid) { |
78851988 VY |
275 | u16 pvid = br_get_pvid(v); |
276 | ||
b90356ce TM |
277 | /* Frame had a tag with VID 0 or did not have a tag. |
278 | * See if pvid is set on this port. That tells us which | |
279 | * vlan untagged or priority-tagged traffic belongs to. | |
78851988 | 280 | */ |
3df6bf45 | 281 | if (!pvid) |
eb707618 | 282 | goto drop; |
78851988 | 283 | |
b90356ce TM |
284 | /* PVID is set on this port. Any untagged or priority-tagged |
285 | * ingress frame is considered to belong to this vlan. | |
78851988 | 286 | */ |
dfb5fa32 | 287 | *vid = pvid; |
8580e211 | 288 | if (likely(!tagged)) |
b90356ce | 289 | /* Untagged Frame. */ |
8580e211 | 290 | __vlan_hwaccel_put_tag(skb, proto, pvid); |
b90356ce TM |
291 | else |
292 | /* Priority-tagged Frame. | |
293 | * At this point, We know that skb->vlan_tci had | |
294 | * VLAN_TAG_PRESENT bit and its VID field was 0x000. | |
295 | * We update only VID field and preserve PCP field. | |
296 | */ | |
297 | skb->vlan_tci |= pvid; | |
298 | ||
78851988 VY |
299 | return true; |
300 | } | |
301 | ||
302 | /* Frame had a valid vlan tag. See if vlan is allowed */ | |
303 | if (test_bit(*vid, v->vlan_bitmap)) | |
a37b85c9 | 304 | return true; |
eb707618 TM |
305 | drop: |
306 | kfree_skb(skb); | |
a37b85c9 VY |
307 | return false; |
308 | } | |
309 | ||
85f46c6b VY |
310 | /* Called under RCU. */ |
311 | bool br_allowed_egress(struct net_bridge *br, | |
312 | const struct net_port_vlans *v, | |
313 | const struct sk_buff *skb) | |
314 | { | |
315 | u16 vid; | |
316 | ||
20adfa1a VY |
317 | /* If this packet was not filtered at input, let it pass */ |
318 | if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) | |
85f46c6b VY |
319 | return true; |
320 | ||
321 | if (!v) | |
322 | return false; | |
323 | ||
324 | br_vlan_get_tag(skb, &vid); | |
325 | if (test_bit(vid, v->vlan_bitmap)) | |
326 | return true; | |
327 | ||
328 | return false; | |
329 | } | |
330 | ||
e0d7968a TM |
331 | /* Called under RCU */ |
332 | bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) | |
333 | { | |
334 | struct net_bridge *br = p->br; | |
335 | struct net_port_vlans *v; | |
336 | ||
20adfa1a | 337 | /* If filtering was disabled at input, let it pass. */ |
c095f248 | 338 | if (!br->vlan_enabled) |
e0d7968a TM |
339 | return true; |
340 | ||
341 | v = rcu_dereference(p->vlan_info); | |
342 | if (!v) | |
343 | return false; | |
344 | ||
8580e211 TM |
345 | if (!br_vlan_get_tag(skb, vid) && skb->vlan_proto != br->vlan_proto) |
346 | *vid = 0; | |
347 | ||
e0d7968a TM |
348 | if (!*vid) { |
349 | *vid = br_get_pvid(v); | |
3df6bf45 | 350 | if (!*vid) |
e0d7968a TM |
351 | return false; |
352 | ||
353 | return true; | |
354 | } | |
355 | ||
356 | if (test_bit(*vid, v->vlan_bitmap)) | |
357 | return true; | |
358 | ||
359 | return false; | |
360 | } | |
361 | ||
8adff41c TM |
362 | /* Must be protected by RTNL. |
363 | * Must be called with vid in range from 1 to 4094 inclusive. | |
364 | */ | |
552406c4 | 365 | int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags) |
243a2e63 VY |
366 | { |
367 | struct net_port_vlans *pv = NULL; | |
368 | int err; | |
369 | ||
370 | ASSERT_RTNL(); | |
371 | ||
372 | pv = rtnl_dereference(br->vlan_info); | |
373 | if (pv) | |
552406c4 | 374 | return __vlan_add(pv, vid, flags); |
243a2e63 VY |
375 | |
376 | /* Create port vlan infomration | |
377 | */ | |
378 | pv = kzalloc(sizeof(*pv), GFP_KERNEL); | |
379 | if (!pv) | |
380 | return -ENOMEM; | |
381 | ||
382 | pv->parent.br = br; | |
552406c4 | 383 | err = __vlan_add(pv, vid, flags); |
243a2e63 VY |
384 | if (err) |
385 | goto out; | |
386 | ||
387 | rcu_assign_pointer(br->vlan_info, pv); | |
388 | return 0; | |
389 | out: | |
390 | kfree(pv); | |
391 | return err; | |
392 | } | |
393 | ||
8adff41c TM |
394 | /* Must be protected by RTNL. |
395 | * Must be called with vid in range from 1 to 4094 inclusive. | |
396 | */ | |
243a2e63 VY |
397 | int br_vlan_delete(struct net_bridge *br, u16 vid) |
398 | { | |
399 | struct net_port_vlans *pv; | |
400 | ||
401 | ASSERT_RTNL(); | |
402 | ||
403 | pv = rtnl_dereference(br->vlan_info); | |
404 | if (!pv) | |
405 | return -EINVAL; | |
406 | ||
424bb9c9 | 407 | br_fdb_find_delete_local(br, NULL, br->dev->dev_addr, vid); |
bc9a25d2 | 408 | |
243a2e63 VY |
409 | __vlan_del(pv, vid); |
410 | return 0; | |
411 | } | |
412 | ||
413 | void br_vlan_flush(struct net_bridge *br) | |
414 | { | |
415 | struct net_port_vlans *pv; | |
416 | ||
417 | ASSERT_RTNL(); | |
243a2e63 VY |
418 | pv = rtnl_dereference(br->vlan_info); |
419 | if (!pv) | |
420 | return; | |
421 | ||
422 | __vlan_flush(pv); | |
423 | } | |
424 | ||
2b292fb4 TM |
425 | bool br_vlan_find(struct net_bridge *br, u16 vid) |
426 | { | |
427 | struct net_port_vlans *pv; | |
428 | bool found = false; | |
429 | ||
430 | rcu_read_lock(); | |
431 | pv = rcu_dereference(br->vlan_info); | |
432 | ||
433 | if (!pv) | |
434 | goto out; | |
435 | ||
436 | if (test_bit(vid, pv->vlan_bitmap)) | |
437 | found = true; | |
438 | ||
439 | out: | |
440 | rcu_read_unlock(); | |
441 | return found; | |
442 | } | |
443 | ||
204177f3 TM |
444 | /* Must be protected by RTNL. */ |
445 | static void recalculate_group_addr(struct net_bridge *br) | |
446 | { | |
447 | if (br->group_addr_set) | |
448 | return; | |
449 | ||
450 | spin_lock_bh(&br->lock); | |
451 | if (!br->vlan_enabled || br->vlan_proto == htons(ETH_P_8021Q)) { | |
452 | /* Bridge Group Address */ | |
453 | br->group_addr[5] = 0x00; | |
454 | } else { /* vlan_enabled && ETH_P_8021AD */ | |
455 | /* Provider Bridge Group Address */ | |
456 | br->group_addr[5] = 0x08; | |
457 | } | |
458 | spin_unlock_bh(&br->lock); | |
459 | } | |
460 | ||
461 | /* Must be protected by RTNL. */ | |
462 | void br_recalculate_fwd_mask(struct net_bridge *br) | |
463 | { | |
464 | if (!br->vlan_enabled || br->vlan_proto == htons(ETH_P_8021Q)) | |
465 | br->group_fwd_mask_required = BR_GROUPFWD_DEFAULT; | |
466 | else /* vlan_enabled && ETH_P_8021AD */ | |
467 | br->group_fwd_mask_required = BR_GROUPFWD_8021AD & | |
468 | ~(1u << br->group_addr[5]); | |
469 | } | |
470 | ||
243a2e63 VY |
471 | int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) |
472 | { | |
473 | if (!rtnl_trylock()) | |
474 | return restart_syscall(); | |
475 | ||
476 | if (br->vlan_enabled == val) | |
477 | goto unlock; | |
478 | ||
479 | br->vlan_enabled = val; | |
2796d0c6 | 480 | br_manage_promisc(br); |
204177f3 TM |
481 | recalculate_group_addr(br); |
482 | br_recalculate_fwd_mask(br); | |
243a2e63 VY |
483 | |
484 | unlock: | |
485 | rtnl_unlock(); | |
486 | return 0; | |
487 | } | |
488 | ||
204177f3 TM |
489 | int br_vlan_set_proto(struct net_bridge *br, unsigned long val) |
490 | { | |
491 | int err = 0; | |
492 | struct net_bridge_port *p; | |
493 | struct net_port_vlans *pv; | |
494 | __be16 proto, oldproto; | |
495 | u16 vid, errvid; | |
496 | ||
497 | if (val != ETH_P_8021Q && val != ETH_P_8021AD) | |
498 | return -EPROTONOSUPPORT; | |
499 | ||
500 | if (!rtnl_trylock()) | |
501 | return restart_syscall(); | |
502 | ||
503 | proto = htons(val); | |
504 | if (br->vlan_proto == proto) | |
505 | goto unlock; | |
506 | ||
507 | /* Add VLANs for the new proto to the device filter. */ | |
508 | list_for_each_entry(p, &br->port_list, list) { | |
509 | pv = rtnl_dereference(p->vlan_info); | |
510 | if (!pv) | |
511 | continue; | |
512 | ||
513 | for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { | |
514 | err = vlan_vid_add(p->dev, proto, vid); | |
515 | if (err) | |
516 | goto err_filt; | |
517 | } | |
518 | } | |
519 | ||
520 | oldproto = br->vlan_proto; | |
521 | br->vlan_proto = proto; | |
522 | ||
523 | recalculate_group_addr(br); | |
524 | br_recalculate_fwd_mask(br); | |
525 | ||
526 | /* Delete VLANs for the old proto from the device filter. */ | |
527 | list_for_each_entry(p, &br->port_list, list) { | |
528 | pv = rtnl_dereference(p->vlan_info); | |
529 | if (!pv) | |
530 | continue; | |
531 | ||
532 | for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) | |
533 | vlan_vid_del(p->dev, oldproto, vid); | |
534 | } | |
535 | ||
536 | unlock: | |
537 | rtnl_unlock(); | |
538 | return err; | |
539 | ||
540 | err_filt: | |
541 | errvid = vid; | |
542 | for_each_set_bit(vid, pv->vlan_bitmap, errvid) | |
543 | vlan_vid_del(p->dev, proto, vid); | |
544 | ||
545 | list_for_each_entry_continue_reverse(p, &br->port_list, list) { | |
546 | pv = rtnl_dereference(p->vlan_info); | |
547 | if (!pv) | |
548 | continue; | |
549 | ||
550 | for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) | |
551 | vlan_vid_del(p->dev, proto, vid); | |
552 | } | |
553 | ||
554 | goto unlock; | |
555 | } | |
556 | ||
5be5a2df VY |
557 | static bool vlan_default_pvid(struct net_port_vlans *pv, u16 vid) |
558 | { | |
559 | return pv && vid == pv->pvid && test_bit(vid, pv->untagged_bitmap); | |
560 | } | |
561 | ||
562 | static void br_vlan_disable_default_pvid(struct net_bridge *br) | |
563 | { | |
564 | struct net_bridge_port *p; | |
565 | u16 pvid = br->default_pvid; | |
566 | ||
567 | /* Disable default_pvid on all ports where it is still | |
568 | * configured. | |
569 | */ | |
570 | if (vlan_default_pvid(br_get_vlan_info(br), pvid)) | |
571 | br_vlan_delete(br, pvid); | |
572 | ||
573 | list_for_each_entry(p, &br->port_list, list) { | |
574 | if (vlan_default_pvid(nbp_get_vlan_info(p), pvid)) | |
575 | nbp_vlan_delete(p, pvid); | |
576 | } | |
577 | ||
578 | br->default_pvid = 0; | |
579 | } | |
580 | ||
581 | static int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid) | |
582 | { | |
583 | struct net_bridge_port *p; | |
584 | u16 old_pvid; | |
585 | int err = 0; | |
586 | unsigned long *changed; | |
587 | ||
588 | changed = kcalloc(BITS_TO_LONGS(BR_MAX_PORTS), sizeof(unsigned long), | |
589 | GFP_KERNEL); | |
590 | if (!changed) | |
591 | return -ENOMEM; | |
592 | ||
593 | old_pvid = br->default_pvid; | |
594 | ||
595 | /* Update default_pvid config only if we do not conflict with | |
596 | * user configuration. | |
597 | */ | |
598 | if ((!old_pvid || vlan_default_pvid(br_get_vlan_info(br), old_pvid)) && | |
599 | !br_vlan_find(br, pvid)) { | |
600 | err = br_vlan_add(br, pvid, | |
601 | BRIDGE_VLAN_INFO_PVID | | |
602 | BRIDGE_VLAN_INFO_UNTAGGED); | |
603 | if (err) | |
604 | goto out; | |
605 | br_vlan_delete(br, old_pvid); | |
606 | set_bit(0, changed); | |
607 | } | |
608 | ||
609 | list_for_each_entry(p, &br->port_list, list) { | |
610 | /* Update default_pvid config only if we do not conflict with | |
611 | * user configuration. | |
612 | */ | |
613 | if ((old_pvid && | |
614 | !vlan_default_pvid(nbp_get_vlan_info(p), old_pvid)) || | |
615 | nbp_vlan_find(p, pvid)) | |
616 | continue; | |
617 | ||
618 | err = nbp_vlan_add(p, pvid, | |
619 | BRIDGE_VLAN_INFO_PVID | | |
620 | BRIDGE_VLAN_INFO_UNTAGGED); | |
621 | if (err) | |
622 | goto err_port; | |
623 | nbp_vlan_delete(p, old_pvid); | |
624 | set_bit(p->port_no, changed); | |
625 | } | |
626 | ||
627 | br->default_pvid = pvid; | |
628 | ||
629 | out: | |
630 | kfree(changed); | |
631 | return err; | |
632 | ||
633 | err_port: | |
634 | list_for_each_entry_continue_reverse(p, &br->port_list, list) { | |
635 | if (!test_bit(p->port_no, changed)) | |
636 | continue; | |
637 | ||
638 | if (old_pvid) | |
639 | nbp_vlan_add(p, old_pvid, | |
640 | BRIDGE_VLAN_INFO_PVID | | |
641 | BRIDGE_VLAN_INFO_UNTAGGED); | |
642 | nbp_vlan_delete(p, pvid); | |
643 | } | |
644 | ||
645 | if (test_bit(0, changed)) { | |
646 | if (old_pvid) | |
647 | br_vlan_add(br, old_pvid, | |
648 | BRIDGE_VLAN_INFO_PVID | | |
649 | BRIDGE_VLAN_INFO_UNTAGGED); | |
650 | br_vlan_delete(br, pvid); | |
651 | } | |
652 | goto out; | |
653 | } | |
654 | ||
96a20d9d VY |
655 | int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val) |
656 | { | |
657 | u16 pvid = val; | |
658 | int err = 0; | |
659 | ||
5be5a2df | 660 | if (val >= VLAN_VID_MASK) |
96a20d9d VY |
661 | return -EINVAL; |
662 | ||
663 | if (!rtnl_trylock()) | |
664 | return restart_syscall(); | |
665 | ||
666 | if (pvid == br->default_pvid) | |
667 | goto unlock; | |
668 | ||
669 | /* Only allow default pvid change when filtering is disabled */ | |
670 | if (br->vlan_enabled) { | |
671 | pr_info_once("Please disable vlan filtering to change default_pvid\n"); | |
672 | err = -EPERM; | |
673 | goto unlock; | |
674 | } | |
675 | ||
5be5a2df VY |
676 | if (!pvid) |
677 | br_vlan_disable_default_pvid(br); | |
678 | else | |
679 | err = __br_vlan_set_default_pvid(br, pvid); | |
96a20d9d VY |
680 | |
681 | unlock: | |
682 | rtnl_unlock(); | |
683 | return err; | |
684 | } | |
685 | ||
5be5a2df | 686 | int br_vlan_init(struct net_bridge *br) |
8580e211 TM |
687 | { |
688 | br->vlan_proto = htons(ETH_P_8021Q); | |
96a20d9d | 689 | br->default_pvid = 1; |
5be5a2df VY |
690 | return br_vlan_add(br, 1, |
691 | BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED); | |
8580e211 TM |
692 | } |
693 | ||
8adff41c TM |
694 | /* Must be protected by RTNL. |
695 | * Must be called with vid in range from 1 to 4094 inclusive. | |
696 | */ | |
552406c4 | 697 | int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) |
243a2e63 VY |
698 | { |
699 | struct net_port_vlans *pv = NULL; | |
700 | int err; | |
701 | ||
702 | ASSERT_RTNL(); | |
703 | ||
704 | pv = rtnl_dereference(port->vlan_info); | |
705 | if (pv) | |
552406c4 | 706 | return __vlan_add(pv, vid, flags); |
243a2e63 VY |
707 | |
708 | /* Create port vlan infomration | |
709 | */ | |
710 | pv = kzalloc(sizeof(*pv), GFP_KERNEL); | |
711 | if (!pv) { | |
712 | err = -ENOMEM; | |
713 | goto clean_up; | |
714 | } | |
715 | ||
716 | pv->port_idx = port->port_no; | |
717 | pv->parent.port = port; | |
552406c4 | 718 | err = __vlan_add(pv, vid, flags); |
243a2e63 VY |
719 | if (err) |
720 | goto clean_up; | |
721 | ||
722 | rcu_assign_pointer(port->vlan_info, pv); | |
723 | return 0; | |
724 | ||
725 | clean_up: | |
726 | kfree(pv); | |
727 | return err; | |
728 | } | |
729 | ||
8adff41c TM |
730 | /* Must be protected by RTNL. |
731 | * Must be called with vid in range from 1 to 4094 inclusive. | |
732 | */ | |
243a2e63 VY |
733 | int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) |
734 | { | |
735 | struct net_port_vlans *pv; | |
736 | ||
737 | ASSERT_RTNL(); | |
738 | ||
739 | pv = rtnl_dereference(port->vlan_info); | |
740 | if (!pv) | |
741 | return -EINVAL; | |
742 | ||
424bb9c9 | 743 | br_fdb_find_delete_local(port->br, port, port->dev->dev_addr, vid); |
1ea2d020 | 744 | br_fdb_delete_by_port(port->br, port, vid, 0); |
bc9a25d2 | 745 | |
243a2e63 VY |
746 | return __vlan_del(pv, vid); |
747 | } | |
748 | ||
749 | void nbp_vlan_flush(struct net_bridge_port *port) | |
750 | { | |
751 | struct net_port_vlans *pv; | |
dbbaf949 | 752 | u16 vid; |
243a2e63 VY |
753 | |
754 | ASSERT_RTNL(); | |
755 | ||
756 | pv = rtnl_dereference(port->vlan_info); | |
757 | if (!pv) | |
758 | return; | |
759 | ||
dbbaf949 | 760 | for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) |
8580e211 | 761 | vlan_vid_del(port->dev, port->br->vlan_proto, vid); |
dbbaf949 | 762 | |
243a2e63 VY |
763 | __vlan_flush(pv); |
764 | } | |
bc9a25d2 VY |
765 | |
766 | bool nbp_vlan_find(struct net_bridge_port *port, u16 vid) | |
767 | { | |
768 | struct net_port_vlans *pv; | |
769 | bool found = false; | |
770 | ||
771 | rcu_read_lock(); | |
772 | pv = rcu_dereference(port->vlan_info); | |
773 | ||
774 | if (!pv) | |
775 | goto out; | |
776 | ||
777 | if (test_bit(vid, pv->vlan_bitmap)) | |
778 | found = true; | |
779 | ||
780 | out: | |
781 | rcu_read_unlock(); | |
782 | return found; | |
783 | } | |
5be5a2df VY |
784 | |
785 | int nbp_vlan_init(struct net_bridge_port *p) | |
786 | { | |
787 | return p->br->default_pvid ? | |
788 | nbp_vlan_add(p, p->br->default_pvid, | |
789 | BRIDGE_VLAN_INFO_PVID | | |
790 | BRIDGE_VLAN_INFO_UNTAGGED) : | |
791 | 0; | |
792 | } |