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