From 7e3389b172375b485028b58d9ee782d6928458d8 Mon Sep 17 00:00:00 2001 From: Qi Zhang Date: Tue, 24 Apr 2018 17:59:02 +0200 Subject: [PATCH] ethdev: add VLAN and MPLS actions to flow API Add support for the following OpenFlow-defined actions: - RTE_FLOW_ACTION_OF_POP_VLAN: pop the outer VLAN tag. - RTE_FLOW_ACTION_OF_PUSH_VLAN: push a new VLAN tag. - RTE_FLOW_ACTION_OF_SET_VLAN_VID: set the 802.1q VLAN id. - RTE_FLOW_ACTION_OF_SET_VLAN_PCP: set the 802.1q priority. - RTE_FLOW_ACTION_OF_POP_MPLS: pop the outer MPLS tag. - RTE_FLOW_ACTION_OF_PUSH_MPLS: push a new MPLS tag. Signed-off-by: Qi Zhang Signed-off-by: Adrien Mazarguil --- app/test-pmd/cmdline_flow.c | 143 ++++++++++++++++++++ app/test-pmd/config.c | 11 ++ doc/guides/prog_guide/rte_flow.rst | 96 +++++++++++++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 22 +++ lib/librte_ether/rte_flow.c | 11 ++ lib/librte_ether/rte_flow.h | 98 ++++++++++++++ 6 files changed, 381 insertions(+) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 5bda08f879..4239602b6b 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -222,6 +222,17 @@ enum index { ACTION_OF_DEC_NW_TTL, ACTION_OF_COPY_TTL_OUT, ACTION_OF_COPY_TTL_IN, + ACTION_OF_POP_VLAN, + ACTION_OF_PUSH_VLAN, + ACTION_OF_PUSH_VLAN_ETHERTYPE, + ACTION_OF_SET_VLAN_VID, + ACTION_OF_SET_VLAN_VID_VLAN_VID, + ACTION_OF_SET_VLAN_PCP, + ACTION_OF_SET_VLAN_PCP_VLAN_PCP, + ACTION_OF_POP_MPLS, + ACTION_OF_POP_MPLS_ETHERTYPE, + ACTION_OF_PUSH_MPLS, + ACTION_OF_PUSH_MPLS_ETHERTYPE, }; /** Maximum size for pattern in struct rte_flow_item_raw. */ @@ -744,6 +755,12 @@ static const enum index next_action[] = { ACTION_OF_DEC_NW_TTL, ACTION_OF_COPY_TTL_OUT, ACTION_OF_COPY_TTL_IN, + ACTION_OF_POP_VLAN, + ACTION_OF_PUSH_VLAN, + ACTION_OF_SET_VLAN_VID, + ACTION_OF_SET_VLAN_PCP, + ACTION_OF_POP_MPLS, + ACTION_OF_PUSH_MPLS, ZERO, }; @@ -809,6 +826,36 @@ static const enum index action_of_set_nw_ttl[] = { ZERO, }; +static const enum index action_of_push_vlan[] = { + ACTION_OF_PUSH_VLAN_ETHERTYPE, + ACTION_NEXT, + ZERO, +}; + +static const enum index action_of_set_vlan_vid[] = { + ACTION_OF_SET_VLAN_VID_VLAN_VID, + ACTION_NEXT, + ZERO, +}; + +static const enum index action_of_set_vlan_pcp[] = { + ACTION_OF_SET_VLAN_PCP_VLAN_PCP, + ACTION_NEXT, + ZERO, +}; + +static const enum index action_of_pop_mpls[] = { + ACTION_OF_POP_MPLS_ETHERTYPE, + ACTION_NEXT, + ZERO, +}; + +static const enum index action_of_push_mpls[] = { + ACTION_OF_PUSH_MPLS_ETHERTYPE, + ACTION_NEXT, + ZERO, +}; + static int parse_init(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -2174,6 +2221,102 @@ static const struct token token_list[] = { .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), .call = parse_vc, }, + [ACTION_OF_POP_VLAN] = { + .name = "of_pop_vlan", + .help = "OpenFlow's OFPAT_POP_VLAN", + .priv = PRIV_ACTION(OF_POP_VLAN, 0), + .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), + .call = parse_vc, + }, + [ACTION_OF_PUSH_VLAN] = { + .name = "of_push_vlan", + .help = "OpenFlow's OFPAT_PUSH_VLAN", + .priv = PRIV_ACTION + (OF_PUSH_VLAN, + sizeof(struct rte_flow_action_of_push_vlan)), + .next = NEXT(action_of_push_vlan), + .call = parse_vc, + }, + [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { + .name = "ethertype", + .help = "EtherType", + .next = NEXT(action_of_push_vlan, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY_HTON + (struct rte_flow_action_of_push_vlan, + ethertype)), + .call = parse_vc_conf, + }, + [ACTION_OF_SET_VLAN_VID] = { + .name = "of_set_vlan_vid", + .help = "OpenFlow's OFPAT_SET_VLAN_VID", + .priv = PRIV_ACTION + (OF_SET_VLAN_VID, + sizeof(struct rte_flow_action_of_set_vlan_vid)), + .next = NEXT(action_of_set_vlan_vid), + .call = parse_vc, + }, + [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { + .name = "vlan_vid", + .help = "VLAN id", + .next = NEXT(action_of_set_vlan_vid, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY_HTON + (struct rte_flow_action_of_set_vlan_vid, + vlan_vid)), + .call = parse_vc_conf, + }, + [ACTION_OF_SET_VLAN_PCP] = { + .name = "of_set_vlan_pcp", + .help = "OpenFlow's OFPAT_SET_VLAN_PCP", + .priv = PRIV_ACTION + (OF_SET_VLAN_PCP, + sizeof(struct rte_flow_action_of_set_vlan_pcp)), + .next = NEXT(action_of_set_vlan_pcp), + .call = parse_vc, + }, + [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { + .name = "vlan_pcp", + .help = "VLAN priority", + .next = NEXT(action_of_set_vlan_pcp, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY_HTON + (struct rte_flow_action_of_set_vlan_pcp, + vlan_pcp)), + .call = parse_vc_conf, + }, + [ACTION_OF_POP_MPLS] = { + .name = "of_pop_mpls", + .help = "OpenFlow's OFPAT_POP_MPLS", + .priv = PRIV_ACTION(OF_POP_MPLS, + sizeof(struct rte_flow_action_of_pop_mpls)), + .next = NEXT(action_of_pop_mpls), + .call = parse_vc, + }, + [ACTION_OF_POP_MPLS_ETHERTYPE] = { + .name = "ethertype", + .help = "EtherType", + .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY_HTON + (struct rte_flow_action_of_pop_mpls, + ethertype)), + .call = parse_vc_conf, + }, + [ACTION_OF_PUSH_MPLS] = { + .name = "of_push_mpls", + .help = "OpenFlow's OFPAT_PUSH_MPLS", + .priv = PRIV_ACTION + (OF_PUSH_MPLS, + sizeof(struct rte_flow_action_of_push_mpls)), + .next = NEXT(action_of_push_mpls), + .call = parse_vc, + }, + [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { + .name = "ethertype", + .help = "EtherType", + .next = NEXT(action_of_push_mpls, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY_HTON + (struct rte_flow_action_of_push_mpls, + ethertype)), + .call = parse_vc_conf, + }, }; /** Remove and return last entry from argument stack. */ diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index b05cd9c44d..0f2425229a 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1114,6 +1114,17 @@ static const struct { MK_FLOW_ACTION(OF_DEC_NW_TTL, 0), MK_FLOW_ACTION(OF_COPY_TTL_OUT, 0), MK_FLOW_ACTION(OF_COPY_TTL_IN, 0), + MK_FLOW_ACTION(OF_POP_VLAN, 0), + MK_FLOW_ACTION(OF_PUSH_VLAN, + sizeof(struct rte_flow_action_of_push_vlan)), + MK_FLOW_ACTION(OF_SET_VLAN_VID, + sizeof(struct rte_flow_action_of_set_vlan_vid)), + MK_FLOW_ACTION(OF_SET_VLAN_PCP, + sizeof(struct rte_flow_action_of_set_vlan_pcp)), + MK_FLOW_ACTION(OF_POP_MPLS, + sizeof(struct rte_flow_action_of_pop_mpls)), + MK_FLOW_ACTION(OF_PUSH_MPLS, + sizeof(struct rte_flow_action_of_push_mpls)), }; /** Compute storage space needed by action configuration and copy it. */ diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 50cb043a62..629cc90a91 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1813,6 +1813,102 @@ next-to-outermost") as defined by the `OpenFlow Switch Specification`_. | no properties | +---------------+ +Action: ``OF_POP_VLAN`` +^^^^^^^^^^^^^^^^^^^^^^^ + +Implements ``OFPAT_POP_VLAN`` ("pop the outer VLAN tag") as defined +by the `OpenFlow Switch Specification`_. + +.. _table_rte_flow_action_of_pop_vlan: + +.. table:: OF_POP_VLAN + + +---------------+ + | Field | + +===============+ + | no properties | + +---------------+ + +Action: ``OF_PUSH_VLAN`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +Implements ``OFPAT_PUSH_VLAN`` ("push a new VLAN tag") as defined by the +`OpenFlow Switch Specification`_. + +.. _table_rte_flow_action_of_push_vlan: + +.. table:: OF_PUSH_VLAN + + +---------------+-----------+ + | Field | Value | + +===============+===========+ + | ``ethertype`` | EtherType | + +---------------+-----------+ + +Action: ``OF_SET_VLAN_VID`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Implements ``OFPAT_SET_VLAN_VID`` ("set the 802.1q VLAN id") as defined by +the `OpenFlow Switch Specification`_. + +.. _table_rte_flow_action_of_set_vlan_vid: + +.. table:: OF_SET_VLAN_VID + + +--------------+---------+ + | Field | Value | + +==============+=========+ + | ``vlan_vid`` | VLAN id | + +--------------+---------+ + +Action: ``OF_SET_VLAN_PCP`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Implements ``OFPAT_SET_LAN_PCP`` ("set the 802.1q priority") as defined by +the `OpenFlow Switch Specification`_. + +.. _table_rte_flow_action_of_set_vlan_pcp: + +.. table:: OF_SET_VLAN_PCP + + +--------------+---------------+ + | Field | Value | + +==============+===============+ + | ``vlan_pcp`` | VLAN priority | + +--------------+---------------+ + +Action: ``OF_POP_MPLS`` +^^^^^^^^^^^^^^^^^^^^^^^ + +Implements ``OFPAT_POP_MPLS`` ("pop the outer MPLS tag") as defined by the +`OpenFlow Switch Specification`_. + +.. _table_rte_flow_action_of_pop_mpls: + +.. table:: OF_POP_MPLS + + +---------------+-----------+ + | Field | Value | + +===============+===========+ + | ``ethertype`` | EtherType | + +---------------+-----------+ + +Action: ``OF_PUSH_MPLS`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +Implements ``OFPAT_PUSH_MPLS`` ("push a new MPLS tag") as defined by the +`OpenFlow Switch Specification`_. + +.. _table_rte_flow_action_of_push_mpls: + +.. table:: OF_PUSH_MPLS + + +---------------+-----------+ + | Field | Value | + +===============+===========+ + | ``ethertype`` | EtherType | + +---------------+-----------+ + Negative types ~~~~~~~~~~~~~~ diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index e2a967b7b4..2edf96dd63 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -3519,6 +3519,28 @@ This section lists supported actions and their attributes, if any. - ``of_copy_ttl_in``: OpenFlow's ``OFPAT_COPY_TTL_IN``. +- ``of_pop_vlan``: OpenFlow's ``OFPAT_POP_VLAN``. + +- ``of_push_vlan``: OpenFlow's ``OFPAT_PUSH_VLAN``. + + - ``ethertype``: Ethertype. + +- ``of_set_vlan_vid``: OpenFlow's ``OFPAT_SET_VLAN_VID``. + + - ``vlan_vid``: VLAN id. + +- ``of_set_vlan_pcp``: OpenFlow's ``OFPAT_SET_VLAN_PCP``. + + - ``vlan_pcp``: VLAN priority. + +- ``of_pop_mpls``: OpenFlow's ``OFPAT_POP_MPLS``. + + - ``ethertype``: Ethertype. + +- ``of_push_mpls``: OpenFlow's ``OFPAT_PUSH_MPLS``. + + - ``ethertype``: Ethertype. + Destroying flow rules ~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c index 7c0ae5b173..4f94ac9b51 100644 --- a/lib/librte_ether/rte_flow.c +++ b/lib/librte_ether/rte_flow.c @@ -98,6 +98,17 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = { MK_FLOW_ACTION(OF_DEC_NW_TTL, 0), MK_FLOW_ACTION(OF_COPY_TTL_OUT, 0), MK_FLOW_ACTION(OF_COPY_TTL_IN, 0), + MK_FLOW_ACTION(OF_POP_VLAN, 0), + MK_FLOW_ACTION(OF_PUSH_VLAN, + sizeof(struct rte_flow_action_of_push_vlan)), + MK_FLOW_ACTION(OF_SET_VLAN_VID, + sizeof(struct rte_flow_action_of_set_vlan_vid)), + MK_FLOW_ACTION(OF_SET_VLAN_PCP, + sizeof(struct rte_flow_action_of_set_vlan_pcp)), + MK_FLOW_ACTION(OF_POP_MPLS, + sizeof(struct rte_flow_action_of_pop_mpls)), + MK_FLOW_ACTION(OF_PUSH_MPLS, + sizeof(struct rte_flow_action_of_push_mpls)), }; static int diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h index b94ffb0c9c..f70056fbd9 100644 --- a/lib/librte_ether/rte_flow.h +++ b/lib/librte_ether/rte_flow.h @@ -1383,6 +1383,54 @@ enum rte_flow_action_type { * No associated configuration structure. */ RTE_FLOW_ACTION_TYPE_OF_COPY_TTL_IN, + + /** + * Implements OFPAT_POP_VLAN ("pop the outer VLAN tag") as defined + * by the OpenFlow Switch Specification. + * + * No associated configuration structure. + */ + RTE_FLOW_ACTION_TYPE_OF_POP_VLAN, + + /** + * Implements OFPAT_PUSH_VLAN ("push a new VLAN tag") as defined by + * the OpenFlow Switch Specification. + * + * See struct rte_flow_action_of_push_vlan. + */ + RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN, + + /** + * Implements OFPAT_SET_VLAN_VID ("set the 802.1q VLAN id") as + * defined by the OpenFlow Switch Specification. + * + * See struct rte_flow_action_of_set_vlan_vid. + */ + RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID, + + /** + * Implements OFPAT_SET_LAN_PCP ("set the 802.1q priority") as + * defined by the OpenFlow Switch Specification. + * + * See struct rte_flow_action_of_set_vlan_pcp. + */ + RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP, + + /** + * Implements OFPAT_POP_MPLS ("pop the outer MPLS tag") as defined + * by the OpenFlow Switch Specification. + * + * See struct rte_flow_action_of_pop_mpls. + */ + RTE_FLOW_ACTION_TYPE_OF_POP_MPLS, + + /** + * Implements OFPAT_PUSH_MPLS ("push a new MPLS tag") as defined by + * the OpenFlow Switch Specification. + * + * See struct rte_flow_action_of_push_mpls. + */ + RTE_FLOW_ACTION_TYPE_OF_PUSH_MPLS, }; /** @@ -1579,6 +1627,56 @@ struct rte_flow_action_of_set_nw_ttl { uint8_t nw_ttl; /**< IP TTL. */ }; +/** + * RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN + * + * Implements OFPAT_PUSH_VLAN ("push a new VLAN tag") as defined by the + * OpenFlow Switch Specification. + */ +struct rte_flow_action_of_push_vlan { + rte_be16_t ethertype; /**< EtherType. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID + * + * Implements OFPAT_SET_VLAN_VID ("set the 802.1q VLAN id") as defined by + * the OpenFlow Switch Specification. + */ +struct rte_flow_action_of_set_vlan_vid { + rte_be16_t vlan_vid; /**< VLAN id. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP + * + * Implements OFPAT_SET_LAN_PCP ("set the 802.1q priority") as defined by + * the OpenFlow Switch Specification. + */ +struct rte_flow_action_of_set_vlan_pcp { + uint8_t vlan_pcp; /**< VLAN priority. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_POP_MPLS + * + * Implements OFPAT_POP_MPLS ("pop the outer MPLS tag") as defined by the + * OpenFlow Switch Specification. + */ +struct rte_flow_action_of_pop_mpls { + rte_be16_t ethertype; /**< EtherType. */ +}; + +/** + * RTE_FLOW_ACTION_TYPE_OF_PUSH_MPLS + * + * Implements OFPAT_PUSH_MPLS ("push a new MPLS tag") as defined by the + * OpenFlow Switch Specification. + */ +struct rte_flow_action_of_push_mpls { + rte_be16_t ethertype; /**< EtherType. */ +}; + /** * Definition of a single action. * -- 2.20.1