gtpu: offload RX flow
[vpp.git] / src / plugins / gtpu / gtpu_api.c
index 0c4a315..50eb0a1 100644 (file)
 #define REPLY_MSG_ID_BASE gtm->msg_id_base
 #include <vlibapi/api_helper_macros.h>
 
+static void
+vl_api_gtpu_offload_rx_t_handler (vl_api_gtpu_offload_rx_t * mp)
+{
+  vl_api_gtpu_offload_rx_reply_t *rmp;
+  int rv = 0;
+  vl_api_interface_index_t hw_if_index = ntohl (mp->hw_if_index);
+  vl_api_interface_index_t sw_if_index = ntohl (mp->sw_if_index);
+
+  if (!vnet_hw_interface_is_valid (vnet_get_main (), hw_if_index))
+    {
+      rv = VNET_API_ERROR_NO_SUCH_ENTRY;
+      goto err;
+    }
+  VALIDATE_SW_IF_INDEX (mp);
+
+  u32 t_index = vnet_gtpu_get_tunnel_index (sw_if_index);
+  if (t_index == ~0)
+    {
+      rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
+      goto err;
+    }
+
+  gtpu_main_t *gtm = &gtpu_main;
+  gtpu_tunnel_t *t = pool_elt_at_index (gtm->tunnels, t_index);
+  if (!ip46_address_is_ip4 (&t->dst))
+    {
+      rv = VNET_API_ERROR_INVALID_ADDRESS_FAMILY;
+      goto err;
+    }
+
+  if (t->decap_next_index != GTPU_INPUT_NEXT_IP4_INPUT)
+    {
+      rv = VNET_API_ERROR_INVALID_ADDRESS_FAMILY;
+      goto err;
+    }
+
+  vnet_main_t *vnm = vnet_get_main ();
+  vnet_hw_interface_t *hw_if = vnet_get_hw_interface (vnm, hw_if_index);
+  ip4_main_t *im = &ip4_main;
+  u32 rx_fib_index =
+    vec_elt (im->fib_index_by_sw_if_index, hw_if->sw_if_index);
+
+  if (t->encap_fib_index != rx_fib_index)
+    {
+      rv = VNET_API_ERROR_NO_SUCH_FIB;
+      goto err;
+    }
+
+  if (vnet_gtpu_add_del_rx_flow (hw_if_index, t_index, mp->enable))
+    {
+      rv = VNET_API_ERROR_UNSPECIFIED;
+      goto err;
+    }
+  BAD_SW_IF_INDEX_LABEL;
+err:
+
+  REPLY_MACRO (VL_API_GTPU_OFFLOAD_RX_REPLY);
+}
+
 static void
   vl_api_sw_interface_set_gtpu_bypass_t_handler
   (vl_api_sw_interface_set_gtpu_bypass_t * mp)