From mboxrd@z Thu Jan 1 00:00:00 1970 From: Qi Zhang Subject: [PATCH v4 3/3] ethdev: add VLAN and MPLS actions in flow API Date: Mon, 23 Apr 2018 14:36:10 +0800 Message-ID: <20180423063610.246387-4-qi.z.zhang@intel.com> References: <1522279780-34842-1-git-send-email-qi.z.zhang@intel.com> <20180423063610.246387-1-qi.z.zhang@intel.com> Cc: dev@dpdk.org, declan.doherty@intel.com, sugesh.chandran@intel.com, michael.j.glynn@intel.com, yu.y.liu@intel.com, konstantin.ananyev@intel.com, bruce.richardson@intel.com, Qi Zhang To: adrien.mazarguil@6wind.com Return-path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 522D310BD for ; Mon, 23 Apr 2018 08:36:03 +0200 (CEST) In-Reply-To: <20180423063610.246387-1-qi.z.zhang@intel.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add Openflow complied VLAN and MPLS actions. RTE_FLOW_ACTION_OF_VLAN_POP - pop a VLAN header. RTE_FLOW_ACTION_OF_VLAN_PUSH - push a VLAN header. RTE_FLOW_ACTION_OF_VLAN_VID_SET - set VLAN id. RTE_FLOW_ACTION_OF_VLAN_PCP_SET - set VLAN priority. RTE_FLOW_ACTION_OF_MPLS_POP - pop a MPLS header. RTE_FLOW_ACTION_OF_MPLS_PUSH - push a MPLS header. Suggested-by: Adrien Mazarguil Signed-off-by: Qi Zhang --- app/test-pmd/cmdline_flow.c | 134 ++++++++++++++++++++++++++++ doc/guides/prog_guide/rte_flow.rst | 103 +++++++++++++++++++++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 22 +++++ lib/librte_ether/rte_flow.h | 119 ++++++++++++++++++++++++ 4 files changed, 378 insertions(+) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 18a7b4734..8730c80e5 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -203,6 +203,17 @@ enum index { ACTION_OF_IP_TTL_DEC, ACTION_OF_TTL_COPY_OUT, ACTION_OF_TTL_COPY_IN, + ACTION_OF_VLAN_POP, + ACTION_OF_VLAN_PUSH, + ACTION_OF_VLAN_PUSH_TYPE, + ACTION_OF_VLAN_VID_SET, + ACTION_OF_VLAN_VID_SET_VID, + ACTION_OF_VLAN_PCP_SET, + ACTION_OF_VLAN_PCP_SET_PCP, + ACTION_OF_MPLS_POP, + ACTION_OF_MPLS_POP_TYPE, + ACTION_OF_MPLS_PUSH, + ACTION_OF_MPLS_PUSH_TYPE, }; /** Size of pattern[] field in struct rte_flow_item_raw. */ @@ -682,6 +693,12 @@ static const enum index next_action[] = { ACTION_OF_IP_TTL_DEC, ACTION_OF_TTL_COPY_OUT, ACTION_OF_TTL_COPY_IN, + ACTION_OF_VLAN_POP, + ACTION_OF_VLAN_PUSH, + ACTION_OF_VLAN_VID_SET, + ACTION_OF_VLAN_PCP_SET, + ACTION_OF_MPLS_POP, + ACTION_OF_MPLS_PUSH, ZERO, }; @@ -734,6 +751,36 @@ static const enum index action_of_ip_ttl_set[] = { ZERO, }; +static const enum index action_of_vlan_push[] = { + ACTION_OF_VLAN_PUSH_TYPE, + ACTION_NEXT, + ZERO, +}; + +static const enum index action_of_vlan_vid_set[] = { + ACTION_OF_VLAN_VID_SET_VID, + ACTION_NEXT, + ZERO, +}; + +static const enum index action_of_vlan_pcp_set[] = { + ACTION_OF_VLAN_PCP_SET_PCP, + ACTION_NEXT, + ZERO, +}; + +static const enum index action_of_mpls_pop[] = { + ACTION_OF_MPLS_POP_TYPE, + ACTION_NEXT, + ZERO, +}; + +static const enum index action_of_mpls_push[] = { + ACTION_OF_MPLS_PUSH_TYPE, + ACTION_NEXT, + ZERO, +}; + static int parse_init(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -1943,6 +1990,93 @@ static const struct token token_list[] = { .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), .call = parse_vc, }, + [ACTION_OF_VLAN_POP] = { + .name = "of_vlan_pop", + .help = "pop the outermost VLAN header.", + .priv = PRIV_ACTION(OF_VLAN_POP, 0), + .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), + .call = parse_vc, + }, + [ACTION_OF_VLAN_PUSH] = { + .name = "of_vlan_push", + .help = "push new VLAN header onto the packet", + .priv = PRIV_ACTION(OF_VLAN_PUSH, + sizeof(struct rte_flow_action_of_vlan_push)), + .next = NEXT(action_of_vlan_push), + .call = parse_vc, + }, + [ACTION_OF_VLAN_PUSH_TYPE] = { + .name = "type", + .help = "EtherType of VLAN header", + .next = NEXT(action_of_vlan_push, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_vlan_push, + ether_type)), + .call = parse_vc, + }, + [ACTION_OF_VLAN_VID_SET] = { + .name = "of_vlan_vid_set", + .help = "set VLAN id of an exist or new pushed VLAN header", + .priv = PRIV_ACTION(OF_VLAN_VID_SET, + sizeof(struct rte_flow_action_of_vlan_vid_set)), + .next = NEXT(action_of_vlan_vid_set), + .call = parse_vc, + }, + [ACTION_OF_VLAN_VID_SET_VID] = { + .name = "vid", + .help = "VLAN id", + .next = NEXT(action_of_vlan_vid_set, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_vlan_vid_set, + vid)), + .call = parse_vc, + }, + [ACTION_OF_VLAN_PCP_SET] = { + .name = "of_vlan_pcp_set", + .help = "set priority of an exist or new pushed VLAN header", + .priv = PRIV_ACTION(OF_VLAN_PCP_SET, + sizeof(struct rte_flow_action_of_vlan_pcp_set)), + .next = NEXT(action_of_vlan_pcp_set), + .call = parse_vc, + }, + [ACTION_OF_VLAN_PCP_SET_PCP] = { + .name = "pcp", + .help = "VLAN priority", + .next = NEXT(action_of_vlan_pcp_set, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_vlan_pcp_set, + pcp)), + .call = parse_vc, + }, + [ACTION_OF_MPLS_POP] = { + .name = "of_mpls_pop", + .help = "pop the outermost MPLS header", + .priv = PRIV_ACTION(OF_MPLS_POP, + sizeof(struct rte_flow_action_of_mpls_pop)), + .next = NEXT(action_of_mpls_pop), + .call = parse_vc, + }, + [ACTION_OF_MPLS_POP_TYPE] = { + .name = "type", + .help = "EtherType of MPLS header", + .next = NEXT(action_of_mpls_pop, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_mpls_pop, + ether_type)), + .call = parse_vc, + }, + [ACTION_OF_MPLS_PUSH] = { + .name = "mpls_push", + .help = "push new MPLS header onto the packet", + .priv = PRIV_ACTION(OF_MPLS_PUSH, + sizeof(struct rte_flow_action_of_mpls_push)), + .next = NEXT(action_of_mpls_push), + .call = parse_vc, + }, + [ACTION_OF_MPLS_PUSH_TYPE] = { + .name = "type", + .help = "EtherType of MPLS header", + .next = NEXT(action_of_mpls_push, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY(struct rte_flow_action_of_mpls_push, + ether_type)), + .call = parse_vc, + }, }; /** Remove and return last entry from argument stack. */ diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 7b07fe791..f8387d4e8 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1674,6 +1674,109 @@ required MPLS or IP headers. Comply with OpenFlow action "OFPAT_COPY_TTL_IN". | no properties | +---------------+ +Action: ``OF_VLAN_POP`` +^^^^^^^^^^^^^^^^^^^^^^^ + +Pop the outer-most VLAN header from the packet. Comply with OpenFlow action +"OFPAT_POP_VLAN". + +.. _table_rte_flow_action_of_vlan_pop: + +.. table:: OF_VLAN_POP + + +---------------+ + | Field | + +===============+ + | no properties | + +---------------+ + +Action: ``OF_VLAN_PUSH`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +Push a new VLAN header onto the packet, EtherType 0x8100 or 0x88a8 should +be used. The value of VLAN ID and VLAN priority for the new header is copied +from an exist VLAN header in the packet, they will be set to 0 if no such +VLAN header exist. Comply with OpenFlow action "OFPAT_PUSH_VLAN". + +.. _table_rte_flow_action_of_vlan_push: + +.. table:: OF_VLAN_PUSH + + +----------------+------------------------+ + | Field | Value | + +================+========================+ + | ``ether_type`` | EtherType for VLAN tag | + +----------------+------------------------+ + +Action: ``OF_VLAN_VID_SET`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Set VLAN id of an exist VLAN header or a new pushed VLAN header +(when follow action RTE_FLOW_ACTION_TYPE_OF_VLAN_PUSH). Comply with +OpenFlow action "OFPAT_SET_VLAN_VID". + +.. _table_rte_flow_action_of_vlan_vid_set: + +.. table:: OF_VLAN_VID_SET + + +---------+----------------+ + | Field | Value | + +=========+================+ + | ``vid`` | VLAN id to set | + +---------+----------------+ + +Action: ``OF_VLAN_PCP_SET`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Set 3-bit priority of an exist VLAN header or a new pushed VLAN header +(when follow action RTE_FLOW_ACTION_TYPE_OF_VLAN_PUSH). Comply with +OpenFlow action "OFPAT_SET_VLAN_PCP". + +.. _table_rte_flow_action_of_vlan_pcp_set: + +.. table:: OF_VLAN_PCP_SET + + +---------+-----------------+ + | Field | Value | + +=========+=================+ + | ``pcp`` | priority to set | + +---------+-----------------+ + +Action: ``OF_MPLS_POP`` +^^^^^^^^^^^^^^^^^^^^^^^ + +Pop the outer-most MPLS header from the packet, EtherType is required for +the resulting packet if it is not the last MPLS header be popped, EtherType +must be 0x8847 or 0x8848. Comply with OpenFlow action "OFPAT_POP_MPLS". + +.. _table_rte_flow_action_of_mpls_pop: + +.. table:: OF_MPLS_POP + + +----------------+---------------------------+ + | Field | Value | + +================+===========================+ + | ``ether_type`` | EtherType for MPLS header | + +----------------+---------------------------+ + +Action: ``OF_MPLS_PUSH`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +Push a new MPLS header onto the packet, EtherType 0x8847 or 0x8848 should +be used. The value of MPLS label and traffic class is copied from exist +outermost MPLS header, and TTL is copied from exist outermost MPLS or IP +header, they will be set to 0 if exist packet does not contain required +header. Comply with OpenFlow action "OFPAT_PUSH_MPLS". + +.. _table_rte_flow_action_of_mpls_push: + +.. table:: OF_MPLS_PUSH + + +----------------+---------------------------+ + | Field | Value | + +================+===========================+ + | ``ether_type`` | EtherType for MPLS header | + +----------------+---------------------------+ + Negative types ~~~~~~~~~~~~~~ diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index c1bc53741..df04bc59f 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -3465,6 +3465,28 @@ This section lists supported actions and their attributes, if any. - ``of_ttl_copy_in``: copy TTL inwards (note: OpenFlow comply). +- ``of_vlan_pop``: pop the outermost VLAN header (note: OpenFlow comply). + +- ``of_vlan_push``: push new VLAN header onto the packet (note: OpenFlow comply). + + - ``type``: Ethertype of the VLAN header. + +- ``of_vlan_vid_set``: set VLAN id of a VLAN header (note: OpenFlow comply). + + - ``vid``: VLAN id to set. + +- ``of_vlan_pcp_set``: set priority of a VLAN header (note: OpenFlow comply). + + - ``pcp``: priority to set. + +- ``of_mpls_pop``: pop the outermost MPLS header (note: OpenFlow comply). + + - ``type``: Ethertype of the MPLS header. + +- ``of_mpls_push``: push new MPLS header onto the packet (note: OpenFlow comply). + + - ``type``: Ethertype of the MPLS header. + Destroying flow rules ~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h index 72819abd2..b13913816 100644 --- a/lib/librte_ether/rte_flow.h +++ b/lib/librte_ether/rte_flow.h @@ -1301,6 +1301,65 @@ enum rte_flow_action_type { * No associated configuration structure. */ RTE_FLOW_ACTION_TYPE_OF_TTL_COPY_IN, + + /** + * Pop the outer-most VLAN header from the packet. Comply with OpenFlow + * action "OFPAT_POP_VLAN". + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_OF_VLAN_POP, + + /** + * Push a new VLAN header onto the packet, EtherType 0x8100 or 0x88a8 + * should be used. The value of VLAN ID and VLAN priority for the new + * header is copied from an exist VLAN header in the packet, they will + * be set to 0 if no such VLAN header exist. Comply with OpenFlow action + * "OFPAT_PUSH_VLAN". + * + * See struct rte_flow_action_of_vlan_push. + */ + RTE_FLOW_ACTION_TYPE_OF_VLAN_PUSH, + + /** + * Set VLAN id of an exist VLAN header or a new pushed VLAN header + * (when follow action RTE_FLOW_ACTION_TYPE_OF_VLAN_PUSH). Comply with + * OpenFlow action "OFPAT_SET_VLAN_VID". + * + * See struct rte_flow_action_of_vlan_vid_set. + */ + RTE_FLOW_ACTION_TYPE_OF_VLAN_VID_SET, + + /** + * Set 3-bit priority of an exist VLAN header or a new pushed VLAN + * header (when follow action RTE_FLOW_ACTION_TYPE_OF_VLAN_PUSH). + * Comply with OpenFlow action "OFPAT_SET_VLAN_PCP". + * + * See struct rte_flow_action_of_vlan_pcp_set. + */ + RTE_FLOW_ACTION_TYPE_OF_VLAN_PCP_SET, + + /** + * Pop the outer-most MPLS header from the packet, EtherType is required + * for the resulting packet if it is not the last MPLS header be popped, + * EtherType must be 0x8847 or 0x8848. Comply with OpenFlow action + * "OFPAT_POP_MPLS". + * + * See struct rte_flow_action_of_mpls_pop. + */ + RTE_FLOW_ACTION_TYPE_OF_MPLS_POP, + + /** + * Push a new MPLS header onto the packet, EtherType 0x8847 or 0x8848 + * should be used. The value of MPLS label and traffic class is copied + * from exist outermost MPLS header, and TTL is copied from exist + * outermost MPLS or IP header, they will be set to 0 if exist packet + * does not contain required header. Comply with OpenFlow action + * "OFPAT_PUSH_MPLS". + * + * See struct rte_flow_action_of_mpls_push. + */ + RTE_FLOW_ACTION_TYPE_OF_MPLS_PUSH, }; /** @@ -1460,6 +1519,66 @@ struct rte_flow_action_of_ip_ttl_set { }; /** + * RTE_FLOW_ACTION_TYPE_OF_VLAN_PUSH + * + * Push a new VLAN header onto the packet, EtherType 0x8100 or 0x88a8 + * should be used. The value of VLAN ID and VLAN priority for the new + * header is copied from an exist outermost VLAN header in the packet, + * they will be set to 0 if no such VLAN header exist. Comply with + * OpenFlow action "OFPAT_PUSH_VLAN". + */ +struct rte_flow_action_of_vlan_push { + rte_be16_t ether_type; /**< EtherType for vlan tag. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_VLAN_VID_SET + * + * Set VLAN id of an exist VLAN header or a new pushed VLAN header + * (when follow action RTE_FLOW_ACTION_TYPE_OF_VLAN_PUSH). Comply with + * OpenFlow action "OFPAT_SET_VLAN_VID". + */ +struct rte_flow_action_of_vlan_vid_set { + rte_be16_t vid; /**< VLAN id to set. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_VLAN_PCP_SET + * + * Set 3-bit priority of an exist VLAN header or a new pushed VLAN header + * (when follow action RTE_FLOW_ACTION_TYPE_OF_VLAN_PUSH). Comply with + * OpenFlow action "OFPAT_SET_VLAN_PCP". + */ +struct rte_flow_action_of_vlan_pcp_set { + uint8_t pcp; /**< Vlan priority to set. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_MPLS_POP, + * + * Pop the outer-most MPLS header from the packet, EtherType is + * required for the resulting packet if it is not the last MPLS + * header be popped, EtherType must be 0x8847 or 0x8848. Comply + * with OpenFlow action "OFPAT_POP_MPLS". + */ +struct rte_flow_action_of_mpls_pop { + rte_be16_t ether_type; /**< EtherType for MPLS header */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_MPLS_PUSH, + * + * Push a new MPLS header onto the packet, EtherType 0x8847 or 0x8848 + * should be used. The value of MPLS label and traffic class are copied + * from exist outermost MPLS header, and TTL is copied from exist outermost + * MPLS or IP header, they will be set to 0, if exist packet does not + * contain required header. Comply with OpenFlow action "OFPAT_PUSH_MPLS". + */ +struct rte_flow_action_of_mpls_push { + rte_be16_t ether_type; /**< EtherType for MPLS header */ +}; + +/** * Definition of a single action. * * A list of actions is terminated by a END action. -- 2.13.6