mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 14:25:26 +00:00
Add support for 802.1ad (QinQ tunneling)
Flow key handling changes: - Add VLAN header array in struct flow, to record multiple 802.1q VLAN headers. - Add dpif multi-VLAN capability probing. If datapath supports multi-VLAN, increase the maximum depth of nested OVS_KEY_ATTR_ENCAP. Refactor VLAN handling in dpif-xlate: - Introduce 'xvlan' to track VLAN stack during flow processing. - Input and output VLAN translation according to the xbundle type. Push VLAN action support: - Allow ethertype 0x88a8 in VLAN headers and push_vlan action. - Support push_vlan on dot1q packets. Use other_config:vlan-limit in table Open_vSwitch to limit maximum VLANs that can be matched. This allows us to preserve backwards compatibility. Add test cases for VLAN depth limit, Multi-VLAN actions and QinQ VLAN handling Co-authored-by: Thomas F Herbert <thomasfherbert@gmail.com> Signed-off-by: Thomas F Herbert <thomasfherbert@gmail.com> Co-authored-by: Xiao Liang <shaw.leon@gmail.com> Signed-off-by: Xiao Liang <shaw.leon@gmail.com> Signed-off-by: Eric Garver <e@erig.me> Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
29
lib/dpctl.c
29
lib/dpctl.c
@@ -1408,6 +1408,7 @@ dpctl_normalize_actions(int argc, const char *argv[],
|
||||
struct ds s;
|
||||
int left;
|
||||
int i, error;
|
||||
int encaps = 0;
|
||||
|
||||
ds_init(&s);
|
||||
|
||||
@@ -1464,12 +1465,14 @@ dpctl_normalize_actions(int argc, const char *argv[],
|
||||
const struct ovs_action_push_vlan *push;
|
||||
switch(nl_attr_type(a)) {
|
||||
case OVS_ACTION_ATTR_POP_VLAN:
|
||||
flow.vlan_tci = htons(0);
|
||||
flow_pop_vlan(&flow, NULL);
|
||||
continue;
|
||||
|
||||
case OVS_ACTION_ATTR_PUSH_VLAN:
|
||||
flow_push_vlan_uninit(&flow, NULL);
|
||||
push = nl_attr_get_unspec(a, sizeof *push);
|
||||
flow.vlan_tci = push->vlan_tci;
|
||||
flow.vlans[0].tpid = push->vlan_tpid;
|
||||
flow.vlans[0].tci = push->vlan_tci;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1495,12 +1498,22 @@ dpctl_normalize_actions(int argc, const char *argv[],
|
||||
|
||||
sort_output_actions(af->actions.data, af->actions.size);
|
||||
|
||||
if (af->flow.vlan_tci != htons(0)) {
|
||||
dpctl_print(dpctl_p, "vlan(vid=%"PRIu16",pcp=%d): ",
|
||||
vlan_tci_to_vid(af->flow.vlan_tci),
|
||||
vlan_tci_to_pcp(af->flow.vlan_tci));
|
||||
} else {
|
||||
dpctl_print(dpctl_p, "no vlan: ");
|
||||
for (encaps = 0; encaps < FLOW_MAX_VLAN_HEADERS; encaps ++) {
|
||||
union flow_vlan_hdr *vlan = &af->flow.vlans[encaps];
|
||||
if (vlan->tci != htons(0)) {
|
||||
dpctl_print(dpctl_p, "vlan(");
|
||||
if (vlan->tpid != htons(ETH_TYPE_VLAN)) {
|
||||
dpctl_print(dpctl_p, "tpid=0x%04"PRIx16",", vlan->tpid);
|
||||
}
|
||||
dpctl_print(dpctl_p, "vid=%"PRIu16",pcp=%d): ",
|
||||
vlan_tci_to_vid(vlan->tci),
|
||||
vlan_tci_to_pcp(vlan->tci));
|
||||
} else {
|
||||
if (encaps == 0) {
|
||||
dpctl_print(dpctl_p, "no vlan: ");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (eth_type_mpls(af->flow.dl_type)) {
|
||||
|
Reference in New Issue
Block a user