flow: add vnet/flow formal API 68/28068/5
authorChenmin Sun <chenmin.sun@intel.com>
Mon, 27 Jul 2020 09:54:40 +0000 (17:54 +0800)
committerDamjan Marion <dmarion@me.com>
Tue, 25 Aug 2020 12:13:43 +0000 (12:13 +0000)
This patch adds the API for vnet/flow infra.
Currently this API supports the below flow types:
    VNET_FLOW_TYPE_IP4_N_TUPLE
    VNET_FLOW_TYPE_IP6_N_TUPLE
    VNET_FLOW_TYPE_IP4_N_TUPLE_TAGGED
    VNET_FLOW_TYPE_IP6_N_TUPLE_TAGGED
    VNET_FLOW_TYPE_IP4_L2TPV3OIP
    VNET_FLOW_TYPE_IP4_IPSEC_ESP
    VNET_FLOW_TYPE_IP4_IPSEC_AH
    VNET_FLOW_TYPE_IP4_GTPU

All the above flows are tested with Intel E810/X710 NIC

Type: feature

Signed-off-by: Chenmin Sun <chenmin.sun@intel.com>
Change-Id: Icb8ae20cab9bdad6b120dddc3bd4fb1d85634f3f

src/vat/api_format.c
src/vnet/CMakeLists.txt
src/vnet/flow/FEATURE.yaml [new file with mode: 0644]
src/vnet/flow/flow.api [new file with mode: 0644]
src/vnet/flow/flow_api.c [new file with mode: 0644]
src/vnet/flow/flow_types.api [new file with mode: 0644]
src/vnet/ip/ip_types.api
src/vnet/vnet.h
src/vnet/vnet_all_api_h.h
src/vpp/api/vpe.api

index 950096d..fcf0b60 100644 (file)
@@ -5168,7 +5168,8 @@ _(tcp_configure_src_addresses_reply)                      \
 _(session_rule_add_del_reply)                          \
 _(ip_container_proxy_add_del_reply)                     \
 _(output_acl_set_interface_reply)                       \
-_(qos_record_enable_disable_reply)
+_(qos_record_enable_disable_reply)                     \
+_(flow_add_reply)
 
 #define _(n)                                    \
     static void vl_api_##n##_t_handler          \
@@ -5466,7 +5467,8 @@ _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)         \
 _(SESSION_RULES_DETAILS, session_rules_details)                                \
 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)  \
 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
-_(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
+_(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)            \
+_(FLOW_ADD_REPLY, flow_add_reply)   \
 
 #define foreach_standalone_reply_msg                                   \
 _(SW_INTERFACE_EVENT, sw_interface_event)
index fd490d6..737a17e 100644 (file)
@@ -29,6 +29,7 @@ list(APPEND VNET_SOURCES
   devices/netlink.c
   flow/flow.c
   flow/flow_cli.c
+  flow/flow_api.c
   handoff.c
   interface.c
   interface_api.c
@@ -77,6 +78,8 @@ list(APPEND VNET_API_FILES
   interface.api
   interface_types.api
   ip/ip_types.api
+  flow/flow_types.api
+  flow/flow.api
 )
 
 ##############################################################################
diff --git a/src/vnet/flow/FEATURE.yaml b/src/vnet/flow/FEATURE.yaml
new file mode 100644 (file)
index 0000000..cd86429
--- /dev/null
@@ -0,0 +1,25 @@
+---
+name: Flow infrastructure
+maintainer: Damjan Marion <damarion@cisco.com>
+features:
+  - Four APIs are provided - flow_add, flow_del, flow_enable and flow_disable
+  - The below flow types are currently supported:
+      - FLOW_TYPE_IP4_N_TUPLE,
+      - FLOW_TYPE_IP6_N_TUPLE,
+      - FLOW_TYPE_IP4_N_TUPLE_TAGGED,
+      - FLOW_TYPE_IP6_N_TUPLE_TAGGED,
+      - FLOW_TYPE_IP4_L2TPV3OIP,
+      - FLOW_TYPE_IP4_IPSEC_ESP,
+      - FLOW_TYPE_IP4_IPSEC_AH,
+      - FLOW_TYPE_IP4_GTPC,
+      - FLOW_TYPE_IP4_GTPU
+  - 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_DROP
+description: "Flow infrastructure to provide hardware offload capabilities"
+state: development
+properties: [API, CLI]
diff --git a/src/vnet/flow/flow.api b/src/vnet/flow/flow.api
new file mode 100644 (file)
index 0000000..b819847
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2020 Intel and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+option version = "0.0.1";
+
+import "vnet/interface_types.api";
+import "vnet/ip/ip_types.api";
+import "vnet/flow/flow_types.api";
+
+/** \brief flow add request
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param flow - flow rule
+*/
+define flow_add
+{
+  u32 client_index;
+  u32 context;
+  vl_api_flow_rule_t flow;
+  option vat_help = "test flow add [src-ip <ip-addr/mask>] [dst-ip <ip-addr/mask>] [src-port <port/mask>] [dst-port <port/mask>] [proto <ip-proto>]";
+};
+
+/** \brief reply for adding flow
+    @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_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
+    @param flow_index - flow index
+*/
+autoreply define flow_del
+{
+  u32 client_index;
+  u32 context;
+  u32 flow_index;
+  option vat_help = "test flow del index <index>";
+};
+
+/** \brief flow enable request
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param flow_index - flow index
+       @param hw_if_index - hardware interface index
+*/
+autoreply define flow_enable
+{
+  u32 client_index;
+  u32 context;
+  u32 flow_index;
+  u32 hw_if_index;
+  option vat_help = "test flow enable index <index> <interface name>";
+};
+
+/** \brief flow disable request
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param flow_index - flow index
+       @param hw_if_index - hardware interface index
+*/
+autoreply define flow_disable
+{
+  u32 client_index;
+  u32 context;
+  u32 flow_index;
+  u32 hw_if_index;
+  option vat_help = "test flow disable index <index> <interface name>";
+};
+
+/*
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vnet/flow/flow_api.c b/src/vnet/flow/flow_api.c
new file mode 100644 (file)
index 0000000..bd077d7
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ *------------------------------------------------------------------
+ * flow_api.c - flow api
+ *
+ * Copyright (c) 2020 Intel and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *------------------------------------------------------------------
+ */
+
+#include <stddef.h>
+
+#include <vnet/vnet.h>
+#include <vlibmemory/api.h>
+#include <vnet/interface.h>
+#include <vnet/api_errno.h>
+#include <vnet/flow/flow.h>
+#include <vnet/fib/fib_table.h>
+#include <vnet/tunnel/tunnel_types_api.h>
+#include <vnet/ip/ip_types_api.h>
+#include <vnet/vnet_msg_enum.h>
+
+#define vl_typedefs            /* define message structures */
+#include <vnet/vnet_all_api_h.h>
+#undef vl_typedefs
+
+#define vl_endianfun           /* define message structures */
+#include <vnet/vnet_all_api_h.h>
+#undef vl_endianfun
+
+/* instantiate all the print functions we know about */
+#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
+#define vl_printfun
+#include <vnet/vnet_all_api_h.h>
+#undef vl_printfun
+
+#include <vlibapi/api_helper_macros.h>
+
+#define foreach_vpe_api_msg         \
+_(FLOW_ADD, flow_add)               \
+_(FLOW_DEL, flow_del)               \
+_(FLOW_ENABLE, flow_enable)         \
+_(FLOW_DISABLE, flow_disable)
+
+static inline void
+ipv4_addr_and_mask_convert (vl_api_ip4_address_and_mask_t * vl_api_addr,
+                           ip4_address_and_mask_t * vnet_addr)
+{
+  clib_memcpy (vnet_addr, vl_api_addr, sizeof (*vnet_addr));
+}
+
+static inline void
+ipv6_addr_and_mask_convert (vl_api_ip6_address_and_mask_t * vl_api_addr,
+                           ip6_address_and_mask_t * vnet_addr)
+{
+  clib_memcpy (vnet_addr, vl_api_addr, sizeof (*vnet_addr));
+}
+
+static inline void
+port_and_mask_convert (vl_api_ip_port_and_mask_t * vl_api_port,
+                      ip_port_and_mask_t * vnet_port)
+{
+  vnet_port->port = ntohs (vl_api_port->port);
+  vnet_port->mask = ntohs (vl_api_port->mask);
+}
+
+static inline void
+ipv4_n_tuple_flow_convert (vl_api_flow_ip4_n_tuple_t * vl_api_flow,
+                          vnet_flow_ip4_n_tuple_t * f)
+{
+  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
+  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
+
+  port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
+  port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
+
+  f->protocol = (ip_protocol_t) vl_api_flow->protocol;
+}
+
+static void
+ipv6_n_tuple_flow_convert (vl_api_flow_ip6_n_tuple_t * vl_api_flow,
+                          vnet_flow_ip6_n_tuple_t * f)
+{
+  ipv6_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
+  ipv6_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
+
+  port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
+  port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
+
+  f->protocol = (ip_protocol_t) vl_api_flow->protocol;
+}
+
+static inline void
+ipv4_n_tuple_tagged_flow_convert (vl_api_flow_ip4_n_tuple_tagged_t *
+                                 vl_api_flow,
+                                 vnet_flow_ip4_n_tuple_tagged_t * f)
+{
+  return ipv4_n_tuple_flow_convert ((vl_api_flow_ip4_n_tuple_t *) vl_api_flow,
+                                   (vnet_flow_ip4_n_tuple_t *) f);
+}
+
+static inline void
+ipv6_n_tuple_tagged_flow_convert (vl_api_flow_ip6_n_tuple_tagged_t *
+                                 vl_api_flow,
+                                 vnet_flow_ip6_n_tuple_tagged_t * f)
+{
+  return ipv6_n_tuple_flow_convert ((vl_api_flow_ip6_n_tuple_t *) vl_api_flow,
+                                   (vnet_flow_ip6_n_tuple_t *) f);
+}
+
+static inline void
+ipv4_l2tpv3oip_flow_convert (vl_api_flow_ip4_l2tpv3oip_t * vl_api_flow,
+                            vnet_flow_ip4_l2tpv3oip_t * f)
+{
+  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
+  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
+
+  f->protocol = (ip_protocol_t) vl_api_flow->protocol;
+  f->session_id = ntohl (vl_api_flow->session_id);
+}
+
+static inline void
+ipv4_ipsec_esp_flow_convert (vl_api_flow_ip4_ipsec_esp_t * vl_api_flow,
+                            vnet_flow_ip4_ipsec_esp_t * f)
+{
+  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
+  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
+
+  f->protocol = (ip_protocol_t) vl_api_flow->protocol;
+  f->spi = ntohl (vl_api_flow->spi);
+}
+
+static inline void
+ipv4_ipsec_ah_flow_convert (vl_api_flow_ip4_ipsec_ah_t * vl_api_flow,
+                           vnet_flow_ip4_ipsec_ah_t * f)
+{
+  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
+  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
+
+  f->protocol = (ip_protocol_t) vl_api_flow->protocol;
+  f->spi = ntohl (vl_api_flow->spi);
+}
+
+static inline void
+ipv4_gtpu_flow_convert (vl_api_flow_ip4_gtpu_t * vl_api_flow,
+                       vnet_flow_ip4_gtpu_t * f)
+{
+  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
+  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
+
+  port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
+  port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
+
+  f->protocol = (ip_protocol_t) vl_api_flow->protocol;
+  f->teid = ntohl (vl_api_flow->teid);
+}
+
+static inline void
+ipv4_gtpc_flow_convert (vl_api_flow_ip4_gtpc_t * vl_api_flow,
+                       vnet_flow_ip4_gtpc_t * f)
+{
+  ipv4_addr_and_mask_convert (&vl_api_flow->src_addr, &f->src_addr);
+  ipv4_addr_and_mask_convert (&vl_api_flow->dst_addr, &f->dst_addr);
+
+  port_and_mask_convert (&vl_api_flow->src_port, &f->src_port);
+  port_and_mask_convert (&vl_api_flow->dst_port, &f->dst_port);
+
+  f->protocol = (ip_protocol_t) vl_api_flow->protocol;
+  f->teid = ntohl (vl_api_flow->teid);
+}
+
+static void
+vl_api_flow_add_t_handler (vl_api_flow_add_t * mp)
+{
+  vl_api_flow_add_reply_t *rmp;
+  int rv = 0;
+  vnet_flow_t flow;
+  u32 flow_index = ~0;
+  vl_api_flow_rule_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);
+
+  switch (flow.type)
+    {
+    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_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;
+    default:
+      rv = VNET_FLOW_ERROR_NOT_SUPPORTED;
+      goto out;
+      break;
+
+    }
+
+  rv = vnet_flow_add (vnm, &flow, &flow_index);
+
+  goto out;
+out:
+  /* *INDENT-OFF* */
+  REPLY_MACRO2(VL_API_FLOW_ADD_REPLY,
+  ({
+    rmp->flow_index = ntohl (flow_index);
+  }));
+}
+
+static void
+vl_api_flow_del_t_handler (vl_api_flow_del_t * mp)
+{
+  vl_api_flow_add_reply_t *rmp;
+  int rv = 0;
+
+  vnet_main_t *vnm = vnet_get_main();
+  rv = vnet_flow_del(vnm, ntohl(mp->flow_index));
+
+  REPLY_MACRO (VL_API_FLOW_DEL_REPLY);
+}
+
+static void
+vl_api_flow_enable_t_handler (vl_api_flow_enable_t * mp)
+{
+  vl_api_flow_add_reply_t *rmp;
+  int rv = 0;
+
+  vnet_main_t *vnm = vnet_get_main();
+  rv = vnet_flow_enable(vnm, ntohl(mp->flow_index), ntohl(mp->hw_if_index));
+
+  REPLY_MACRO (VL_API_FLOW_ENABLE_REPLY);
+}
+
+static void
+vl_api_flow_disable_t_handler (vl_api_flow_disable_t * mp)
+{
+  vl_api_flow_add_reply_t *rmp;
+  int rv = 0;
+
+  vnet_main_t *vnm = vnet_get_main();
+  rv = vnet_flow_disable(vnm, ntohl(mp->flow_index), ntohl(mp->hw_if_index));
+
+  REPLY_MACRO (VL_API_FLOW_DISABLE_REPLY);
+}
+
+#define vl_msg_name_crc_list
+#include <vnet/flow/flow.api.h>
+#undef vl_msg_name_crc_list
+
+/*
+ * flow_api_hookup
+ * Add vpe's API message handlers to the table.
+ * vlib has already mapped shared memory and
+ * added the client registration handlers.
+ * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
+ */
+
+
+static void
+setup_message_id_table (api_main_t * am)
+{
+#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
+  foreach_vl_msg_name_crc_flow;
+#undef _
+}
+
+static clib_error_t *
+hw_flow_api_hookup (vlib_main_t * vm)
+{
+  api_main_t *am = vlibapi_get_main ();
+
+#define _(N,n)                                                  \
+    vl_msg_api_set_handlers(VL_API_##N, #n,                     \
+                           vl_api_##n##_t_handler,              \
+                           vl_noop_handler,                     \
+                           vl_api_##n##_t_endian,               \
+                           vl_api_##n##_t_print,                \
+                           sizeof(vl_api_##n##_t), 1);
+  foreach_vpe_api_msg;
+#undef _
+
+  /*
+   * Set up the (msg_name, crc, message-id) table
+   */
+  setup_message_id_table (am);
+
+  return 0;
+}
+
+VLIB_API_INIT_FUNCTION (hw_flow_api_hookup);
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vnet/flow/flow_types.api b/src/vnet/flow/flow_types.api
new file mode 100644 (file)
index 0000000..d872d6e
--- /dev/null
@@ -0,0 +1,218 @@
+/* Hey Emacs use -*- mode: C -*- */
+/*
+ * Copyright (c) 2020 Intel and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+option version = "0.0.1";
+import "vnet/ethernet/ethernet_types.api";
+import "vnet/ip/ip_types.api";
+
+enum flow_type
+{
+  FLOW_TYPE_ETHERNET = 1,
+  FLOW_TYPE_IP4_N_TUPLE,
+  FLOW_TYPE_IP6_N_TUPLE,
+  FLOW_TYPE_IP4_N_TUPLE_TAGGED,
+  FLOW_TYPE_IP6_N_TUPLE_TAGGED,
+  FLOW_TYPE_IP4_L2TPV3OIP,
+  FLOW_TYPE_IP4_IPSEC_ESP,
+  FLOW_TYPE_IP4_IPSEC_AH,
+  FLOW_TYPE_IP4_VXLAN,
+  FLOW_TYPE_IP6_VXLAN,
+  FLOW_TYPE_IP4_GTPC,
+  FLOW_TYPE_IP4_GTPU,
+};
+
+enum flow_action
+{
+  FLOW_ACTION_COUNT = 1,
+  FLOW_ACTION_MARK = 2,
+  FLOW_ACTION_BUFFER_ADVANCE = 4,
+  FLOW_ACTION_REDIRECT_TO_NODE = 8,
+  FLOW_ACTION_REDIRECT_TO_QUEUE = 16,
+  FLOW_ACTION_DROP = 64,
+};
+
+typedef ip_port_and_mask
+{
+  u16 port;
+  u16 mask;
+};
+
+typedef flow_ethernet
+{
+  i32 foo;
+  vl_api_mac_address_t src_addr;
+  vl_api_mac_address_t dst_addr;
+  u16 type;
+};
+
+typedef flow_ip4_n_tuple
+{
+  i32 foo;
+  vl_api_ip4_address_and_mask_t src_addr;
+  vl_api_ip4_address_and_mask_t dst_addr;
+  vl_api_ip_port_and_mask_t src_port;
+  vl_api_ip_port_and_mask_t dst_port;
+  vl_api_ip_proto_t protocol;
+};
+
+typedef flow_ip6_n_tuple
+{
+  i32 foo;
+  vl_api_ip6_address_and_mask_t src_addr;
+  vl_api_ip6_address_and_mask_t dst_addr;
+  vl_api_ip_port_and_mask_t src_port;
+  vl_api_ip_port_and_mask_t dst_port;
+  vl_api_ip_proto_t protocol;
+};
+
+typedef flow_ip4_n_tuple_tagged
+{
+  i32 foo;
+  vl_api_ip4_address_and_mask_t src_addr;
+  vl_api_ip4_address_and_mask_t dst_addr;
+  vl_api_ip_port_and_mask_t src_port;
+  vl_api_ip_port_and_mask_t dst_port;
+  vl_api_ip_proto_t protocol;
+};
+
+typedef flow_ip6_n_tuple_tagged
+{
+  i32 foo;
+  vl_api_ip6_address_and_mask_t src_addr;
+  vl_api_ip6_address_and_mask_t dst_addr;
+  vl_api_ip_port_and_mask_t src_port;
+  vl_api_ip_port_and_mask_t dst_port;
+  vl_api_ip_proto_t protocol;
+};
+
+typedef flow_ip4_l2tpv3oip
+{
+  i32 foo;
+  vl_api_ip4_address_and_mask_t src_addr;
+  vl_api_ip4_address_and_mask_t dst_addr;
+  vl_api_ip_port_and_mask_t src_port;
+  vl_api_ip_port_and_mask_t dst_port;
+  vl_api_ip_proto_t protocol;
+  u32 session_id;
+};
+
+typedef flow_ip4_ipsec_esp
+{
+  i32 foo;
+  vl_api_ip4_address_and_mask_t src_addr;
+  vl_api_ip4_address_and_mask_t dst_addr;
+  vl_api_ip_port_and_mask_t src_port;
+  vl_api_ip_port_and_mask_t dst_port;
+  vl_api_ip_proto_t protocol;
+  u32 spi;
+};
+
+typedef flow_ip4_ipsec_ah
+{
+  i32 foo;
+  vl_api_ip4_address_and_mask_t src_addr;
+  vl_api_ip4_address_and_mask_t dst_addr;
+  vl_api_ip_port_and_mask_t src_port;
+  vl_api_ip_port_and_mask_t dst_port;
+  vl_api_ip_proto_t protocol;
+  u32 spi;
+};
+
+typedef flow_ip4_vxlan
+{
+  i32 foo;
+  vl_api_ip4_address_t src_addr;
+  vl_api_ip4_address_t dst_addr;
+  u16 dst_port;
+  u16 vni;
+};
+
+typedef flow_ip6_vxlan
+{
+  i32 foo;
+  vl_api_ip6_address_t src_addr;
+  vl_api_ip6_address_t dst_addr;
+  u16 dst_port;
+  u16 vni;
+};
+
+typedef flow_ip4_gtpc
+{
+  i32 foo;
+  vl_api_ip4_address_and_mask_t src_addr;
+  vl_api_ip4_address_and_mask_t dst_addr;
+  vl_api_ip_port_and_mask_t src_port;
+  vl_api_ip_port_and_mask_t dst_port;
+  vl_api_ip_proto_t protocol;
+  u32 teid;
+};
+
+typedef flow_ip4_gtpu
+{
+  i32 foo;
+  vl_api_ip4_address_and_mask_t src_addr;
+  vl_api_ip4_address_and_mask_t dst_addr;
+  vl_api_ip_port_and_mask_t src_port;
+  vl_api_ip_port_and_mask_t dst_port;
+  vl_api_ip_proto_t protocol;
+  u32 teid;
+};
+
+union flow
+{
+  vl_api_flow_ethernet_t ethernet;
+  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_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_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;
+};
+
+/* main flow struct */
+typedef flow_rule
+{
+  /* flow type */
+  vl_api_flow_type_t type;
+  
+  /* flow index */
+  u32 index;
+  
+  /* bitmap of flow actions (FLOW_ACTION_*) */
+  vl_api_flow_action_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;
+
+  /* buffer offset for FLOW_ACTION_BUFFER_ADVANCE */
+  i32 buffer_advance;
+  
+  /* flow enum */
+  vl_api_flow_t flow;
+};
+
index 72bd39e..8ea7733 100644 (file)
@@ -92,6 +92,18 @@ manual_print typedef prefix {
   u8 len;
 };
 
+typedef ip4_address_and_mask
+{
+  vl_api_ip4_address_t addr;
+  vl_api_ip4_address_t mask;
+};
+
+typedef ip6_address_and_mask
+{
+  vl_api_ip6_address_t addr;
+  vl_api_ip6_address_t mask;
+};
+
 typedef mprefix {
   vl_api_address_family_t af;
   u16 grp_address_length;
index 42f7333..14da23f 100644 (file)
@@ -40,6 +40,8 @@
 #ifndef included_vnet_vnet_h
 #define included_vnet_vnet_h
 
+#include <stddef.h>
+
 #include <vppinfra/types.h>
 
 #include <vppinfra/pcap.h>
index 400caf5..800c5b7 100644 (file)
@@ -73,6 +73,7 @@
 #include <vnet/syslog/syslog.api.h>
 #include <vnet/devices/virtio/virtio.api.h>
 #include <vnet/gso/gso.api.h>
+#include <vnet/flow/flow.api.h>
 
 /*
  * fd.io coding-style-patch-verification: ON
index 3db34fe..9047d0e 100644 (file)
@@ -49,7 +49,8 @@ import "vpp/api/vpe_types.api";
  * DHCP APIs: see ... /src/vnet/dhcp/{dhcp.api, dhcp_api.c}
  * COP APIs: see ... /src/vnet/cop/{cop.api, cop_api.c}
  * POLICER APIs: see ... /src/vnet/policer/{policer.api, policer_api.c}
- * BIER APIs: see ... /src/vnet/policer/{bier.api, bier_api.c}
+ * BIER APIs: see ... /src/vnet/policer/{bier.api, bier_api.c}.
+ * flow APIs: see .../vnet/vnet/flow/{flow.api, flow_api.c}
  */
 
 /** \brief Control ping from client to api server request