From 337960b8a4496e6187478ea6e2bc0ac892a1f7d5 Mon Sep 17 00:00:00 2001 From: Ting Xu Date: Tue, 8 Mar 2022 07:22:56 +0000 Subject: [PATCH] flow: support generic flow and RSS action in vapi Add generic flow type and rss action type to vapi. It is to support creating generic flow rule via vapi. Type: feature Signed-off-by: Ting Xu Change-Id: Ifeaa007679487e02bd2903dc591d80a1caba33bc --- src/vnet/flow/FEATURE.yaml | 4 +- src/vnet/flow/flow.api | 27 ++++++++++- src/vnet/flow/flow_api.c | 95 +++++++++++++++++++++++++++++++++++++ src/vnet/flow/flow_types.api | 109 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 232 insertions(+), 3 deletions(-) diff --git a/src/vnet/flow/FEATURE.yaml b/src/vnet/flow/FEATURE.yaml index a26571c35e8..8633f4febdd 100644 --- a/src/vnet/flow/FEATURE.yaml +++ b/src/vnet/flow/FEATURE.yaml @@ -16,13 +16,15 @@ features: - FLOW_TYPE_IP4_VXLAN, - FLOW_TYPE_IP6_VXLAN, - FLOW_TYPE_IP4_GTPC, - - FLOW_TYPE_IP4_GTPU + - FLOW_TYPE_IP4_GTPU, + - FLOW_TYPE_GENERIC - The below flow actions can be specified for the flows: - FLOW_ACTION_COUNT, - FLOW_ACTION_MARK, - FLOW_ACTION_BUFFER_ADVANCE, - FLOW_ACTION_REDIRECT_TO_NODE, - FLOW_ACTION_REDIRECT_TO_QUEUE, + - FLOW_ACTION_RSS, - FLOW_ACTION_DROP description: "Flow infrastructure to provide hardware offload capabilities" state: development diff --git a/src/vnet/flow/flow.api b/src/vnet/flow/flow.api index 7bb21cdcd72..dff3eec370d 100644 --- a/src/vnet/flow/flow.api +++ b/src/vnet/flow/flow.api @@ -13,7 +13,7 @@ * limitations under the License. */ -option version = "0.0.2"; +option version = "0.0.3"; import "vnet/interface_types.api"; import "vnet/ip/ip_types.api"; @@ -32,6 +32,19 @@ define flow_add option vat_help = "test flow add [src-ip ] [dst-ip ] [src-port ] [dst-port ] [proto ]"; }; +/** \brief flow add request v2 + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param flow - flow rule v2 +*/ +define flow_add_v2 +{ + u32 client_index; + u32 context; + vl_api_flow_rule_v2_t flow; + option vat_help = "test flow add [src-ip ] [dst-ip ] [src-port ] [dst-port ] [proto ] [spec ] [mask ]"; +}; + /** \brief reply for adding flow @param context - sender context, to match reply w/ request @param retval - return code @@ -44,6 +57,18 @@ define flow_add_reply u32 flow_index; }; +/** \brief reply for adding flow v2 + @param context - sender context, to match reply w/ request + @param retval - return code + @param flow_index - flow index, can be used for flow del/enable/disable +*/ +define flow_add_v2_reply +{ + u32 context; + i32 retval; + u32 flow_index; +}; + /** \brief flow del request @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request diff --git a/src/vnet/flow/flow_api.c b/src/vnet/flow/flow_api.c index 6f08f0314a4..0e25fb3017b 100644 --- a/src/vnet/flow/flow_api.c +++ b/src/vnet/flow/flow_api.c @@ -215,6 +215,16 @@ ipv4_gtpc_flow_convert (vl_api_flow_ip4_gtpc_t * vl_api_flow, f->teid = ntohl (vl_api_flow->teid); } +static inline void +generic_flow_convert (vl_api_flow_generic_t *vl_api_flow, + vnet_flow_generic_t *f) +{ + clib_memcpy (f->pattern.spec, vl_api_flow->pattern.spec, + sizeof (vl_api_flow->pattern.spec)); + clib_memcpy (f->pattern.mask, vl_api_flow->pattern.mask, + sizeof (vl_api_flow->pattern.mask)); +} + static void vl_api_flow_add_t_handler (vl_api_flow_add_t * mp) { @@ -297,6 +307,91 @@ out: /* *INDENT-ON* */ } +static void +vl_api_flow_add_v2_t_handler (vl_api_flow_add_v2_t *mp) +{ + vl_api_flow_add_v2_reply_t *rmp; + int rv = 0; + vnet_flow_t flow; + u32 flow_index = ~0; + vl_api_flow_rule_v2_t *f = &mp->flow; + + vnet_main_t *vnm = vnet_get_main (); + + flow.type = ntohl (f->type); + flow.actions = ntohl (f->actions); + flow.mark_flow_id = ntohl (f->mark_flow_id); + flow.redirect_node_index = ntohl (f->redirect_node_index); + flow.redirect_device_input_next_index = + ntohl (f->redirect_device_input_next_index); + flow.redirect_queue = ntohl (f->redirect_queue); + flow.buffer_advance = ntohl (f->buffer_advance); + flow.queue_index = ntohl (f->queue_index); + flow.queue_num = ntohl (f->queue_num); + flow.rss_types = ntohl (f->rss_types); + flow.rss_fun = ntohl (f->rss_fun); + + switch (flow.type) + { + case VNET_FLOW_TYPE_IP4: + ipv4_flow_convert (&f->flow.ip4, &flow.ip4); + break; + case VNET_FLOW_TYPE_IP6: + ipv6_flow_convert (&f->flow.ip6, &flow.ip6); + break; + case VNET_FLOW_TYPE_IP4_N_TUPLE: + ipv4_n_tuple_flow_convert (&f->flow.ip4_n_tuple, &flow.ip4_n_tuple); + break; + case VNET_FLOW_TYPE_IP6_N_TUPLE: + ipv6_n_tuple_flow_convert (&f->flow.ip6_n_tuple, &flow.ip6_n_tuple); + break; + case VNET_FLOW_TYPE_IP4_N_TUPLE_TAGGED: + ipv4_n_tuple_tagged_flow_convert (&f->flow.ip4_n_tuple_tagged, + &flow.ip4_n_tuple_tagged); + break; + case VNET_FLOW_TYPE_IP6_N_TUPLE_TAGGED: + ipv6_n_tuple_tagged_flow_convert (&f->flow.ip6_n_tuple_tagged, + &flow.ip6_n_tuple_tagged); + break; + case VNET_FLOW_TYPE_IP4_L2TPV3OIP: + ipv4_l2tpv3oip_flow_convert (&f->flow.ip4_l2tpv3oip, + &flow.ip4_l2tpv3oip); + break; + case VNET_FLOW_TYPE_IP4_IPSEC_ESP: + ipv4_ipsec_esp_flow_convert (&f->flow.ip4_ipsec_esp, + &flow.ip4_ipsec_esp); + break; + case VNET_FLOW_TYPE_IP4_IPSEC_AH: + ipv4_ipsec_ah_flow_convert (&f->flow.ip4_ipsec_ah, &flow.ip4_ipsec_ah); + break; + case VNET_FLOW_TYPE_IP4_VXLAN: + ipv4_vxlan_flow_convert (&f->flow.ip4_vxlan, &flow.ip4_vxlan); + break; + case VNET_FLOW_TYPE_IP6_VXLAN: + ipv6_vxlan_flow_convert (&f->flow.ip6_vxlan, &flow.ip6_vxlan); + break; + case VNET_FLOW_TYPE_IP4_GTPU: + ipv4_gtpu_flow_convert (&f->flow.ip4_gtpu, &flow.ip4_gtpu); + break; + case VNET_FLOW_TYPE_IP4_GTPC: + ipv4_gtpc_flow_convert (&f->flow.ip4_gtpc, &flow.ip4_gtpc); + break; + case VNET_FLOW_TYPE_GENERIC: + generic_flow_convert (&f->flow.generic, &flow.generic); + break; + default: + rv = VNET_FLOW_ERROR_NOT_SUPPORTED; + goto out; + break; + } + + rv = vnet_flow_add (vnm, &flow, &flow_index); + +out: + REPLY_MACRO2 (VL_API_FLOW_ADD_V2_REPLY, + ({ rmp->flow_index = ntohl (flow_index); })); +} + static void vl_api_flow_del_t_handler (vl_api_flow_del_t * mp) { diff --git a/src/vnet/flow/flow_types.api b/src/vnet/flow/flow_types.api index 86f7ce128cb..1696001d975 100644 --- a/src/vnet/flow/flow_types.api +++ b/src/vnet/flow/flow_types.api @@ -14,7 +14,7 @@ * limitations under the License. */ -option version = "0.0.3"; +option version = "0.0.4"; import "vnet/ethernet/ethernet_types.api"; import "vnet/ip/ip_types.api"; @@ -36,6 +36,25 @@ enum flow_type FLOW_TYPE_IP4_GTPU, }; +enum flow_type_v2 +{ + FLOW_TYPE_ETHERNET_V2 = 1, + FLOW_TYPE_IP4_V2, + FLOW_TYPE_IP6_V2, + FLOW_TYPE_IP4_L2TPV3OIP_V2, + FLOW_TYPE_IP4_IPSEC_ESP_V2, + FLOW_TYPE_IP4_IPSEC_AH_V2, + FLOW_TYPE_IP4_N_TUPLE_V2, + FLOW_TYPE_IP6_N_TUPLE_V2, + FLOW_TYPE_IP4_N_TUPLE_TAGGED_V2, + FLOW_TYPE_IP6_N_TUPLE_TAGGED_V2, + FLOW_TYPE_IP4_VXLAN_V2, + FLOW_TYPE_IP6_VXLAN_V2, + FLOW_TYPE_IP4_GTPC_V2, + FLOW_TYPE_IP4_GTPU_V2, + FLOW_TYPE_GENERIC_V2, +}; + enum flow_action { FLOW_ACTION_COUNT = 1, @@ -46,6 +65,31 @@ enum flow_action FLOW_ACTION_DROP = 64, }; +enum flow_action_v2 +{ + FLOW_ACTION_COUNT_V2 = 1, + FLOW_ACTION_MARK_V2 = 2, + FLOW_ACTION_BUFFER_ADVANCE_V2 = 4, + FLOW_ACTION_REDIRECT_TO_NODE_V2 = 8, + FLOW_ACTION_REDIRECT_TO_QUEUE_V2 = 16, + FLOW_ACTION_RSS_V2 = 32, + FLOW_ACTION_DROP_V2 = 64, +}; + +enum rss_function +{ + RSS_FUNC_DEFAULT, + RSS_FUNC_TOEPLITZ, + RSS_FUNC_SIMPLE_XOR, + RSS_FUNC_SYMMETRIC_TOEPLITZ, +}; + +typedef generic_pattern +{ + u8 spec[1024]; + u8 mask[1024]; +}; + typedef ip_port_and_mask { u16 port; @@ -193,6 +237,12 @@ typedef flow_ip4_gtpu u32 teid; }; +typedef flow_generic +{ + i32 foo; + vl_api_generic_pattern_t pattern; +}; + union flow { vl_api_flow_ethernet_t ethernet; @@ -211,6 +261,25 @@ union flow vl_api_flow_ip4_gtpu_t ip4_gtpu; }; +union flow_v2 +{ + vl_api_flow_ethernet_t ethernet; + vl_api_flow_ip4_t ip4; + vl_api_flow_ip6_t ip6; + vl_api_flow_ip4_l2tpv3oip_t ip4_l2tpv3oip; + vl_api_flow_ip4_ipsec_esp_t ip4_ipsec_esp; + vl_api_flow_ip4_ipsec_ah_t ip4_ipsec_ah; + vl_api_flow_ip4_n_tuple_t ip4_n_tuple; + vl_api_flow_ip6_n_tuple_t ip6_n_tuple; + vl_api_flow_ip4_n_tuple_tagged_t ip4_n_tuple_tagged; + vl_api_flow_ip6_n_tuple_tagged_t ip6_n_tuple_tagged; + vl_api_flow_ip4_vxlan_t ip4_vxlan; + vl_api_flow_ip6_vxlan_t ip6_vxlan; + vl_api_flow_ip4_gtpc_t ip4_gtpc; + vl_api_flow_ip4_gtpu_t ip4_gtpu; + vl_api_flow_generic_t generic; +}; + /* main flow struct */ typedef flow_rule { @@ -240,3 +309,41 @@ typedef flow_rule vl_api_flow_t flow; }; +/* main flow struct */ +typedef flow_rule_v2 +{ + /* flow type */ + vl_api_flow_type_v2_t type; + + /* flow index */ + u32 index; + + /* bitmap of flow actions (FLOW_ACTION_*) */ + vl_api_flow_action_v2_t actions; + + /* flow id for VNET_FLOW_ACTION_MARK */ + u32 mark_flow_id; + + /* node index and next index for FLOW_ACTION_REDIRECT_TO_NODE */ + u32 redirect_node_index; + u32 redirect_device_input_next_index; + + /* queue for FLOW_ACTION_REDIRECT_TO_QUEUE */ + u32 redirect_queue; + + /* start queue index and queue numbers for RSS queue group with FLOW_ACTION_RSS */ + u32 queue_index; + u32 queue_num; + + /* buffer offset for FLOW_ACTION_BUFFER_ADVANCE */ + i32 buffer_advance; + + /* RSS types, including IPv4/IPv6/TCP/UDP... */ + u64 rss_types; + + /* RSS functions, including IPv4/IPv6/TCP/UDP... */ + vl_api_rss_function_t rss_fun; + + /* flow enum */ + vl_api_flow_v2_t flow; +}; -- 2.16.6