1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | #include <linux/kernel.h> |
3 | #include <linux/netdevice.h> |
4 | #include <linux/rtnetlink.h> |
5 | #include <linux/slab.h> |
6 | #include <net/switchdev.h> |
7 | |
8 | #include "br_private.h" |
9 | #include "br_private_tunnel.h" |
10 | |
11 | static void nbp_vlan_set_vlan_dev_state(struct net_bridge_port *p, u16 vid); |
12 | |
13 | static inline int br_vlan_cmp(struct rhashtable_compare_arg *arg, |
14 | const void *ptr) |
15 | { |
16 | const struct net_bridge_vlan *vle = ptr; |
17 | u16 vid = *(u16 *)arg->key; |
18 | |
19 | return vle->vid != vid; |
20 | } |
21 | |
22 | static const struct rhashtable_params br_vlan_rht_params = { |
23 | .head_offset = offsetof(struct net_bridge_vlan, vnode), |
24 | .key_offset = offsetof(struct net_bridge_vlan, vid), |
25 | .key_len = sizeof(u16), |
26 | .nelem_hint = 3, |
27 | .max_size = VLAN_N_VID, |
28 | .obj_cmpfn = br_vlan_cmp, |
29 | .automatic_shrinking = true, |
30 | }; |
31 | |
32 | static struct net_bridge_vlan *br_vlan_lookup(struct rhashtable *tbl, u16 vid) |
33 | { |
34 | return rhashtable_lookup_fast(ht: tbl, key: &vid, params: br_vlan_rht_params); |
35 | } |
36 | |
37 | static void __vlan_add_pvid(struct net_bridge_vlan_group *vg, |
38 | const struct net_bridge_vlan *v) |
39 | { |
40 | if (vg->pvid == v->vid) |
41 | return; |
42 | |
43 | smp_wmb(); |
44 | br_vlan_set_pvid_state(vg, state: v->state); |
45 | vg->pvid = v->vid; |
46 | } |
47 | |
48 | static void __vlan_delete_pvid(struct net_bridge_vlan_group *vg, u16 vid) |
49 | { |
50 | if (vg->pvid != vid) |
51 | return; |
52 | |
53 | smp_wmb(); |
54 | vg->pvid = 0; |
55 | } |
56 | |
57 | /* Update the BRIDGE_VLAN_INFO_PVID and BRIDGE_VLAN_INFO_UNTAGGED flags of @v. |
58 | * If @commit is false, return just whether the BRIDGE_VLAN_INFO_PVID and |
59 | * BRIDGE_VLAN_INFO_UNTAGGED bits of @flags would produce any change onto @v. |
60 | */ |
61 | static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags, |
62 | bool commit) |
63 | { |
64 | struct net_bridge_vlan_group *vg; |
65 | bool change; |
66 | |
67 | if (br_vlan_is_master(v)) |
68 | vg = br_vlan_group(br: v->br); |
69 | else |
70 | vg = nbp_vlan_group(p: v->port); |
71 | |
72 | /* check if anything would be changed on commit */ |
73 | change = !!(flags & BRIDGE_VLAN_INFO_PVID) == !!(vg->pvid != v->vid) || |
74 | ((flags ^ v->flags) & BRIDGE_VLAN_INFO_UNTAGGED); |
75 | |
76 | if (!commit) |
77 | goto out; |
78 | |
79 | if (flags & BRIDGE_VLAN_INFO_PVID) |
80 | __vlan_add_pvid(vg, v); |
81 | else |
82 | __vlan_delete_pvid(vg, vid: v->vid); |
83 | |
84 | if (flags & BRIDGE_VLAN_INFO_UNTAGGED) |
85 | v->flags |= BRIDGE_VLAN_INFO_UNTAGGED; |
86 | else |
87 | v->flags &= ~BRIDGE_VLAN_INFO_UNTAGGED; |
88 | |
89 | out: |
90 | return change; |
91 | } |
92 | |
93 | static bool __vlan_flags_would_change(struct net_bridge_vlan *v, u16 flags) |
94 | { |
95 | return __vlan_flags_update(v, flags, commit: false); |
96 | } |
97 | |
98 | static void __vlan_flags_commit(struct net_bridge_vlan *v, u16 flags) |
99 | { |
100 | __vlan_flags_update(v, flags, commit: true); |
101 | } |
102 | |
103 | static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br, |
104 | struct net_bridge_vlan *v, u16 flags, |
105 | struct netlink_ext_ack *extack) |
106 | { |
107 | int err; |
108 | |
109 | /* Try switchdev op first. In case it is not supported, fallback to |
110 | * 8021q add. |
111 | */ |
112 | err = br_switchdev_port_vlan_add(dev, vid: v->vid, flags, changed: false, extack); |
113 | if (err == -EOPNOTSUPP) |
114 | return vlan_vid_add(dev, proto: br->vlan_proto, vid: v->vid); |
115 | v->priv_flags |= BR_VLFLAG_ADDED_BY_SWITCHDEV; |
116 | return err; |
117 | } |
118 | |
119 | static void __vlan_add_list(struct net_bridge_vlan *v) |
120 | { |
121 | struct net_bridge_vlan_group *vg; |
122 | struct list_head *headp, *hpos; |
123 | struct net_bridge_vlan *vent; |
124 | |
125 | if (br_vlan_is_master(v)) |
126 | vg = br_vlan_group(br: v->br); |
127 | else |
128 | vg = nbp_vlan_group(p: v->port); |
129 | |
130 | headp = &vg->vlan_list; |
131 | list_for_each_prev(hpos, headp) { |
132 | vent = list_entry(hpos, struct net_bridge_vlan, vlist); |
133 | if (v->vid >= vent->vid) |
134 | break; |
135 | } |
136 | list_add_rcu(new: &v->vlist, head: hpos); |
137 | } |
138 | |
139 | static void __vlan_del_list(struct net_bridge_vlan *v) |
140 | { |
141 | list_del_rcu(entry: &v->vlist); |
142 | } |
143 | |
144 | static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br, |
145 | const struct net_bridge_vlan *v) |
146 | { |
147 | int err; |
148 | |
149 | /* Try switchdev op first. In case it is not supported, fallback to |
150 | * 8021q del. |
151 | */ |
152 | err = br_switchdev_port_vlan_del(dev, vid: v->vid); |
153 | if (!(v->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)) |
154 | vlan_vid_del(dev, proto: br->vlan_proto, vid: v->vid); |
155 | return err == -EOPNOTSUPP ? 0 : err; |
156 | } |
157 | |
158 | /* Returns a master vlan, if it didn't exist it gets created. In all cases |
159 | * a reference is taken to the master vlan before returning. |
160 | */ |
161 | static struct net_bridge_vlan * |
162 | br_vlan_get_master(struct net_bridge *br, u16 vid, |
163 | struct netlink_ext_ack *extack) |
164 | { |
165 | struct net_bridge_vlan_group *vg; |
166 | struct net_bridge_vlan *masterv; |
167 | |
168 | vg = br_vlan_group(br); |
169 | masterv = br_vlan_find(vg, vid); |
170 | if (!masterv) { |
171 | bool changed; |
172 | |
173 | /* missing global ctx, create it now */ |
174 | if (br_vlan_add(br, vid, flags: 0, changed: &changed, extack)) |
175 | return NULL; |
176 | masterv = br_vlan_find(vg, vid); |
177 | if (WARN_ON(!masterv)) |
178 | return NULL; |
179 | refcount_set(r: &masterv->refcnt, n: 1); |
180 | return masterv; |
181 | } |
182 | refcount_inc(r: &masterv->refcnt); |
183 | |
184 | return masterv; |
185 | } |
186 | |
187 | static void br_master_vlan_rcu_free(struct rcu_head *rcu) |
188 | { |
189 | struct net_bridge_vlan *v; |
190 | |
191 | v = container_of(rcu, struct net_bridge_vlan, rcu); |
192 | WARN_ON(!br_vlan_is_master(v)); |
193 | free_percpu(pdata: v->stats); |
194 | v->stats = NULL; |
195 | kfree(objp: v); |
196 | } |
197 | |
198 | static void br_vlan_put_master(struct net_bridge_vlan *masterv) |
199 | { |
200 | struct net_bridge_vlan_group *vg; |
201 | |
202 | if (!br_vlan_is_master(v: masterv)) |
203 | return; |
204 | |
205 | vg = br_vlan_group(br: masterv->br); |
206 | if (refcount_dec_and_test(r: &masterv->refcnt)) { |
207 | rhashtable_remove_fast(ht: &vg->vlan_hash, |
208 | obj: &masterv->vnode, params: br_vlan_rht_params); |
209 | __vlan_del_list(v: masterv); |
210 | br_multicast_toggle_one_vlan(vlan: masterv, on: false); |
211 | br_multicast_ctx_deinit(brmctx: &masterv->br_mcast_ctx); |
212 | call_rcu(head: &masterv->rcu, func: br_master_vlan_rcu_free); |
213 | } |
214 | } |
215 | |
216 | static void nbp_vlan_rcu_free(struct rcu_head *rcu) |
217 | { |
218 | struct net_bridge_vlan *v; |
219 | |
220 | v = container_of(rcu, struct net_bridge_vlan, rcu); |
221 | WARN_ON(br_vlan_is_master(v)); |
222 | /* if we had per-port stats configured then free them here */ |
223 | if (v->priv_flags & BR_VLFLAG_PER_PORT_STATS) |
224 | free_percpu(pdata: v->stats); |
225 | v->stats = NULL; |
226 | kfree(objp: v); |
227 | } |
228 | |
229 | static void br_vlan_init_state(struct net_bridge_vlan *v) |
230 | { |
231 | struct net_bridge *br; |
232 | |
233 | if (br_vlan_is_master(v)) |
234 | br = v->br; |
235 | else |
236 | br = v->port->br; |
237 | |
238 | if (br_opt_get(br, opt: BROPT_MST_ENABLED)) { |
239 | br_mst_vlan_init_state(v); |
240 | return; |
241 | } |
242 | |
243 | v->state = BR_STATE_FORWARDING; |
244 | v->msti = 0; |
245 | } |
246 | |
247 | /* This is the shared VLAN add function which works for both ports and bridge |
248 | * devices. There are four possible calls to this function in terms of the |
249 | * vlan entry type: |
250 | * 1. vlan is being added on a port (no master flags, global entry exists) |
251 | * 2. vlan is being added on a bridge (both master and brentry flags) |
252 | * 3. vlan is being added on a port, but a global entry didn't exist which |
253 | * is being created right now (master flag set, brentry flag unset), the |
254 | * global entry is used for global per-vlan features, but not for filtering |
255 | * 4. same as 3 but with both master and brentry flags set so the entry |
256 | * will be used for filtering in both the port and the bridge |
257 | */ |
258 | static int __vlan_add(struct net_bridge_vlan *v, u16 flags, |
259 | struct netlink_ext_ack *extack) |
260 | { |
261 | struct net_bridge_vlan *masterv = NULL; |
262 | struct net_bridge_port *p = NULL; |
263 | struct net_bridge_vlan_group *vg; |
264 | struct net_device *dev; |
265 | struct net_bridge *br; |
266 | int err; |
267 | |
268 | if (br_vlan_is_master(v)) { |
269 | br = v->br; |
270 | dev = br->dev; |
271 | vg = br_vlan_group(br); |
272 | } else { |
273 | p = v->port; |
274 | br = p->br; |
275 | dev = p->dev; |
276 | vg = nbp_vlan_group(p); |
277 | } |
278 | |
279 | if (p) { |
280 | /* Add VLAN to the device filter if it is supported. |
281 | * This ensures tagged traffic enters the bridge when |
282 | * promiscuous mode is disabled by br_manage_promisc(). |
283 | */ |
284 | err = __vlan_vid_add(dev, br, v, flags, extack); |
285 | if (err) |
286 | goto out; |
287 | |
288 | /* need to work on the master vlan too */ |
289 | if (flags & BRIDGE_VLAN_INFO_MASTER) { |
290 | bool changed; |
291 | |
292 | err = br_vlan_add(br, vid: v->vid, |
293 | flags: flags | BRIDGE_VLAN_INFO_BRENTRY, |
294 | changed: &changed, extack); |
295 | if (err) |
296 | goto out_filt; |
297 | |
298 | if (changed) |
299 | br_vlan_notify(br, NULL, vid: v->vid, vid_range: 0, |
300 | cmd: RTM_NEWVLAN); |
301 | } |
302 | |
303 | masterv = br_vlan_get_master(br, vid: v->vid, extack); |
304 | if (!masterv) { |
305 | err = -ENOMEM; |
306 | goto out_filt; |
307 | } |
308 | v->brvlan = masterv; |
309 | if (br_opt_get(br, opt: BROPT_VLAN_STATS_PER_PORT)) { |
310 | v->stats = |
311 | netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); |
312 | if (!v->stats) { |
313 | err = -ENOMEM; |
314 | goto out_filt; |
315 | } |
316 | v->priv_flags |= BR_VLFLAG_PER_PORT_STATS; |
317 | } else { |
318 | v->stats = masterv->stats; |
319 | } |
320 | br_multicast_port_ctx_init(port: p, vlan: v, pmctx: &v->port_mcast_ctx); |
321 | } else { |
322 | if (br_vlan_should_use(v)) { |
323 | err = br_switchdev_port_vlan_add(dev, vid: v->vid, flags, |
324 | changed: false, extack); |
325 | if (err && err != -EOPNOTSUPP) |
326 | goto out; |
327 | } |
328 | br_multicast_ctx_init(br, vlan: v, brmctx: &v->br_mcast_ctx); |
329 | v->priv_flags |= BR_VLFLAG_GLOBAL_MCAST_ENABLED; |
330 | } |
331 | |
332 | /* Add the dev mac and count the vlan only if it's usable */ |
333 | if (br_vlan_should_use(v)) { |
334 | err = br_fdb_add_local(br, source: p, addr: dev->dev_addr, vid: v->vid); |
335 | if (err) { |
336 | br_err(br, "failed insert local address into bridge forwarding table\n" ); |
337 | goto out_filt; |
338 | } |
339 | vg->num_vlans++; |
340 | } |
341 | |
342 | /* set the state before publishing */ |
343 | br_vlan_init_state(v); |
344 | |
345 | err = rhashtable_lookup_insert_fast(ht: &vg->vlan_hash, obj: &v->vnode, |
346 | params: br_vlan_rht_params); |
347 | if (err) |
348 | goto out_fdb_insert; |
349 | |
350 | __vlan_add_list(v); |
351 | __vlan_flags_commit(v, flags); |
352 | br_multicast_toggle_one_vlan(vlan: v, on: true); |
353 | |
354 | if (p) |
355 | nbp_vlan_set_vlan_dev_state(p, vid: v->vid); |
356 | out: |
357 | return err; |
358 | |
359 | out_fdb_insert: |
360 | if (br_vlan_should_use(v)) { |
361 | br_fdb_find_delete_local(br, p, addr: dev->dev_addr, vid: v->vid); |
362 | vg->num_vlans--; |
363 | } |
364 | |
365 | out_filt: |
366 | if (p) { |
367 | __vlan_vid_del(dev, br, v); |
368 | if (masterv) { |
369 | if (v->stats && masterv->stats != v->stats) |
370 | free_percpu(pdata: v->stats); |
371 | v->stats = NULL; |
372 | |
373 | br_vlan_put_master(masterv); |
374 | v->brvlan = NULL; |
375 | } |
376 | } else { |
377 | br_switchdev_port_vlan_del(dev, vid: v->vid); |
378 | } |
379 | |
380 | goto out; |
381 | } |
382 | |
383 | static int __vlan_del(struct net_bridge_vlan *v) |
384 | { |
385 | struct net_bridge_vlan *masterv = v; |
386 | struct net_bridge_vlan_group *vg; |
387 | struct net_bridge_port *p = NULL; |
388 | int err = 0; |
389 | |
390 | if (br_vlan_is_master(v)) { |
391 | vg = br_vlan_group(br: v->br); |
392 | } else { |
393 | p = v->port; |
394 | vg = nbp_vlan_group(p: v->port); |
395 | masterv = v->brvlan; |
396 | } |
397 | |
398 | __vlan_delete_pvid(vg, vid: v->vid); |
399 | if (p) { |
400 | err = __vlan_vid_del(dev: p->dev, br: p->br, v); |
401 | if (err) |
402 | goto out; |
403 | } else { |
404 | err = br_switchdev_port_vlan_del(dev: v->br->dev, vid: v->vid); |
405 | if (err && err != -EOPNOTSUPP) |
406 | goto out; |
407 | err = 0; |
408 | } |
409 | |
410 | if (br_vlan_should_use(v)) { |
411 | v->flags &= ~BRIDGE_VLAN_INFO_BRENTRY; |
412 | vg->num_vlans--; |
413 | } |
414 | |
415 | if (masterv != v) { |
416 | vlan_tunnel_info_del(vg, vlan: v); |
417 | rhashtable_remove_fast(ht: &vg->vlan_hash, obj: &v->vnode, |
418 | params: br_vlan_rht_params); |
419 | __vlan_del_list(v); |
420 | nbp_vlan_set_vlan_dev_state(p, vid: v->vid); |
421 | br_multicast_toggle_one_vlan(vlan: v, on: false); |
422 | br_multicast_port_ctx_deinit(pmctx: &v->port_mcast_ctx); |
423 | call_rcu(head: &v->rcu, func: nbp_vlan_rcu_free); |
424 | } |
425 | |
426 | br_vlan_put_master(masterv); |
427 | out: |
428 | return err; |
429 | } |
430 | |
431 | static void __vlan_group_free(struct net_bridge_vlan_group *vg) |
432 | { |
433 | WARN_ON(!list_empty(&vg->vlan_list)); |
434 | rhashtable_destroy(ht: &vg->vlan_hash); |
435 | vlan_tunnel_deinit(vg); |
436 | kfree(objp: vg); |
437 | } |
438 | |
439 | static void __vlan_flush(const struct net_bridge *br, |
440 | const struct net_bridge_port *p, |
441 | struct net_bridge_vlan_group *vg) |
442 | { |
443 | struct net_bridge_vlan *vlan, *tmp; |
444 | u16 v_start = 0, v_end = 0; |
445 | int err; |
446 | |
447 | __vlan_delete_pvid(vg, vid: vg->pvid); |
448 | list_for_each_entry_safe(vlan, tmp, &vg->vlan_list, vlist) { |
449 | /* take care of disjoint ranges */ |
450 | if (!v_start) { |
451 | v_start = vlan->vid; |
452 | } else if (vlan->vid - v_end != 1) { |
453 | /* found range end, notify and start next one */ |
454 | br_vlan_notify(br, p, vid: v_start, vid_range: v_end, RTM_DELVLAN); |
455 | v_start = vlan->vid; |
456 | } |
457 | v_end = vlan->vid; |
458 | |
459 | err = __vlan_del(v: vlan); |
460 | if (err) { |
461 | br_err(br, |
462 | "port %u(%s) failed to delete vlan %d: %pe\n" , |
463 | (unsigned int) p->port_no, p->dev->name, |
464 | vlan->vid, ERR_PTR(err)); |
465 | } |
466 | } |
467 | |
468 | /* notify about the last/whole vlan range */ |
469 | if (v_start) |
470 | br_vlan_notify(br, p, vid: v_start, vid_range: v_end, RTM_DELVLAN); |
471 | } |
472 | |
473 | struct sk_buff *br_handle_vlan(struct net_bridge *br, |
474 | const struct net_bridge_port *p, |
475 | struct net_bridge_vlan_group *vg, |
476 | struct sk_buff *skb) |
477 | { |
478 | struct pcpu_sw_netstats *stats; |
479 | struct net_bridge_vlan *v; |
480 | u16 vid; |
481 | |
482 | /* If this packet was not filtered at input, let it pass */ |
483 | if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) |
484 | goto out; |
485 | |
486 | /* At this point, we know that the frame was filtered and contains |
487 | * a valid vlan id. If the vlan id has untagged flag set, |
488 | * send untagged; otherwise, send tagged. |
489 | */ |
490 | br_vlan_get_tag(skb, vid: &vid); |
491 | v = br_vlan_find(vg, vid); |
492 | /* Vlan entry must be configured at this point. The |
493 | * only exception is the bridge is set in promisc mode and the |
494 | * packet is destined for the bridge device. In this case |
495 | * pass the packet as is. |
496 | */ |
497 | if (!v || !br_vlan_should_use(v)) { |
498 | if ((br->dev->flags & IFF_PROMISC) && skb->dev == br->dev) { |
499 | goto out; |
500 | } else { |
501 | kfree_skb(skb); |
502 | return NULL; |
503 | } |
504 | } |
505 | if (br_opt_get(br, opt: BROPT_VLAN_STATS_ENABLED)) { |
506 | stats = this_cpu_ptr(v->stats); |
507 | u64_stats_update_begin(syncp: &stats->syncp); |
508 | u64_stats_add(p: &stats->tx_bytes, val: skb->len); |
509 | u64_stats_inc(p: &stats->tx_packets); |
510 | u64_stats_update_end(syncp: &stats->syncp); |
511 | } |
512 | |
513 | /* If the skb will be sent using forwarding offload, the assumption is |
514 | * that the switchdev will inject the packet into hardware together |
515 | * with the bridge VLAN, so that it can be forwarded according to that |
516 | * VLAN. The switchdev should deal with popping the VLAN header in |
517 | * hardware on each egress port as appropriate. So only strip the VLAN |
518 | * header if forwarding offload is not being used. |
519 | */ |
520 | if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED && |
521 | !br_switchdev_frame_uses_tx_fwd_offload(skb)) |
522 | __vlan_hwaccel_clear_tag(skb); |
523 | |
524 | if (p && (p->flags & BR_VLAN_TUNNEL) && |
525 | br_handle_egress_vlan_tunnel(skb, vlan: v)) { |
526 | kfree_skb(skb); |
527 | return NULL; |
528 | } |
529 | out: |
530 | return skb; |
531 | } |
532 | |
533 | /* Called under RCU */ |
534 | static bool __allowed_ingress(const struct net_bridge *br, |
535 | struct net_bridge_vlan_group *vg, |
536 | struct sk_buff *skb, u16 *vid, |
537 | u8 *state, |
538 | struct net_bridge_vlan **vlan) |
539 | { |
540 | struct pcpu_sw_netstats *stats; |
541 | struct net_bridge_vlan *v; |
542 | bool tagged; |
543 | |
544 | BR_INPUT_SKB_CB(skb)->vlan_filtered = true; |
545 | /* If vlan tx offload is disabled on bridge device and frame was |
546 | * sent from vlan device on the bridge device, it does not have |
547 | * HW accelerated vlan tag. |
548 | */ |
549 | if (unlikely(!skb_vlan_tag_present(skb) && |
550 | skb->protocol == br->vlan_proto)) { |
551 | skb = skb_vlan_untag(skb); |
552 | if (unlikely(!skb)) |
553 | return false; |
554 | } |
555 | |
556 | if (!br_vlan_get_tag(skb, vid)) { |
557 | /* Tagged frame */ |
558 | if (skb->vlan_proto != br->vlan_proto) { |
559 | /* Protocol-mismatch, empty out vlan_tci for new tag */ |
560 | skb_push(skb, ETH_HLEN); |
561 | skb = vlan_insert_tag_set_proto(skb, vlan_proto: skb->vlan_proto, |
562 | skb_vlan_tag_get(skb)); |
563 | if (unlikely(!skb)) |
564 | return false; |
565 | |
566 | skb_pull(skb, ETH_HLEN); |
567 | skb_reset_mac_len(skb); |
568 | *vid = 0; |
569 | tagged = false; |
570 | } else { |
571 | tagged = true; |
572 | } |
573 | } else { |
574 | /* Untagged frame */ |
575 | tagged = false; |
576 | } |
577 | |
578 | if (!*vid) { |
579 | u16 pvid = br_get_pvid(vg); |
580 | |
581 | /* Frame had a tag with VID 0 or did not have a tag. |
582 | * See if pvid is set on this port. That tells us which |
583 | * vlan untagged or priority-tagged traffic belongs to. |
584 | */ |
585 | if (!pvid) |
586 | goto drop; |
587 | |
588 | /* PVID is set on this port. Any untagged or priority-tagged |
589 | * ingress frame is considered to belong to this vlan. |
590 | */ |
591 | *vid = pvid; |
592 | if (likely(!tagged)) |
593 | /* Untagged Frame. */ |
594 | __vlan_hwaccel_put_tag(skb, vlan_proto: br->vlan_proto, vlan_tci: pvid); |
595 | else |
596 | /* Priority-tagged Frame. |
597 | * At this point, we know that skb->vlan_tci VID |
598 | * field was 0. |
599 | * We update only VID field and preserve PCP field. |
600 | */ |
601 | skb->vlan_tci |= pvid; |
602 | |
603 | /* if snooping and stats are disabled we can avoid the lookup */ |
604 | if (!br_opt_get(br, opt: BROPT_MCAST_VLAN_SNOOPING_ENABLED) && |
605 | !br_opt_get(br, opt: BROPT_VLAN_STATS_ENABLED)) { |
606 | if (*state == BR_STATE_FORWARDING) { |
607 | *state = br_vlan_get_pvid_state(vg); |
608 | if (!br_vlan_state_allowed(state: *state, learn_allow: true)) |
609 | goto drop; |
610 | } |
611 | return true; |
612 | } |
613 | } |
614 | v = br_vlan_find(vg, vid: *vid); |
615 | if (!v || !br_vlan_should_use(v)) |
616 | goto drop; |
617 | |
618 | if (*state == BR_STATE_FORWARDING) { |
619 | *state = br_vlan_get_state(v); |
620 | if (!br_vlan_state_allowed(state: *state, learn_allow: true)) |
621 | goto drop; |
622 | } |
623 | |
624 | if (br_opt_get(br, opt: BROPT_VLAN_STATS_ENABLED)) { |
625 | stats = this_cpu_ptr(v->stats); |
626 | u64_stats_update_begin(syncp: &stats->syncp); |
627 | u64_stats_add(p: &stats->rx_bytes, val: skb->len); |
628 | u64_stats_inc(p: &stats->rx_packets); |
629 | u64_stats_update_end(syncp: &stats->syncp); |
630 | } |
631 | |
632 | *vlan = v; |
633 | |
634 | return true; |
635 | |
636 | drop: |
637 | kfree_skb(skb); |
638 | return false; |
639 | } |
640 | |
641 | bool br_allowed_ingress(const struct net_bridge *br, |
642 | struct net_bridge_vlan_group *vg, struct sk_buff *skb, |
643 | u16 *vid, u8 *state, |
644 | struct net_bridge_vlan **vlan) |
645 | { |
646 | /* If VLAN filtering is disabled on the bridge, all packets are |
647 | * permitted. |
648 | */ |
649 | *vlan = NULL; |
650 | if (!br_opt_get(br, opt: BROPT_VLAN_ENABLED)) { |
651 | BR_INPUT_SKB_CB(skb)->vlan_filtered = false; |
652 | return true; |
653 | } |
654 | |
655 | return __allowed_ingress(br, vg, skb, vid, state, vlan); |
656 | } |
657 | |
658 | /* Called under RCU. */ |
659 | bool br_allowed_egress(struct net_bridge_vlan_group *vg, |
660 | const struct sk_buff *skb) |
661 | { |
662 | const struct net_bridge_vlan *v; |
663 | u16 vid; |
664 | |
665 | /* If this packet was not filtered at input, let it pass */ |
666 | if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) |
667 | return true; |
668 | |
669 | br_vlan_get_tag(skb, vid: &vid); |
670 | v = br_vlan_find(vg, vid); |
671 | if (v && br_vlan_should_use(v) && |
672 | br_vlan_state_allowed(state: br_vlan_get_state(v), learn_allow: false)) |
673 | return true; |
674 | |
675 | return false; |
676 | } |
677 | |
678 | /* Called under RCU */ |
679 | bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) |
680 | { |
681 | struct net_bridge_vlan_group *vg; |
682 | struct net_bridge *br = p->br; |
683 | struct net_bridge_vlan *v; |
684 | |
685 | /* If filtering was disabled at input, let it pass. */ |
686 | if (!br_opt_get(br, opt: BROPT_VLAN_ENABLED)) |
687 | return true; |
688 | |
689 | vg = nbp_vlan_group_rcu(p); |
690 | if (!vg || !vg->num_vlans) |
691 | return false; |
692 | |
693 | if (!br_vlan_get_tag(skb, vid) && skb->vlan_proto != br->vlan_proto) |
694 | *vid = 0; |
695 | |
696 | if (!*vid) { |
697 | *vid = br_get_pvid(vg); |
698 | if (!*vid || |
699 | !br_vlan_state_allowed(state: br_vlan_get_pvid_state(vg), learn_allow: true)) |
700 | return false; |
701 | |
702 | return true; |
703 | } |
704 | |
705 | v = br_vlan_find(vg, vid: *vid); |
706 | if (v && br_vlan_state_allowed(state: br_vlan_get_state(v), learn_allow: true)) |
707 | return true; |
708 | |
709 | return false; |
710 | } |
711 | |
712 | static int br_vlan_add_existing(struct net_bridge *br, |
713 | struct net_bridge_vlan_group *vg, |
714 | struct net_bridge_vlan *vlan, |
715 | u16 flags, bool *changed, |
716 | struct netlink_ext_ack *extack) |
717 | { |
718 | bool would_change = __vlan_flags_would_change(v: vlan, flags); |
719 | bool becomes_brentry = false; |
720 | int err; |
721 | |
722 | if (!br_vlan_is_brentry(v: vlan)) { |
723 | /* Trying to change flags of non-existent bridge vlan */ |
724 | if (!(flags & BRIDGE_VLAN_INFO_BRENTRY)) |
725 | return -EINVAL; |
726 | |
727 | becomes_brentry = true; |
728 | } |
729 | |
730 | /* Master VLANs that aren't brentries weren't notified before, |
731 | * time to notify them now. |
732 | */ |
733 | if (becomes_brentry || would_change) { |
734 | err = br_switchdev_port_vlan_add(dev: br->dev, vid: vlan->vid, flags, |
735 | changed: would_change, extack); |
736 | if (err && err != -EOPNOTSUPP) |
737 | return err; |
738 | } |
739 | |
740 | if (becomes_brentry) { |
741 | /* It was only kept for port vlans, now make it real */ |
742 | err = br_fdb_add_local(br, NULL, addr: br->dev->dev_addr, vid: vlan->vid); |
743 | if (err) { |
744 | br_err(br, "failed to insert local address into bridge forwarding table\n" ); |
745 | goto err_fdb_insert; |
746 | } |
747 | |
748 | refcount_inc(r: &vlan->refcnt); |
749 | vlan->flags |= BRIDGE_VLAN_INFO_BRENTRY; |
750 | vg->num_vlans++; |
751 | *changed = true; |
752 | br_multicast_toggle_one_vlan(vlan, on: true); |
753 | } |
754 | |
755 | __vlan_flags_commit(v: vlan, flags); |
756 | if (would_change) |
757 | *changed = true; |
758 | |
759 | return 0; |
760 | |
761 | err_fdb_insert: |
762 | br_switchdev_port_vlan_del(dev: br->dev, vid: vlan->vid); |
763 | return err; |
764 | } |
765 | |
766 | /* Must be protected by RTNL. |
767 | * Must be called with vid in range from 1 to 4094 inclusive. |
768 | * changed must be true only if the vlan was created or updated |
769 | */ |
770 | int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed, |
771 | struct netlink_ext_ack *extack) |
772 | { |
773 | struct net_bridge_vlan_group *vg; |
774 | struct net_bridge_vlan *vlan; |
775 | int ret; |
776 | |
777 | ASSERT_RTNL(); |
778 | |
779 | *changed = false; |
780 | vg = br_vlan_group(br); |
781 | vlan = br_vlan_find(vg, vid); |
782 | if (vlan) |
783 | return br_vlan_add_existing(br, vg, vlan, flags, changed, |
784 | extack); |
785 | |
786 | vlan = kzalloc(size: sizeof(*vlan), GFP_KERNEL); |
787 | if (!vlan) |
788 | return -ENOMEM; |
789 | |
790 | vlan->stats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); |
791 | if (!vlan->stats) { |
792 | kfree(objp: vlan); |
793 | return -ENOMEM; |
794 | } |
795 | vlan->vid = vid; |
796 | vlan->flags = flags | BRIDGE_VLAN_INFO_MASTER; |
797 | vlan->flags &= ~BRIDGE_VLAN_INFO_PVID; |
798 | vlan->br = br; |
799 | if (flags & BRIDGE_VLAN_INFO_BRENTRY) |
800 | refcount_set(r: &vlan->refcnt, n: 1); |
801 | ret = __vlan_add(v: vlan, flags, extack); |
802 | if (ret) { |
803 | free_percpu(pdata: vlan->stats); |
804 | kfree(objp: vlan); |
805 | } else { |
806 | *changed = true; |
807 | } |
808 | |
809 | return ret; |
810 | } |
811 | |
812 | /* Must be protected by RTNL. |
813 | * Must be called with vid in range from 1 to 4094 inclusive. |
814 | */ |
815 | int br_vlan_delete(struct net_bridge *br, u16 vid) |
816 | { |
817 | struct net_bridge_vlan_group *vg; |
818 | struct net_bridge_vlan *v; |
819 | |
820 | ASSERT_RTNL(); |
821 | |
822 | vg = br_vlan_group(br); |
823 | v = br_vlan_find(vg, vid); |
824 | if (!v || !br_vlan_is_brentry(v)) |
825 | return -ENOENT; |
826 | |
827 | br_fdb_find_delete_local(br, NULL, addr: br->dev->dev_addr, vid); |
828 | br_fdb_delete_by_port(br, NULL, vid, do_all: 0); |
829 | |
830 | vlan_tunnel_info_del(vg, vlan: v); |
831 | |
832 | return __vlan_del(v); |
833 | } |
834 | |
835 | void br_vlan_flush(struct net_bridge *br) |
836 | { |
837 | struct net_bridge_vlan_group *vg; |
838 | |
839 | ASSERT_RTNL(); |
840 | |
841 | vg = br_vlan_group(br); |
842 | __vlan_flush(br, NULL, vg); |
843 | RCU_INIT_POINTER(br->vlgrp, NULL); |
844 | synchronize_net(); |
845 | __vlan_group_free(vg); |
846 | } |
847 | |
848 | struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid) |
849 | { |
850 | if (!vg) |
851 | return NULL; |
852 | |
853 | return br_vlan_lookup(tbl: &vg->vlan_hash, vid); |
854 | } |
855 | |
856 | /* Must be protected by RTNL. */ |
857 | static void recalculate_group_addr(struct net_bridge *br) |
858 | { |
859 | if (br_opt_get(br, opt: BROPT_GROUP_ADDR_SET)) |
860 | return; |
861 | |
862 | spin_lock_bh(lock: &br->lock); |
863 | if (!br_opt_get(br, opt: BROPT_VLAN_ENABLED) || |
864 | br->vlan_proto == htons(ETH_P_8021Q)) { |
865 | /* Bridge Group Address */ |
866 | br->group_addr[5] = 0x00; |
867 | } else { /* vlan_enabled && ETH_P_8021AD */ |
868 | /* Provider Bridge Group Address */ |
869 | br->group_addr[5] = 0x08; |
870 | } |
871 | spin_unlock_bh(lock: &br->lock); |
872 | } |
873 | |
874 | /* Must be protected by RTNL. */ |
875 | void br_recalculate_fwd_mask(struct net_bridge *br) |
876 | { |
877 | if (!br_opt_get(br, opt: BROPT_VLAN_ENABLED) || |
878 | br->vlan_proto == htons(ETH_P_8021Q)) |
879 | br->group_fwd_mask_required = BR_GROUPFWD_DEFAULT; |
880 | else /* vlan_enabled && ETH_P_8021AD */ |
881 | br->group_fwd_mask_required = BR_GROUPFWD_8021AD & |
882 | ~(1u << br->group_addr[5]); |
883 | } |
884 | |
885 | int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val, |
886 | struct netlink_ext_ack *extack) |
887 | { |
888 | struct switchdev_attr attr = { |
889 | .orig_dev = br->dev, |
890 | .id = SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING, |
891 | .flags = SWITCHDEV_F_SKIP_EOPNOTSUPP, |
892 | .u.vlan_filtering = val, |
893 | }; |
894 | int err; |
895 | |
896 | if (br_opt_get(br, opt: BROPT_VLAN_ENABLED) == !!val) |
897 | return 0; |
898 | |
899 | br_opt_toggle(br, opt: BROPT_VLAN_ENABLED, on: !!val); |
900 | |
901 | err = switchdev_port_attr_set(dev: br->dev, attr: &attr, extack); |
902 | if (err && err != -EOPNOTSUPP) { |
903 | br_opt_toggle(br, opt: BROPT_VLAN_ENABLED, on: !val); |
904 | return err; |
905 | } |
906 | |
907 | br_manage_promisc(br); |
908 | recalculate_group_addr(br); |
909 | br_recalculate_fwd_mask(br); |
910 | if (!val && br_opt_get(br, opt: BROPT_MCAST_VLAN_SNOOPING_ENABLED)) { |
911 | br_info(br, "vlan filtering disabled, automatically disabling multicast vlan snooping\n" ); |
912 | br_multicast_toggle_vlan_snooping(br, on: false, NULL); |
913 | } |
914 | |
915 | return 0; |
916 | } |
917 | |
918 | bool br_vlan_enabled(const struct net_device *dev) |
919 | { |
920 | struct net_bridge *br = netdev_priv(dev); |
921 | |
922 | return br_opt_get(br, opt: BROPT_VLAN_ENABLED); |
923 | } |
924 | EXPORT_SYMBOL_GPL(br_vlan_enabled); |
925 | |
926 | int br_vlan_get_proto(const struct net_device *dev, u16 *p_proto) |
927 | { |
928 | struct net_bridge *br = netdev_priv(dev); |
929 | |
930 | *p_proto = ntohs(br->vlan_proto); |
931 | |
932 | return 0; |
933 | } |
934 | EXPORT_SYMBOL_GPL(br_vlan_get_proto); |
935 | |
936 | int __br_vlan_set_proto(struct net_bridge *br, __be16 proto, |
937 | struct netlink_ext_ack *extack) |
938 | { |
939 | struct switchdev_attr attr = { |
940 | .orig_dev = br->dev, |
941 | .id = SWITCHDEV_ATTR_ID_BRIDGE_VLAN_PROTOCOL, |
942 | .flags = SWITCHDEV_F_SKIP_EOPNOTSUPP, |
943 | .u.vlan_protocol = ntohs(proto), |
944 | }; |
945 | int err = 0; |
946 | struct net_bridge_port *p; |
947 | struct net_bridge_vlan *vlan; |
948 | struct net_bridge_vlan_group *vg; |
949 | __be16 oldproto = br->vlan_proto; |
950 | |
951 | if (br->vlan_proto == proto) |
952 | return 0; |
953 | |
954 | err = switchdev_port_attr_set(dev: br->dev, attr: &attr, extack); |
955 | if (err && err != -EOPNOTSUPP) |
956 | return err; |
957 | |
958 | /* Add VLANs for the new proto to the device filter. */ |
959 | list_for_each_entry(p, &br->port_list, list) { |
960 | vg = nbp_vlan_group(p); |
961 | list_for_each_entry(vlan, &vg->vlan_list, vlist) { |
962 | if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV) |
963 | continue; |
964 | err = vlan_vid_add(dev: p->dev, proto, vid: vlan->vid); |
965 | if (err) |
966 | goto err_filt; |
967 | } |
968 | } |
969 | |
970 | br->vlan_proto = proto; |
971 | |
972 | recalculate_group_addr(br); |
973 | br_recalculate_fwd_mask(br); |
974 | |
975 | /* Delete VLANs for the old proto from the device filter. */ |
976 | list_for_each_entry(p, &br->port_list, list) { |
977 | vg = nbp_vlan_group(p); |
978 | list_for_each_entry(vlan, &vg->vlan_list, vlist) { |
979 | if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV) |
980 | continue; |
981 | vlan_vid_del(dev: p->dev, proto: oldproto, vid: vlan->vid); |
982 | } |
983 | } |
984 | |
985 | return 0; |
986 | |
987 | err_filt: |
988 | attr.u.vlan_protocol = ntohs(oldproto); |
989 | switchdev_port_attr_set(dev: br->dev, attr: &attr, NULL); |
990 | |
991 | list_for_each_entry_continue_reverse(vlan, &vg->vlan_list, vlist) { |
992 | if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV) |
993 | continue; |
994 | vlan_vid_del(dev: p->dev, proto, vid: vlan->vid); |
995 | } |
996 | |
997 | list_for_each_entry_continue_reverse(p, &br->port_list, list) { |
998 | vg = nbp_vlan_group(p); |
999 | list_for_each_entry(vlan, &vg->vlan_list, vlist) { |
1000 | if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV) |
1001 | continue; |
1002 | vlan_vid_del(dev: p->dev, proto, vid: vlan->vid); |
1003 | } |
1004 | } |
1005 | |
1006 | return err; |
1007 | } |
1008 | |
1009 | int br_vlan_set_proto(struct net_bridge *br, unsigned long val, |
1010 | struct netlink_ext_ack *extack) |
1011 | { |
1012 | if (!eth_type_vlan(htons(val))) |
1013 | return -EPROTONOSUPPORT; |
1014 | |
1015 | return __br_vlan_set_proto(br, htons(val), extack); |
1016 | } |
1017 | |
1018 | int br_vlan_set_stats(struct net_bridge *br, unsigned long val) |
1019 | { |
1020 | switch (val) { |
1021 | case 0: |
1022 | case 1: |
1023 | br_opt_toggle(br, opt: BROPT_VLAN_STATS_ENABLED, on: !!val); |
1024 | break; |
1025 | default: |
1026 | return -EINVAL; |
1027 | } |
1028 | |
1029 | return 0; |
1030 | } |
1031 | |
1032 | int br_vlan_set_stats_per_port(struct net_bridge *br, unsigned long val) |
1033 | { |
1034 | struct net_bridge_port *p; |
1035 | |
1036 | /* allow to change the option if there are no port vlans configured */ |
1037 | list_for_each_entry(p, &br->port_list, list) { |
1038 | struct net_bridge_vlan_group *vg = nbp_vlan_group(p); |
1039 | |
1040 | if (vg->num_vlans) |
1041 | return -EBUSY; |
1042 | } |
1043 | |
1044 | switch (val) { |
1045 | case 0: |
1046 | case 1: |
1047 | br_opt_toggle(br, opt: BROPT_VLAN_STATS_PER_PORT, on: !!val); |
1048 | break; |
1049 | default: |
1050 | return -EINVAL; |
1051 | } |
1052 | |
1053 | return 0; |
1054 | } |
1055 | |
1056 | static bool vlan_default_pvid(struct net_bridge_vlan_group *vg, u16 vid) |
1057 | { |
1058 | struct net_bridge_vlan *v; |
1059 | |
1060 | if (vid != vg->pvid) |
1061 | return false; |
1062 | |
1063 | v = br_vlan_lookup(tbl: &vg->vlan_hash, vid); |
1064 | if (v && br_vlan_should_use(v) && |
1065 | (v->flags & BRIDGE_VLAN_INFO_UNTAGGED)) |
1066 | return true; |
1067 | |
1068 | return false; |
1069 | } |
1070 | |
1071 | static void br_vlan_disable_default_pvid(struct net_bridge *br) |
1072 | { |
1073 | struct net_bridge_port *p; |
1074 | u16 pvid = br->default_pvid; |
1075 | |
1076 | /* Disable default_pvid on all ports where it is still |
1077 | * configured. |
1078 | */ |
1079 | if (vlan_default_pvid(vg: br_vlan_group(br), vid: pvid)) { |
1080 | if (!br_vlan_delete(br, vid: pvid)) |
1081 | br_vlan_notify(br, NULL, vid: pvid, vid_range: 0, RTM_DELVLAN); |
1082 | } |
1083 | |
1084 | list_for_each_entry(p, &br->port_list, list) { |
1085 | if (vlan_default_pvid(vg: nbp_vlan_group(p), vid: pvid) && |
1086 | !nbp_vlan_delete(port: p, vid: pvid)) |
1087 | br_vlan_notify(br, p, vid: pvid, vid_range: 0, RTM_DELVLAN); |
1088 | } |
1089 | |
1090 | br->default_pvid = 0; |
1091 | } |
1092 | |
1093 | int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid, |
1094 | struct netlink_ext_ack *extack) |
1095 | { |
1096 | const struct net_bridge_vlan *pvent; |
1097 | struct net_bridge_vlan_group *vg; |
1098 | struct net_bridge_port *p; |
1099 | unsigned long *changed; |
1100 | bool vlchange; |
1101 | u16 old_pvid; |
1102 | int err = 0; |
1103 | |
1104 | if (!pvid) { |
1105 | br_vlan_disable_default_pvid(br); |
1106 | return 0; |
1107 | } |
1108 | |
1109 | changed = bitmap_zalloc(BR_MAX_PORTS, GFP_KERNEL); |
1110 | if (!changed) |
1111 | return -ENOMEM; |
1112 | |
1113 | old_pvid = br->default_pvid; |
1114 | |
1115 | /* Update default_pvid config only if we do not conflict with |
1116 | * user configuration. |
1117 | */ |
1118 | vg = br_vlan_group(br); |
1119 | pvent = br_vlan_find(vg, vid: pvid); |
1120 | if ((!old_pvid || vlan_default_pvid(vg, vid: old_pvid)) && |
1121 | (!pvent || !br_vlan_should_use(v: pvent))) { |
1122 | err = br_vlan_add(br, vid: pvid, |
1123 | BRIDGE_VLAN_INFO_PVID | |
1124 | BRIDGE_VLAN_INFO_UNTAGGED | |
1125 | BRIDGE_VLAN_INFO_BRENTRY, |
1126 | changed: &vlchange, extack); |
1127 | if (err) |
1128 | goto out; |
1129 | |
1130 | if (br_vlan_delete(br, vid: old_pvid)) |
1131 | br_vlan_notify(br, NULL, vid: old_pvid, vid_range: 0, RTM_DELVLAN); |
1132 | br_vlan_notify(br, NULL, vid: pvid, vid_range: 0, cmd: RTM_NEWVLAN); |
1133 | __set_bit(0, changed); |
1134 | } |
1135 | |
1136 | list_for_each_entry(p, &br->port_list, list) { |
1137 | /* Update default_pvid config only if we do not conflict with |
1138 | * user configuration. |
1139 | */ |
1140 | vg = nbp_vlan_group(p); |
1141 | if ((old_pvid && |
1142 | !vlan_default_pvid(vg, vid: old_pvid)) || |
1143 | br_vlan_find(vg, vid: pvid)) |
1144 | continue; |
1145 | |
1146 | err = nbp_vlan_add(port: p, vid: pvid, |
1147 | BRIDGE_VLAN_INFO_PVID | |
1148 | BRIDGE_VLAN_INFO_UNTAGGED, |
1149 | changed: &vlchange, extack); |
1150 | if (err) |
1151 | goto err_port; |
1152 | if (nbp_vlan_delete(port: p, vid: old_pvid)) |
1153 | br_vlan_notify(br, p, vid: old_pvid, vid_range: 0, RTM_DELVLAN); |
1154 | br_vlan_notify(br: p->br, p, vid: pvid, vid_range: 0, cmd: RTM_NEWVLAN); |
1155 | __set_bit(p->port_no, changed); |
1156 | } |
1157 | |
1158 | br->default_pvid = pvid; |
1159 | |
1160 | out: |
1161 | bitmap_free(bitmap: changed); |
1162 | return err; |
1163 | |
1164 | err_port: |
1165 | list_for_each_entry_continue_reverse(p, &br->port_list, list) { |
1166 | if (!test_bit(p->port_no, changed)) |
1167 | continue; |
1168 | |
1169 | if (old_pvid) { |
1170 | nbp_vlan_add(port: p, vid: old_pvid, |
1171 | BRIDGE_VLAN_INFO_PVID | |
1172 | BRIDGE_VLAN_INFO_UNTAGGED, |
1173 | changed: &vlchange, NULL); |
1174 | br_vlan_notify(br: p->br, p, vid: old_pvid, vid_range: 0, cmd: RTM_NEWVLAN); |
1175 | } |
1176 | nbp_vlan_delete(port: p, vid: pvid); |
1177 | br_vlan_notify(br, p, vid: pvid, vid_range: 0, RTM_DELVLAN); |
1178 | } |
1179 | |
1180 | if (test_bit(0, changed)) { |
1181 | if (old_pvid) { |
1182 | br_vlan_add(br, vid: old_pvid, |
1183 | BRIDGE_VLAN_INFO_PVID | |
1184 | BRIDGE_VLAN_INFO_UNTAGGED | |
1185 | BRIDGE_VLAN_INFO_BRENTRY, |
1186 | changed: &vlchange, NULL); |
1187 | br_vlan_notify(br, NULL, vid: old_pvid, vid_range: 0, cmd: RTM_NEWVLAN); |
1188 | } |
1189 | br_vlan_delete(br, vid: pvid); |
1190 | br_vlan_notify(br, NULL, vid: pvid, vid_range: 0, RTM_DELVLAN); |
1191 | } |
1192 | goto out; |
1193 | } |
1194 | |
1195 | int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val, |
1196 | struct netlink_ext_ack *extack) |
1197 | { |
1198 | u16 pvid = val; |
1199 | int err = 0; |
1200 | |
1201 | if (val >= VLAN_VID_MASK) |
1202 | return -EINVAL; |
1203 | |
1204 | if (pvid == br->default_pvid) |
1205 | goto out; |
1206 | |
1207 | /* Only allow default pvid change when filtering is disabled */ |
1208 | if (br_opt_get(br, opt: BROPT_VLAN_ENABLED)) { |
1209 | pr_info_once("Please disable vlan filtering to change default_pvid\n" ); |
1210 | err = -EPERM; |
1211 | goto out; |
1212 | } |
1213 | err = __br_vlan_set_default_pvid(br, pvid, extack); |
1214 | out: |
1215 | return err; |
1216 | } |
1217 | |
1218 | int br_vlan_init(struct net_bridge *br) |
1219 | { |
1220 | struct net_bridge_vlan_group *vg; |
1221 | int ret = -ENOMEM; |
1222 | |
1223 | vg = kzalloc(size: sizeof(*vg), GFP_KERNEL); |
1224 | if (!vg) |
1225 | goto out; |
1226 | ret = rhashtable_init(ht: &vg->vlan_hash, params: &br_vlan_rht_params); |
1227 | if (ret) |
1228 | goto err_rhtbl; |
1229 | ret = vlan_tunnel_init(vg); |
1230 | if (ret) |
1231 | goto err_tunnel_init; |
1232 | INIT_LIST_HEAD(list: &vg->vlan_list); |
1233 | br->vlan_proto = htons(ETH_P_8021Q); |
1234 | br->default_pvid = 1; |
1235 | rcu_assign_pointer(br->vlgrp, vg); |
1236 | |
1237 | out: |
1238 | return ret; |
1239 | |
1240 | err_tunnel_init: |
1241 | rhashtable_destroy(ht: &vg->vlan_hash); |
1242 | err_rhtbl: |
1243 | kfree(objp: vg); |
1244 | |
1245 | goto out; |
1246 | } |
1247 | |
1248 | int nbp_vlan_init(struct net_bridge_port *p, struct netlink_ext_ack *extack) |
1249 | { |
1250 | struct switchdev_attr attr = { |
1251 | .orig_dev = p->br->dev, |
1252 | .id = SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING, |
1253 | .flags = SWITCHDEV_F_SKIP_EOPNOTSUPP, |
1254 | .u.vlan_filtering = br_opt_get(br: p->br, opt: BROPT_VLAN_ENABLED), |
1255 | }; |
1256 | struct net_bridge_vlan_group *vg; |
1257 | int ret = -ENOMEM; |
1258 | |
1259 | vg = kzalloc(size: sizeof(struct net_bridge_vlan_group), GFP_KERNEL); |
1260 | if (!vg) |
1261 | goto out; |
1262 | |
1263 | ret = switchdev_port_attr_set(dev: p->dev, attr: &attr, extack); |
1264 | if (ret && ret != -EOPNOTSUPP) |
1265 | goto err_vlan_enabled; |
1266 | |
1267 | ret = rhashtable_init(ht: &vg->vlan_hash, params: &br_vlan_rht_params); |
1268 | if (ret) |
1269 | goto err_rhtbl; |
1270 | ret = vlan_tunnel_init(vg); |
1271 | if (ret) |
1272 | goto err_tunnel_init; |
1273 | INIT_LIST_HEAD(list: &vg->vlan_list); |
1274 | rcu_assign_pointer(p->vlgrp, vg); |
1275 | if (p->br->default_pvid) { |
1276 | bool changed; |
1277 | |
1278 | ret = nbp_vlan_add(port: p, vid: p->br->default_pvid, |
1279 | BRIDGE_VLAN_INFO_PVID | |
1280 | BRIDGE_VLAN_INFO_UNTAGGED, |
1281 | changed: &changed, extack); |
1282 | if (ret) |
1283 | goto err_vlan_add; |
1284 | br_vlan_notify(br: p->br, p, vid: p->br->default_pvid, vid_range: 0, cmd: RTM_NEWVLAN); |
1285 | } |
1286 | out: |
1287 | return ret; |
1288 | |
1289 | err_vlan_add: |
1290 | RCU_INIT_POINTER(p->vlgrp, NULL); |
1291 | synchronize_rcu(); |
1292 | vlan_tunnel_deinit(vg); |
1293 | err_tunnel_init: |
1294 | rhashtable_destroy(ht: &vg->vlan_hash); |
1295 | err_rhtbl: |
1296 | err_vlan_enabled: |
1297 | kfree(objp: vg); |
1298 | |
1299 | goto out; |
1300 | } |
1301 | |
1302 | /* Must be protected by RTNL. |
1303 | * Must be called with vid in range from 1 to 4094 inclusive. |
1304 | * changed must be true only if the vlan was created or updated |
1305 | */ |
1306 | int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags, |
1307 | bool *changed, struct netlink_ext_ack *extack) |
1308 | { |
1309 | struct net_bridge_vlan *vlan; |
1310 | int ret; |
1311 | |
1312 | ASSERT_RTNL(); |
1313 | |
1314 | *changed = false; |
1315 | vlan = br_vlan_find(vg: nbp_vlan_group(p: port), vid); |
1316 | if (vlan) { |
1317 | bool would_change = __vlan_flags_would_change(v: vlan, flags); |
1318 | |
1319 | if (would_change) { |
1320 | /* Pass the flags to the hardware bridge */ |
1321 | ret = br_switchdev_port_vlan_add(dev: port->dev, vid, flags, |
1322 | changed: true, extack); |
1323 | if (ret && ret != -EOPNOTSUPP) |
1324 | return ret; |
1325 | } |
1326 | |
1327 | __vlan_flags_commit(v: vlan, flags); |
1328 | *changed = would_change; |
1329 | |
1330 | return 0; |
1331 | } |
1332 | |
1333 | vlan = kzalloc(size: sizeof(*vlan), GFP_KERNEL); |
1334 | if (!vlan) |
1335 | return -ENOMEM; |
1336 | |
1337 | vlan->vid = vid; |
1338 | vlan->port = port; |
1339 | ret = __vlan_add(v: vlan, flags, extack); |
1340 | if (ret) |
1341 | kfree(objp: vlan); |
1342 | else |
1343 | *changed = true; |
1344 | |
1345 | return ret; |
1346 | } |
1347 | |
1348 | /* Must be protected by RTNL. |
1349 | * Must be called with vid in range from 1 to 4094 inclusive. |
1350 | */ |
1351 | int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) |
1352 | { |
1353 | struct net_bridge_vlan *v; |
1354 | |
1355 | ASSERT_RTNL(); |
1356 | |
1357 | v = br_vlan_find(vg: nbp_vlan_group(p: port), vid); |
1358 | if (!v) |
1359 | return -ENOENT; |
1360 | br_fdb_find_delete_local(br: port->br, p: port, addr: port->dev->dev_addr, vid); |
1361 | br_fdb_delete_by_port(br: port->br, p: port, vid, do_all: 0); |
1362 | |
1363 | return __vlan_del(v); |
1364 | } |
1365 | |
1366 | void nbp_vlan_flush(struct net_bridge_port *port) |
1367 | { |
1368 | struct net_bridge_vlan_group *vg; |
1369 | |
1370 | ASSERT_RTNL(); |
1371 | |
1372 | vg = nbp_vlan_group(p: port); |
1373 | __vlan_flush(br: port->br, p: port, vg); |
1374 | RCU_INIT_POINTER(port->vlgrp, NULL); |
1375 | synchronize_net(); |
1376 | __vlan_group_free(vg); |
1377 | } |
1378 | |
1379 | void br_vlan_get_stats(const struct net_bridge_vlan *v, |
1380 | struct pcpu_sw_netstats *stats) |
1381 | { |
1382 | int i; |
1383 | |
1384 | memset(stats, 0, sizeof(*stats)); |
1385 | for_each_possible_cpu(i) { |
1386 | u64 rxpackets, rxbytes, txpackets, txbytes; |
1387 | struct pcpu_sw_netstats *cpu_stats; |
1388 | unsigned int start; |
1389 | |
1390 | cpu_stats = per_cpu_ptr(v->stats, i); |
1391 | do { |
1392 | start = u64_stats_fetch_begin(syncp: &cpu_stats->syncp); |
1393 | rxpackets = u64_stats_read(p: &cpu_stats->rx_packets); |
1394 | rxbytes = u64_stats_read(p: &cpu_stats->rx_bytes); |
1395 | txbytes = u64_stats_read(p: &cpu_stats->tx_bytes); |
1396 | txpackets = u64_stats_read(p: &cpu_stats->tx_packets); |
1397 | } while (u64_stats_fetch_retry(syncp: &cpu_stats->syncp, start)); |
1398 | |
1399 | u64_stats_add(p: &stats->rx_packets, val: rxpackets); |
1400 | u64_stats_add(p: &stats->rx_bytes, val: rxbytes); |
1401 | u64_stats_add(p: &stats->tx_bytes, val: txbytes); |
1402 | u64_stats_add(p: &stats->tx_packets, val: txpackets); |
1403 | } |
1404 | } |
1405 | |
1406 | int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid) |
1407 | { |
1408 | struct net_bridge_vlan_group *vg; |
1409 | struct net_bridge_port *p; |
1410 | |
1411 | ASSERT_RTNL(); |
1412 | p = br_port_get_check_rtnl(dev); |
1413 | if (p) |
1414 | vg = nbp_vlan_group(p); |
1415 | else if (netif_is_bridge_master(dev)) |
1416 | vg = br_vlan_group(br: netdev_priv(dev)); |
1417 | else |
1418 | return -EINVAL; |
1419 | |
1420 | *p_pvid = br_get_pvid(vg); |
1421 | return 0; |
1422 | } |
1423 | EXPORT_SYMBOL_GPL(br_vlan_get_pvid); |
1424 | |
1425 | int br_vlan_get_pvid_rcu(const struct net_device *dev, u16 *p_pvid) |
1426 | { |
1427 | struct net_bridge_vlan_group *vg; |
1428 | struct net_bridge_port *p; |
1429 | |
1430 | p = br_port_get_check_rcu(dev); |
1431 | if (p) |
1432 | vg = nbp_vlan_group_rcu(p); |
1433 | else if (netif_is_bridge_master(dev)) |
1434 | vg = br_vlan_group_rcu(br: netdev_priv(dev)); |
1435 | else |
1436 | return -EINVAL; |
1437 | |
1438 | *p_pvid = br_get_pvid(vg); |
1439 | return 0; |
1440 | } |
1441 | EXPORT_SYMBOL_GPL(br_vlan_get_pvid_rcu); |
1442 | |
1443 | void br_vlan_fill_forward_path_pvid(struct net_bridge *br, |
1444 | struct net_device_path_ctx *ctx, |
1445 | struct net_device_path *path) |
1446 | { |
1447 | struct net_bridge_vlan_group *vg; |
1448 | int idx = ctx->num_vlans - 1; |
1449 | u16 vid; |
1450 | |
1451 | path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP; |
1452 | |
1453 | if (!br_opt_get(br, opt: BROPT_VLAN_ENABLED)) |
1454 | return; |
1455 | |
1456 | vg = br_vlan_group(br); |
1457 | |
1458 | if (idx >= 0 && |
1459 | ctx->vlan[idx].proto == br->vlan_proto) { |
1460 | vid = ctx->vlan[idx].id; |
1461 | } else { |
1462 | path->bridge.vlan_mode = DEV_PATH_BR_VLAN_TAG; |
1463 | vid = br_get_pvid(vg); |
1464 | } |
1465 | |
1466 | path->bridge.vlan_id = vid; |
1467 | path->bridge.vlan_proto = br->vlan_proto; |
1468 | } |
1469 | |
1470 | int br_vlan_fill_forward_path_mode(struct net_bridge *br, |
1471 | struct net_bridge_port *dst, |
1472 | struct net_device_path *path) |
1473 | { |
1474 | struct net_bridge_vlan_group *vg; |
1475 | struct net_bridge_vlan *v; |
1476 | |
1477 | if (!br_opt_get(br, opt: BROPT_VLAN_ENABLED)) |
1478 | return 0; |
1479 | |
1480 | vg = nbp_vlan_group_rcu(p: dst); |
1481 | v = br_vlan_find(vg, vid: path->bridge.vlan_id); |
1482 | if (!v || !br_vlan_should_use(v)) |
1483 | return -EINVAL; |
1484 | |
1485 | if (!(v->flags & BRIDGE_VLAN_INFO_UNTAGGED)) |
1486 | return 0; |
1487 | |
1488 | if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG) |
1489 | path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP; |
1490 | else if (v->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV) |
1491 | path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW; |
1492 | else |
1493 | path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG; |
1494 | |
1495 | return 0; |
1496 | } |
1497 | |
1498 | int br_vlan_get_info(const struct net_device *dev, u16 vid, |
1499 | struct bridge_vlan_info *p_vinfo) |
1500 | { |
1501 | struct net_bridge_vlan_group *vg; |
1502 | struct net_bridge_vlan *v; |
1503 | struct net_bridge_port *p; |
1504 | |
1505 | ASSERT_RTNL(); |
1506 | p = br_port_get_check_rtnl(dev); |
1507 | if (p) |
1508 | vg = nbp_vlan_group(p); |
1509 | else if (netif_is_bridge_master(dev)) |
1510 | vg = br_vlan_group(br: netdev_priv(dev)); |
1511 | else |
1512 | return -EINVAL; |
1513 | |
1514 | v = br_vlan_find(vg, vid); |
1515 | if (!v) |
1516 | return -ENOENT; |
1517 | |
1518 | p_vinfo->vid = vid; |
1519 | p_vinfo->flags = v->flags; |
1520 | if (vid == br_get_pvid(vg)) |
1521 | p_vinfo->flags |= BRIDGE_VLAN_INFO_PVID; |
1522 | return 0; |
1523 | } |
1524 | EXPORT_SYMBOL_GPL(br_vlan_get_info); |
1525 | |
1526 | int br_vlan_get_info_rcu(const struct net_device *dev, u16 vid, |
1527 | struct bridge_vlan_info *p_vinfo) |
1528 | { |
1529 | struct net_bridge_vlan_group *vg; |
1530 | struct net_bridge_vlan *v; |
1531 | struct net_bridge_port *p; |
1532 | |
1533 | p = br_port_get_check_rcu(dev); |
1534 | if (p) |
1535 | vg = nbp_vlan_group_rcu(p); |
1536 | else if (netif_is_bridge_master(dev)) |
1537 | vg = br_vlan_group_rcu(br: netdev_priv(dev)); |
1538 | else |
1539 | return -EINVAL; |
1540 | |
1541 | v = br_vlan_find(vg, vid); |
1542 | if (!v) |
1543 | return -ENOENT; |
1544 | |
1545 | p_vinfo->vid = vid; |
1546 | p_vinfo->flags = v->flags; |
1547 | if (vid == br_get_pvid(vg)) |
1548 | p_vinfo->flags |= BRIDGE_VLAN_INFO_PVID; |
1549 | return 0; |
1550 | } |
1551 | EXPORT_SYMBOL_GPL(br_vlan_get_info_rcu); |
1552 | |
1553 | static int br_vlan_is_bind_vlan_dev(const struct net_device *dev) |
1554 | { |
1555 | return is_vlan_dev(dev) && |
1556 | !!(vlan_dev_priv(dev)->flags & VLAN_FLAG_BRIDGE_BINDING); |
1557 | } |
1558 | |
1559 | static int br_vlan_is_bind_vlan_dev_fn(struct net_device *dev, |
1560 | __always_unused struct netdev_nested_priv *priv) |
1561 | { |
1562 | return br_vlan_is_bind_vlan_dev(dev); |
1563 | } |
1564 | |
1565 | static bool br_vlan_has_upper_bind_vlan_dev(struct net_device *dev) |
1566 | { |
1567 | int found; |
1568 | |
1569 | rcu_read_lock(); |
1570 | found = netdev_walk_all_upper_dev_rcu(dev, fn: br_vlan_is_bind_vlan_dev_fn, |
1571 | NULL); |
1572 | rcu_read_unlock(); |
1573 | |
1574 | return !!found; |
1575 | } |
1576 | |
1577 | struct br_vlan_bind_walk_data { |
1578 | u16 vid; |
1579 | struct net_device *result; |
1580 | }; |
1581 | |
1582 | static int br_vlan_match_bind_vlan_dev_fn(struct net_device *dev, |
1583 | struct netdev_nested_priv *priv) |
1584 | { |
1585 | struct br_vlan_bind_walk_data *data = priv->data; |
1586 | int found = 0; |
1587 | |
1588 | if (br_vlan_is_bind_vlan_dev(dev) && |
1589 | vlan_dev_priv(dev)->vlan_id == data->vid) { |
1590 | data->result = dev; |
1591 | found = 1; |
1592 | } |
1593 | |
1594 | return found; |
1595 | } |
1596 | |
1597 | static struct net_device * |
1598 | br_vlan_get_upper_bind_vlan_dev(struct net_device *dev, u16 vid) |
1599 | { |
1600 | struct br_vlan_bind_walk_data data = { |
1601 | .vid = vid, |
1602 | }; |
1603 | struct netdev_nested_priv priv = { |
1604 | .data = (void *)&data, |
1605 | }; |
1606 | |
1607 | rcu_read_lock(); |
1608 | netdev_walk_all_upper_dev_rcu(dev, fn: br_vlan_match_bind_vlan_dev_fn, |
1609 | priv: &priv); |
1610 | rcu_read_unlock(); |
1611 | |
1612 | return data.result; |
1613 | } |
1614 | |
1615 | static bool br_vlan_is_dev_up(const struct net_device *dev) |
1616 | { |
1617 | return !!(dev->flags & IFF_UP) && netif_oper_up(dev); |
1618 | } |
1619 | |
1620 | static void br_vlan_set_vlan_dev_state(const struct net_bridge *br, |
1621 | struct net_device *vlan_dev) |
1622 | { |
1623 | u16 vid = vlan_dev_priv(dev: vlan_dev)->vlan_id; |
1624 | struct net_bridge_vlan_group *vg; |
1625 | struct net_bridge_port *p; |
1626 | bool has_carrier = false; |
1627 | |
1628 | if (!netif_carrier_ok(dev: br->dev)) { |
1629 | netif_carrier_off(dev: vlan_dev); |
1630 | return; |
1631 | } |
1632 | |
1633 | list_for_each_entry(p, &br->port_list, list) { |
1634 | vg = nbp_vlan_group(p); |
1635 | if (br_vlan_find(vg, vid) && br_vlan_is_dev_up(dev: p->dev)) { |
1636 | has_carrier = true; |
1637 | break; |
1638 | } |
1639 | } |
1640 | |
1641 | if (has_carrier) |
1642 | netif_carrier_on(dev: vlan_dev); |
1643 | else |
1644 | netif_carrier_off(dev: vlan_dev); |
1645 | } |
1646 | |
1647 | static void br_vlan_set_all_vlan_dev_state(struct net_bridge_port *p) |
1648 | { |
1649 | struct net_bridge_vlan_group *vg = nbp_vlan_group(p); |
1650 | struct net_bridge_vlan *vlan; |
1651 | struct net_device *vlan_dev; |
1652 | |
1653 | list_for_each_entry(vlan, &vg->vlan_list, vlist) { |
1654 | vlan_dev = br_vlan_get_upper_bind_vlan_dev(dev: p->br->dev, |
1655 | vid: vlan->vid); |
1656 | if (vlan_dev) { |
1657 | if (br_vlan_is_dev_up(dev: p->dev)) { |
1658 | if (netif_carrier_ok(dev: p->br->dev)) |
1659 | netif_carrier_on(dev: vlan_dev); |
1660 | } else { |
1661 | br_vlan_set_vlan_dev_state(br: p->br, vlan_dev); |
1662 | } |
1663 | } |
1664 | } |
1665 | } |
1666 | |
1667 | static void br_vlan_upper_change(struct net_device *dev, |
1668 | struct net_device *upper_dev, |
1669 | bool linking) |
1670 | { |
1671 | struct net_bridge *br = netdev_priv(dev); |
1672 | |
1673 | if (!br_vlan_is_bind_vlan_dev(dev: upper_dev)) |
1674 | return; |
1675 | |
1676 | if (linking) { |
1677 | br_vlan_set_vlan_dev_state(br, vlan_dev: upper_dev); |
1678 | br_opt_toggle(br, opt: BROPT_VLAN_BRIDGE_BINDING, on: true); |
1679 | } else { |
1680 | br_opt_toggle(br, opt: BROPT_VLAN_BRIDGE_BINDING, |
1681 | on: br_vlan_has_upper_bind_vlan_dev(dev)); |
1682 | } |
1683 | } |
1684 | |
1685 | struct br_vlan_link_state_walk_data { |
1686 | struct net_bridge *br; |
1687 | }; |
1688 | |
1689 | static int br_vlan_link_state_change_fn(struct net_device *vlan_dev, |
1690 | struct netdev_nested_priv *priv) |
1691 | { |
1692 | struct br_vlan_link_state_walk_data *data = priv->data; |
1693 | |
1694 | if (br_vlan_is_bind_vlan_dev(dev: vlan_dev)) |
1695 | br_vlan_set_vlan_dev_state(br: data->br, vlan_dev); |
1696 | |
1697 | return 0; |
1698 | } |
1699 | |
1700 | static void br_vlan_link_state_change(struct net_device *dev, |
1701 | struct net_bridge *br) |
1702 | { |
1703 | struct br_vlan_link_state_walk_data data = { |
1704 | .br = br |
1705 | }; |
1706 | struct netdev_nested_priv priv = { |
1707 | .data = (void *)&data, |
1708 | }; |
1709 | |
1710 | rcu_read_lock(); |
1711 | netdev_walk_all_upper_dev_rcu(dev, fn: br_vlan_link_state_change_fn, |
1712 | priv: &priv); |
1713 | rcu_read_unlock(); |
1714 | } |
1715 | |
1716 | /* Must be protected by RTNL. */ |
1717 | static void nbp_vlan_set_vlan_dev_state(struct net_bridge_port *p, u16 vid) |
1718 | { |
1719 | struct net_device *vlan_dev; |
1720 | |
1721 | if (!br_opt_get(br: p->br, opt: BROPT_VLAN_BRIDGE_BINDING)) |
1722 | return; |
1723 | |
1724 | vlan_dev = br_vlan_get_upper_bind_vlan_dev(dev: p->br->dev, vid); |
1725 | if (vlan_dev) |
1726 | br_vlan_set_vlan_dev_state(br: p->br, vlan_dev); |
1727 | } |
1728 | |
1729 | /* Must be protected by RTNL. */ |
1730 | int br_vlan_bridge_event(struct net_device *dev, unsigned long event, void *ptr) |
1731 | { |
1732 | struct netdev_notifier_changeupper_info *info; |
1733 | struct net_bridge *br = netdev_priv(dev); |
1734 | int vlcmd = 0, ret = 0; |
1735 | bool changed = false; |
1736 | |
1737 | switch (event) { |
1738 | case NETDEV_REGISTER: |
1739 | ret = br_vlan_add(br, vid: br->default_pvid, |
1740 | BRIDGE_VLAN_INFO_PVID | |
1741 | BRIDGE_VLAN_INFO_UNTAGGED | |
1742 | BRIDGE_VLAN_INFO_BRENTRY, changed: &changed, NULL); |
1743 | vlcmd = RTM_NEWVLAN; |
1744 | break; |
1745 | case NETDEV_UNREGISTER: |
1746 | changed = !br_vlan_delete(br, vid: br->default_pvid); |
1747 | vlcmd = RTM_DELVLAN; |
1748 | break; |
1749 | case NETDEV_CHANGEUPPER: |
1750 | info = ptr; |
1751 | br_vlan_upper_change(dev, upper_dev: info->upper_dev, linking: info->linking); |
1752 | break; |
1753 | |
1754 | case NETDEV_CHANGE: |
1755 | case NETDEV_UP: |
1756 | if (!br_opt_get(br, opt: BROPT_VLAN_BRIDGE_BINDING)) |
1757 | break; |
1758 | br_vlan_link_state_change(dev, br); |
1759 | break; |
1760 | } |
1761 | if (changed) |
1762 | br_vlan_notify(br, NULL, vid: br->default_pvid, vid_range: 0, cmd: vlcmd); |
1763 | |
1764 | return ret; |
1765 | } |
1766 | |
1767 | /* Must be protected by RTNL. */ |
1768 | void br_vlan_port_event(struct net_bridge_port *p, unsigned long event) |
1769 | { |
1770 | if (!br_opt_get(br: p->br, opt: BROPT_VLAN_BRIDGE_BINDING)) |
1771 | return; |
1772 | |
1773 | switch (event) { |
1774 | case NETDEV_CHANGE: |
1775 | case NETDEV_DOWN: |
1776 | case NETDEV_UP: |
1777 | br_vlan_set_all_vlan_dev_state(p); |
1778 | break; |
1779 | } |
1780 | } |
1781 | |
1782 | static bool br_vlan_stats_fill(struct sk_buff *skb, |
1783 | const struct net_bridge_vlan *v) |
1784 | { |
1785 | struct pcpu_sw_netstats stats; |
1786 | struct nlattr *nest; |
1787 | |
1788 | nest = nla_nest_start(skb, attrtype: BRIDGE_VLANDB_ENTRY_STATS); |
1789 | if (!nest) |
1790 | return false; |
1791 | |
1792 | br_vlan_get_stats(v, stats: &stats); |
1793 | if (nla_put_u64_64bit(skb, attrtype: BRIDGE_VLANDB_STATS_RX_BYTES, |
1794 | value: u64_stats_read(p: &stats.rx_bytes), |
1795 | padattr: BRIDGE_VLANDB_STATS_PAD) || |
1796 | nla_put_u64_64bit(skb, attrtype: BRIDGE_VLANDB_STATS_RX_PACKETS, |
1797 | value: u64_stats_read(p: &stats.rx_packets), |
1798 | padattr: BRIDGE_VLANDB_STATS_PAD) || |
1799 | nla_put_u64_64bit(skb, attrtype: BRIDGE_VLANDB_STATS_TX_BYTES, |
1800 | value: u64_stats_read(p: &stats.tx_bytes), |
1801 | padattr: BRIDGE_VLANDB_STATS_PAD) || |
1802 | nla_put_u64_64bit(skb, attrtype: BRIDGE_VLANDB_STATS_TX_PACKETS, |
1803 | value: u64_stats_read(p: &stats.tx_packets), |
1804 | padattr: BRIDGE_VLANDB_STATS_PAD)) |
1805 | goto out_err; |
1806 | |
1807 | nla_nest_end(skb, start: nest); |
1808 | |
1809 | return true; |
1810 | |
1811 | out_err: |
1812 | nla_nest_cancel(skb, start: nest); |
1813 | return false; |
1814 | } |
1815 | |
1816 | /* v_opts is used to dump the options which must be equal in the whole range */ |
1817 | static bool br_vlan_fill_vids(struct sk_buff *skb, u16 vid, u16 vid_range, |
1818 | const struct net_bridge_vlan *v_opts, |
1819 | const struct net_bridge_port *p, |
1820 | u16 flags, |
1821 | bool dump_stats) |
1822 | { |
1823 | struct bridge_vlan_info info; |
1824 | struct nlattr *nest; |
1825 | |
1826 | nest = nla_nest_start(skb, attrtype: BRIDGE_VLANDB_ENTRY); |
1827 | if (!nest) |
1828 | return false; |
1829 | |
1830 | memset(&info, 0, sizeof(info)); |
1831 | info.vid = vid; |
1832 | if (flags & BRIDGE_VLAN_INFO_UNTAGGED) |
1833 | info.flags |= BRIDGE_VLAN_INFO_UNTAGGED; |
1834 | if (flags & BRIDGE_VLAN_INFO_PVID) |
1835 | info.flags |= BRIDGE_VLAN_INFO_PVID; |
1836 | |
1837 | if (nla_put(skb, attrtype: BRIDGE_VLANDB_ENTRY_INFO, attrlen: sizeof(info), data: &info)) |
1838 | goto out_err; |
1839 | |
1840 | if (vid_range && vid < vid_range && |
1841 | !(flags & BRIDGE_VLAN_INFO_PVID) && |
1842 | nla_put_u16(skb, attrtype: BRIDGE_VLANDB_ENTRY_RANGE, value: vid_range)) |
1843 | goto out_err; |
1844 | |
1845 | if (v_opts) { |
1846 | if (!br_vlan_opts_fill(skb, v: v_opts, p)) |
1847 | goto out_err; |
1848 | |
1849 | if (dump_stats && !br_vlan_stats_fill(skb, v: v_opts)) |
1850 | goto out_err; |
1851 | } |
1852 | |
1853 | nla_nest_end(skb, start: nest); |
1854 | |
1855 | return true; |
1856 | |
1857 | out_err: |
1858 | nla_nest_cancel(skb, start: nest); |
1859 | return false; |
1860 | } |
1861 | |
1862 | static size_t rtnl_vlan_nlmsg_size(void) |
1863 | { |
1864 | return NLMSG_ALIGN(sizeof(struct br_vlan_msg)) |
1865 | + nla_total_size(payload: 0) /* BRIDGE_VLANDB_ENTRY */ |
1866 | + nla_total_size(payload: sizeof(u16)) /* BRIDGE_VLANDB_ENTRY_RANGE */ |
1867 | + nla_total_size(payload: sizeof(struct bridge_vlan_info)) /* BRIDGE_VLANDB_ENTRY_INFO */ |
1868 | + br_vlan_opts_nl_size(); /* bridge vlan options */ |
1869 | } |
1870 | |
1871 | void br_vlan_notify(const struct net_bridge *br, |
1872 | const struct net_bridge_port *p, |
1873 | u16 vid, u16 vid_range, |
1874 | int cmd) |
1875 | { |
1876 | struct net_bridge_vlan_group *vg; |
1877 | struct net_bridge_vlan *v = NULL; |
1878 | struct br_vlan_msg *bvm; |
1879 | struct nlmsghdr *nlh; |
1880 | struct sk_buff *skb; |
1881 | int err = -ENOBUFS; |
1882 | struct net *net; |
1883 | u16 flags = 0; |
1884 | int ifindex; |
1885 | |
1886 | /* right now notifications are done only with rtnl held */ |
1887 | ASSERT_RTNL(); |
1888 | |
1889 | if (p) { |
1890 | ifindex = p->dev->ifindex; |
1891 | vg = nbp_vlan_group(p); |
1892 | net = dev_net(dev: p->dev); |
1893 | } else { |
1894 | ifindex = br->dev->ifindex; |
1895 | vg = br_vlan_group(br); |
1896 | net = dev_net(dev: br->dev); |
1897 | } |
1898 | |
1899 | skb = nlmsg_new(payload: rtnl_vlan_nlmsg_size(), GFP_KERNEL); |
1900 | if (!skb) |
1901 | goto out_err; |
1902 | |
1903 | err = -EMSGSIZE; |
1904 | nlh = nlmsg_put(skb, portid: 0, seq: 0, type: cmd, payload: sizeof(*bvm), flags: 0); |
1905 | if (!nlh) |
1906 | goto out_err; |
1907 | bvm = nlmsg_data(nlh); |
1908 | memset(bvm, 0, sizeof(*bvm)); |
1909 | bvm->family = AF_BRIDGE; |
1910 | bvm->ifindex = ifindex; |
1911 | |
1912 | switch (cmd) { |
1913 | case RTM_NEWVLAN: |
1914 | /* need to find the vlan due to flags/options */ |
1915 | v = br_vlan_find(vg, vid); |
1916 | if (!v || !br_vlan_should_use(v)) |
1917 | goto out_kfree; |
1918 | |
1919 | flags = v->flags; |
1920 | if (br_get_pvid(vg) == v->vid) |
1921 | flags |= BRIDGE_VLAN_INFO_PVID; |
1922 | break; |
1923 | case RTM_DELVLAN: |
1924 | break; |
1925 | default: |
1926 | goto out_kfree; |
1927 | } |
1928 | |
1929 | if (!br_vlan_fill_vids(skb, vid, vid_range, v_opts: v, p, flags, dump_stats: false)) |
1930 | goto out_err; |
1931 | |
1932 | nlmsg_end(skb, nlh); |
1933 | rtnl_notify(skb, net, pid: 0, RTNLGRP_BRVLAN, NULL, GFP_KERNEL); |
1934 | return; |
1935 | |
1936 | out_err: |
1937 | rtnl_set_sk_err(net, RTNLGRP_BRVLAN, error: err); |
1938 | out_kfree: |
1939 | kfree_skb(skb); |
1940 | } |
1941 | |
1942 | /* check if v_curr can enter a range ending in range_end */ |
1943 | bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr, |
1944 | const struct net_bridge_vlan *range_end) |
1945 | { |
1946 | return v_curr->vid - range_end->vid == 1 && |
1947 | range_end->flags == v_curr->flags && |
1948 | br_vlan_opts_eq_range(v_curr, range_end); |
1949 | } |
1950 | |
1951 | static int br_vlan_dump_dev(const struct net_device *dev, |
1952 | struct sk_buff *skb, |
1953 | struct netlink_callback *cb, |
1954 | u32 dump_flags) |
1955 | { |
1956 | struct net_bridge_vlan *v, *range_start = NULL, *range_end = NULL; |
1957 | bool dump_global = !!(dump_flags & BRIDGE_VLANDB_DUMPF_GLOBAL); |
1958 | bool dump_stats = !!(dump_flags & BRIDGE_VLANDB_DUMPF_STATS); |
1959 | struct net_bridge_vlan_group *vg; |
1960 | int idx = 0, s_idx = cb->args[1]; |
1961 | struct nlmsghdr *nlh = NULL; |
1962 | struct net_bridge_port *p; |
1963 | struct br_vlan_msg *bvm; |
1964 | struct net_bridge *br; |
1965 | int err = 0; |
1966 | u16 pvid; |
1967 | |
1968 | if (!netif_is_bridge_master(dev) && !netif_is_bridge_port(dev)) |
1969 | return -EINVAL; |
1970 | |
1971 | if (netif_is_bridge_master(dev)) { |
1972 | br = netdev_priv(dev); |
1973 | vg = br_vlan_group_rcu(br); |
1974 | p = NULL; |
1975 | } else { |
1976 | /* global options are dumped only for bridge devices */ |
1977 | if (dump_global) |
1978 | return 0; |
1979 | |
1980 | p = br_port_get_rcu(dev); |
1981 | if (WARN_ON(!p)) |
1982 | return -EINVAL; |
1983 | vg = nbp_vlan_group_rcu(p); |
1984 | br = p->br; |
1985 | } |
1986 | |
1987 | if (!vg) |
1988 | return 0; |
1989 | |
1990 | nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, seq: cb->nlh->nlmsg_seq, |
1991 | type: RTM_NEWVLAN, payload: sizeof(*bvm), NLM_F_MULTI); |
1992 | if (!nlh) |
1993 | return -EMSGSIZE; |
1994 | bvm = nlmsg_data(nlh); |
1995 | memset(bvm, 0, sizeof(*bvm)); |
1996 | bvm->family = PF_BRIDGE; |
1997 | bvm->ifindex = dev->ifindex; |
1998 | pvid = br_get_pvid(vg); |
1999 | |
2000 | /* idx must stay at range's beginning until it is filled in */ |
2001 | list_for_each_entry_rcu(v, &vg->vlan_list, vlist) { |
2002 | if (!dump_global && !br_vlan_should_use(v)) |
2003 | continue; |
2004 | if (idx < s_idx) { |
2005 | idx++; |
2006 | continue; |
2007 | } |
2008 | |
2009 | if (!range_start) { |
2010 | range_start = v; |
2011 | range_end = v; |
2012 | continue; |
2013 | } |
2014 | |
2015 | if (dump_global) { |
2016 | if (br_vlan_global_opts_can_enter_range(v_curr: v, r_end: range_end)) |
2017 | goto update_end; |
2018 | if (!br_vlan_global_opts_fill(skb, vid: range_start->vid, |
2019 | vid_range: range_end->vid, |
2020 | v_opts: range_start)) { |
2021 | err = -EMSGSIZE; |
2022 | break; |
2023 | } |
2024 | /* advance number of filled vlans */ |
2025 | idx += range_end->vid - range_start->vid + 1; |
2026 | |
2027 | range_start = v; |
2028 | } else if (dump_stats || v->vid == pvid || |
2029 | !br_vlan_can_enter_range(v_curr: v, range_end)) { |
2030 | u16 vlan_flags = br_vlan_flags(v: range_start, pvid); |
2031 | |
2032 | if (!br_vlan_fill_vids(skb, vid: range_start->vid, |
2033 | vid_range: range_end->vid, v_opts: range_start, |
2034 | p, flags: vlan_flags, dump_stats)) { |
2035 | err = -EMSGSIZE; |
2036 | break; |
2037 | } |
2038 | /* advance number of filled vlans */ |
2039 | idx += range_end->vid - range_start->vid + 1; |
2040 | |
2041 | range_start = v; |
2042 | } |
2043 | update_end: |
2044 | range_end = v; |
2045 | } |
2046 | |
2047 | /* err will be 0 and range_start will be set in 3 cases here: |
2048 | * - first vlan (range_start == range_end) |
2049 | * - last vlan (range_start == range_end, not in range) |
2050 | * - last vlan range (range_start != range_end, in range) |
2051 | */ |
2052 | if (!err && range_start) { |
2053 | if (dump_global && |
2054 | !br_vlan_global_opts_fill(skb, vid: range_start->vid, |
2055 | vid_range: range_end->vid, v_opts: range_start)) |
2056 | err = -EMSGSIZE; |
2057 | else if (!dump_global && |
2058 | !br_vlan_fill_vids(skb, vid: range_start->vid, |
2059 | vid_range: range_end->vid, v_opts: range_start, |
2060 | p, flags: br_vlan_flags(v: range_start, pvid), |
2061 | dump_stats)) |
2062 | err = -EMSGSIZE; |
2063 | } |
2064 | |
2065 | cb->args[1] = err ? idx : 0; |
2066 | |
2067 | nlmsg_end(skb, nlh); |
2068 | |
2069 | return err; |
2070 | } |
2071 | |
2072 | static const struct nla_policy br_vlan_db_dump_pol[BRIDGE_VLANDB_DUMP_MAX + 1] = { |
2073 | [BRIDGE_VLANDB_DUMP_FLAGS] = { .type = NLA_U32 }, |
2074 | }; |
2075 | |
2076 | static int br_vlan_rtm_dump(struct sk_buff *skb, struct netlink_callback *cb) |
2077 | { |
2078 | struct nlattr *dtb[BRIDGE_VLANDB_DUMP_MAX + 1]; |
2079 | int idx = 0, err = 0, s_idx = cb->args[0]; |
2080 | struct net *net = sock_net(sk: skb->sk); |
2081 | struct br_vlan_msg *bvm; |
2082 | struct net_device *dev; |
2083 | u32 dump_flags = 0; |
2084 | |
2085 | err = nlmsg_parse(nlh: cb->nlh, hdrlen: sizeof(*bvm), tb: dtb, BRIDGE_VLANDB_DUMP_MAX, |
2086 | policy: br_vlan_db_dump_pol, extack: cb->extack); |
2087 | if (err < 0) |
2088 | return err; |
2089 | |
2090 | bvm = nlmsg_data(nlh: cb->nlh); |
2091 | if (dtb[BRIDGE_VLANDB_DUMP_FLAGS]) |
2092 | dump_flags = nla_get_u32(nla: dtb[BRIDGE_VLANDB_DUMP_FLAGS]); |
2093 | |
2094 | rcu_read_lock(); |
2095 | if (bvm->ifindex) { |
2096 | dev = dev_get_by_index_rcu(net, ifindex: bvm->ifindex); |
2097 | if (!dev) { |
2098 | err = -ENODEV; |
2099 | goto out_err; |
2100 | } |
2101 | err = br_vlan_dump_dev(dev, skb, cb, dump_flags); |
2102 | /* if the dump completed without an error we return 0 here */ |
2103 | if (err != -EMSGSIZE) |
2104 | goto out_err; |
2105 | } else { |
2106 | for_each_netdev_rcu(net, dev) { |
2107 | if (idx < s_idx) |
2108 | goto skip; |
2109 | |
2110 | err = br_vlan_dump_dev(dev, skb, cb, dump_flags); |
2111 | if (err == -EMSGSIZE) |
2112 | break; |
2113 | skip: |
2114 | idx++; |
2115 | } |
2116 | } |
2117 | cb->args[0] = idx; |
2118 | rcu_read_unlock(); |
2119 | |
2120 | return skb->len; |
2121 | |
2122 | out_err: |
2123 | rcu_read_unlock(); |
2124 | |
2125 | return err; |
2126 | } |
2127 | |
2128 | static const struct nla_policy br_vlan_db_policy[BRIDGE_VLANDB_ENTRY_MAX + 1] = { |
2129 | [BRIDGE_VLANDB_ENTRY_INFO] = |
2130 | NLA_POLICY_EXACT_LEN(sizeof(struct bridge_vlan_info)), |
2131 | [BRIDGE_VLANDB_ENTRY_RANGE] = { .type = NLA_U16 }, |
2132 | [BRIDGE_VLANDB_ENTRY_STATE] = { .type = NLA_U8 }, |
2133 | [BRIDGE_VLANDB_ENTRY_TUNNEL_INFO] = { .type = NLA_NESTED }, |
2134 | [BRIDGE_VLANDB_ENTRY_MCAST_ROUTER] = { .type = NLA_U8 }, |
2135 | [BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS] = { .type = NLA_REJECT }, |
2136 | [BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS] = { .type = NLA_U32 }, |
2137 | [BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS] = NLA_POLICY_MAX(NLA_U8, 1), |
2138 | }; |
2139 | |
2140 | static int br_vlan_rtm_process_one(struct net_device *dev, |
2141 | const struct nlattr *attr, |
2142 | int cmd, struct netlink_ext_ack *extack) |
2143 | { |
2144 | struct bridge_vlan_info *vinfo, vrange_end, *vinfo_last = NULL; |
2145 | struct nlattr *tb[BRIDGE_VLANDB_ENTRY_MAX + 1]; |
2146 | bool changed = false, skip_processing = false; |
2147 | struct net_bridge_vlan_group *vg; |
2148 | struct net_bridge_port *p = NULL; |
2149 | int err = 0, cmdmap = 0; |
2150 | struct net_bridge *br; |
2151 | |
2152 | if (netif_is_bridge_master(dev)) { |
2153 | br = netdev_priv(dev); |
2154 | vg = br_vlan_group(br); |
2155 | } else { |
2156 | p = br_port_get_rtnl(dev); |
2157 | if (WARN_ON(!p)) |
2158 | return -ENODEV; |
2159 | br = p->br; |
2160 | vg = nbp_vlan_group(p); |
2161 | } |
2162 | |
2163 | if (WARN_ON(!vg)) |
2164 | return -ENODEV; |
2165 | |
2166 | err = nla_parse_nested(tb, BRIDGE_VLANDB_ENTRY_MAX, nla: attr, |
2167 | policy: br_vlan_db_policy, extack); |
2168 | if (err) |
2169 | return err; |
2170 | |
2171 | if (!tb[BRIDGE_VLANDB_ENTRY_INFO]) { |
2172 | NL_SET_ERR_MSG_MOD(extack, "Missing vlan entry info" ); |
2173 | return -EINVAL; |
2174 | } |
2175 | memset(&vrange_end, 0, sizeof(vrange_end)); |
2176 | |
2177 | vinfo = nla_data(nla: tb[BRIDGE_VLANDB_ENTRY_INFO]); |
2178 | if (vinfo->flags & (BRIDGE_VLAN_INFO_RANGE_BEGIN | |
2179 | BRIDGE_VLAN_INFO_RANGE_END)) { |
2180 | NL_SET_ERR_MSG_MOD(extack, "Old-style vlan ranges are not allowed when using RTM vlan calls" ); |
2181 | return -EINVAL; |
2182 | } |
2183 | if (!br_vlan_valid_id(vid: vinfo->vid, extack)) |
2184 | return -EINVAL; |
2185 | |
2186 | if (tb[BRIDGE_VLANDB_ENTRY_RANGE]) { |
2187 | vrange_end.vid = nla_get_u16(nla: tb[BRIDGE_VLANDB_ENTRY_RANGE]); |
2188 | /* validate user-provided flags without RANGE_BEGIN */ |
2189 | vrange_end.flags = BRIDGE_VLAN_INFO_RANGE_END | vinfo->flags; |
2190 | vinfo->flags |= BRIDGE_VLAN_INFO_RANGE_BEGIN; |
2191 | |
2192 | /* vinfo_last is the range start, vinfo the range end */ |
2193 | vinfo_last = vinfo; |
2194 | vinfo = &vrange_end; |
2195 | |
2196 | if (!br_vlan_valid_id(vid: vinfo->vid, extack) || |
2197 | !br_vlan_valid_range(cur: vinfo, last: vinfo_last, extack)) |
2198 | return -EINVAL; |
2199 | } |
2200 | |
2201 | switch (cmd) { |
2202 | case RTM_NEWVLAN: |
2203 | cmdmap = RTM_SETLINK; |
2204 | skip_processing = !!(vinfo->flags & BRIDGE_VLAN_INFO_ONLY_OPTS); |
2205 | break; |
2206 | case RTM_DELVLAN: |
2207 | cmdmap = RTM_DELLINK; |
2208 | break; |
2209 | } |
2210 | |
2211 | if (!skip_processing) { |
2212 | struct bridge_vlan_info *tmp_last = vinfo_last; |
2213 | |
2214 | /* br_process_vlan_info may overwrite vinfo_last */ |
2215 | err = br_process_vlan_info(br, p, cmd: cmdmap, vinfo_curr: vinfo, vinfo_last: &tmp_last, |
2216 | changed: &changed, extack); |
2217 | |
2218 | /* notify first if anything changed */ |
2219 | if (changed) |
2220 | br_ifinfo_notify(event: cmdmap, br, port: p); |
2221 | |
2222 | if (err) |
2223 | return err; |
2224 | } |
2225 | |
2226 | /* deal with options */ |
2227 | if (cmd == RTM_NEWVLAN) { |
2228 | struct net_bridge_vlan *range_start, *range_end; |
2229 | |
2230 | if (vinfo_last) { |
2231 | range_start = br_vlan_find(vg, vid: vinfo_last->vid); |
2232 | range_end = br_vlan_find(vg, vid: vinfo->vid); |
2233 | } else { |
2234 | range_start = br_vlan_find(vg, vid: vinfo->vid); |
2235 | range_end = range_start; |
2236 | } |
2237 | |
2238 | err = br_vlan_process_options(br, p, range_start, range_end, |
2239 | tb, extack); |
2240 | } |
2241 | |
2242 | return err; |
2243 | } |
2244 | |
2245 | static int br_vlan_rtm_process(struct sk_buff *skb, struct nlmsghdr *nlh, |
2246 | struct netlink_ext_ack *extack) |
2247 | { |
2248 | struct net *net = sock_net(sk: skb->sk); |
2249 | struct br_vlan_msg *bvm; |
2250 | struct net_device *dev; |
2251 | struct nlattr *attr; |
2252 | int err, vlans = 0; |
2253 | int rem; |
2254 | |
2255 | /* this should validate the header and check for remaining bytes */ |
2256 | err = nlmsg_parse(nlh, hdrlen: sizeof(*bvm), NULL, BRIDGE_VLANDB_MAX, NULL, |
2257 | extack); |
2258 | if (err < 0) |
2259 | return err; |
2260 | |
2261 | bvm = nlmsg_data(nlh); |
2262 | dev = __dev_get_by_index(net, ifindex: bvm->ifindex); |
2263 | if (!dev) |
2264 | return -ENODEV; |
2265 | |
2266 | if (!netif_is_bridge_master(dev) && !netif_is_bridge_port(dev)) { |
2267 | NL_SET_ERR_MSG_MOD(extack, "The device is not a valid bridge or bridge port" ); |
2268 | return -EINVAL; |
2269 | } |
2270 | |
2271 | nlmsg_for_each_attr(attr, nlh, sizeof(*bvm), rem) { |
2272 | switch (nla_type(nla: attr)) { |
2273 | case BRIDGE_VLANDB_ENTRY: |
2274 | err = br_vlan_rtm_process_one(dev, attr, |
2275 | cmd: nlh->nlmsg_type, |
2276 | extack); |
2277 | break; |
2278 | case BRIDGE_VLANDB_GLOBAL_OPTIONS: |
2279 | err = br_vlan_rtm_process_global_options(dev, attr, |
2280 | cmd: nlh->nlmsg_type, |
2281 | extack); |
2282 | break; |
2283 | default: |
2284 | continue; |
2285 | } |
2286 | |
2287 | vlans++; |
2288 | if (err) |
2289 | break; |
2290 | } |
2291 | if (!vlans) { |
2292 | NL_SET_ERR_MSG_MOD(extack, "No vlans found to process" ); |
2293 | err = -EINVAL; |
2294 | } |
2295 | |
2296 | return err; |
2297 | } |
2298 | |
2299 | void br_vlan_rtnl_init(void) |
2300 | { |
2301 | rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_GETVLAN, NULL, |
2302 | br_vlan_rtm_dump, flags: 0); |
2303 | rtnl_register_module(THIS_MODULE, PF_BRIDGE, msgtype: RTM_NEWVLAN, |
2304 | br_vlan_rtm_process, NULL, flags: 0); |
2305 | rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_DELVLAN, |
2306 | br_vlan_rtm_process, NULL, flags: 0); |
2307 | } |
2308 | |
2309 | void br_vlan_rtnl_uninit(void) |
2310 | { |
2311 | rtnl_unregister(PF_BRIDGE, RTM_GETVLAN); |
2312 | rtnl_unregister(PF_BRIDGE, msgtype: RTM_NEWVLAN); |
2313 | rtnl_unregister(PF_BRIDGE, RTM_DELVLAN); |
2314 | } |
2315 | |