Enabling AES-GCM-128 with 16B ICV support
[vpp.git] / vpp / vpp-api / api.c
index ad5d43b..1da0729 100644 (file)
 #undef __included_bihash_template_h__
 #include <vnet/l2/l2_fib.h>
 
+#if DPDK > 0
+#include <vnet/devices/dpdk/dpdk.h>
+#endif
+
 #if IPSEC > 0
 #include <vnet/ipsec/ipsec.h>
 #include <vnet/ipsec/ikev2.h>
 #include <vnet/dpo/classify_dpo.h>
 #include <vnet/dpo/ip_null_dpo.h>
 
-#define f64_endian(a)
-#define f64_print(a,b)
-
 #define vl_typedefs            /* define message structures */
 #include <vpp-api/vpe_all_api_h.h>
 #undef vl_typedefs
 #include <vpp-api/vpe_all_api_h.h>
 #undef vl_printfun
 
-#define REPLY_MACRO(t)                                          \
-do {                                                            \
-    unix_shared_memory_queue_t * q;                             \
-    rv = vl_msg_api_pd_handler (mp, rv);                        \
-    q = vl_api_client_index_to_input_queue (mp->client_index);  \
-    if (!q)                                                     \
-        return;                                                 \
-                                                                \
-    rmp = vl_msg_api_alloc (sizeof (*rmp));                     \
-    rmp->_vl_msg_id = ntohs((t));                               \
-    rmp->context = mp->context;                                 \
-    rmp->retval = ntohl(rv);                                    \
-                                                                \
-    vl_msg_api_send_shmem (q, (u8 *)&rmp);                      \
-} while(0);
-
-#define REPLY_MACRO2(t, body)                                   \
-do {                                                            \
-    unix_shared_memory_queue_t * q;                             \
-    rv = vl_msg_api_pd_handler (mp, rv);                        \
-    q = vl_api_client_index_to_input_queue (mp->client_index);  \
-    if (!q)                                                     \
-        return;                                                 \
-                                                                \
-    rmp = vl_msg_api_alloc (sizeof (*rmp));                     \
-    rmp->_vl_msg_id = ntohs((t));                               \
-    rmp->context = mp->context;                                 \
-    rmp->retval = ntohl(rv);                                    \
-    do {body;} while (0);                                       \
-    vl_msg_api_send_shmem (q, (u8 *)&rmp);                      \
-} while(0);
-
-#define REPLY_MACRO3(t, n, body)                               \
-do {                                                            \
-    unix_shared_memory_queue_t * q;                             \
-    rv = vl_msg_api_pd_handler (mp, rv);                        \
-    q = vl_api_client_index_to_input_queue (mp->client_index);  \
-    if (!q)                                                     \
-        return;                                                 \
-                                                                \
-    rmp = vl_msg_api_alloc (sizeof (*rmp) + n);                 \
-    rmp->_vl_msg_id = ntohs((t));                               \
-    rmp->context = mp->context;                                 \
-    rmp->retval = ntohl(rv);                                    \
-    do {body;} while (0);                                       \
-    vl_msg_api_send_shmem (q, (u8 *)&rmp);                      \
-} while(0);
-
-#define REPLY_MACRO4(t, n, body)                                \
-do {                                                            \
-    unix_shared_memory_queue_t * q;                             \
-    u8 is_error = 0;                                            \
-    rv = vl_msg_api_pd_handler (mp, rv);                        \
-    q = vl_api_client_index_to_input_queue (mp->client_index);  \
-    if (!q)                                                     \
-        return;                                                 \
-                                                                \
-    rmp = vl_msg_api_alloc_or_null (sizeof (*rmp) + n);         \
-    if (!rmp)                                                   \
-      {                                                         \
-        /* if there isn't enough memory, try to allocate */     \
-        /* some at least for returning an error */              \
-        rmp = vl_msg_api_alloc (sizeof (*rmp));                 \
-        if (!rmp)                                               \
-          return;                                               \
-                                                                \
-        memset (rmp, 0, sizeof (*rmp));                         \
-        rv = VNET_API_ERROR_TABLE_TOO_BIG;                      \
-        is_error = 1;                                           \
-      }                                                         \
-    rmp->_vl_msg_id = ntohs((t));                               \
-    rmp->context = mp->context;                                 \
-    rmp->retval = ntohl(rv);                                    \
-    if (!is_error)                                              \
-      do {body;} while (0);                                     \
-    vl_msg_api_send_shmem (q, (u8 *)&rmp);                      \
-} while(0);
-
-#if (1 || CLIB_DEBUG > 0)      /* "trust, but verify" */
-
-#define VALIDATE_SW_IF_INDEX(mp)                               \
- do { u32 __sw_if_index = ntohl(mp->sw_if_index);              \
-    vnet_main_t *__vnm = vnet_get_main();                       \
-    if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
-                           __sw_if_index)) {                    \
-        rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;                \
-        goto bad_sw_if_index;                                   \
-    }                                                           \
-} while(0);
-
-#define BAD_SW_IF_INDEX_LABEL                   \
-do {                                            \
-bad_sw_if_index:                                \
-    ;                                           \
-} while (0);
-
-#define VALIDATE_RX_SW_IF_INDEX(mp)                            \
- do { u32 __rx_sw_if_index = ntohl(mp->rx_sw_if_index);                \
-    vnet_main_t *__vnm = vnet_get_main();                       \
-    if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
-                           __rx_sw_if_index)) {                        \
-        rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;                \
-        goto bad_rx_sw_if_index;                               \
-    }                                                           \
-} while(0);
-
-#define BAD_RX_SW_IF_INDEX_LABEL               \
-do {                                            \
-bad_rx_sw_if_index:                            \
-    ;                                           \
-} while (0);
-
-#define VALIDATE_TX_SW_IF_INDEX(mp)                            \
- do { u32 __tx_sw_if_index = ntohl(mp->tx_sw_if_index);                \
-    vnet_main_t *__vnm = vnet_get_main();                       \
-    if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
-                           __tx_sw_if_index)) {                        \
-        rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;                \
-        goto bad_tx_sw_if_index;                               \
-    }                                                           \
-} while(0);
-
-#define BAD_TX_SW_IF_INDEX_LABEL               \
-do {                                            \
-bad_tx_sw_if_index:                            \
-    ;                                           \
-} while (0);
-
-#else
-
-#define VALIDATE_SW_IF_INDEX(mp)
-#define BAD_SW_IF_INDEX_LABEL
-#define VALIDATE_RX_SW_IF_INDEX(mp)
-#define BAD_RX_SW_IF_INDEX_LABEL
-#define VALIDATE_TX_SW_IF_INDEX(mp)
-#define BAD_TX_SW_IF_INDEX_LABEL
-
-#endif /* CLIB_DEBUG > 0 */
+#include <vlibapi/api_helper_macros.h>
 
 #define foreach_vpe_api_msg                                             \
 _(WANT_INTERFACE_EVENTS, want_interface_events)                         \
@@ -283,7 +147,6 @@ _(WANT_OAM_EVENTS, want_oam_events)                                     \
 _(OAM_ADD_DEL, oam_add_del)                                             \
 _(SW_INTERFACE_DUMP, sw_interface_dump)                                 \
 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
-_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
 _(IP_ADD_DEL_ROUTE, ip_add_del_route)                                   \
 _(MPLS_ROUTE_ADD_DEL, mpls_route_add_del)                               \
 _(MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind)                             \
@@ -2711,30 +2574,6 @@ vl_api_sw_interface_details_t_handler (vl_api_sw_interface_details_t * mp)
   clib_warning ("BUG");
 }
 
-static void
-vl_api_sw_interface_set_flags_t_handler (vl_api_sw_interface_set_flags_t * mp)
-{
-  vl_api_sw_interface_set_flags_reply_t *rmp;
-  vnet_main_t *vnm = vnet_get_main ();
-  int rv = 0;
-  clib_error_t *error;
-  u16 flags;
-
-  VALIDATE_SW_IF_INDEX (mp);
-
-  flags = mp->admin_up_down ? VNET_SW_INTERFACE_FLAG_ADMIN_UP : 0;
-
-  error = vnet_sw_interface_set_flags (vnm, ntohl (mp->sw_if_index), flags);
-  if (error)
-    {
-      rv = -1;
-      clib_error_report (error);
-    }
-
-  BAD_SW_IF_INDEX_LABEL;
-  REPLY_MACRO (VL_API_SW_INTERFACE_SET_FLAGS_REPLY);
-}
-
 static void
   vl_api_sw_interface_set_mpls_enable_t_handler
   (vl_api_sw_interface_set_mpls_enable_t * mp)
@@ -4840,31 +4679,22 @@ static void vl_api_vxlan_add_del_tunnel_t_handler
       goto out;
     }
   encap_fib_index = p[0];
-
-  /* Check src & dst are different */
-  if ((mp->is_ipv6 && memcmp (mp->src_address, mp->dst_address, 16) == 0) ||
-      (!mp->is_ipv6 && memcmp (mp->src_address, mp->dst_address, 4) == 0))
-    {
-      rv = VNET_API_ERROR_SAME_SRC_DST;
-      goto out;
-    }
   memset (a, 0, sizeof (*a));
 
   a->is_add = mp->is_add;
   a->is_ip6 = mp->is_ipv6;
 
   /* ip addresses sent in network byte order */
-  if (a->is_ip6)
-    {
-      memcpy (&(a->src.ip6), mp->src_address, 16);
-      memcpy (&(a->dst.ip6), mp->dst_address, 16);
-    }
-  else
+  ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &a->dst);
+  ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &a->src);
+
+  /* Check src & dst are different */
+  if (ip46_address_cmp (&a->dst, &a->src) == 0)
     {
-      memcpy (&(a->src.ip4), mp->src_address, 4);
-      memcpy (&(a->dst.ip4), mp->dst_address, 4);
+      rv = VNET_API_ERROR_SAME_SRC_DST;
+      goto out;
     }
-
+  a->mcast_sw_if_index = ntohl (mp->mcast_sw_if_index);
   a->encap_fib_index = encap_fib_index;
   a->decap_next_index = ntohl (mp->decap_next_index);
   a->vni = ntohl (mp->vni);
@@ -4892,16 +4722,17 @@ static void send_vxlan_tunnel_details
   rmp->_vl_msg_id = ntohs (VL_API_VXLAN_TUNNEL_DETAILS);
   if (is_ipv6)
     {
-      memcpy (rmp->src_address, &(t->src.ip6), 16);
-      memcpy (rmp->dst_address, &(t->dst.ip6), 16);
+      memcpy (rmp->src_address, t->src.ip6.as_u8, 16);
+      memcpy (rmp->dst_address, t->dst.ip6.as_u8, 16);
       rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].ft_table_id);
     }
   else
     {
-      memcpy (rmp->src_address, &(t->src.ip4), 4);
-      memcpy (rmp->dst_address, &(t->dst.ip4), 4);
+      memcpy (rmp->src_address, t->src.ip4.as_u8, 4);
+      memcpy (rmp->dst_address, t->dst.ip4.as_u8, 4);
       rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id);
     }
+  rmp->mcast_sw_if_index = htonl (t->mcast_sw_if_index);
   rmp->vni = htonl (t->vni);
   /* decap_next_index is deprecated, hard code to l2-input */
   rmp->decap_next_index = htonl (VXLAN_INPUT_NEXT_L2_INPUT);
@@ -5008,7 +4839,7 @@ static void send_gre_tunnel_details
   clib_memcpy (rmp->src_address, &(t->tunnel_src), 4);
   clib_memcpy (rmp->dst_address, &(t->tunnel_dst), 4);
   rmp->outer_fib_id = htonl (im->fibs[t->outer_fib_index].ft_table_id);
-  rmp->teb = t->teb;
+  rmp->teb = (GRE_TUNNEL_TYPE_TEB == t->type);
   rmp->sw_if_index = htonl (t->sw_if_index);
   rmp->context = context;
 
@@ -6735,7 +6566,7 @@ static void vl_api_ipsec_sad_add_del_entry_t_handler
   sa.protocol = mp->protocol;
   /* check for unsupported crypto-alg */
   if (mp->crypto_algorithm < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
-      mp->crypto_algorithm > IPSEC_CRYPTO_ALG_AES_CBC_256)
+      mp->crypto_algorithm >= IPSEC_CRYPTO_N_ALG)
     {
       clib_warning ("unsupported crypto-alg: '%U'", format_ipsec_crypto_alg,
                    mp->crypto_algorithm);
@@ -6746,14 +6577,48 @@ static void vl_api_ipsec_sad_add_del_entry_t_handler
   sa.crypto_key_len = mp->crypto_key_length;
   clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key));
   /* check for unsupported integ-alg */
+#if DPDK_CRYPTO==1
+  if (mp->integrity_algorithm < IPSEC_INTEG_ALG_NONE ||
+#else
   if (mp->integrity_algorithm < IPSEC_INTEG_ALG_SHA1_96 ||
-      mp->integrity_algorithm > IPSEC_INTEG_ALG_SHA_512_256)
+#endif
+      mp->integrity_algorithm >= IPSEC_INTEG_N_ALG)
     {
       clib_warning ("unsupported integ-alg: '%U'", format_ipsec_integ_alg,
                    mp->integrity_algorithm);
       rv = VNET_API_ERROR_UNIMPLEMENTED;
       goto out;
     }
+
+#if DPDK_CRYPTO==1
+  /*Special cases, aes-gcm-128 encryption */
+  if (mp->crypto_algorithm == IPSEC_CRYPTO_ALG_AES_GCM_128)
+    {
+      if (mp->integrity_algorithm != IPSEC_INTEG_ALG_NONE
+         && mp->integrity_algorithm != IPSEC_INTEG_ALG_AES_GCM_128)
+       {
+         clib_warning
+           ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
+         rv = VNET_API_ERROR_UNIMPLEMENTED;
+         goto out;
+       }
+      else                     /*set integ-alg internally to aes-gcm-128 */
+       mp->integrity_algorithm = IPSEC_INTEG_ALG_AES_GCM_128;
+    }
+  else if (mp->integrity_algorithm == IPSEC_INTEG_ALG_AES_GCM_128)
+    {
+      clib_warning ("unsupported integ-alg: aes-gcm-128");
+      rv = VNET_API_ERROR_UNIMPLEMENTED;
+      goto out;
+    }
+  else if (mp->integrity_algorithm == IPSEC_INTEG_ALG_NONE)
+    {
+      clib_warning ("unsupported integ-alg: none");
+      rv = VNET_API_ERROR_UNIMPLEMENTED;
+      goto out;
+    }
+#endif
+
   sa.integ_alg = mp->integrity_algorithm;
   sa.integ_key_len = mp->integrity_key_length;
   clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key));
@@ -8628,6 +8493,9 @@ vl_api_sw_interface_span_dump_t_handler (vl_api_sw_interface_span_dump_t * mp)
   u32 src_sw_if_index = 0, *dst_sw_if_index;
 
   q = vl_api_client_index_to_input_queue (mp->client_index);
+  if (!q)
+    return;
+
   vec_foreach (dst_sw_if_index, sm->dst_by_src_sw_if_index)
   {
     if (*dst_sw_if_index > 0)
@@ -9163,14 +9031,14 @@ vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp)
   spd_index = p[0];
   spd = pool_elt_at_index (im->spds, spd_index);
 
-  pool_foreach (policy, spd->policies, (
-                                        {
-                                        if (mp->sa_id == ~(0)
-                                            || ntohl (mp->sa_id) ==
-                                            policy->sa_id)
-                                        send_ipsec_spd_details (policy, q,
-                                                                mp->context);}
-               ));
+  /* *INDENT-OFF* */
+  pool_foreach (policy, spd->policies,
+  ({
+    if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id)
+      send_ipsec_spd_details (policy, q,
+                              mp->context);}
+    ));
+  /* *INDENT-ON* */
 #else
   clib_warning ("unimplemented");
 #endif
@@ -9181,10 +9049,12 @@ vl_api_feature_enable_disable_t_handler (vl_api_feature_enable_disable_t * mp)
 {
   vl_api_feature_enable_disable_reply_t *rmp;
   int rv = 0;
+  u8 *arc_name, *feature_name;
 
-  u8 *arc_name = format (0, "%s%c", mp->arc_name, 0);
-  u8 *feature_name = format (0, "%s%c", mp->feature_name, 0);
-  u32 sw_if_index = ntohl (mp->sw_if_index);
+  VALIDATE_SW_IF_INDEX (mp);
+
+  arc_name = format (0, "%s%c", mp->arc_name, 0);
+  feature_name = format (0, "%s%c", mp->feature_name, 0);
 
   vnet_feature_registration_t *reg;
   reg =
@@ -9194,8 +9064,10 @@ vl_api_feature_enable_disable_t_handler (vl_api_feature_enable_disable_t * mp)
     rv = VNET_API_ERROR_INVALID_VALUE;
   else
     {
+      u32 sw_if_index;
       clib_error_t *error = 0;
 
+      sw_if_index = ntohl (mp->sw_if_index);
       if (reg->enable_disable_cb)
        error = reg->enable_disable_cb (sw_if_index, mp->enable);
       if (!error)
@@ -9212,6 +9084,8 @@ vl_api_feature_enable_disable_t_handler (vl_api_feature_enable_disable_t * mp)
   vec_free (feature_name);
   vec_free (arc_name);
 
+  BAD_SW_IF_INDEX_LABEL;
+
   REPLY_MACRO (VL_API_FEATURE_ENABLE_DISABLE_REPLY);
 }