blob: 0b3dbbec80d0dd8b029ad8dfeaf5fe432aef464f [file] [log] [blame]
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001#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
Vlad Yasevich552406c2013-02-13 12:00:15 +00008static 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
17static 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
Vlad Yasevich35e03f32013-02-13 12:00:20 +000026static 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
Vlad Yasevich552406c2013-02-13 12:00:15 +000035static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags)
Vlad Yasevich243a2e62013-02-13 12:00:09 +000036{
Vlad Yasevichbc9a25d2013-02-13 12:00:19 +000037 struct net_bridge_port *p = NULL;
38 struct net_bridge *br;
39 struct net_device *dev;
Vlad Yasevich243a2e62013-02-13 12:00:09 +000040 int err;
41
Vlad Yasevich552406c2013-02-13 12:00:15 +000042 if (test_bit(vid, v->vlan_bitmap)) {
Vlad Yasevich35e03f32013-02-13 12:00:20 +000043 __vlan_add_flags(v, vid, flags);
Vlad Yasevich552406c2013-02-13 12:00:15 +000044 return 0;
45 }
Vlad Yasevich243a2e62013-02-13 12:00:09 +000046
Vlad Yasevichbc9a25d2013-02-13 12:00:19 +000047 if (vid) {
48 if (v->port_idx) {
49 p = v->parent.port;
50 br = p->br;
51 dev = p->dev;
52 } else {
53 br = v->parent.br;
54 dev = br->dev;
55 }
Vlad Yasevich243a2e62013-02-13 12:00:09 +000056
Patrick McHardyf6469682013-04-19 02:04:27 +000057 if (p && (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) {
Vlad Yasevichbc9a25d2013-02-13 12:00:19 +000058 /* Add VLAN to the device filter if it is supported.
59 * Stricly speaking, this is not necessary now, since
60 * devices are made promiscuous by the bridge, but if
61 * that ever changes this code will allow tagged
62 * traffic to enter the bridge.
63 */
Vlad Yasevich243a2e62013-02-13 12:00:09 +000064 err = dev->netdev_ops->ndo_vlan_rx_add_vid(dev, vid);
65 if (err)
66 return err;
67 }
Vlad Yasevichbc9a25d2013-02-13 12:00:19 +000068
69 err = br_fdb_insert(br, p, dev->dev_addr, vid);
70 if (err) {
71 br_err(br, "failed insert local address into bridge "
72 "forwarding table\n");
73 goto out_filt;
74 }
75
Vlad Yasevich243a2e62013-02-13 12:00:09 +000076 }
77
78 set_bit(vid, v->vlan_bitmap);
Vlad Yasevich6cbdcee2013-02-13 12:00:13 +000079 v->num_vlans++;
Vlad Yasevich35e03f32013-02-13 12:00:20 +000080 __vlan_add_flags(v, vid, flags);
Vlad Yasevich552406c2013-02-13 12:00:15 +000081
Vlad Yasevich243a2e62013-02-13 12:00:09 +000082 return 0;
Vlad Yasevichbc9a25d2013-02-13 12:00:19 +000083
84out_filt:
Patrick McHardyf6469682013-04-19 02:04:27 +000085 if (p && (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
Vlad Yasevichbc9a25d2013-02-13 12:00:19 +000086 dev->netdev_ops->ndo_vlan_rx_kill_vid(dev, vid);
87 return err;
Vlad Yasevich243a2e62013-02-13 12:00:09 +000088}
89
90static int __vlan_del(struct net_port_vlans *v, u16 vid)
91{
92 if (!test_bit(vid, v->vlan_bitmap))
93 return -EINVAL;
94
Vlad Yasevich552406c2013-02-13 12:00:15 +000095 __vlan_delete_pvid(v, vid);
Vlad Yasevich35e03f32013-02-13 12:00:20 +000096 clear_bit(vid, v->untagged_bitmap);
Vlad Yasevich552406c2013-02-13 12:00:15 +000097
Vlad Yasevich243a2e62013-02-13 12:00:09 +000098 if (v->port_idx && vid) {
99 struct net_device *dev = v->parent.port->dev;
100
Patrick McHardyf6469682013-04-19 02:04:27 +0000101 if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000102 dev->netdev_ops->ndo_vlan_rx_kill_vid(dev, vid);
103 }
104
105 clear_bit(vid, v->vlan_bitmap);
Vlad Yasevich6cbdcee2013-02-13 12:00:13 +0000106 v->num_vlans--;
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000107 if (bitmap_empty(v->vlan_bitmap, BR_VLAN_BITMAP_LEN)) {
108 if (v->port_idx)
109 rcu_assign_pointer(v->parent.port->vlan_info, NULL);
110 else
111 rcu_assign_pointer(v->parent.br->vlan_info, NULL);
112 kfree_rcu(v, rcu);
113 }
114 return 0;
115}
116
117static void __vlan_flush(struct net_port_vlans *v)
118{
Vlad Yasevich552406c2013-02-13 12:00:15 +0000119 smp_wmb();
120 v->pvid = 0;
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000121 bitmap_zero(v->vlan_bitmap, BR_VLAN_BITMAP_LEN);
122 if (v->port_idx)
123 rcu_assign_pointer(v->parent.port->vlan_info, NULL);
124 else
125 rcu_assign_pointer(v->parent.br->vlan_info, NULL);
126 kfree_rcu(v, rcu);
127}
128
Vlad Yasevich78851982013-02-13 12:00:14 +0000129/* Strip the tag from the packet. Will return skb with tci set 0. */
130static struct sk_buff *br_vlan_untag(struct sk_buff *skb)
131{
132 if (skb->protocol != htons(ETH_P_8021Q)) {
133 skb->vlan_tci = 0;
134 return skb;
135 }
136
137 skb->vlan_tci = 0;
138 skb = vlan_untag(skb);
139 if (skb)
140 skb->vlan_tci = 0;
141
142 return skb;
143}
144
145struct sk_buff *br_handle_vlan(struct net_bridge *br,
146 const struct net_port_vlans *pv,
147 struct sk_buff *skb)
Vlad Yasevicha37b85c2013-02-13 12:00:10 +0000148{
149 u16 vid;
150
Vlad Yasevich78851982013-02-13 12:00:14 +0000151 if (!br->vlan_enabled)
152 goto out;
153
154 /* At this point, we know that the frame was filtered and contains
Vlad Yasevich35e03f32013-02-13 12:00:20 +0000155 * a valid vlan id. If the vlan id is set in the untagged bitmap,
Vlad Yasevich78851982013-02-13 12:00:14 +0000156 * send untagged; otherwise, send taged.
157 */
158 br_vlan_get_tag(skb, &vid);
Vlad Yasevich35e03f32013-02-13 12:00:20 +0000159 if (test_bit(vid, pv->untagged_bitmap))
Vlad Yasevich78851982013-02-13 12:00:14 +0000160 skb = br_vlan_untag(skb);
161 else {
162 /* Egress policy says "send tagged". If output device
163 * is the bridge, we need to add the VLAN header
164 * ourselves since we'll be going through the RX path.
165 * Sending to ports puts the frame on the TX path and
166 * we let dev_hard_start_xmit() add the header.
167 */
168 if (skb->protocol != htons(ETH_P_8021Q) &&
169 pv->port_idx == 0) {
170 /* vlan_put_tag expects skb->data to point to
171 * mac header.
172 */
173 skb_push(skb, ETH_HLEN);
174 skb = __vlan_put_tag(skb, skb->vlan_tci);
175 if (!skb)
176 goto out;
177 /* put skb->data back to where it was */
178 skb_pull(skb, ETH_HLEN);
179 skb->vlan_tci = 0;
180 }
181 }
182
183out:
184 return skb;
185}
186
187/* Called under RCU */
188bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
189 struct sk_buff *skb, u16 *vid)
190{
Vlad Yasevicha37b85c2013-02-13 12:00:10 +0000191 /* If VLAN filtering is disabled on the bridge, all packets are
192 * permitted.
193 */
194 if (!br->vlan_enabled)
195 return true;
196
197 /* If there are no vlan in the permitted list, all packets are
198 * rejected.
199 */
200 if (!v)
201 return false;
202
Vlad Yasevich78851982013-02-13 12:00:14 +0000203 if (br_vlan_get_tag(skb, vid)) {
204 u16 pvid = br_get_pvid(v);
205
206 /* Frame did not have a tag. See if pvid is set
207 * on this port. That tells us which vlan untagged
208 * traffic belongs to.
209 */
210 if (pvid == VLAN_N_VID)
211 return false;
212
213 /* PVID is set on this port. Any untagged ingress
214 * frame is considered to belong to this vlan.
215 */
216 __vlan_hwaccel_put_tag(skb, pvid);
217 return true;
218 }
219
220 /* Frame had a valid vlan tag. See if vlan is allowed */
221 if (test_bit(*vid, v->vlan_bitmap))
Vlad Yasevicha37b85c2013-02-13 12:00:10 +0000222 return true;
223
224 return false;
225}
226
Vlad Yasevich85f46c62013-02-13 12:00:11 +0000227/* Called under RCU. */
228bool br_allowed_egress(struct net_bridge *br,
229 const struct net_port_vlans *v,
230 const struct sk_buff *skb)
231{
232 u16 vid;
233
234 if (!br->vlan_enabled)
235 return true;
236
237 if (!v)
238 return false;
239
240 br_vlan_get_tag(skb, &vid);
241 if (test_bit(vid, v->vlan_bitmap))
242 return true;
243
244 return false;
245}
246
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000247/* Must be protected by RTNL */
Vlad Yasevich552406c2013-02-13 12:00:15 +0000248int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags)
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000249{
250 struct net_port_vlans *pv = NULL;
251 int err;
252
253 ASSERT_RTNL();
254
255 pv = rtnl_dereference(br->vlan_info);
256 if (pv)
Vlad Yasevich552406c2013-02-13 12:00:15 +0000257 return __vlan_add(pv, vid, flags);
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000258
259 /* Create port vlan infomration
260 */
261 pv = kzalloc(sizeof(*pv), GFP_KERNEL);
262 if (!pv)
263 return -ENOMEM;
264
265 pv->parent.br = br;
Vlad Yasevich552406c2013-02-13 12:00:15 +0000266 err = __vlan_add(pv, vid, flags);
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000267 if (err)
268 goto out;
269
270 rcu_assign_pointer(br->vlan_info, pv);
271 return 0;
272out:
273 kfree(pv);
274 return err;
275}
276
277/* Must be protected by RTNL */
278int 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
Vlad Yasevichbc9a25d2013-02-13 12:00:19 +0000288 if (vid) {
289 /* If the VID !=0 remove fdb for this vid. VID 0 is special
290 * in that it's the default and is always there in the fdb.
291 */
292 spin_lock_bh(&br->hash_lock);
293 fdb_delete_by_addr(br, br->dev->dev_addr, vid);
294 spin_unlock_bh(&br->hash_lock);
295 }
296
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000297 __vlan_del(pv, vid);
298 return 0;
299}
300
301void br_vlan_flush(struct net_bridge *br)
302{
303 struct net_port_vlans *pv;
304
305 ASSERT_RTNL();
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000306 pv = rtnl_dereference(br->vlan_info);
307 if (!pv)
308 return;
309
310 __vlan_flush(pv);
311}
312
313int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val)
314{
315 if (!rtnl_trylock())
316 return restart_syscall();
317
318 if (br->vlan_enabled == val)
319 goto unlock;
320
321 br->vlan_enabled = val;
322
323unlock:
324 rtnl_unlock();
325 return 0;
326}
327
328/* Must be protected by RTNL */
Vlad Yasevich552406c2013-02-13 12:00:15 +0000329int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags)
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000330{
331 struct net_port_vlans *pv = NULL;
332 int err;
333
334 ASSERT_RTNL();
335
336 pv = rtnl_dereference(port->vlan_info);
337 if (pv)
Vlad Yasevich552406c2013-02-13 12:00:15 +0000338 return __vlan_add(pv, vid, flags);
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000339
340 /* Create port vlan infomration
341 */
342 pv = kzalloc(sizeof(*pv), GFP_KERNEL);
343 if (!pv) {
344 err = -ENOMEM;
345 goto clean_up;
346 }
347
348 pv->port_idx = port->port_no;
349 pv->parent.port = port;
Vlad Yasevich552406c2013-02-13 12:00:15 +0000350 err = __vlan_add(pv, vid, flags);
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000351 if (err)
352 goto clean_up;
353
354 rcu_assign_pointer(port->vlan_info, pv);
355 return 0;
356
357clean_up:
358 kfree(pv);
359 return err;
360}
361
362/* Must be protected by RTNL */
363int nbp_vlan_delete(struct net_bridge_port *port, u16 vid)
364{
365 struct net_port_vlans *pv;
366
367 ASSERT_RTNL();
368
369 pv = rtnl_dereference(port->vlan_info);
370 if (!pv)
371 return -EINVAL;
372
Vlad Yasevichbc9a25d2013-02-13 12:00:19 +0000373 if (vid) {
374 /* If the VID !=0 remove fdb for this vid. VID 0 is special
375 * in that it's the default and is always there in the fdb.
376 */
377 spin_lock_bh(&port->br->hash_lock);
378 fdb_delete_by_addr(port->br, port->dev->dev_addr, vid);
379 spin_unlock_bh(&port->br->hash_lock);
380 }
381
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000382 return __vlan_del(pv, vid);
383}
384
385void nbp_vlan_flush(struct net_bridge_port *port)
386{
387 struct net_port_vlans *pv;
388
389 ASSERT_RTNL();
390
391 pv = rtnl_dereference(port->vlan_info);
392 if (!pv)
393 return;
394
395 __vlan_flush(pv);
396}
Vlad Yasevichbc9a25d2013-02-13 12:00:19 +0000397
398bool nbp_vlan_find(struct net_bridge_port *port, u16 vid)
399{
400 struct net_port_vlans *pv;
401 bool found = false;
402
403 rcu_read_lock();
404 pv = rcu_dereference(port->vlan_info);
405
406 if (!pv)
407 goto out;
408
409 if (test_bit(vid, pv->vlan_bitmap))
410 found = true;
411
412out:
413 rcu_read_unlock();
414 return found;
415}