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; }
/* 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 */ }
/* 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; }