*------------------------------------------------------------------
* api.c - message handler registration
*
- * Copyright (c) 2010 Cisco and/or its affiliates.
+ * Copyright (c) 2010-2016 Cisco 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:
#include <vnet/classify/vnet_classify.h>
#include <vnet/classify/input_acl.h>
#include <vnet/classify/policer_classify.h>
+#include <vnet/classify/flow_classify.h>
#include <vnet/l2/l2_classify.h>
#include <vnet/vxlan/vxlan.h>
#include <vnet/gre/gre.h>
#include <vnet/flow/flow_report.h>
#include <vnet/ipsec-gre/ipsec_gre.h>
#include <vnet/flow/flow_report_classify.h>
+#include <vnet/ip/punt.h>
#undef BIHASH_TYPE
#undef __included_bihash_template_h__
#define REPLY_MACRO3(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 (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); \
- do {body;} while (0); \
+ if (!is_error) \
+ do {body;} while (0); \
vl_msg_api_send_shmem (q, (u8 *)&rmp); \
} while(0);
_(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump) \
_(LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump) \
_(LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump) \
+_(LISP_ADJACENCIES_GET, lisp_adjacencies_get) \
_(SHOW_LISP_STATUS, show_lisp_status) \
_(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, \
lisp_add_del_map_request_itr_rlocs) \
_(IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel) \
_(IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump) \
_(DELETE_SUBIF, delete_subif) \
-_(L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite)
+_(L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite) \
+_(PUNT, punt) \
+_(FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface) \
+_(FLOW_CLASSIFY_DUMP, flow_classify_dump)
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
vl_msg_api_send_shmem (q, (u8 *) & rmp);
}
+static void
+lisp_adjacency_copy (vl_api_lisp_adjacency_t * dst, lisp_adjacency_t * adjs)
+{
+ lisp_adjacency_t *adj;
+ vl_api_lisp_adjacency_t a;
+ u32 i, n = vec_len (adjs);
+
+ for (i = 0; i < n; i++)
+ {
+ adj = vec_elt_at_index (adjs, i);
+ memset (&a, 0, sizeof (a));
+
+ switch (gid_address_type (&adj->reid))
+ {
+ case GID_ADDR_IP_PREFIX:
+ a.reid_prefix_len = gid_address_ippref_len (&adj->reid);
+ a.leid_prefix_len = gid_address_ippref_len (&adj->leid);
+ if (gid_address_ip_version (&adj->reid) == IP4)
+ {
+ a.eid_type = 0; /* ipv4 type */
+ clib_memcpy (a.reid, &gid_address_ip (&adj->reid), 4);
+ clib_memcpy (a.leid, &gid_address_ip (&adj->leid), 4);
+ }
+ else
+ {
+ a.eid_type = 1; /* ipv6 type */
+ clib_memcpy (a.reid, &gid_address_ip (&adj->reid), 16);
+ clib_memcpy (a.leid, &gid_address_ip (&adj->leid), 16);
+ }
+ break;
+ case GID_ADDR_MAC:
+ a.eid_type = 2; /* l2 mac type */
+ mac_copy (a.reid, gid_address_mac (&adj->reid));
+ mac_copy (a.leid, gid_address_mac (&adj->leid));
+ break;
+ default:
+ ASSERT (0);
+ }
+ dst[i] = a;
+ }
+}
+
+static void
+vl_api_lisp_adjacencies_get_t_handler (vl_api_lisp_adjacencies_get_t * mp)
+{
+ vl_api_lisp_adjacencies_get_reply_t *rmp = 0;
+ lisp_adjacency_t *adjs = 0;
+ int rv = 0;
+ vl_api_lisp_adjacency_t a;
+ u32 size = ~0;
+ u32 vni = clib_net_to_host_u32 (mp->vni);
+
+ adjs = vnet_lisp_adjacencies_get_by_vni (vni);
+ size = vec_len (adjs) * sizeof (a);
+
+ /* *INDENT-OFF* */
+ REPLY_MACRO3 (VL_API_LISP_ADJACENCIES_GET_REPLY, size,
+ {
+ rmp->count = clib_host_to_net_u32 (vec_len (adjs));
+ lisp_adjacency_copy (rmp->adjacencies, adjs);
+ });
+ /* *INDENT-ON* */
+
+ vec_free (adjs);
+}
+
static void
vl_api_lisp_eid_table_vni_dump_t_handler (vl_api_lisp_eid_table_vni_dump_t *
mp)
REPLY_MACRO (VL_API_L2_INTERFACE_PBB_TAG_REWRITE_REPLY);
}
+static void
+vl_api_punt_t_handler (vl_api_punt_t * mp)
+{
+ vl_api_punt_reply_t *rmp;
+ vlib_main_t *vm = vlib_get_main ();
+ int rv = 0;
+ clib_error_t *error;
+
+ error = vnet_punt_add_del (vm, mp->ipv, mp->l4_protocol,
+ ntohs (mp->l4_port), mp->is_add);
+ if (error)
+ {
+ rv = -1;
+ clib_error_report (error);
+ }
+
+ REPLY_MACRO (VL_API_PUNT_REPLY);
+}
+
+static void
+ vl_api_flow_classify_set_interface_t_handler
+ (vl_api_flow_classify_set_interface_t * mp)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ vl_api_flow_classify_set_interface_reply_t *rmp;
+ int rv;
+ u32 sw_if_index, ip4_table_index, ip6_table_index;
+
+ ip4_table_index = ntohl (mp->ip4_table_index);
+ ip6_table_index = ntohl (mp->ip6_table_index);
+ sw_if_index = ntohl (mp->sw_if_index);
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ rv = vnet_set_flow_classify_intfc (vm, sw_if_index, ip4_table_index,
+ ip6_table_index, mp->is_add);
+
+ BAD_SW_IF_INDEX_LABEL;
+
+ REPLY_MACRO (VL_API_FLOW_CLASSIFY_SET_INTERFACE_REPLY);
+}
+
+static void
+send_flow_classify_details (u32 sw_if_index,
+ u32 table_index,
+ unix_shared_memory_queue_t * q, u32 context)
+{
+ vl_api_flow_classify_details_t *mp;
+
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_FLOW_CLASSIFY_DETAILS);
+ mp->context = context;
+ mp->sw_if_index = htonl (sw_if_index);
+ mp->table_index = htonl (table_index);
+
+ vl_msg_api_send_shmem (q, (u8 *) & mp);
+}
+
+static void
+vl_api_flow_classify_dump_t_handler (vl_api_flow_classify_dump_t * mp)
+{
+ unix_shared_memory_queue_t *q;
+ flow_classify_main_t *pcm = &flow_classify_main;
+ u32 *vec_tbl;
+ int i;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (q == 0)
+ return;
+
+ vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type];
+
+ if (vec_len (vec_tbl))
+ {
+ for (i = 0; i < vec_len (vec_tbl); i++)
+ {
+ if (vec_elt (vec_tbl, i) == ~0)
+ continue;
+
+ send_flow_classify_details (i, vec_elt (vec_tbl, i), q,
+ mp->context);
+ }
+ }
+}
+
#define BOUNCE_HANDLER(nn) \
static void vl_api_##nn##_t_handler ( \
vl_api_##nn##_t *mp) \