]>
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 | ||
a7854037 | 471 | int __br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) |
243a2e63 | 472 | { |
243a2e63 | 473 | if (br->vlan_enabled == val) |
a7854037 | 474 | return 0; |
243a2e63 VY |
475 | |
476 | br->vlan_enabled = val; | |
2796d0c6 | 477 | br_manage_promisc(br); |
204177f3 TM |
478 | recalculate_group_addr(br); |
479 | br_recalculate_fwd_mask(br); | |
243a2e63 | 480 | |
a7854037 NA |
481 | return 0; |
482 | } | |
483 | ||
484 | int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val) | |
485 | { | |
486 | if (!rtnl_trylock()) | |
487 | return restart_syscall(); | |
488 | ||
489 | __br_vlan_filter_toggle(br, val); | |
243a2e63 | 490 | rtnl_unlock(); |
a7854037 | 491 | |
243a2e63 VY |
492 | return 0; |
493 | } | |
494 | ||
d2d427b3 | 495 | int __br_vlan_set_proto(struct net_bridge *br, __be16 proto) |
204177f3 TM |
496 | { |
497 | int err = 0; | |
498 | struct net_bridge_port *p; | |
499 | struct net_port_vlans *pv; | |
d2d427b3 | 500 | __be16 oldproto; |
204177f3 TM |
501 | u16 vid, errvid; |
502 | ||
204177f3 | 503 | if (br->vlan_proto == proto) |
d2d427b3 | 504 | return 0; |
204177f3 TM |
505 | |
506 | /* Add VLANs for the new proto to the device filter. */ | |
507 | list_for_each_entry(p, &br->port_list, list) { | |
508 | pv = rtnl_dereference(p->vlan_info); | |
509 | if (!pv) | |
510 | continue; | |
511 | ||
512 | for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) { | |
513 | err = vlan_vid_add(p->dev, proto, vid); | |
514 | if (err) | |
515 | goto err_filt; | |
516 | } | |
517 | } | |
518 | ||
519 | oldproto = br->vlan_proto; | |
520 | br->vlan_proto = proto; | |
521 | ||
522 | recalculate_group_addr(br); | |
523 | br_recalculate_fwd_mask(br); | |
524 | ||
525 | /* Delete VLANs for the old proto from the device filter. */ | |
526 | list_for_each_entry(p, &br->port_list, list) { | |
527 | pv = rtnl_dereference(p->vlan_info); | |
528 | if (!pv) | |
529 | continue; | |
530 | ||
531 | for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) | |
532 | vlan_vid_del(p->dev, oldproto, vid); | |
533 | } | |
534 | ||
d2d427b3 | 535 | return 0; |
204177f3 TM |
536 | |
537 | err_filt: | |
538 | errvid = vid; | |
539 | for_each_set_bit(vid, pv->vlan_bitmap, errvid) | |
540 | vlan_vid_del(p->dev, proto, vid); | |
541 | ||
542 | list_for_each_entry_continue_reverse(p, &br->port_list, list) { | |
543 | pv = rtnl_dereference(p->vlan_info); | |
544 | if (!pv) | |
545 | continue; | |
546 | ||
547 | for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) | |
548 | vlan_vid_del(p->dev, proto, vid); | |
549 | } | |
550 | ||
d2d427b3 TM |
551 | return err; |
552 | } | |
553 | ||
554 | int br_vlan_set_proto(struct net_bridge *br, unsigned long val) | |
555 | { | |
556 | int err; | |
557 | ||
558 | if (val != ETH_P_8021Q && val != ETH_P_8021AD) | |
559 | return -EPROTONOSUPPORT; | |
560 | ||
561 | if (!rtnl_trylock()) | |
562 | return restart_syscall(); | |
563 | ||
564 | err = __br_vlan_set_proto(br, htons(val)); | |
565 | rtnl_unlock(); | |
566 | ||
567 | return err; | |
204177f3 TM |
568 | } |
569 | ||
5be5a2df VY |
570 | static bool vlan_default_pvid(struct net_port_vlans *pv, u16 vid) |
571 | { | |
572 | return pv && vid == pv->pvid && test_bit(vid, pv->untagged_bitmap); | |
573 | } | |
574 | ||
575 | static void br_vlan_disable_default_pvid(struct net_bridge *br) | |
576 | { | |
577 | struct net_bridge_port *p; | |
578 | u16 pvid = br->default_pvid; | |
579 | ||
580 | /* Disable default_pvid on all ports where it is still | |
581 | * configured. | |
582 | */ | |
583 | if (vlan_default_pvid(br_get_vlan_info(br), pvid)) | |
584 | br_vlan_delete(br, pvid); | |
585 | ||
586 | list_for_each_entry(p, &br->port_list, list) { | |
587 | if (vlan_default_pvid(nbp_get_vlan_info(p), pvid)) | |
588 | nbp_vlan_delete(p, pvid); | |
589 | } | |
590 | ||
591 | br->default_pvid = 0; | |
592 | } | |
593 | ||
594 | static int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid) | |
595 | { | |
596 | struct net_bridge_port *p; | |
597 | u16 old_pvid; | |
598 | int err = 0; | |
599 | unsigned long *changed; | |
600 | ||
601 | changed = kcalloc(BITS_TO_LONGS(BR_MAX_PORTS), sizeof(unsigned long), | |
602 | GFP_KERNEL); | |
603 | if (!changed) | |
604 | return -ENOMEM; | |
605 | ||
606 | old_pvid = br->default_pvid; | |
607 | ||
608 | /* Update default_pvid config only if we do not conflict with | |
609 | * user configuration. | |
610 | */ | |
611 | if ((!old_pvid || vlan_default_pvid(br_get_vlan_info(br), old_pvid)) && | |
612 | !br_vlan_find(br, pvid)) { | |
613 | err = br_vlan_add(br, pvid, | |
614 | BRIDGE_VLAN_INFO_PVID | | |
615 | BRIDGE_VLAN_INFO_UNTAGGED); | |
616 | if (err) | |
617 | goto out; | |
618 | br_vlan_delete(br, old_pvid); | |
619 | set_bit(0, changed); | |
620 | } | |
621 | ||
622 | list_for_each_entry(p, &br->port_list, list) { | |
623 | /* Update default_pvid config only if we do not conflict with | |
624 | * user configuration. | |
625 | */ | |
626 | if ((old_pvid && | |
627 | !vlan_default_pvid(nbp_get_vlan_info(p), old_pvid)) || | |
628 | nbp_vlan_find(p, pvid)) | |
629 | continue; | |
630 | ||
631 | err = nbp_vlan_add(p, pvid, | |
632 | BRIDGE_VLAN_INFO_PVID | | |
633 | BRIDGE_VLAN_INFO_UNTAGGED); | |
634 | if (err) | |
635 | goto err_port; | |
636 | nbp_vlan_delete(p, old_pvid); | |
637 | set_bit(p->port_no, changed); | |
638 | } | |
639 | ||
640 | br->default_pvid = pvid; | |
641 | ||
642 | out: | |
643 | kfree(changed); | |
644 | return err; | |
645 | ||
646 | err_port: | |
647 | list_for_each_entry_continue_reverse(p, &br->port_list, list) { | |
648 | if (!test_bit(p->port_no, changed)) | |
649 | continue; | |
650 | ||
651 | if (old_pvid) | |
652 | nbp_vlan_add(p, old_pvid, | |
653 | BRIDGE_VLAN_INFO_PVID | | |
654 | BRIDGE_VLAN_INFO_UNTAGGED); | |
655 | nbp_vlan_delete(p, pvid); | |
656 | } | |
657 | ||
658 | if (test_bit(0, changed)) { | |
659 | if (old_pvid) | |
660 | br_vlan_add(br, old_pvid, | |
661 | BRIDGE_VLAN_INFO_PVID | | |
662 | BRIDGE_VLAN_INFO_UNTAGGED); | |
663 | br_vlan_delete(br, pvid); | |
664 | } | |
665 | goto out; | |
666 | } | |
667 | ||
96a20d9d VY |
668 | int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val) |
669 | { | |
670 | u16 pvid = val; | |
671 | int err = 0; | |
672 | ||
5be5a2df | 673 | if (val >= VLAN_VID_MASK) |
96a20d9d VY |
674 | return -EINVAL; |
675 | ||
676 | if (!rtnl_trylock()) | |
677 | return restart_syscall(); | |
678 | ||
679 | if (pvid == br->default_pvid) | |
680 | goto unlock; | |
681 | ||
682 | /* Only allow default pvid change when filtering is disabled */ | |
683 | if (br->vlan_enabled) { | |
684 | pr_info_once("Please disable vlan filtering to change default_pvid\n"); | |
685 | err = -EPERM; | |
686 | goto unlock; | |
687 | } | |
688 | ||
5be5a2df VY |
689 | if (!pvid) |
690 | br_vlan_disable_default_pvid(br); | |
691 | else | |
692 | err = __br_vlan_set_default_pvid(br, pvid); | |
96a20d9d VY |
693 | |
694 | unlock: | |
695 | rtnl_unlock(); | |
696 | return err; | |
697 | } | |
698 | ||
5be5a2df | 699 | int br_vlan_init(struct net_bridge *br) |
8580e211 TM |
700 | { |
701 | br->vlan_proto = htons(ETH_P_8021Q); | |
96a20d9d | 702 | br->default_pvid = 1; |
5be5a2df VY |
703 | return br_vlan_add(br, 1, |
704 | BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED); | |
8580e211 TM |
705 | } |
706 | ||
8adff41c TM |
707 | /* Must be protected by RTNL. |
708 | * Must be called with vid in range from 1 to 4094 inclusive. | |
709 | */ | |
552406c4 | 710 | int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags) |
243a2e63 VY |
711 | { |
712 | struct net_port_vlans *pv = NULL; | |
713 | int err; | |
714 | ||
715 | ASSERT_RTNL(); | |
716 | ||
717 | pv = rtnl_dereference(port->vlan_info); | |
718 | if (pv) | |
552406c4 | 719 | return __vlan_add(pv, vid, flags); |
243a2e63 VY |
720 | |
721 | /* Create port vlan infomration | |
722 | */ | |
723 | pv = kzalloc(sizeof(*pv), GFP_KERNEL); | |
724 | if (!pv) { | |
725 | err = -ENOMEM; | |
726 | goto clean_up; | |
727 | } | |
728 | ||
729 | pv->port_idx = port->port_no; | |
730 | pv->parent.port = port; | |
552406c4 | 731 | err = __vlan_add(pv, vid, flags); |
243a2e63 VY |
732 | if (err) |
733 | goto clean_up; | |
734 | ||
735 | rcu_assign_pointer(port->vlan_info, pv); | |
736 | return 0; | |
737 | ||
738 | clean_up: | |
739 | kfree(pv); | |
740 | return err; | |
741 | } | |
742 | ||
8adff41c TM |
743 | /* Must be protected by RTNL. |
744 | * Must be called with vid in range from 1 to 4094 inclusive. | |
745 | */ | |
243a2e63 VY |
746 | int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) |
747 | { | |
748 | struct net_port_vlans *pv; | |
749 | ||
750 | ASSERT_RTNL(); | |
751 | ||
752 | pv = rtnl_dereference(port->vlan_info); | |
753 | if (!pv) | |
754 | return -EINVAL; | |
755 | ||
424bb9c9 | 756 | br_fdb_find_delete_local(port->br, port, port->dev->dev_addr, vid); |
1ea2d020 | 757 | br_fdb_delete_by_port(port->br, port, vid, 0); |
bc9a25d2 | 758 | |
243a2e63 VY |
759 | return __vlan_del(pv, vid); |
760 | } | |
761 | ||
762 | void nbp_vlan_flush(struct net_bridge_port *port) | |
763 | { | |
764 | struct net_port_vlans *pv; | |
dbbaf949 | 765 | u16 vid; |
243a2e63 VY |
766 | |
767 | ASSERT_RTNL(); | |
768 | ||
769 | pv = rtnl_dereference(port->vlan_info); | |
770 | if (!pv) | |
771 | return; | |
772 | ||
dbbaf949 | 773 | for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) |
8580e211 | 774 | vlan_vid_del(port->dev, port->br->vlan_proto, vid); |
dbbaf949 | 775 | |
243a2e63 VY |
776 | __vlan_flush(pv); |
777 | } | |
bc9a25d2 VY |
778 | |
779 | bool nbp_vlan_find(struct net_bridge_port *port, u16 vid) | |
780 | { | |
781 | struct net_port_vlans *pv; | |
782 | bool found = false; | |
783 | ||
784 | rcu_read_lock(); | |
785 | pv = rcu_dereference(port->vlan_info); | |
786 | ||
787 | if (!pv) | |
788 | goto out; | |
789 | ||
790 | if (test_bit(vid, pv->vlan_bitmap)) | |
791 | found = true; | |
792 | ||
793 | out: | |
794 | rcu_read_unlock(); | |
795 | return found; | |
796 | } | |
5be5a2df VY |
797 | |
798 | int nbp_vlan_init(struct net_bridge_port *p) | |
799 | { | |
800 | return p->br->default_pvid ? | |
801 | nbp_vlan_add(p, p->br->default_pvid, | |
802 | BRIDGE_VLAN_INFO_PVID | | |
803 | BRIDGE_VLAN_INFO_UNTAGGED) : | |
804 | 0; | |
805 | } |