Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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
  8static 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
 26static 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
 35static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags)
 36{
 37	struct net_bridge_port *p = NULL;
 38	struct net_bridge *br;
 39	struct net_device *dev;
 40	int err;
 41
 42	if (test_bit(vid, v->vlan_bitmap)) {
 43		__vlan_add_flags(v, vid, flags);
 44		return 0;
 45	}
 46
 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	}
 55
 56	if (p) {
 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		 */
 63		err = vlan_vid_add(dev, htons(ETH_P_8021Q), vid);
 64		if (err)
 65			return err;
 66	}
 67
 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;
 73	}
 74
 75	set_bit(vid, v->vlan_bitmap);
 76	v->num_vlans++;
 77	__vlan_add_flags(v, vid, flags);
 78
 79	return 0;
 80
 81out_filt:
 82	if (p)
 83		vlan_vid_del(dev, htons(ETH_P_8021Q), vid);
 84	return err;
 85}
 86
 87static int __vlan_del(struct net_port_vlans *v, u16 vid)
 88{
 89	if (!test_bit(vid, v->vlan_bitmap))
 90		return -EINVAL;
 91
 92	__vlan_delete_pvid(v, vid);
 93	clear_bit(vid, v->untagged_bitmap);
 94
 95	if (v->port_idx)
 96		vlan_vid_del(v->parent.port->dev, htons(ETH_P_8021Q), vid);
 97
 98	clear_bit(vid, v->vlan_bitmap);
 99	v->num_vlans--;
100	if (bitmap_empty(v->vlan_bitmap, VLAN_N_VID)) {
101		if (v->port_idx)
102			RCU_INIT_POINTER(v->parent.port->vlan_info, NULL);
103		else
104			RCU_INIT_POINTER(v->parent.br->vlan_info, NULL);
105		kfree_rcu(v, rcu);
106	}
107	return 0;
108}
109
110static void __vlan_flush(struct net_port_vlans *v)
111{
112	smp_wmb();
113	v->pvid = 0;
114	bitmap_zero(v->vlan_bitmap, VLAN_N_VID);
115	if (v->port_idx)
116		RCU_INIT_POINTER(v->parent.port->vlan_info, NULL);
117	else
118		RCU_INIT_POINTER(v->parent.br->vlan_info, NULL);
119	kfree_rcu(v, rcu);
120}
121
122struct sk_buff *br_handle_vlan(struct net_bridge *br,
123			       const struct net_port_vlans *pv,
124			       struct sk_buff *skb)
125{
126	u16 vid;
127
128	if (!br->vlan_enabled)
129		goto out;
130
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
145	/* At this point, we know that the frame was filtered and contains
146	 * a valid vlan id.  If the vlan id is set in the untagged bitmap,
147	 * send untagged; otherwise, send tagged.
148	 */
149	br_vlan_get_tag(skb, &vid);
150	if (test_bit(vid, pv->untagged_bitmap))
151		skb->vlan_tci = 0;
152
153out:
154	return skb;
155}
156
157/* Called under RCU */
158bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
159			struct sk_buff *skb, u16 *vid)
160{
161	int err;
162
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		goto drop;
174
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
187	err = br_vlan_get_tag(skb, vid);
188	if (!*vid) {
189		u16 pvid = br_get_pvid(v);
190
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.
194		 */
195		if (pvid == VLAN_N_VID)
196			goto drop;
197
198		/* PVID is set on this port.  Any untagged or priority-tagged
199		 * ingress frame is considered to belong to this vlan.
200		 */
201		*vid = pvid;
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
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))
218		return true;
219drop:
220	kfree_skb(skb);
221	return false;
222}
223
224/* Called under RCU. */
225bool br_allowed_egress(struct net_bridge *br,
226		       const struct net_port_vlans *v,
227		       const struct sk_buff *skb)
228{
229	u16 vid;
230
231	if (!br->vlan_enabled)
232		return true;
233
234	if (!v)
235		return false;
236
237	br_vlan_get_tag(skb, &vid);
238	if (test_bit(vid, v->vlan_bitmap))
239		return true;
240
241	return false;
242}
243
244/* Called under RCU */
245bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid)
246{
247	struct net_bridge *br = p->br;
248	struct net_port_vlans *v;
249
250	if (!br->vlan_enabled)
251		return true;
252
253	v = rcu_dereference(p->vlan_info);
254	if (!v)
255		return false;
256
257	br_vlan_get_tag(skb, vid);
258	if (!*vid) {
259		*vid = br_get_pvid(v);
260		if (*vid == VLAN_N_VID)
261			return false;
262
263		return true;
264	}
265
266	if (test_bit(*vid, v->vlan_bitmap))
267		return true;
268
269	return false;
270}
271
272/* Must be protected by RTNL.
273 * Must be called with vid in range from 1 to 4094 inclusive.
274 */
275int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags)
276{
277	struct net_port_vlans *pv = NULL;
278	int err;
279
280	ASSERT_RTNL();
281
282	pv = rtnl_dereference(br->vlan_info);
283	if (pv)
284		return __vlan_add(pv, vid, flags);
285
286	/* Create port vlan infomration
287	 */
288	pv = kzalloc(sizeof(*pv), GFP_KERNEL);
289	if (!pv)
290		return -ENOMEM;
291
292	pv->parent.br = br;
293	err = __vlan_add(pv, vid, flags);
294	if (err)
295		goto out;
296
297	rcu_assign_pointer(br->vlan_info, pv);
298	return 0;
299out:
300	kfree(pv);
301	return err;
302}
303
304/* Must be protected by RTNL.
305 * Must be called with vid in range from 1 to 4094 inclusive.
306 */
307int br_vlan_delete(struct net_bridge *br, u16 vid)
308{
309	struct net_port_vlans *pv;
310
311	ASSERT_RTNL();
312
313	pv = rtnl_dereference(br->vlan_info);
314	if (!pv)
315		return -EINVAL;
316
317	br_fdb_find_delete_local(br, NULL, br->dev->dev_addr, vid);
318
319	__vlan_del(pv, vid);
320	return 0;
321}
322
323void br_vlan_flush(struct net_bridge *br)
324{
325	struct net_port_vlans *pv;
326
327	ASSERT_RTNL();
328	pv = rtnl_dereference(br->vlan_info);
329	if (!pv)
330		return;
331
332	__vlan_flush(pv);
333}
334
335bool br_vlan_find(struct net_bridge *br, u16 vid)
336{
337	struct net_port_vlans *pv;
338	bool found = false;
339
340	rcu_read_lock();
341	pv = rcu_dereference(br->vlan_info);
342
343	if (!pv)
344		goto out;
345
346	if (test_bit(vid, pv->vlan_bitmap))
347		found = true;
348
349out:
350	rcu_read_unlock();
351	return found;
352}
353
354int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val)
355{
356	if (!rtnl_trylock())
357		return restart_syscall();
358
359	if (br->vlan_enabled == val)
360		goto unlock;
361
362	br->vlan_enabled = val;
363
364unlock:
365	rtnl_unlock();
366	return 0;
367}
368
369/* Must be protected by RTNL.
370 * Must be called with vid in range from 1 to 4094 inclusive.
371 */
372int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags)
373{
374	struct net_port_vlans *pv = NULL;
375	int err;
376
377	ASSERT_RTNL();
378
379	pv = rtnl_dereference(port->vlan_info);
380	if (pv)
381		return __vlan_add(pv, vid, flags);
382
383	/* Create port vlan infomration
384	 */
385	pv = kzalloc(sizeof(*pv), GFP_KERNEL);
386	if (!pv) {
387		err = -ENOMEM;
388		goto clean_up;
389	}
390
391	pv->port_idx = port->port_no;
392	pv->parent.port = port;
393	err = __vlan_add(pv, vid, flags);
394	if (err)
395		goto clean_up;
396
397	rcu_assign_pointer(port->vlan_info, pv);
398	return 0;
399
400clean_up:
401	kfree(pv);
402	return err;
403}
404
405/* Must be protected by RTNL.
406 * Must be called with vid in range from 1 to 4094 inclusive.
407 */
408int nbp_vlan_delete(struct net_bridge_port *port, u16 vid)
409{
410	struct net_port_vlans *pv;
411
412	ASSERT_RTNL();
413
414	pv = rtnl_dereference(port->vlan_info);
415	if (!pv)
416		return -EINVAL;
417
418	br_fdb_find_delete_local(port->br, port, port->dev->dev_addr, vid);
419
420	return __vlan_del(pv, vid);
421}
422
423void nbp_vlan_flush(struct net_bridge_port *port)
424{
425	struct net_port_vlans *pv;
426	u16 vid;
427
428	ASSERT_RTNL();
429
430	pv = rtnl_dereference(port->vlan_info);
431	if (!pv)
432		return;
433
434	for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID)
435		vlan_vid_del(port->dev, htons(ETH_P_8021Q), vid);
436
437	__vlan_flush(pv);
438}
439
440bool nbp_vlan_find(struct net_bridge_port *port, u16 vid)
441{
442	struct net_port_vlans *pv;
443	bool found = false;
444
445	rcu_read_lock();
446	pv = rcu_dereference(port->vlan_info);
447
448	if (!pv)
449		goto out;
450
451	if (test_bit(vid, pv->vlan_bitmap))
452		found = true;
453
454out:
455	rcu_read_unlock();
456	return found;
457}