diff --git a/include/openvswitch/match.h b/include/openvswitch/match.h
index 49e463a..b43ecb1 100644
--- a/include/openvswitch/match.h
+++ b/include/openvswitch/match.h
@@ -163,11 +163,11 @@ void match_set_dl_dst_masked(struct match *, const struct eth_addr dl_dst,
 void match_set_dl_tci(struct match *, ovs_be16 tci);
 void match_set_dl_tci_masked(struct match *, ovs_be16 tci, ovs_be16 mask);
 void match_set_any_vid(struct match *);
-void match_set_dl_vlan(struct match *, ovs_be16);
+void match_set_dl_vlan(struct match *, ovs_be16, int id);
 void match_set_vlan_vid(struct match *, ovs_be16);
 void match_set_vlan_vid_masked(struct match *, ovs_be16 vid, ovs_be16 mask);
 void match_set_any_pcp(struct match *);
-void match_set_dl_vlan_pcp(struct match *, uint8_t);
+void match_set_dl_vlan_pcp(struct match *, uint8_t, int id);
 void match_set_any_mpls_lse(struct match *, int idx);
 void match_set_mpls_lse(struct match *, int idx, ovs_be32);
 void match_set_any_mpls_label(struct match *, int idx);
diff --git a/lib/flow.c b/lib/flow.c
index 76a8b9a..77ed3d9 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -2520,14 +2520,14 @@ flow_hash_in_wildcards(const struct flow *flow,
  *
  *      - Other values of 'vid' should not be used. */
 void
-flow_set_dl_vlan(struct flow *flow, ovs_be16 vid)
+flow_set_dl_vlan(struct flow *flow, ovs_be16 vid, int id)
 {
     if (vid == htons(OFP10_VLAN_NONE)) {
-        flow->vlans[0].tci = htons(0);
+        flow->vlans[id].tci = htons(0);
     } else {
         vid &= htons(VLAN_VID_MASK);
-        flow->vlans[0].tci &= ~htons(VLAN_VID_MASK);
-        flow->vlans[0].tci |= htons(VLAN_CFI) | vid;
+        flow->vlans[id].tci &= ~htons(VLAN_VID_MASK);
+        flow->vlans[id].tci |= htons(VLAN_CFI) | vid;
     }
 }
 
@@ -2560,11 +2560,11 @@ flow_set_vlan_vid(struct flow *flow, ovs_be16 vid)
  * After calling this function, 'flow' will not match packets without a VLAN
  * header. */
 void
-flow_set_vlan_pcp(struct flow *flow, uint8_t pcp)
+flow_set_vlan_pcp(struct flow *flow, uint8_t pcp, int id)
 {
     pcp &= 0x07;
-    flow->vlans[0].tci &= ~htons(VLAN_PCP_MASK);
-    flow->vlans[0].tci |= htons((pcp << VLAN_PCP_SHIFT) | VLAN_CFI);
+    flow->vlans[id].tci &= ~htons(VLAN_PCP_MASK);
+    flow->vlans[id].tci |= htons((pcp << VLAN_PCP_SHIFT) | VLAN_CFI);
 }
 
 /* Counts the number of VLAN headers. */
diff --git a/lib/flow.h b/lib/flow.h
index af7b5e9..d03f1ba 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -99,10 +99,10 @@ static inline int flow_compare_3way(const struct flow *, const struct flow *);
 static inline bool flow_equal(const struct flow *, const struct flow *);
 static inline size_t flow_hash(const struct flow *, uint32_t basis);
 
-void flow_set_dl_vlan(struct flow *, ovs_be16 vid);
+void flow_set_dl_vlan(struct flow *, ovs_be16 vid, int id);
 void flow_fix_vlan_tpid(struct flow *);
 void flow_set_vlan_vid(struct flow *, ovs_be16 vid);
-void flow_set_vlan_pcp(struct flow *, uint8_t pcp);
+void flow_set_vlan_pcp(struct flow *, uint8_t pcp, int id);
 
 void flow_limit_vlans(int vlan_limit);
 int flow_count_vlan_headers(const struct flow *);
diff --git a/lib/match.c b/lib/match.c
index bf7e636..2281fa0 100644
--- a/lib/match.c
+++ b/lib/match.c
@@ -705,13 +705,13 @@ match_set_any_vid(struct match *match)
  *     VID equals the low 12 bits of 'dl_vlan'.
  */
 void
-match_set_dl_vlan(struct match *match, ovs_be16 dl_vlan)
+match_set_dl_vlan(struct match *match, ovs_be16 dl_vlan, int id)
 {
-    flow_set_dl_vlan(&match->flow, dl_vlan);
+    flow_set_dl_vlan(&match->flow, dl_vlan, id);
     if (dl_vlan == htons(OFP10_VLAN_NONE)) {
-        match->wc.masks.vlans[0].tci = OVS_BE16_MAX;
+        match->wc.masks.vlans[id].tci = OVS_BE16_MAX;
     } else {
-        match->wc.masks.vlans[0].tci |= htons(VLAN_VID_MASK | VLAN_CFI);
+        match->wc.masks.vlans[id].tci |= htons(VLAN_VID_MASK | VLAN_CFI);
     }
 }
 
@@ -757,10 +757,10 @@ match_set_any_pcp(struct match *match)
 /* Modifies 'match' so that it matches only packets with an 802.1Q header whose
  * PCP equals the low 3 bits of 'dl_vlan_pcp'. */
 void
-match_set_dl_vlan_pcp(struct match *match, uint8_t dl_vlan_pcp)
+match_set_dl_vlan_pcp(struct match *match, uint8_t dl_vlan_pcp, int id)
 {
-    flow_set_vlan_pcp(&match->flow, dl_vlan_pcp);
-    match->wc.masks.vlans[0].tci |= htons(VLAN_CFI | VLAN_PCP_MASK);
+    flow_set_vlan_pcp(&match->flow, dl_vlan_pcp, id);
+    match->wc.masks.vlans[id].tci |= htons(VLAN_CFI | VLAN_PCP_MASK);
 }
 
 /* Modifies 'match' so that the MPLS label 'idx' matches 'lse' exactly. */
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index db0abb3..fd8f3c6 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -1136,7 +1136,7 @@ mf_set_value(const struct mf_field *mf,
         break;
 
     case MFF_DL_VLAN:
-        match_set_dl_vlan(match, value->be16);
+        match_set_dl_vlan(match, value->be16, 0);
         break;
     case MFF_VLAN_VID:
         match_set_vlan_vid(match, value->be16);
@@ -1144,7 +1144,7 @@ mf_set_value(const struct mf_field *mf,
 
     case MFF_DL_VLAN_PCP:
     case MFF_VLAN_PCP:
-        match_set_dl_vlan_pcp(match, value->u8);
+        match_set_dl_vlan_pcp(match, value->u8, 0);
         break;
 
     case MFF_MPLS_LABEL:
@@ -1538,7 +1538,7 @@ mf_set_flow_value(const struct mf_field *mf,
         break;
 
     case MFF_DL_VLAN:
-        flow_set_dl_vlan(flow, value->be16);
+        flow_set_dl_vlan(flow, value->be16, 0);
         flow_fix_vlan_tpid(flow);
         break;
 
@@ -1549,7 +1549,7 @@ mf_set_flow_value(const struct mf_field *mf,
 
     case MFF_DL_VLAN_PCP:
     case MFF_VLAN_PCP:
-        flow_set_vlan_pcp(flow, value->u8);
+        flow_set_vlan_pcp(flow, value->u8, 0);
         flow_fix_vlan_tpid(flow);
         break;
 
diff --git a/lib/netdev-tc-offloads.c b/lib/netdev-tc-offloads.c
index 5c15f6a..3405458 100644
--- a/lib/netdev-tc-offloads.c
+++ b/lib/netdev-tc-offloads.c
@@ -432,8 +432,8 @@ parse_tc_flower_to_match(struct tc_flower *flower,
 
     if (eth_type_vlan(key->eth_type)) {
         match_set_dl_vlan(match, htons(key->vlan_id));
-        match_set_dl_vlan_pcp(match, key->vlan_prio);
-        match_set_dl_type(match, key->encap_eth_type);
+        match_set_dl_vlan_pcp(match, key->vlan_prio, 0);
+        match_set_dl_type(match, key->encap_eth_type, 0);
         flow_fix_vlan_tpid(&match->flow);
     } else {
         match_set_dl_type(match, key->eth_type);
diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c
index dcf2183..c38d7b0 100644
--- a/ovn/controller/physical.c
+++ b/ovn/controller/physical.c
@@ -549,7 +549,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_chassis_by_name,
          * for frames that lack any 802.1Q header later. */
         if (tag || !strcmp(binding->type, "localnet")
             || !strcmp(binding->type, "l2gateway")) {
-            match_set_dl_vlan(&match, htons(tag));
+            match_set_dl_vlan(&match, htons(tag), 0);
             if (nested_container) {
                 /* When a packet comes from a container sitting behind a
                  * parent_port, we should let it loopback to other containers
