From d9065a90b6b955aa38586c952e8804ca7a22547e Mon Sep 17 00:00:00 2001 From: Pravin Shelar Date: Fri, 9 Sep 2011 18:13:26 -0700 Subject: datapath: VLAN actions should use push/pop semantics Currently the kernel vlan actions mirror those used by OpenFlow 1.0. i.e. MODIFY and STRIP. More flexible approach is to have an action to push a tag and pop a tag off, so that it can handle multiple levels of vlan tags. Plus it aligns with newer version of OpenFlow. As this patch replaces MODIFY with PUSH semantic, action mapping done in userpace is fixed accordingly. GSO handling for multiple levels of vlan tags is also added as Jesse suggested before. Signed-off-by: Pravin B Shelar Acked-by: Jesse Gross --- ofproto/ofproto-dpif-sflow.c | 2 +- ofproto/ofproto-dpif.c | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'ofproto') diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c index d41b7da21..21ef799f7 100644 --- a/ofproto/ofproto-dpif-sflow.c +++ b/ofproto/ofproto-dpif-sflow.c @@ -538,7 +538,7 @@ dpif_sflow_received(struct dpif_sflow *ds, const struct dpif_upcall *upcall, n_outputs++; break; - case OVS_ACTION_ATTR_SET_DL_TCI: + case OVS_ACTION_ATTR_PUSH_VLAN: tci = nl_attr_get_be16(a); switchElem.flowType.sw.dst_vlan = vlan_tci_to_vid(tci); switchElem.flowType.sw.dst_priority = vlan_tci_to_pcp(tci); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 5d93153a1..3074881ea 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -2289,11 +2289,11 @@ facet_account(struct ofproto_dpif *ofproto, struct facet *facet) } break; - case OVS_ACTION_ATTR_STRIP_VLAN: + case OVS_ACTION_ATTR_POP_VLAN: vlan_tci = htons(0); break; - case OVS_ACTION_ATTR_SET_DL_TCI: + case OVS_ACTION_ATTR_PUSH_VLAN: vlan_tci = nl_attr_get_be16(a); break; } @@ -2857,9 +2857,12 @@ commit_odp_actions(struct action_xlate_ctx *ctx) if (base->vlan_tci != flow->vlan_tci) { if (!(flow->vlan_tci & htons(VLAN_CFI))) { - nl_msg_put_flag(odp_actions, OVS_ACTION_ATTR_STRIP_VLAN); + nl_msg_put_flag(odp_actions, OVS_ACTION_ATTR_POP_VLAN); } else { - nl_msg_put_be16(odp_actions, OVS_ACTION_ATTR_SET_DL_TCI, + if (base->vlan_tci != OFP_VLAN_NONE) { + nl_msg_put_flag(odp_actions, OVS_ACTION_ATTR_POP_VLAN); + } + nl_msg_put_be16(odp_actions, OVS_ACTION_ATTR_PUSH_VLAN, flow->vlan_tci & ~htons(VLAN_CFI)); } base->vlan_tci = flow->vlan_tci; @@ -3656,13 +3659,17 @@ compose_actions(struct action_xlate_ctx *ctx, uint16_t vlan, } if (dst->vlan != cur_vlan) { if (dst->vlan == OFP_VLAN_NONE) { - nl_msg_put_flag(ctx->odp_actions, OVS_ACTION_ATTR_STRIP_VLAN); + nl_msg_put_flag(ctx->odp_actions, OVS_ACTION_ATTR_POP_VLAN); } else { ovs_be16 tci; + + if (cur_vlan != OFP_VLAN_NONE) { + nl_msg_put_flag(ctx->odp_actions, OVS_ACTION_ATTR_POP_VLAN); + } tci = htons(dst->vlan & VLAN_VID_MASK); tci |= ctx->flow.vlan_tci & htons(VLAN_PCP_MASK); nl_msg_put_be16(ctx->odp_actions, - OVS_ACTION_ATTR_SET_DL_TCI, tci); + OVS_ACTION_ATTR_PUSH_VLAN, tci); } cur_vlan = dst->vlan; } -- cgit v1.2.1