-/* Returns the effective vlan of a packet, taking into account both the
- * 802.1Q header and implicitly tagged ports. A value of 0 indicates that
- * the packet is untagged and -1 indicates it has an invalid header and
- * should be dropped. */
-static int
-flow_get_vlan(struct ofproto_dpif *ofproto, const struct flow *flow,
- struct ofbundle *in_bundle, bool have_packet)
-{
- int vlan = vlan_tci_to_vid(flow->vlan_tci);
- if (vlan) {
- if (in_bundle->vlan_mode == PORT_VLAN_ACCESS) {
- /* Drop tagged packet on access port */
- if (have_packet) {
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
- VLOG_WARN_RL(&rl, "bridge %s: dropping VLAN %d tagged "
- "packet received on port %s configured with "
- "implicit VLAN %"PRIu16,
- ofproto->up.name, vlan,
- in_bundle->name, in_bundle->vlan);
- }
- return -1;
- } else if (ofbundle_includes_vlan(in_bundle, vlan)) {
- return vlan;
- } else {
- /* Drop packets from a VLAN not member of the trunk */
- if (have_packet) {
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
- VLOG_WARN_RL(&rl, "bridge %s: dropping VLAN %d tagged "
- "packet received on port %s not configured for "
- "trunking VLAN %d",
- ofproto->up.name, vlan, in_bundle->name, vlan);
- }
- return -1;
- }
- } else {
- if (flow->dl_type == htons(ETH_TYPE_VLAN) &&
- !(flow->vlan_tci & htons(VLAN_CFI))) {
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
- VLOG_WARN_RL(&rl, "bridge %s: dropping packet with partial "
- "VLAN tag received on port %s",
- ofproto->up.name, in_bundle->name);
- return -1;
- }
- if (in_bundle->vlan_mode != PORT_VLAN_TRUNK) {
- return in_bundle->vlan;
- } else {
- return ofbundle_includes_vlan(in_bundle, 0) ? 0 : -1;
- }
- }
-}
-