Example #1
0
File: br_vlan.c Project: 7799/linux
struct sk_buff *br_handle_vlan(struct net_bridge *br,
			       const struct net_port_vlans *pv,
			       struct sk_buff *skb)
{
	u16 vid;

	if (!br->vlan_enabled)
		goto out;

	/* Vlan filter table must be configured at this point.  The
	 * only exception is the bridge is set in promisc mode and the
	 * packet is destined for the bridge device.  In this case
	 * pass the packet as is.
	 */
	if (!pv) {
		if ((br->dev->flags & IFF_PROMISC) && skb->dev == br->dev) {
			goto out;
		} else {
			kfree_skb(skb);
			return NULL;
		}
	}

	/* At this point, we know that the frame was filtered and contains
	 * a valid vlan id.  If the vlan id is set in the untagged bitmap,
	 * send untagged; otherwise, send tagged.
	 */
	br_vlan_get_tag(skb, &vid);
	if (test_bit(vid, pv->untagged_bitmap))
		skb->vlan_tci = 0;

out:
	return skb;
}
Example #2
0
/* Called under RCU */
bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid)
{
	struct net_bridge *br = p->br;
	struct net_port_vlans *v;

	if (!br->vlan_enabled)
		return true;

	v = rcu_dereference(p->vlan_info);
	if (!v)
		return false;

	br_vlan_get_tag(skb, vid);
	if (!*vid) {
		*vid = br_get_pvid(v);
		if (*vid == VLAN_N_VID)
			return false;

		return true;
	}

	if (test_bit(*vid, v->vlan_bitmap))
		return true;

	return false;
}
/* note: already called with rcu_read_lock */
static int br_handle_local_finish(struct sk_buff *skb)
{
	struct net_bridge_port *p = br_port_get_rcu(skb->dev);
	u16 vid = 0;

	br_vlan_get_tag(skb, &vid);
	if (p->flags & BR_LEARNING)
		br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid);
	return 0;	 /* process further */
}
Example #4
0
/* Called under RCU */
bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
			struct sk_buff *skb, u16 *vid)
{
	int err;

	/* If VLAN filtering is disabled on the bridge, all packets are
	 * permitted.
	 */
	if (!br->vlan_enabled)
		return true;

	/* If there are no vlan in the permitted list, all packets are
	 * rejected.
	 */
	if (!v)
		return false;

	err = br_vlan_get_tag(skb, vid);
	if (!*vid) {
		u16 pvid = br_get_pvid(v);

		/* Frame had a tag with VID 0 or did not have a tag.
		 * See if pvid is set on this port.  That tells us which
		 * vlan untagged or priority-tagged traffic belongs to.
		 */
		if (pvid == VLAN_N_VID)
			return false;

		/* PVID is set on this port.  Any untagged or priority-tagged
		 * ingress frame is considered to belong to this vlan.
		 */
		*vid = pvid;
		if (likely(err))
			/* Untagged Frame. */
			__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), pvid);
		else
			/* Priority-tagged Frame.
			 * At this point, We know that skb->vlan_tci had
			 * VLAN_TAG_PRESENT bit and its VID field was 0x000.
			 * We update only VID field and preserve PCP field.
			 */
			skb->vlan_tci |= pvid;

		return true;
	}

	/* Frame had a valid vlan tag.  See if vlan is allowed */
	if (test_bit(*vid, v->vlan_bitmap))
		return true;

	return false;
}
/* Called under RCU. */
bool br_allowed_egress(struct net_bridge *br,
		       const struct net_port_vlans *v,
		       const struct sk_buff *skb)
{
	u16 vid;

	if (!br->vlan_enabled)
		return true;

	if (!v)
		return false;

	br_vlan_get_tag(skb, &vid);
	if (test_bit(vid, v->vlan_bitmap))
		return true;

	return false;
}
struct sk_buff *br_handle_vlan(struct net_bridge *br,
			       const struct net_port_vlans *pv,
			       struct sk_buff *skb)
{
	u16 vid;

	if (!br->vlan_enabled)
		goto out;

	/* At this point, we know that the frame was filtered and contains
	 * a valid vlan id.  If the vlan id is set in the untagged bitmap,
	 * send untagged; otherwise, send taged.
	 */
	br_vlan_get_tag(skb, &vid);
	if (test_bit(vid, pv->untagged_bitmap))
		skb = br_vlan_untag(skb);
	else {
		/* Egress policy says "send tagged".  If output device
		 * is the  bridge, we need to add the VLAN header
		 * ourselves since we'll be going through the RX path.
		 * Sending to ports puts the frame on the TX path and
		 * we let dev_hard_start_xmit() add the header.
		 */
		if (skb->protocol != htons(ETH_P_8021Q) &&
		    pv->port_idx == 0) {
			/* vlan_put_tag expects skb->data to point to
			 * mac header.
			 */
			skb_push(skb, ETH_HLEN);
			skb = __vlan_put_tag(skb, skb->vlan_proto, skb->vlan_tci);
			if (!skb)
				goto out;
			/* put skb->data back to where it was */
			skb_pull(skb, ETH_HLEN);
			skb->vlan_tci = 0;
		}
	}

out:
	return skb;
}
/* Called under RCU */
bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
			struct sk_buff *skb, u16 *vid)
{
	/* If VLAN filtering is disabled on the bridge, all packets are
	 * permitted.
	 */
	if (!br->vlan_enabled)
		return true;

	/* If there are no vlan in the permitted list, all packets are
	 * rejected.
	 */
	if (!v)
		return false;

	if (br_vlan_get_tag(skb, vid)) {
		u16 pvid = br_get_pvid(v);

		/* Frame did not have a tag.  See if pvid is set
		 * on this port.  That tells us which vlan untagged
		 * traffic belongs to.
		 */
		if (pvid == VLAN_N_VID)
			return false;

		/* PVID is set on this port.  Any untagged ingress
		 * frame is considered to belong to this vlan.
		 */
		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), pvid);
		return true;
	}

	/* Frame had a valid vlan tag.  See if vlan is allowed */
	if (test_bit(*vid, v->vlan_bitmap))
		return true;

	return false;
}