#include <vnet/ipsec-gre/ipsec_gre.h>
#include <vnet/flow/flow_report_classify.h>
#include <vnet/ip/punt.h>
+#include <vnet/feature/feature.h>
#undef BIHASH_TYPE
#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) \
_(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) \
_(IP_FIB_DUMP, ip_fib_dump) \
_(IP_FIB_DETAILS, ip_fib_details) \
_(IP6_FIB_DUMP, ip6_fib_dump) \
-_(IP6_FIB_DETAILS, ip6_fib_details)
+_(IP6_FIB_DETAILS, ip6_fib_details) \
+_(FEATURE_ENABLE_DISABLE, feature_enable_disable)
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
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)
else
{
u32 *tp = (u32 *) mp->ip;
- *tp = ntohl (*(u32 *) ip);
+ *tp = *(u32 *) ip;
}
mp->prefix_length = prefix_length;
mp->context = context;
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);
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);
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;
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);
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));
clib_warning ("BUG");
}
+
+static void
+copy_fib_next_hop (fib_route_path_encode_t * api_rpath,
+ vl_api_fib_path_t * fp)
+{
+ int is_ip4;
+
+ if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP4)
+ fp->afi = IP46_TYPE_IP4;
+ else if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP6)
+ fp->afi = IP46_TYPE_IP6;
+ else
+ {
+ is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
+ if (is_ip4)
+ fp->afi = IP46_TYPE_IP4;
+ else
+ fp->afi = IP46_TYPE_IP6;
+ }
+ if (fp->afi == IP46_TYPE_IP4)
+ memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip4,
+ sizeof (api_rpath->rpath.frp_addr.ip4));
+ else
+ memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip6,
+ sizeof (api_rpath->rpath.frp_addr.ip6));
+}
+
static void
send_mpls_fib_details (vpe_api_main_t * am,
unix_shared_memory_queue_t * q,
vl_api_mpls_fib_details_t *mp;
fib_route_path_encode_t *api_rpath;
vl_api_fib_path_t *fp;
- int is_ip4, path_count;
+ int path_count;
path_count = vec_len (api_rpaths);
mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
memset (fp, 0, sizeof (*fp));
fp->weight = htonl (api_rpath->rpath.frp_weight);
fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
- memcpy (fp->next_hop, &api_rpath->rpath.frp_addr, sizeof (fp->next_hop));
- if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP4)
- fp->afi = IP46_TYPE_IP4;
- else if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP6)
- fp->afi = IP46_TYPE_IP6;
- else
- {
- is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
- if (is_ip4)
- fp->afi = IP46_TYPE_IP4;
- else
- fp->afi = IP46_TYPE_IP6;
- }
+ copy_fib_next_hop (api_rpath, fp);
fp++;
}
vl_api_ip_fib_details_t *mp;
fib_route_path_encode_t *api_rpath;
vl_api_fib_path_t *fp;
- int is_ip4, path_count;
+ int path_count;
path_count = vec_len(api_rpaths);
mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
}
fp->weight = htonl(api_rpath->rpath.frp_weight);
fp->sw_if_index = htonl(api_rpath->rpath.frp_sw_if_index);
- memcpy(fp->next_hop, &api_rpath->rpath.frp_addr, sizeof(fp->next_hop));
- if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP4)
- fp->afi = IP46_TYPE_IP4;
- else if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP6)
- fp->afi = IP46_TYPE_IP6;
- else
- {
- is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
- if (is_ip4)
- fp->afi = IP46_TYPE_IP4;
- else
- fp->afi = IP46_TYPE_IP6;
- }
+ copy_fib_next_hop (api_rpath, fp);
fp++;
}
vl_api_ip6_fib_details_t *mp;
fib_route_path_encode_t *api_rpath;
vl_api_fib_path_t *fp;
- int is_ip4, path_count;
+ int path_count;
path_count = vec_len(api_rpaths);
mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
}
fp->weight = htonl(api_rpath->rpath.frp_weight);
fp->sw_if_index = htonl(api_rpath->rpath.frp_sw_if_index);
- memcpy(fp->next_hop, &api_rpath->rpath.frp_addr, sizeof(fp->next_hop));
- if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP4)
- fp->afi = IP46_TYPE_IP4;
- else if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP6)
- fp->afi = IP46_TYPE_IP6;
- else
- {
- is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
- if (is_ip4)
- fp->afi = IP46_TYPE_IP4;
- else
- fp->afi = IP46_TYPE_IP6;
- }
+ copy_fib_next_hop (api_rpath, fp);
fp++;
}
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)
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
}
+static void
+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;
+
+ 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 =
+ vnet_get_feature_reg ((const char *) arc_name,
+ (const char *) feature_name);
+ if (reg == 0)
+ 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)
+ vnet_feature_enable_disable ((const char *) arc_name,
+ (const char *) feature_name,
+ sw_if_index, mp->enable, 0, 0);
+ else
+ {
+ clib_error_report (error);
+ rv = VNET_API_ERROR_CANNOT_ENABLE_DISABLE_FEATURE;
+ }
+ }
+
+ vec_free (feature_name);
+ vec_free (arc_name);
+
+ BAD_SW_IF_INDEX_LABEL;
+
+ REPLY_MACRO (VL_API_FEATURE_ENABLE_DISABLE_REPLY);
+}
+
#define BOUNCE_HANDLER(nn) \
static void vl_api_##nn##_t_handler ( \
vl_api_##nn##_t *mp) \
vl_msg_api_free (mp); \
}
+static void setup_message_id_table (api_main_t * am);
+
/*
* vpe_api_hookup
* Add vpe's API message handlers to the table.
* added the client registration handlers.
* See .../open-repo/vlib/memclnt_vlib.c:memclnt_process()
*/
-
static clib_error_t *
vpe_api_hookup (vlib_main_t * vm)
{
am->is_mp_safe[VL_API_IP_ADD_DEL_ROUTE] = 1;
am->is_mp_safe[VL_API_GET_NODE_GRAPH] = 1;
+ /*
+ * Set up the (msg_name, crc, message-id) table
+ */
+ setup_message_id_table (am);
+
return 0;
}
return (void *) &unformat_vnet_sw_interface;
}
-#undef vl_api_version
-#define vl_api_version(n,v) static u32 vpe_api_version = v;
-#include <vpp-api/vpe.api.h>
-#undef vl_api_version
-
-int
-vl_msg_api_version_check (vl_api_memclnt_create_t * mp)
-{
- if (clib_host_to_net_u32 (mp->api_versions[0]) != vpe_api_version)
- {
- clib_warning ("vpe API mismatch: 0x%08x instead of 0x%08x",
- clib_host_to_net_u32 (mp->api_versions[0]),
- vpe_api_version);
- return -1;
- }
- return 0;
-}
-
static u8 *
format_arp_event (u8 * s, va_list * args)
{
};
/* *INDENT-ON* */
+#define vl_msg_name_crc_list
+#include <vpp-api/vpe_all_api_h.h>
+#undef vl_msg_name_crc_list
+
+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_memclnt;
+ foreach_vl_msg_name_crc_vpe;
+#undef _
+}
+
+
/*
* fd.io coding-style-patch-verification: ON
*