*------------------------------------------------------------------
* 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/l2/l2_bd.h>
#include <vnet/l2tp/l2tp.h>
#include <vnet/ip/ip.h>
+#include <vnet/ip/ip6.h>
#include <vnet/unix/tuntap.h>
#include <vnet/unix/tapcli.h>
-#include <vnet/mpls-gre/mpls.h>
+#include <vnet/mpls/mpls.h>
#include <vnet/dhcp/proxy.h>
#include <vnet/dhcp/client.h>
#if IPV6SR > 0
#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/l2/l2_vtr.h>
#include <vnet/vxlan-gpe/vxlan_gpe.h>
#include <vnet/lisp-gpe/lisp_gpe.h>
+#include <vnet/lisp-gpe/lisp_gpe_fwd_entry.h>
+#include <vnet/lisp-gpe/lisp_gpe_tenant.h>
#include <vnet/lisp-cp/control.h>
#include <vnet/map/map.h>
#include <vnet/cop/cop.h>
#include <vnet/devices/netmap/netmap.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__
#include <vnet/l2/l2_bd.h>
#include <vpp-api/vpe_msg_enum.h>
+#include <vnet/fib/ip6_fib.h>
+#include <vnet/fib/ip4_fib.h>
+#include <vnet/dpo/drop_dpo.h>
+#include <vnet/dpo/receive_dpo.h>
+#include <vnet/dpo/lookup_dpo.h>
+#include <vnet/dpo/classify_dpo.h>
+#include <vnet/dpo/ip_null_dpo.h>
+
#define f64_endian(a)
#define f64_print(a,b)
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) \
_(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) \
_(IS_ADDRESS_REACHABLE, is_address_reachable) \
_(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address) \
_(SW_INTERFACE_SET_TABLE, sw_interface_set_table) \
+_(SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable) \
_(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath) \
_(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect) \
_(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge) \
+_(SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe) \
+_(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport) \
+_(SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl) \
_(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del) \
_(BRIDGE_DOMAIN_DUMP, bridge_domain_dump) \
_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
_(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump) \
_(CREATE_VLAN_SUBIF, create_vlan_subif) \
_(CREATE_SUBIF, create_subif) \
-_(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel) \
_(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel) \
_(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2) \
_(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap) \
-_(MPLS_ADD_DEL_DECAP, mpls_add_del_decap) \
_(PROXY_ARP_ADD_DEL, proxy_arp_add_del) \
_(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable) \
_(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del) \
_(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered) \
_(CREATE_LOOPBACK, create_loopback) \
_(CONTROL_PING, control_ping) \
-_(NOPRINT_CONTROL_PING, noprint_control_ping) \
_(CLI_REQUEST, cli_request) \
+_(CLI_INBAND, cli_inband) \
_(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \
_(L2_PATCH_ADD_DEL, l2_patch_add_del) \
_(CLASSIFY_ADD_DEL_TABLE, classify_add_del_table) \
_(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump) \
_(INTERFACE_NAME_RENUMBER, interface_name_renumber) \
_(WANT_IP4_ARP_EVENTS, want_ip4_arp_events) \
+_(WANT_IP6_ND_EVENTS, want_ip6_nd_events) \
_(INPUT_ACL_SET_INTERFACE, input_acl_set_interface) \
_(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
_(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
_(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable) \
_(GET_NODE_GRAPH, get_node_graph) \
_(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats) \
-_(TRACE_PROFILE_ADD, trace_profile_add) \
-_(TRACE_PROFILE_APPLY, trace_profile_apply) \
-_(TRACE_PROFILE_DEL, trace_profile_del) \
+_(IOAM_ENABLE, ioam_enable) \
+_(IOAM_DISABLE, ioam_disable) \
_(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set) \
_(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator) \
_(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid) \
_(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping) \
_(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency) \
_(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set) \
+_(LISP_MAP_REQUEST_MODE, lisp_map_request_mode) \
_(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map) \
_(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump) \
_(LISP_LOCATOR_DUMP, lisp_locator_dump) \
_(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) \
_(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs) \
_(SHOW_LISP_PITR, show_lisp_pitr) \
+_(SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode) \
_(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del) \
_(AF_PACKET_CREATE, af_packet_create) \
_(AF_PACKET_DELETE, af_packet_delete) \
_(POLICER_CLASSIFY_DUMP, policer_classify_dump) \
_(NETMAP_CREATE, netmap_create) \
_(NETMAP_DELETE, netmap_delete) \
-_(MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump) \
-_(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details) \
_(MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump) \
_(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details) \
_(MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump) \
_(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details) \
-_(MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump) \
-_(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details) \
+_(MPLS_FIB_DUMP, mpls_fib_dump) \
+_(MPLS_FIB_DETAILS, mpls_fib_details) \
_(CLASSIFY_TABLE_IDS,classify_table_ids) \
_(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface) \
_(CLASSIFY_TABLE_INFO,classify_table_info) \
_(CLASSIFY_SESSION_DUMP,classify_session_dump) \
_(CLASSIFY_SESSION_DETAILS,classify_session_details) \
-_(IPFIX_ENABLE,ipfix_enable) \
-_(IPFIX_DUMP,ipfix_dump) \
+_(SET_IPFIX_EXPORTER, set_ipfix_exporter) \
+_(IPFIX_EXPORTER_DUMP, ipfix_exporter_dump) \
+_(SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream) \
+_(IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump) \
+_(IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del) \
+_(IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump) \
_(GET_NEXT_INDEX, get_next_index) \
_(PG_CREATE_INTERFACE, pg_create_interface) \
_(PG_CAPTURE, pg_capture) \
ip_source_and_port_range_check_interface_add_del) \
_(IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel) \
_(IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump) \
-_(DELETE_SUBIF, delete_subif)
+_(DELETE_SUBIF, delete_subif) \
+_(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)
/* notifications happen really early in the game */
u8 link_state_process_up;
- /* ip4 pending route adds */
+ /* ip4 and ip6 pending route adds */
pending_route_t *pending_routes;
/* ip4 arp event registration pool */
vl_api_ip4_arp_event_t *arp_events;
+ /* ip6 nd event registration pool */
+ vl_api_ip6_nd_event_t *nd_events;
+
/* convenience */
vlib_main_t *vlib_main;
vnet_main_t *vnet_main;
u32 sw_if_index);
static int arp_change_delete_callback (u32 pool_index, u8 * notused);
+static int nd_change_delete_callback (u32 pool_index, u8 * notused);
/* Clean up all registrations belonging to the indicated client */
REPLY_MACRO (VL_API_WANT_##UCA##_REPLY); \
}
+/* *INDENT-OFF* */
pub_sub_handler (interface_events, INTERFACE_EVENTS)
pub_sub_handler (oam_events, OAM_EVENTS)
+/* *INDENT-ON* */
+
#define RESOLUTION_EVENT 1
#define RESOLUTION_PENDING_EVENT 2
#define IP4_ARP_EVENT 3
- static int ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
- static int ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
- static int mpls_ethernet_add_del_tunnel_2_t_handler
- (vl_api_mpls_ethernet_add_del_tunnel_2_t * mp);
+#define IP6_ND_EVENT 4
+
+static int ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
+
+static int ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
+
+static int mpls_ethernet_add_del_tunnel_2_t_handler
+ (vl_api_mpls_ethernet_add_del_tunnel_2_t * mp);
- void handle_ip4_arp_event (u32 pool_index)
+void
+handle_ip4_arp_event (u32 pool_index)
{
vpe_api_main_t *vam = &vpe_api_main;
vnet_main_t *vnm = vam->vnet_main;
}
}
+void
+handle_ip6_nd_event (u32 pool_index)
+{
+ vpe_api_main_t *vam = &vpe_api_main;
+ vnet_main_t *vnm = vam->vnet_main;
+ vlib_main_t *vm = vam->vlib_main;
+ vl_api_ip6_nd_event_t *event;
+ vl_api_ip6_nd_event_t *mp;
+ unix_shared_memory_queue_t *q;
+
+ /* Client can cancel, die, etc. */
+ if (pool_is_free_index (vam->nd_events, pool_index))
+ return;
+
+ event = pool_elt_at_index (vam->nd_events, pool_index);
+
+ q = vl_api_client_index_to_input_queue (event->client_index);
+ if (!q)
+ {
+ (void) vnet_add_del_ip6_nd_change_event
+ (vnm, nd_change_delete_callback,
+ event->pid, &event->address,
+ vpe_resolver_process_node.index, IP6_ND_EVENT,
+ ~0 /* pool index, notused */ , 0 /* is_add */ );
+ return;
+ }
+
+ if (q->cursize < q->maxsize)
+ {
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ clib_memcpy (mp, event, sizeof (*mp));
+ vl_msg_api_send_shmem (q, (u8 *) & mp);
+ }
+ else
+ {
+ static f64 last_time;
+ /*
+ * Throttle syslog msgs.
+ * It's pretty tempting to just revoke the registration...
+ */
+ if (vlib_time_now (vm) > last_time + 10.0)
+ {
+ clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
+ format_ip6_address, &event->address, event->pid);
+ last_time = vlib_time_now (vm);
+ }
+ }
+}
+
static uword
resolver_process (vlib_main_t * vm,
vlib_node_runtime_t * rt, vlib_frame_t * f)
handle_ip4_arp_event (event_data[i]);
break;
+ case IP6_ND_EVENT:
+ for (i = 0; i < vec_len (event_data); i++)
+ handle_ip6_nd_event (event_data[i]);
+ break;
+
case ~0: /* timeout, retry pending resolutions */
/* *INDENT-OFF* */
pool_foreach (pr, vam->pending_routes,
/* *INDENT-ON* */
static int
-ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
+add_del_route_t_handler (u8 is_multipath,
+ u8 is_add,
+ u8 is_drop,
+ u8 is_unreach,
+ u8 is_prohibit,
+ u8 is_local,
+ u8 is_classify,
+ u32 classify_table_index,
+ u8 is_resolve_host,
+ u8 is_resolve_attached,
+ u32 fib_index,
+ const fib_prefix_t * prefix,
+ u8 next_hop_proto_is_ip4,
+ const ip46_address_t * next_hop,
+ u32 next_hop_sw_if_index,
+ u8 next_hop_fib_index,
+ u32 next_hop_weight, u32 next_hop_out_label)
{
- ip4_main_t *im = &ip4_main;
- ip_lookup_main_t *lm = &im->lookup_main;
vnet_classify_main_t *cm = &vnet_classify_main;
stats_main_t *sm = &stats_main;
- ip4_add_del_route_args_t a;
- ip4_address_t next_hop_address;
- u32 fib_index;
- vpe_api_main_t *vam = &vpe_api_main;
- vnet_main_t *vnm = vam->vnet_main;
- vlib_main_t *vm = vlib_get_main ();
- pending_route_t *pr;
- vl_api_ip_add_del_route_t *adr;
- uword *p;
- clib_error_t *e;
- u32 ai;
- ip_adjacency_t *adj;
- p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
- if (!p)
+ if (is_multipath)
{
- if (mp->create_vrf_if_needed)
- {
- ip4_fib_t *f;
- f = find_ip4_fib_by_table_index_or_id (im, ntohl (mp->vrf_id),
- 0 /* flags */ );
- fib_index = f->index;
- }
- else
- {
- /* No such VRF, and we weren't asked to create one */
- return VNET_API_ERROR_NO_SUCH_FIB;
- }
- }
- else
- {
- fib_index = p[0];
- }
-
- if (~0 != mp->next_hop_sw_if_index &&
- pool_is_free_index (vnm->interface_main.sw_interfaces,
- ntohl (mp->next_hop_sw_if_index)))
- return VNET_API_ERROR_NO_MATCHING_INTERFACE;
-
- clib_memcpy (next_hop_address.data, mp->next_hop_address,
- sizeof (next_hop_address.data));
-
- /* Arp for the next_hop if necessary */
- if (mp->is_add && mp->resolve_if_needed && ~0 != mp->next_hop_sw_if_index)
- {
- u32 lookup_result;
- ip_adjacency_t *adj;
-
- lookup_result = ip4_fib_lookup_with_table
- (im, fib_index, &next_hop_address, 1 /* disable default route */ );
-
- adj = ip_get_adjacency (lm, lookup_result);
-
- if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
- {
- pool_get (vam->pending_routes, pr);
- pr->resolve_type = RESOLVE_IP4_ADD_DEL_ROUTE;
- adr = &pr->r;
- clib_memcpy (adr, mp, sizeof (*adr));
- /* recursion block, "just in case" */
- adr->resolve_if_needed = 0;
- adr->resolve_attempts = ntohl (mp->resolve_attempts);
- vnet_register_ip4_arp_resolution_event
- (vnm, &next_hop_address, vpe_resolver_process_node.index,
- RESOLUTION_EVENT, pr - vam->pending_routes);
-
- vlib_process_signal_event
- (vm, vpe_resolver_process_node.index,
- RESOLUTION_PENDING_EVENT, 0 /* data */ );
-
- /* The interface may be down, etc. */
- e = ip4_probe_neighbor
- (vm, (ip4_address_t *) & (mp->next_hop_address),
- ntohl (mp->next_hop_sw_if_index));
-
- if (e)
- clib_error_report (e);
-
- return VNET_API_ERROR_IN_PROGRESS;
- }
- }
-
- if (mp->is_multipath)
- {
- u32 flags;
+ fib_route_path_flags_t path_flags = FIB_ROUTE_PATH_FLAG_NONE;
dslock (sm, 1 /* release hint */ , 10 /* tag */ );
- if (mp->is_add)
- flags = IP4_ROUTE_FLAG_ADD;
+ if (is_resolve_host)
+ path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
+ if (is_resolve_attached)
+ path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED;
+
+ if (is_add)
+ fib_table_entry_path_add (fib_index,
+ prefix,
+ FIB_SOURCE_API,
+ FIB_ENTRY_FLAG_NONE,
+ (next_hop_proto_is_ip4 ?
+ FIB_PROTOCOL_IP4 :
+ FIB_PROTOCOL_IP6),
+ next_hop,
+ next_hop_sw_if_index,
+ next_hop_fib_index,
+ next_hop_weight,
+ next_hop_out_label, path_flags);
else
- flags = IP4_ROUTE_FLAG_DEL;
-
- if (mp->not_last)
- flags |= IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP;
-
- ip4_add_del_route_next_hop (im, flags,
- (ip4_address_t *) mp->dst_address,
- (u32) mp->dst_address_length,
- (ip4_address_t *) mp->next_hop_address,
- ntohl (mp->next_hop_sw_if_index),
- (u32) mp->next_hop_weight,
- ~0 /* adj_index */ ,
- fib_index);
+ fib_table_entry_path_remove (fib_index,
+ prefix,
+ FIB_SOURCE_API,
+ (next_hop_proto_is_ip4 ?
+ FIB_PROTOCOL_IP4 :
+ FIB_PROTOCOL_IP6),
+ next_hop,
+ next_hop_sw_if_index,
+ next_hop_fib_index,
+ next_hop_weight, path_flags);
+
dsunlock (sm);
return 0;
}
- memset (&a, 0, sizeof (a));
- clib_memcpy (a.dst_address.data, mp->dst_address,
- sizeof (a.dst_address.data));
-
- a.dst_address_length = mp->dst_address_length;
-
- a.flags = (mp->is_add ? IP4_ROUTE_FLAG_ADD : IP4_ROUTE_FLAG_DEL);
- a.flags |= IP4_ROUTE_FLAG_FIB_INDEX;
- a.table_index_or_table_id = fib_index;
- a.add_adj = 0;
- a.n_add_adj = 0;
-
- if (mp->not_last)
- a.flags |= IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP;
-
dslock (sm, 1 /* release hint */ , 2 /* tag */ );
- if (mp->is_add)
+ if (is_drop || is_local || is_classify || is_unreach || is_prohibit)
{
- if (mp->is_drop)
- ai = lm->drop_adj_index;
- else if (mp->is_local)
- ai = lm->local_adj_index;
- else if (mp->is_classify)
+ /*
+ * special route types that link directly to the adj
+ */
+ if (is_add)
{
- if (pool_is_free_index
- (cm->tables, ntohl (mp->classify_table_index)))
+ dpo_id_t dpo = DPO_INVALID;
+ dpo_proto_t dproto;
+
+ dproto = fib_proto_to_dpo (prefix->fp_proto);
+
+ if (is_drop)
+ ip_null_dpo_add_and_lock (dproto, IP_NULL_ACTION_NONE, &dpo);
+ else if (is_local)
+ receive_dpo_add_or_lock (dproto, ~0, NULL, &dpo);
+ else if (is_unreach)
+ ip_null_dpo_add_and_lock (dproto,
+ IP_NULL_ACTION_SEND_ICMP_UNREACH, &dpo);
+ else if (is_prohibit)
+ ip_null_dpo_add_and_lock (dproto,
+ IP_NULL_ACTION_SEND_ICMP_PROHIBIT,
+ &dpo);
+ else if (is_classify)
{
- dsunlock (sm);
- return VNET_API_ERROR_NO_SUCH_TABLE;
- }
- adj = ip_add_adjacency (lm,
- /* template */ 0,
- /* block size */ 1,
- &ai);
+ if (pool_is_free_index (cm->tables,
+ ntohl (classify_table_index)))
+ {
+ dsunlock (sm);
+ return VNET_API_ERROR_NO_SUCH_TABLE;
+ }
- adj->lookup_next_index = IP_LOOKUP_NEXT_CLASSIFY;
- adj->classify.table_index = ntohl (mp->classify_table_index);
- }
- else if (mp->lookup_in_vrf)
- {
- p = hash_get (im->fib_index_by_table_id, ntohl (mp->lookup_in_vrf));
- if (p)
- {
- adj = ip_add_adjacency (lm,
- /* template */ 0,
- /* block size */ 1,
- &ai);
- adj->explicit_fib_index = p[0];
+ dpo_set (&dpo, DPO_CLASSIFY, dproto,
+ classify_dpo_create (prefix->fp_proto,
+ ntohl (classify_table_index)));
}
else
{
dsunlock (sm);
- return VNET_API_ERROR_NO_SUCH_INNER_FIB;
+ return VNET_API_ERROR_NO_SUCH_TABLE;
}
+
+ fib_table_entry_special_dpo_update (fib_index,
+ prefix,
+ FIB_SOURCE_API,
+ FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
+ dpo_reset (&dpo);
}
else
- ai = ip4_route_get_next_hop_adj (im,
- fib_index,
- &next_hop_address,
- ntohl (mp->next_hop_sw_if_index),
- fib_index);
-
- if (ai == lm->miss_adj_index)
{
- dsunlock (sm);
- return VNET_API_ERROR_NO_SUCH_INNER_FIB;
+ fib_table_entry_special_remove (fib_index, prefix, FIB_SOURCE_API);
}
}
else
{
- ip_adjacency_t *adj;
- int disable_default_route = 1;
-
- /* Trying to delete the default route? */
- if (a.dst_address.as_u32 == 0 && a.dst_address_length == 0)
- disable_default_route = 0;
-
- ai = ip4_fib_lookup_with_table
- (im, fib_index, &a.dst_address, disable_default_route);
- if (ai == lm->miss_adj_index)
+ if (is_add)
{
- dsunlock (sm);
- return VNET_API_ERROR_UNKNOWN_DESTINATION;
+ fib_route_path_flags_t path_flags = FIB_ROUTE_PATH_FLAG_NONE;
+
+ if (is_resolve_host)
+ path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
+ if (is_resolve_attached)
+ path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED;
+
+ fib_table_entry_update_one_path (fib_index,
+ prefix,
+ FIB_SOURCE_API,
+ FIB_ENTRY_FLAG_NONE,
+ (next_hop_proto_is_ip4 ?
+ FIB_PROTOCOL_IP4 :
+ FIB_PROTOCOL_IP6),
+ next_hop,
+ next_hop_sw_if_index,
+ next_hop_fib_index,
+ next_hop_weight,
+ next_hop_out_label, path_flags);
}
-
- adj = ip_get_adjacency (lm, ai);
- if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
+ else
{
- dsunlock (sm);
- return VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
+ fib_table_entry_delete (fib_index, prefix, FIB_SOURCE_API);
}
}
- a.adj_index = ai;
- ip4_add_del_route (im, &a);
-
dsunlock (sm);
- return 0;
+ return (0);
}
static int
-ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
+add_del_route_check (fib_protocol_t table_proto,
+ u32 table_id,
+ u32 next_hop_sw_if_index,
+ fib_protocol_t next_hop_table_proto,
+ u32 next_hop_table_id,
+ u8 create_missing_tables,
+ u32 * fib_index, u32 * next_hop_fib_index)
{
- ip6_main_t *im = &ip6_main;
- ip_lookup_main_t *lm = &im->lookup_main;
vnet_main_t *vnm = vnet_get_main ();
- vlib_main_t *vm = vlib_get_main ();
- vpe_api_main_t *vam = &vpe_api_main;
- stats_main_t *sm = &stats_main;
- ip6_add_del_route_args_t a;
- ip6_address_t next_hop_address;
- pending_route_t *pr;
- vl_api_ip_add_del_route_t *adr;
-
- u32 fib_index;
- uword *p;
- clib_error_t *e;
- ip_adjacency_t *adj = 0;
- u32 ai;
-
- p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
- if (!p)
+ *fib_index = fib_table_find (table_proto, ntohl (table_id));
+ if (~0 == *fib_index)
{
- if (mp->create_vrf_if_needed)
+ if (create_missing_tables)
{
- ip6_fib_t *f;
- f = find_ip6_fib_by_table_index_or_id (im, ntohl (mp->vrf_id),
- 0 /* flags */ );
- fib_index = f->index;
+ *fib_index = fib_table_find_or_create_and_lock (table_proto,
+ ntohl (table_id));
}
else
{
return VNET_API_ERROR_NO_SUCH_FIB;
}
}
- else
+
+ if (~0 != ntohl (next_hop_sw_if_index))
{
- fib_index = p[0];
+ if (pool_is_free_index (vnm->interface_main.sw_interfaces,
+ ntohl (next_hop_sw_if_index)))
+ {
+ return VNET_API_ERROR_NO_MATCHING_INTERFACE;
+ }
}
-
- if (~0 != mp->next_hop_sw_if_index &&
- pool_is_free_index (vnm->interface_main.sw_interfaces,
- ntohl (mp->next_hop_sw_if_index)))
- return VNET_API_ERROR_NO_MATCHING_INTERFACE;
-
- clib_memcpy (next_hop_address.as_u8, mp->next_hop_address,
- sizeof (next_hop_address.as_u8));
-
- /* Arp for the next_hop if necessary */
- if (mp->is_add && mp->resolve_if_needed && ~0 != mp->next_hop_sw_if_index)
+ else
{
- u32 lookup_result;
- ip_adjacency_t *adj;
-
- lookup_result = ip6_fib_lookup_with_table
- (im, fib_index, &next_hop_address);
+ *next_hop_fib_index = fib_table_find (next_hop_table_proto,
+ ntohl (next_hop_table_id));
- adj = ip_get_adjacency (lm, lookup_result);
-
- if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
+ if (~0 == *next_hop_fib_index)
{
- pool_get (vam->pending_routes, pr);
- adr = &pr->r;
- pr->resolve_type = RESOLVE_IP6_ADD_DEL_ROUTE;
- clib_memcpy (adr, mp, sizeof (*adr));
- /* recursion block, "just in case" */
- adr->resolve_if_needed = 0;
- adr->resolve_attempts = ntohl (mp->resolve_attempts);
- vnet_register_ip6_neighbor_resolution_event
- (vnm, &next_hop_address, vpe_resolver_process_node.index,
- RESOLUTION_EVENT, pr - vam->pending_routes);
-
- vlib_process_signal_event
- (vm, vpe_resolver_process_node.index,
- RESOLUTION_PENDING_EVENT, 0 /* data */ );
+ if (create_missing_tables)
+ {
+ *next_hop_fib_index =
+ fib_table_find_or_create_and_lock (next_hop_table_proto,
+ ntohl (next_hop_table_id));
+ }
+ else
+ {
+ /* No such VRF, and we weren't asked to create one */
+ return VNET_API_ERROR_NO_SUCH_FIB;
+ }
+ }
+ }
- /* The interface may be down, etc. */
- e = ip6_probe_neighbor
- (vm, (ip6_address_t *) & (mp->next_hop_address),
- ntohl (mp->next_hop_sw_if_index));
+ return (0);
+}
- if (e)
- clib_error_report (e);
+static int
+ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
+{
+ u32 fib_index, next_hop_fib_index;
+ int rv;
- return VNET_API_ERROR_IN_PROGRESS;
- }
- }
+ rv = add_del_route_check (FIB_PROTOCOL_IP4,
+ mp->table_id,
+ mp->next_hop_sw_if_index,
+ FIB_PROTOCOL_IP4,
+ mp->next_hop_table_id,
+ mp->create_vrf_if_needed,
+ &fib_index, &next_hop_fib_index);
- if (mp->is_multipath)
- {
- u32 flags;
+ if (0 != rv)
+ return (rv);
- dslock (sm, 1 /* release hint */ , 11 /* tag */ );
+ fib_prefix_t pfx = {
+ .fp_len = mp->dst_address_length,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ };
+ clib_memcpy (&pfx.fp_addr.ip4, mp->dst_address, sizeof (pfx.fp_addr.ip4));
+
+ ip46_address_t nh;
+ memset (&nh, 0, sizeof (nh));
+ memcpy (&nh.ip4, mp->next_hop_address, sizeof (nh.ip4));
+
+ return (add_del_route_t_handler (mp->is_multipath,
+ mp->is_add,
+ mp->is_drop,
+ mp->is_unreach,
+ mp->is_prohibit,
+ mp->is_local,
+ mp->is_classify,
+ mp->classify_table_index,
+ mp->is_resolve_host,
+ mp->is_resolve_attached,
+ fib_index, &pfx, 1,
+ &nh,
+ ntohl (mp->next_hop_sw_if_index),
+ next_hop_fib_index,
+ mp->next_hop_weight,
+ ntohl (mp->next_hop_out_label)));
+}
- if (mp->is_add)
- flags = IP6_ROUTE_FLAG_ADD;
- else
- flags = IP6_ROUTE_FLAG_DEL;
-
- if (mp->not_last)
- flags |= IP6_ROUTE_FLAG_NOT_LAST_IN_GROUP;
-
- ip6_add_del_route_next_hop (im, flags,
- (ip6_address_t *) mp->dst_address,
- (u32) mp->dst_address_length,
- (ip6_address_t *) mp->next_hop_address,
- ntohl (mp->next_hop_sw_if_index),
- (u32) mp->next_hop_weight,
- ~0 /* adj_index */ ,
- fib_index);
- dsunlock (sm);
- return 0;
- }
+static int
+ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
+{
+ u32 fib_index, next_hop_fib_index;
+ int rv;
- memset (&a, 0, sizeof (a));
- clib_memcpy (a.dst_address.as_u8, mp->dst_address,
- sizeof (a.dst_address.as_u8));
+ rv = add_del_route_check (FIB_PROTOCOL_IP6,
+ mp->table_id,
+ mp->next_hop_sw_if_index,
+ FIB_PROTOCOL_IP6,
+ mp->next_hop_table_id,
+ mp->create_vrf_if_needed,
+ &fib_index, &next_hop_fib_index);
- a.dst_address_length = mp->dst_address_length;
+ if (0 != rv)
+ return (rv);
- a.flags = (mp->is_add ? IP6_ROUTE_FLAG_ADD : IP6_ROUTE_FLAG_DEL);
- a.flags |= IP6_ROUTE_FLAG_FIB_INDEX;
- a.table_index_or_table_id = fib_index;
- a.add_adj = 0;
- a.n_add_adj = 0;
+ fib_prefix_t pfx = {
+ .fp_len = mp->dst_address_length,
+ .fp_proto = FIB_PROTOCOL_IP6,
+ };
+ clib_memcpy (&pfx.fp_addr.ip6, mp->dst_address, sizeof (pfx.fp_addr.ip6));
+
+ ip46_address_t nh;
+ memset (&nh, 0, sizeof (nh));
+ memcpy (&nh.ip6, mp->next_hop_address, sizeof (nh.ip6));
+
+ return (add_del_route_t_handler (mp->is_multipath,
+ mp->is_add,
+ mp->is_drop,
+ mp->is_unreach,
+ mp->is_prohibit,
+ mp->is_local,
+ mp->is_classify,
+ mp->classify_table_index,
+ mp->is_resolve_host,
+ mp->is_resolve_attached,
+ fib_index, &pfx, 0,
+ &nh, ntohl (mp->next_hop_sw_if_index),
+ next_hop_fib_index,
+ mp->next_hop_weight,
+ ntohl (mp->next_hop_out_label)));
+}
- if (mp->not_last)
- a.flags |= IP6_ROUTE_FLAG_NOT_LAST_IN_GROUP;
+static int
+mpls_route_add_del_t_handler (vnet_main_t * vnm,
+ vl_api_mpls_route_add_del_t * mp)
+{
+ u32 fib_index, next_hop_fib_index;
- dslock (sm, 1 /* release hint */ , 3 /* tag */ );
+ int rv;
- if (mp->is_add)
+ fib_prefix_t pfx = {
+ .fp_len = 21,
+ .fp_proto = FIB_PROTOCOL_MPLS,
+ .fp_eos = mp->mr_eos,
+ .fp_label = ntohl (mp->mr_label),
+ };
+ if (pfx.fp_eos)
{
- if (mp->is_drop)
- ai = lm->drop_adj_index;
- else if (mp->is_local)
- ai = lm->local_adj_index;
- else if (mp->lookup_in_vrf)
+ if (mp->mr_next_hop_proto_is_ip4)
{
- p = hash_get (im->fib_index_by_table_id, ntohl (mp->lookup_in_vrf));
- if (p)
- {
- adj = ip_add_adjacency (lm,
- /* template */ 0,
- /* block size */ 1,
- &ai);
- adj->explicit_fib_index = p[0];
- }
- else
- {
- dsunlock (sm);
- return VNET_API_ERROR_NO_SUCH_INNER_FIB;
- }
+ pfx.fp_payload_proto = DPO_PROTO_IP4;
}
else
- ai = ip6_route_get_next_hop_adj (im,
- fib_index,
- &next_hop_address,
- ntohl (mp->next_hop_sw_if_index),
- fib_index);
- if (ai == lm->miss_adj_index)
{
- dsunlock (sm);
- return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
+ pfx.fp_payload_proto = DPO_PROTO_IP6;
}
}
else
{
- ip_adjacency_t *adj;
-
- ai = ip6_fib_lookup_with_table (im, fib_index, &a.dst_address);
- if (ai == lm->miss_adj_index)
- {
- dsunlock (sm);
- return VNET_API_ERROR_UNKNOWN_DESTINATION;
- }
- adj = ip_get_adjacency (lm, ai);
- if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
- {
- dsunlock (sm);
- return VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
- }
+ pfx.fp_payload_proto = DPO_PROTO_MPLS;
}
- a.adj_index = ai;
- ip6_add_del_route (im, &a);
+ rv = add_del_route_check (FIB_PROTOCOL_MPLS,
+ mp->mr_table_id,
+ mp->mr_next_hop_sw_if_index,
+ dpo_proto_to_fib (pfx.fp_payload_proto),
+ mp->mr_next_hop_table_id,
+ mp->mr_create_table_if_needed,
+ &fib_index, &next_hop_fib_index);
- dsunlock (sm);
- return 0;
+ if (0 != rv)
+ return (rv);
+
+ ip46_address_t nh;
+ memset (&nh, 0, sizeof (nh));
+
+ if (mp->mr_next_hop_proto_is_ip4)
+ memcpy (&nh.ip4, mp->mr_next_hop, sizeof (nh.ip4));
+ else
+ memcpy (&nh.ip6, mp->mr_next_hop, sizeof (nh.ip6));
+
+ return (add_del_route_t_handler (mp->mr_is_multipath, mp->mr_is_add, 0, // mp->is_drop,
+ 0, // mp->is_unreach,
+ 0, // mp->is_prohibit,
+ 0, // mp->is_local,
+ mp->mr_is_classify,
+ mp->mr_classify_table_index,
+ mp->mr_is_resolve_host,
+ mp->mr_is_resolve_attached,
+ fib_index, &pfx,
+ mp->mr_next_hop_proto_is_ip4,
+ &nh, ntohl (mp->mr_next_hop_sw_if_index),
+ next_hop_fib_index,
+ mp->mr_next_hop_weight,
+ ntohl (mp->mr_next_hop_out_label)));
}
void
}
void
-api_config_default_ip_route (u8 is_ipv6, u8 is_add, u32 vrf_id,
- u32 sw_if_index, u8 * next_hop_addr)
+vl_api_mpls_route_add_del_t_handler (vl_api_mpls_route_add_del_t * mp)
{
- vl_api_ip_add_del_route_t mp;
+ vl_api_mpls_route_add_del_reply_t *rmp;
+ vnet_main_t *vnm;
int rv;
- memset (&mp, 0, sizeof (vl_api_ip_add_del_route_t));
+ vnm = vnet_get_main ();
+ vnm->api_errno = 0;
- /*
- * Configure default IP route:
- * - ip route add 0.0.0.0/1 via <GW IP>
- * - ip route add 128.0.0.0/1 via <GW IP>
- */
- mp.next_hop_sw_if_index = ntohl (sw_if_index);
- mp.vrf_id = vrf_id;
- mp.resolve_attempts = ~0;
- mp.resolve_if_needed = 1;
- mp.is_add = is_add;
- mp.is_ipv6 = is_ipv6;
- mp.next_hop_weight = 1;
+ rv = mpls_route_add_del_t_handler (vnm, mp);
- clib_memcpy (&mp.next_hop_address[0], next_hop_addr, 16);
+ rv = (rv == 0) ? vnm->api_errno : rv;
- if (is_ipv6)
- rv = ip6_add_del_route_t_handler (&mp);
- else
+ REPLY_MACRO (VL_API_MPLS_ROUTE_ADD_DEL_REPLY);
+}
+
+static int
+mpls_ip_bind_unbind_handler (vnet_main_t * vnm,
+ vl_api_mpls_ip_bind_unbind_t * mp)
+{
+ u32 mpls_fib_index, ip_fib_index;
+
+ mpls_fib_index =
+ fib_table_find (FIB_PROTOCOL_MPLS, ntohl (mp->mb_mpls_table_id));
+
+ if (~0 == mpls_fib_index)
{
- mp.dst_address_length = 1;
+ if (mp->mb_create_table_if_needed)
+ {
+ mpls_fib_index =
+ fib_table_find_or_create_and_lock (FIB_PROTOCOL_MPLS,
+ ntohl (mp->mb_mpls_table_id));
+ }
+ else
+ return VNET_API_ERROR_NO_SUCH_FIB;
+ }
+
+ ip_fib_index = fib_table_find ((mp->mb_is_ip4 ?
+ FIB_PROTOCOL_IP4 :
+ FIB_PROTOCOL_IP6),
+ ntohl (mp->mb_ip_table_id));
+ if (~0 == ip_fib_index)
+ return VNET_API_ERROR_NO_SUCH_FIB;
- mp.dst_address[0] = 0;
- rv = ip4_add_del_route_t_handler (&mp);
+ fib_prefix_t pfx = {
+ .fp_len = mp->mb_address_length,
+ };
- mp.dst_address[0] = 128;
- rv |= ip4_add_del_route_t_handler (&mp);
+ if (mp->mb_is_ip4)
+ {
+ pfx.fp_proto = FIB_PROTOCOL_IP4;
+ clib_memcpy (&pfx.fp_addr.ip4, mp->mb_address,
+ sizeof (pfx.fp_addr.ip4));
+ }
+ else
+ {
+ pfx.fp_proto = FIB_PROTOCOL_IP6;
+ clib_memcpy (&pfx.fp_addr.ip6, mp->mb_address,
+ sizeof (pfx.fp_addr.ip6));
}
- if (rv)
- clib_error_return (0, "failed to config default IP route");
+ if (mp->mb_is_bind)
+ fib_table_entry_local_label_add (ip_fib_index, &pfx,
+ ntohl (mp->mb_label));
+ else
+ fib_table_entry_local_label_remove (ip_fib_index, &pfx,
+ ntohl (mp->mb_label));
+ return (0);
+}
+
+void
+vl_api_mpls_ip_bind_unbind_t_handler (vl_api_mpls_ip_bind_unbind_t * mp)
+{
+ vl_api_mpls_route_add_del_reply_t *rmp;
+ vnet_main_t *vnm;
+ int rv;
+
+ vnm = vnet_get_main ();
+ vnm->api_errno = 0;
+
+ rv = mpls_ip_bind_unbind_handler (vnm, mp);
+
+ rv = (rv == 0) ? vnm->api_errno : rv;
+
+ REPLY_MACRO (VL_API_MPLS_ROUTE_ADD_DEL_REPLY);
}
static void
u32 sw_if_index = ntohl (mp->sw_if_index);
vl_api_sw_interface_set_table_reply_t *rmp;
stats_main_t *sm = &stats_main;
+ u32 fib_index;
VALIDATE_SW_IF_INDEX (mp);
if (mp->is_ipv6)
{
- ip6_main_t *im = &ip6_main;
- ip6_fib_t *fib = find_ip6_fib_by_table_index_or_id (im, table_id,
- IP6_ROUTE_FLAG_TABLE_ID);
- if (fib)
- {
- vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
- im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
- }
- else
- {
- rv = VNET_API_ERROR_NO_SUCH_FIB;
- }
+ fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6,
+ table_id);
+
+ vec_validate (ip6_main.fib_index_by_sw_if_index, sw_if_index);
+ ip6_main.fib_index_by_sw_if_index[sw_if_index] = fib_index;
}
else
{
- ip4_main_t *im = &ip4_main;
- ip4_fib_t *fib = find_ip4_fib_by_table_index_or_id
- (im, table_id, IP4_ROUTE_FLAG_TABLE_ID);
- /* Truthfully this can't fail */
- if (fib)
- {
- vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
- im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
- }
- else
- {
- rv = VNET_API_ERROR_NO_SUCH_FIB;
- }
+ fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4,
+ table_id);
+
+ vec_validate (ip4_main.fib_index_by_sw_if_index, sw_if_index);
+ ip4_main.fib_index_by_sw_if_index[sw_if_index] = fib_index;
}
dsunlock (sm);
BAD_RX_SW_IF_INDEX_LABEL;
BAD_TX_SW_IF_INDEX_LABEL;
- REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_XCONNECT_REPLY);
+ REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_XCONNECT_REPLY);
+}
+
+static void
+ vl_api_sw_interface_set_l2_bridge_t_handler
+ (vl_api_sw_interface_set_l2_bridge_t * mp)
+{
+ bd_main_t *bdm = &bd_main;
+ vl_api_sw_interface_set_l2_bridge_reply_t *rmp;
+ int rv = 0;
+ u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
+ u32 bd_id = ntohl (mp->bd_id);
+ u32 bd_index;
+ u32 bvi = mp->bvi;
+ u8 shg = mp->shg;
+ vlib_main_t *vm = vlib_get_main ();
+ vnet_main_t *vnm = vnet_get_main ();
+
+ VALIDATE_RX_SW_IF_INDEX (mp);
+
+ bd_index = bd_find_or_add_bd_index (bdm, bd_id);
+
+ if (mp->enable)
+ {
+ //VALIDATE_TX_SW_IF_INDEX(mp);
+ rv = set_int_l2_mode (vm, vnm, MODE_L2_BRIDGE,
+ rx_sw_if_index, bd_index, bvi, shg, 0);
+ }
+ else
+ {
+ rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
+ }
+
+ BAD_RX_SW_IF_INDEX_LABEL;
+
+ REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_BRIDGE_REPLY);
+}
+
+static void
+ vl_api_sw_interface_set_dpdk_hqos_pipe_t_handler
+ (vl_api_sw_interface_set_dpdk_hqos_pipe_t * mp)
+{
+ vl_api_sw_interface_set_dpdk_hqos_pipe_reply_t *rmp;
+ int rv = 0;
+
+#if DPDK > 0
+ dpdk_main_t *dm = &dpdk_main;
+ dpdk_device_t *xd;
+
+ u32 sw_if_index = ntohl (mp->sw_if_index);
+ u32 subport = ntohl (mp->subport);
+ u32 pipe = ntohl (mp->pipe);
+ u32 profile = ntohl (mp->profile);
+ vnet_hw_interface_t *hw;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ /* hw_if & dpdk device */
+ hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
+
+ xd = vec_elt_at_index (dm->devices, hw->dev_instance);
+
+ rv = rte_sched_pipe_config (xd->hqos_ht->hqos, subport, pipe, profile);
+
+ BAD_SW_IF_INDEX_LABEL;
+#else
+ clib_warning ("setting HQoS pipe parameters without DPDK not implemented");
+ rv = VNET_API_ERROR_UNIMPLEMENTED;
+#endif /* DPDK */
+
+ REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY);
+}
+
+static void
+ vl_api_sw_interface_set_dpdk_hqos_subport_t_handler
+ (vl_api_sw_interface_set_dpdk_hqos_subport_t * mp)
+{
+ vl_api_sw_interface_set_dpdk_hqos_subport_reply_t *rmp;
+ int rv = 0;
+
+#if DPDK > 0
+ dpdk_main_t *dm = &dpdk_main;
+ dpdk_device_t *xd;
+ struct rte_sched_subport_params p;
+
+ u32 sw_if_index = ntohl (mp->sw_if_index);
+ u32 subport = ntohl (mp->subport);
+ p.tb_rate = ntohl (mp->tb_rate);
+ p.tb_size = ntohl (mp->tb_size);
+ p.tc_rate[0] = ntohl (mp->tc_rate[0]);
+ p.tc_rate[1] = ntohl (mp->tc_rate[1]);
+ p.tc_rate[2] = ntohl (mp->tc_rate[2]);
+ p.tc_rate[3] = ntohl (mp->tc_rate[3]);
+ p.tc_period = ntohl (mp->tc_period);
+
+ vnet_hw_interface_t *hw;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ /* hw_if & dpdk device */
+ hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
+
+ xd = vec_elt_at_index (dm->devices, hw->dev_instance);
+
+ rv = rte_sched_subport_config (xd->hqos_ht->hqos, subport, &p);
+
+ BAD_SW_IF_INDEX_LABEL;
+#else
+ clib_warning
+ ("setting HQoS subport parameters without DPDK not implemented");
+ rv = VNET_API_ERROR_UNIMPLEMENTED;
+#endif /* DPDK */
+
+ REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY);
}
static void
- vl_api_sw_interface_set_l2_bridge_t_handler
- (vl_api_sw_interface_set_l2_bridge_t * mp)
+ vl_api_sw_interface_set_dpdk_hqos_tctbl_t_handler
+ (vl_api_sw_interface_set_dpdk_hqos_tctbl_t * mp)
{
- bd_main_t *bdm = &bd_main;
- vl_api_sw_interface_set_l2_bridge_reply_t *rmp;
+ vl_api_sw_interface_set_dpdk_hqos_tctbl_reply_t *rmp;
int rv = 0;
- u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
- u32 bd_id = ntohl (mp->bd_id);
- u32 bd_index;
- u32 bvi = mp->bvi;
- u8 shg = mp->shg;
- vlib_main_t *vm = vlib_get_main ();
- vnet_main_t *vnm = vnet_get_main ();
- VALIDATE_RX_SW_IF_INDEX (mp);
+#if DPDK > 0
+ dpdk_main_t *dm = &dpdk_main;
+ vlib_thread_main_t *tm = vlib_get_thread_main ();
+ dpdk_device_t *xd;
- bd_index = bd_find_or_add_bd_index (bdm, bd_id);
+ u32 sw_if_index = ntohl (mp->sw_if_index);
+ u32 entry = ntohl (mp->entry);
+ u32 tc = ntohl (mp->tc);
+ u32 queue = ntohl (mp->queue);
+ u32 val, i;
- if (mp->enable)
+ vnet_hw_interface_t *hw;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ /* hw_if & dpdk device */
+ hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
+
+ xd = vec_elt_at_index (dm->devices, hw->dev_instance);
+
+ if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE)
{
- //VALIDATE_TX_SW_IF_INDEX(mp);
- rv = set_int_l2_mode (vm, vnm, MODE_L2_BRIDGE,
- rx_sw_if_index, bd_index, bvi, shg, 0);
+ clib_warning ("invalid traffic class !!");
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto done;
}
- else
+ if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS)
{
- rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
+ clib_warning ("invalid queue !!");
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto done;
}
- BAD_RX_SW_IF_INDEX_LABEL;
+ /* Detect the set of worker threads */
+ uword *p = hash_get_mem (tm->thread_registrations_by_name, "workers");
- REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_BRIDGE_REPLY);
+ if (p == 0)
+ {
+ clib_warning ("worker thread registration AWOL !!");
+ rv = VNET_API_ERROR_INVALID_VALUE_2;
+ goto done;
+ }
+
+ vlib_thread_registration_t *tr = (vlib_thread_registration_t *) p[0];
+ int worker_thread_first = tr->first_index;
+ int worker_thread_count = tr->count;
+
+ val = tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
+ for (i = 0; i < worker_thread_count; i++)
+ xd->hqos_wt[worker_thread_first + i].hqos_tc_table[entry] = val;
+
+ BAD_SW_IF_INDEX_LABEL;
+done:
+#else
+ clib_warning ("setting HQoS DSCP table entry without DPDK not implemented");
+ rv = VNET_API_ERROR_UNIMPLEMENTED;
+#endif /* DPDK */
+
+ REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY);
}
static void
/* *INDENT-ON* */
}
-static void
-vl_api_mpls_gre_add_del_tunnel_t_handler (vl_api_mpls_gre_add_del_tunnel_t *
- mp)
-{
- vl_api_mpls_gre_add_del_tunnel_reply_t *rmp;
- int rv = 0;
- stats_main_t *sm = &stats_main;
- u32 tunnel_sw_if_index = ~0;
-
- dslock (sm, 1 /* release hint */ , 5 /* tag */ );
-
- rv = vnet_mpls_gre_add_del_tunnel ((ip4_address_t *) (mp->src_address),
- (ip4_address_t *) (mp->dst_address),
- (ip4_address_t *) (mp->intfc_address),
- (u32) (mp->intfc_address_length),
- ntohl (mp->inner_vrf_id),
- ntohl (mp->outer_vrf_id),
- &tunnel_sw_if_index,
- mp->l2_only, mp->is_add);
- dsunlock (sm);
-
- /* *INDENT-OFF* */
- REPLY_MACRO2(VL_API_MPLS_GRE_ADD_DEL_TUNNEL_REPLY,
- ({
- rmp->tunnel_sw_if_index = ntohl(tunnel_sw_if_index);
- }));
- /* *INDENT-ON* */
-}
-
static void
vl_api_mpls_ethernet_add_del_tunnel_t_handler
(vl_api_mpls_ethernet_add_del_tunnel_t * mp)
if (inner_fib_index == outer_fib_index)
return VNET_API_ERROR_INVALID_VALUE;
- lookup_result = ip4_fib_lookup_with_table
- (im, outer_fib_index,
- (ip4_address_t *) mp->next_hop_ip4_address_in_outer_vrf,
- 1 /* disable default route */ );
+ // FIXME not an ADJ
+ lookup_result = ip4_fib_table_lookup_lb (ip4_fib_get (outer_fib_index),
+ (ip4_address_t *)
+ mp->next_hop_ip4_address_in_outer_vrf);
adj = ip_get_adjacency (lm, lookup_result);
tx_sw_if_index = adj->rewrite_header.sw_if_index;
REPLY_MACRO (VL_API_MPLS_ADD_DEL_ENCAP_REPLY);
}
-static void
-vl_api_mpls_add_del_decap_t_handler (vl_api_mpls_add_del_decap_t * mp)
-{
- vl_api_mpls_add_del_decap_reply_t *rmp;
- int rv;
-
- rv = vnet_mpls_add_del_decap (ntohl (mp->rx_vrf_id), ntohl (mp->tx_vrf_id),
- ntohl (mp->label), ntohl (mp->next_index),
- mp->s_bit, mp->is_add);
-
- REPLY_MACRO (VL_API_MPLS_ADD_DEL_DECAP_REPLY);
-}
-
static void
vl_api_proxy_arp_add_del_t_handler (vl_api_proxy_arp_add_del_t * mp)
{
{
vl_api_ip_neighbor_add_del_reply_t *rmp;
vnet_main_t *vnm = vnet_get_main ();
- u32 fib_index;
- int rv = 0;
stats_main_t *sm = &stats_main;
+ int rv = 0;
VALIDATE_SW_IF_INDEX (mp);
dslock (sm, 1 /* release hint */ , 7 /* tag */ );
+ /*
+ * there's no validation here of the ND/ARP entry being added.
+ * The expectation is that the FIB will ensure that nothing bad
+ * will come of adding bogus entries.
+ */
if (mp->is_ipv6)
{
if (mp->is_add)
}
else
{
- ip4_main_t *im = &ip4_main;
- ip_lookup_main_t *lm = &im->lookup_main;
ethernet_arp_ip4_over_ethernet_address_t a;
- u32 ai;
- ip_adjacency_t *nh_adj;
-
- uword *p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
- if (!p)
- {
- rv = VNET_API_ERROR_NO_SUCH_FIB;
- goto out;
- }
- fib_index = p[0];
-
- /*
- * Unfortunately, folks have a penchant for
- * adding interface addresses to the ARP cache, and
- * wondering why the forwarder eventually ASSERTs...
- */
- ai = ip4_fib_lookup_with_table
- (im, fib_index, (ip4_address_t *) (mp->dst_address),
- 1 /* disable default route */ );
-
- if (ai != 0)
- {
- nh_adj = ip_get_adjacency (lm, ai);
- /* Never allow manipulation of a local adj! */
- if (nh_adj->lookup_next_index == IP_LOOKUP_NEXT_LOCAL)
- {
- clib_warning ("%U matches local adj",
- format_ip4_address,
- (ip4_address_t *) (mp->dst_address));
- rv = VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
- goto out;
- }
- }
clib_memcpy (&a.ethernet, mp->mac_address, 6);
clib_memcpy (&a.ip4, mp->dst_address, 4);
if (mp->is_add)
rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
- fib_index, &a, mp->is_static);
+ &a, mp->is_static);
else
- rv = vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
- fib_index, &a);
+ rv =
+ vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), &a);
}
BAD_SW_IF_INDEX_LABEL;
-out:
+
dsunlock (sm);
REPLY_MACRO (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY);
}
else
{
lm = &im4->lookup_main;
+ // FIXME NOT an ADJ
adj_index = ip4_fib_lookup (im4, sw_if_index, &addr.ip4);
}
if (adj_index == ~0)
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)
+{
+ vl_api_sw_interface_set_mpls_enable_reply_t *rmp;
+ int rv = 0;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ mpls_sw_interface_enable_disable (&mpls_main,
+ ntohl (mp->sw_if_index), mp->enable);
+
+ BAD_SW_IF_INDEX_LABEL;
+ REPLY_MACRO (VL_API_SW_INTERFACE_SET_MPLS_ENABLE_REPLY);
+}
+
static void
vl_api_sw_interface_clear_stats_t_handler (vl_api_sw_interface_clear_stats_t *
mp)
vnet_main_t *vnm = vnet_get_main ();
vnet_interface_main_t *im = &vnm->interface_main;
ip4_main_t *im4 = &ip4_main;
- static ip4_route_t *routes;
static u32 *sw_if_indices_to_shut;
stats_main_t *sm = &stats_main;
- ip4_route_t *r;
+ fib_table_t *fib_table;
ip4_fib_t *fib;
u32 sw_if_index;
int i;
dslock (sm, 1 /* release hint */ , 8 /* tag */ );
- vec_foreach (fib, im4->fibs)
- {
- vnet_sw_interface_t *si;
+ /* *INDENT-OFF* */
+ pool_foreach (fib_table, im4->fibs,
+ ({
+ fib = &fib_table->v4;
+ vnet_sw_interface_t * si;
if (fib->table_id != target_fib_id)
continue;
- /* remove any mpls/gre tunnels in this fib */
- vnet_mpls_gre_delete_fib_tunnels (fib->table_id);
-
/* remove any mpls encap/decap labels */
mpls_fib_reset_labels (fib->table_id);
vec_reset_length (sw_if_indices_to_shut);
/* Shut down interfaces in this FIB / clean out intfc routes */
- /* *INDENT-OFF* */
pool_foreach (si, im->sw_interfaces,
({
u32 sw_if_index = si->sw_if_index;
if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
&& (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
- fib - im4->fibs))
+ fib->index))
vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
}));
- /* *INDENT-ON* */
-
- for (i = 0; i < vec_len (sw_if_indices_to_shut); i++)
- {
- sw_if_index = sw_if_indices_to_shut[i];
- // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
-
- u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
- flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
- vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
- }
-
- vec_reset_length (routes);
-
- for (i = 0; i < ARRAY_LEN (fib->adj_index_by_dst_address); i++)
- {
- uword *hash = fib->adj_index_by_dst_address[i];
- hash_pair_t *p;
- ip4_route_t x;
- x.address_length = i;
-
- /* *INDENT-OFF* */
- hash_foreach_pair (p, hash,
- ({
- x.address.data_u32 = p->key;
- vec_add1 (routes, x);
- }));
- /* *INDENT-ON* */
- }
+ for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
+ sw_if_index = sw_if_indices_to_shut[i];
+ // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
- vec_foreach (r, routes)
- {
- ip4_add_del_route_args_t a;
+ u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
+ flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
+ vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
+ }
- memset (&a, 0, sizeof (a));
- a.flags = IP4_ROUTE_FLAG_FIB_INDEX | IP4_ROUTE_FLAG_DEL;
- a.table_index_or_table_id = fib - im4->fibs;
- a.dst_address = r->address;
- a.dst_address_length = r->address_length;
- a.adj_index = ~0;
+ fib_table_flush(fib->index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
+ fib_table_flush(fib->index, FIB_PROTOCOL_IP4, FIB_SOURCE_INTERFACE);
- ip4_add_del_route (im4, &a);
- ip4_maybe_remap_adjacencies (im4, fib - im4->fibs,
- IP4_ROUTE_FLAG_FIB_INDEX);
- }
rv = 0;
break;
- } /* vec_foreach (fib) */
+ })); /* pool_foreach (fib) */
+ /* *INDENT-ON* */
dsunlock (sm);
return rv;
}
-typedef struct
-{
- ip6_address_t address;
- u32 address_length;
- u32 index;
-} ip6_route_t;
-
-typedef struct
-{
- u32 fib_index;
- ip6_route_t **routep;
-} add_routes_in_fib_arg_t;
-
-static void
-add_routes_in_fib (clib_bihash_kv_24_8_t * kvp, void *arg)
-{
- add_routes_in_fib_arg_t *ap = arg;
-
- if (kvp->key[2] >> 32 == ap->fib_index)
- {
- ip6_address_t *addr;
- ip6_route_t *r;
- addr = (ip6_address_t *) kvp;
- vec_add2 (*ap->routep, r, 1);
- r->address = addr[0];
- r->address_length = kvp->key[2] & 0xFF;
- r->index = kvp->value;
- }
-}
-
static int
ip6_reset_fib_t_handler (vl_api_reset_fib_t * mp)
{
vnet_interface_main_t *im = &vnm->interface_main;
ip6_main_t *im6 = &ip6_main;
stats_main_t *sm = &stats_main;
- static ip6_route_t *routes;
static u32 *sw_if_indices_to_shut;
- ip6_route_t *r;
+ fib_table_t *fib_table;
ip6_fib_t *fib;
u32 sw_if_index;
int i;
int rv = VNET_API_ERROR_NO_SUCH_FIB;
u32 target_fib_id = ntohl (mp->vrf_id);
- add_routes_in_fib_arg_t _a, *a = &_a;
- clib_bihash_24_8_t *h = &im6->ip6_lookup_table;
dslock (sm, 1 /* release hint */ , 9 /* tag */ );
- vec_foreach (fib, im6->fibs)
- {
- vnet_sw_interface_t *si;
+ /* *INDENT-OFF* */
+ pool_foreach (fib_table, im6->fibs,
+ ({
+ vnet_sw_interface_t * si;
+ fib = &(fib_table->v6);
if (fib->table_id != target_fib_id)
continue;
vec_reset_length (sw_if_indices_to_shut);
/* Shut down interfaces in this FIB / clean out intfc routes */
- /* *INDENT-OFF* */
pool_foreach (si, im->sw_interfaces,
- ({
- if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
- fib - im6->fibs)
- vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
- }));
- /* *INDENT-ON* */
-
- for (i = 0; i < vec_len (sw_if_indices_to_shut); i++)
- {
- sw_if_index = sw_if_indices_to_shut[i];
- // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
+ ({
+ if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
+ fib->index)
+ vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
+ }));
- u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
- flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
- vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
- }
-
- vec_reset_length (routes);
-
- a->fib_index = fib - im6->fibs;
- a->routep = &routes;
-
- clib_bihash_foreach_key_value_pair_24_8 (h, add_routes_in_fib, a);
+ for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
+ sw_if_index = sw_if_indices_to_shut[i];
+ // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
- vec_foreach (r, routes)
- {
- ip6_add_del_route_args_t a;
+ u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
+ flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
+ vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
+ }
- memset (&a, 0, sizeof (a));
- a.flags = IP6_ROUTE_FLAG_FIB_INDEX | IP6_ROUTE_FLAG_DEL;
- a.table_index_or_table_id = fib - im6->fibs;
- a.dst_address = r->address;
- a.dst_address_length = r->address_length;
- a.adj_index = ~0;
+ fib_table_flush(fib->index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
+ fib_table_flush(fib->index, FIB_PROTOCOL_IP6, FIB_SOURCE_INTERFACE);
- ip6_add_del_route (im6, &a);
- ip6_maybe_remap_adjacencies (im6, fib - im6->fibs,
- IP6_ROUTE_FLAG_FIB_INDEX);
- }
rv = 0;
- /* Reinstall the neighbor / router discovery routes */
- vnet_ip6_fib_init (im6, fib - im6->fibs);
break;
- } /* vec_foreach (fib) */
+ })); /* pool_foreach (fib) */
+ /* *INDENT-ON* */
dsunlock (sm);
return rv;
mp->hostname[vec_len (hostname) + 1] = '\n';
clib_memcpy (&mp->host_address[0], host_address, 16);
clib_memcpy (&mp->router_address[0], router_address, 16);
- clib_memcpy (&mp->host_mac[0], host_mac, 6);
+
+ if (NULL != host_mac)
+ clib_memcpy (&mp->host_mac[0], host_mac, 6);
mp->_vl_msg_id = ntohs (VL_API_DHCP_COMPL_EVENT);
vl_api_set_ip_flow_hash_reply_t *rmp;
int rv;
u32 table_id;
- u32 flow_hash_config = 0;
+ flow_hash_config_t flow_hash_config = 0;
table_id = ntohl (mp->vrf_id);
{
si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED;
si->unnumbered_sw_if_index = sw_if_index;
+ ip4_sw_interface_enable_disable (unnumbered_sw_if_index, 1);
+ ip6_sw_interface_enable_disable (unnumbered_sw_if_index, 1);
}
else
{
si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED);
si->unnumbered_sw_if_index = (u32) ~ 0;
+ ip4_sw_interface_enable_disable (unnumbered_sw_if_index, 0);
+ ip6_sw_interface_enable_disable (unnumbered_sw_if_index, 0);
}
done:
/* *INDENT-ON* */
}
-static void vl_api_noprint_control_ping_t_handler
- (vl_api_noprint_control_ping_t * mp)
-{
- vl_api_noprint_control_ping_reply_t *rmp;
- int rv = 0;
-
- /* *INDENT-OFF* */
- REPLY_MACRO2(VL_API_NOPRINT_CONTROL_PING_REPLY,
- ({
- rmp->vpe_pid = ntohl (getpid());
- }));
- /* *INDENT-ON* */
-}
-
static void
shmem_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
{
vl_msg_api_send_shmem (q, (u8 *) & rp);
}
+static void
+inband_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
+{
+ u8 **mem_vecp = (u8 **) arg;
+ u8 *mem_vec = *mem_vecp;
+ u32 offset = vec_len (mem_vec);
+
+ vec_validate (mem_vec, offset + buffer_bytes - 1);
+ clib_memcpy (mem_vec + offset, buffer, buffer_bytes);
+ *mem_vecp = mem_vec;
+}
+
+static void
+vl_api_cli_inband_t_handler (vl_api_cli_inband_t * mp)
+{
+ vl_api_cli_inband_reply_t *rmp;
+ int rv = 0;
+ unix_shared_memory_queue_t *q;
+ vlib_main_t *vm = vlib_get_main ();
+ unformat_input_t input;
+ u8 *out_vec = 0;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (!q)
+ return;
+
+ unformat_init_string (&input, (char *) mp->cmd, ntohl (mp->length));
+ vlib_cli_input (vm, &input, inband_cli_output, (uword) & out_vec);
+
+ u32 len = vec_len (out_vec);
+ /* *INDENT-OFF* */
+ REPLY_MACRO3(VL_API_CLI_INBAND_REPLY, len,
+ ({
+ rmp->length = htonl (len);
+ clib_memcpy (rmp->reply, out_vec, len);
+ }));
+ /* *INDENT-ON* */
+ vec_free (out_vec);
+}
+
static void
vl_api_set_arp_neighbor_limit_t_handler (vl_api_set_arp_neighbor_limit_t * mp)
{
static void vl_api_sr_tunnel_add_del_t_handler
(vl_api_sr_tunnel_add_del_t * mp)
{
-#if IPV6SR == 0
+#if IP6SR == 0
clib_warning ("unimplemented");
#else
ip6_sr_add_del_tunnel_args_t _a, *a = &_a;
static void vl_api_sr_policy_add_del_t_handler
(vl_api_sr_policy_add_del_t * mp)
{
-#if IPV6SR == 0
+#if IP6SR == 0
clib_warning ("unimplemented");
#else
ip6_sr_add_del_policy_args_t _a, *a = &_a;
static void vl_api_sr_multicast_map_add_del_t_handler
(vl_api_sr_multicast_map_add_del_t * mp)
{
-#if IPV6SR == 0
+#if IP6SR == 0
clib_warning ("unimplemented");
#else
ip6_sr_add_del_multicastmap_args_t _a, *a = &_a;
VALIDATE_SW_IF_INDEX (mp);
- rv = vnet_l2_classify_set_tables (sw_if_index, ip4_table_index,
- ip6_table_index, other_table_index);
+ if (mp->is_input)
+ rv = vnet_l2_input_classify_set_tables (sw_if_index, ip4_table_index,
+ ip6_table_index,
+ other_table_index);
+ else
+ rv = vnet_l2_output_classify_set_tables (sw_if_index, ip4_table_index,
+ ip6_table_index,
+ other_table_index);
if (rv == 0)
{
else
enable = 0;
- vnet_l2_classify_enable_disable (sw_if_index, enable);
+ if (mp->is_input)
+ vnet_l2_input_classify_enable_disable (sw_if_index, enable);
+ else
+ vnet_l2_output_classify_enable_disable (sw_if_index, enable);
}
BAD_SW_IF_INDEX_LABEL;
vnet_main_t *vnm = vnet_get_main ();
vlib_main_t *vm = vlib_get_main ();
-#if DPDK > 0 && DPDK_VHOST_USER
- rv = dpdk_vhost_user_create_if (
-#else
- rv = vhost_user_create_if (
-#endif
- vnm, vm, (char *) mp->sock_filename,
- mp->is_server, &sw_if_index, (u64) ~ 0,
- mp->renumber, ntohl (mp->custom_dev_instance),
- (mp->use_custom_mac) ? mp->mac_address : NULL);
+ rv = vhost_user_create_if (vnm, vm, (char *) mp->sock_filename,
+ mp->is_server, &sw_if_index, (u64) ~ 0,
+ mp->renumber, ntohl (mp->custom_dev_instance),
+ (mp->use_custom_mac) ? mp->mac_address : NULL);
/* *INDENT-OFF* */
REPLY_MACRO2(VL_API_CREATE_VHOST_USER_IF_REPLY,
vnet_main_t *vnm = vnet_get_main ();
vlib_main_t *vm = vlib_get_main ();
-#if DPDK > 0 && DPDK_VHOST_USER
- rv = dpdk_vhost_user_modify_if (
-#else
- rv = vhost_user_modify_if (
-#endif
- vnm, vm, (char *) mp->sock_filename,
- mp->is_server, sw_if_index, (u64) ~ 0,
- mp->renumber, ntohl (mp->custom_dev_instance));
+ rv = vhost_user_modify_if (vnm, vm, (char *) mp->sock_filename,
+ mp->is_server, sw_if_index, (u64) ~ 0,
+ mp->renumber, ntohl (mp->custom_dev_instance));
REPLY_MACRO (VL_API_MODIFY_VHOST_USER_IF_REPLY);
}
vnet_main_t *vnm = vnet_get_main ();
vlib_main_t *vm = vlib_get_main ();
-#if DPDK > 0 && DPDK_VHOST_USER
- rv = dpdk_vhost_user_delete_if (vnm, vm, sw_if_index);
-#else
rv = vhost_user_delete_if (vnm, vm, sw_if_index);
-#endif
REPLY_MACRO (VL_API_DELETE_VHOST_USER_IF_REPLY);
if (!rv)
if (q == 0)
return;
-#if DPDK > 0 && DPDK_VHOST_USER
- rv = dpdk_vhost_user_dump_ifs (vnm, vm, &ifaces);
-#else
rv = vhost_user_dump_ifs (vnm, vm, &ifaces);
-#endif
if (rv)
return;
{
memcpy (rmp->src_address, &(t->src.ip6), 16);
memcpy (rmp->dst_address, &(t->dst.ip6), 16);
- rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].table_id);
+ 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);
- rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].table_id);
+ rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id);
}
rmp->vni = htonl (t->vni);
rmp->decap_next_index = htonl (t->decap_next_index);
memset (a, 0, sizeof (*a));
a->is_add = mp->is_add;
+ a->teb = mp->teb;
/* ip addresses sent in network byte order */
clib_memcpy (&(a->src), mp->src_address, 4);
rmp->_vl_msg_id = ntohs (VL_API_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].table_id);
+ rmp->outer_fib_id = htonl (im->fibs[t->outer_fib_index].ft_table_id);
+ rmp->teb = t->teb;
rmp->sw_if_index = htonl (t->sw_if_index);
rmp->context = context;
{
memcpy (rmp->local, &(t->local.ip6), 16);
memcpy (rmp->remote, &(t->remote.ip6), 16);
- rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].table_id);
- rmp->decap_vrf_id = htonl (im6->fibs[t->decap_fib_index].table_id);
+ rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].ft_table_id);
+ rmp->decap_vrf_id = htonl (im6->fibs[t->decap_fib_index].ft_table_id);
}
else
{
memcpy (rmp->local, &(t->local.ip4), 4);
memcpy (rmp->remote, &(t->remote.ip4), 4);
- rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].table_id);
- rmp->decap_vrf_id = htonl (im4->fibs[t->decap_fib_index].table_id);
+ rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id);
+ rmp->decap_vrf_id = htonl (im4->fibs[t->decap_fib_index].ft_table_id);
}
rmp->vni = htonl (t->vni);
rmp->protocol = t->protocol;
{
vl_api_lisp_gpe_add_del_iface_reply_t *rmp;
int rv = 0;
- vnet_lisp_gpe_add_del_iface_args_t _a, *a = &_a;
- a->is_add = mp->is_add;
- a->dp_table = mp->dp_table;
- a->vni = mp->vni;
- a->is_l2 = mp->is_l2;
- rv = vnet_lisp_gpe_add_del_iface (a, 0);
+ if (mp->is_l2)
+ {
+ if (mp->is_add)
+ {
+ if (~0 ==
+ lisp_gpe_tenant_l2_iface_add_or_lock (mp->vni, mp->dp_table))
+ rv = 1;
+ }
+ else
+ lisp_gpe_tenant_l2_iface_unlock (mp->vni);
+ }
+ else
+ {
+ if (mp->is_add)
+ {
+ if (~0 ==
+ lisp_gpe_tenant_l3_iface_add_or_lock (mp->vni, mp->dp_table))
+ rv = 1;
+ }
+ else
+ lisp_gpe_tenant_l3_iface_unlock (mp->vni);
+ }
REPLY_MACRO (VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
}
+static void
+ vl_api_show_lisp_map_request_mode_t_handler
+ (vl_api_show_lisp_map_request_mode_t * mp)
+{
+ int rv = 0;
+ vl_api_show_lisp_map_request_mode_reply_t *rmp;
+
+ /* *INDENT-OFF* */
+ REPLY_MACRO2(VL_API_SHOW_LISP_MAP_REQUEST_MODE_REPLY,
+ ({
+ rmp->mode = vnet_lisp_get_map_request_mode ();
+ }));
+ /* *INDENT-ON* */
+}
+
+static void
+vl_api_lisp_map_request_mode_t_handler (vl_api_lisp_map_request_mode_t * mp)
+{
+ vl_api_lisp_map_request_mode_reply_t *rmp;
+ int rv = 0;
+
+ rv = vnet_lisp_set_map_request_mode (mp->mode);
+
+ REPLY_MACRO (VL_API_LISP_MAP_REQUEST_MODE_REPLY);
+}
+
static void
vl_api_lisp_pitr_set_locator_set_t_handler (vl_api_lisp_pitr_set_locator_set_t
* mp)
if (!mp->is_add)
{
vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
- gid_address_copy (&a->deid, eid);
+ gid_address_copy (&a->reid, eid);
a->is_add = 0;
rv = vnet_lisp_add_del_adjacency (a);
if (rv)
int rv = 0;
memset (a, 0, sizeof (a[0]));
- rv = unformat_lisp_eid_api (&a->seid, clib_net_to_host_u32 (mp->vni),
- mp->eid_type, mp->seid, mp->seid_len);
- rv |= unformat_lisp_eid_api (&a->deid, clib_net_to_host_u32 (mp->vni),
- mp->eid_type, mp->deid, mp->deid_len);
+ rv = unformat_lisp_eid_api (&a->leid, clib_net_to_host_u32 (mp->vni),
+ mp->eid_type, mp->leid, mp->leid_len);
+ rv |= unformat_lisp_eid_api (&a->reid, clib_net_to_host_u32 (mp->vni),
+ mp->eid_type, mp->reid, mp->reid_len);
if (rv)
goto send_reply;
static void
vl_api_lisp_locator_dump_t_handler (vl_api_lisp_locator_dump_t * mp)
{
+ u8 *ls_name = 0;
unix_shared_memory_queue_t *q = 0;
lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
locator_set_t *lsit = 0;
locator_t *loc = 0;
u32 ls_index = ~0, *locit = 0;
- u8 filter;
+ uword *p = 0;
q = vl_api_client_index_to_input_queue (mp->client_index);
if (q == 0)
return;
}
- ls_index = htonl (mp->locator_set_index);
-
- lsit = pool_elt_at_index (lcm->locator_set_pool, ls_index);
-
- filter = mp->filter;
- if (filter && !((1 == filter && lsit->local) ||
- (2 == filter && !lsit->local)))
+ if (mp->is_index_set)
+ ls_index = htonl (mp->ls_index);
+ else
{
- return;
+ /* make sure we get a proper C-string */
+ mp->ls_name[sizeof (mp->ls_name) - 1] = 0;
+ ls_name = format (0, "%s", mp->ls_name);
+ p = hash_get_mem (lcm->locator_set_index_by_name, ls_name);
+ if (!p)
+ goto out;
+ ls_index = p[0];
}
+ if (pool_is_free_index (lcm->locator_set_pool, ls_index))
+ return;
+
+ lsit = pool_elt_at_index (lcm->locator_set_pool, ls_index);
+
vec_foreach (locit, lsit->locator_indices)
{
loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
send_lisp_locator_details (lcm, loc, q, mp->context);
};
+out:
+ vec_free (ls_name);
}
static void
rmp->_vl_msg_id = ntohs (VL_API_LISP_LOCATOR_SET_DETAILS);
rmp->context = context;
- rmp->local = lsit->local;
- rmp->locator_set_index = htonl (ls_index);
+ rmp->ls_index = htonl (ls_index);
if (lsit->local)
{
ASSERT (lsit->name != NULL);
- strncpy ((char *) rmp->locator_set_name,
- (char *) lsit->name, ARRAY_LEN (rmp->locator_set_name) - 1);
+ strncpy ((char *) rmp->ls_name, (char *) lsit->name,
+ vec_len (lsit->name));
}
else
{
- str = format (0, "remote-%d", ls_index);
- strncpy ((char *) rmp->locator_set_name, (char *) str,
- ARRAY_LEN (rmp->locator_set_name) - 1);
+ str = format (0, "<remote-%d>", ls_index);
+ strncpy ((char *) rmp->ls_name, (char *) str, vec_len (str));
vec_free (str);
}
unix_shared_memory_queue_t *q = NULL;
lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
locator_set_t *lsit = NULL;
- u32 index;
u8 filter;
q = vl_api_client_index_to_input_queue (mp->client_index);
}
filter = mp->filter;
- index = 0;
/* *INDENT-OFF* */
pool_foreach (lsit, lcm->locator_set_pool,
({
if (filter && !((1 == filter && lsit->local) ||
- (2 == filter && !lsit->local))) {
- index++;
- continue;
- }
- send_lisp_locator_set_details(lcm, lsit, q, mp->context, index++);
+ (2 == filter && !lsit->local)))
+ {
+ continue;
+ }
+ send_lisp_locator_set_details (lcm, lsit, q, mp->context,
+ lsit - lcm->locator_set_pool);
}));
/* *INDENT-ON* */
}
+static void
+lisp_fid_put_api (u8 * dst, fid_address_t * src, u8 * prefix_length)
+{
+ ASSERT (prefix_length);
+ ip_prefix_t *ippref = &fid_addr_ippref (src);
+
+ switch (fid_addr_type (src))
+ {
+ case FID_ADDR_IP_PREF:
+ if (ip_prefix_version (ippref) == IP4)
+ clib_memcpy (dst, &ip_prefix_v4 (ippref), 4);
+ else
+ clib_memcpy (dst, &ip_prefix_v6 (ippref), 16);
+ prefix_length[0] = ip_prefix_len (ippref);
+ break;
+
+ case FID_ADDR_MAC:
+ prefix_length[0] = 0;
+ clib_memcpy (dst, fid_addr_mac (src), 6);
+ break;
+
+ default:
+ clib_warning ("Unknown FID type %d!", fid_addr_type (src));
+ break;
+ }
+}
+
+static u8
+fid_type_to_api_type (fid_address_t * fid)
+{
+ ip_prefix_t *ippref;
+
+ switch (fid_addr_type (fid))
+ {
+ case FID_ADDR_IP_PREF:
+ ippref = &fid_addr_ippref (fid);
+ if (ip_prefix_version (ippref) == IP4)
+ return 0;
+ else if (ip_prefix_version (ippref) == IP6)
+ return 1;
+ else
+ return ~0;
+
+ case FID_ADDR_MAC:
+ return 2;
+ }
+
+ return ~0;
+}
+
static void
send_lisp_eid_table_details (mapping_t * mapit,
unix_shared_memory_queue_t * q,
u32 context, u8 filter)
{
+ fid_address_t *fid;
lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
locator_set_t *ls = 0;
vl_api_lisp_eid_table_details_t *rmp = NULL;
switch (gid_address_type (gid))
{
+ case GID_ADDR_SRC_DST:
+ rmp->is_src_dst = 1;
+ fid = &gid_address_sd_src (gid);
+ rmp->eid_type = fid_type_to_api_type (fid);
+ lisp_fid_put_api (rmp->seid, &gid_address_sd_src (gid),
+ &rmp->seid_prefix_len);
+ lisp_fid_put_api (rmp->eid, &gid_address_sd_dst (gid),
+ &rmp->eid_prefix_len);
+ break;
case GID_ADDR_IP_PREFIX:
rmp->eid_prefix_len = ip_prefix_len (ip_prefix);
if (ip_prefix_version (ip_prefix) == IP4)
}
static void
-send_lisp_gpe_tunnel_details (lisp_gpe_tunnel_t * tunnel,
- unix_shared_memory_queue_t * q, u32 context)
+send_lisp_gpe_fwd_entry_details (lisp_gpe_fwd_entry_t * lfe,
+ unix_shared_memory_queue_t * q, u32 context)
{
vl_api_lisp_gpe_tunnel_details_t *rmp;
lisp_gpe_main_t *lgm = &lisp_gpe_main;
memset (rmp, 0, sizeof (*rmp));
rmp->_vl_msg_id = ntohs (VL_API_LISP_GPE_TUNNEL_DETAILS);
- rmp->tunnels = tunnel - lgm->tunnels;
-
- rmp->is_ipv6 = ip_addr_version (&tunnel->src) == IP6 ? 1 : 0;
- ip_address_copy_addr (rmp->source_ip, &tunnel->src);
- ip_address_copy_addr (rmp->destination_ip, &tunnel->dst);
-
- rmp->encap_fib_id = htonl (tunnel->encap_fib_index);
- rmp->decap_fib_id = htonl (tunnel->decap_fib_index);
- rmp->dcap_next = htonl (tunnel->decap_next_index);
- rmp->lisp_ver = tunnel->ver_res;
- rmp->next_protocol = tunnel->next_protocol;
- rmp->flags = tunnel->flags;
- rmp->ver_res = tunnel->ver_res;
- rmp->res = tunnel->res;
- rmp->iid = htonl (tunnel->vni);
+ rmp->tunnels = lfe - lgm->lisp_fwd_entry_pool;
+
+ rmp->is_ipv6 = ip_prefix_version (&(lfe->key->rmt.ippref)) == IP6 ? 1 : 0;
+ ip_address_copy_addr (rmp->source_ip,
+ &ip_prefix_addr (&(lfe->key->rmt.ippref)));
+ ip_address_copy_addr (rmp->destination_ip,
+ &ip_prefix_addr (&(lfe->key->rmt.ippref)));
+
+ rmp->encap_fib_id = htonl (0);
+ rmp->decap_fib_id = htonl (lfe->eid_fib_index);
+ rmp->iid = htonl (lfe->key->vni);
rmp->context = context;
vl_msg_api_send_shmem (q, (u8 *) & rmp);
{
unix_shared_memory_queue_t *q = NULL;
lisp_gpe_main_t *lgm = &lisp_gpe_main;
- lisp_gpe_tunnel_t *tunnel = NULL;
+ lisp_gpe_fwd_entry_t *lfe = NULL;
- if (pool_elts (lgm->tunnels) == 0)
+ if (pool_elts (lgm->lisp_fwd_entry_pool) == 0)
{
return;
}
}
/* *INDENT-OFF* */
- pool_foreach(tunnel, lgm->tunnels,
+ pool_foreach(lfe, lgm->lisp_fwd_entry_pool,
({
- send_lisp_gpe_tunnel_details(tunnel, q, mp->context);
+ send_lisp_gpe_fwd_entry_details(lfe, q, mp->context);
}));
/* *INDENT-ON* */
}
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_MACRO4 (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)
return 1;
event = pool_elt_at_index (am->arp_events, pool_index);
+ /* *INDENT-OFF* */
if (memcmp (&event->new_mac, new_mac, sizeof (event->new_mac)))
{
clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
}
else
{ /* same mac */
- if ((sw_if_index == event->sw_if_index) && ((address == 0) ||
- /* for BD case, also check IP address with 10 sec timeout */
- ((address == event->address)
- &&
- ((now -
- arp_event_last_time) <
- 10.0))))
+ if (sw_if_index == event->sw_if_index &&
+ (!event->mac_ip ||
+ /* for BD case, also check IP address with 10 sec timeout */
+ (address == event->address &&
+ (now - arp_event_last_time) < 10.0)))
return 1;
}
+ /* *INDENT-ON* */
arp_event_last_time = now;
event->sw_if_index = sw_if_index;
- if (address)
+ if (event->mac_ip)
event->address = address;
return 0;
}
+static int
+nd_change_data_callback (u32 pool_index, u8 * new_mac,
+ u32 sw_if_index, ip6_address_t * address)
+{
+ vpe_api_main_t *am = &vpe_api_main;
+ vlib_main_t *vm = am->vlib_main;
+ vl_api_ip6_nd_event_t *event;
+ static f64 nd_event_last_time;
+ f64 now = vlib_time_now (vm);
+
+ if (pool_is_free_index (am->nd_events, pool_index))
+ return 1;
+
+ event = pool_elt_at_index (am->nd_events, pool_index);
+
+ /* *INDENT-OFF* */
+ if (memcmp (&event->new_mac, new_mac, sizeof (event->new_mac)))
+ {
+ clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
+ }
+ else
+ { /* same mac */
+ if (sw_if_index == event->sw_if_index &&
+ (!event->mac_ip ||
+ /* for BD case, also check IP address with 10 sec timeout */
+ (ip6_address_is_equal (address,
+ (ip6_address_t *) event->address) &&
+ (now - nd_event_last_time) < 10.0)))
+ return 1;
+ }
+ /* *INDENT-ON* */
+
+ nd_event_last_time = now;
+ event->sw_if_index = sw_if_index;
+ if (event->mac_ip)
+ clib_memcpy (event->address, address, sizeof (event->address));
+ return 0;
+}
+
static int
arp_change_delete_callback (u32 pool_index, u8 * notused)
{
return 0;
}
+static int
+nd_change_delete_callback (u32 pool_index, u8 * notused)
+{
+ vpe_api_main_t *am = &vpe_api_main;
+
+ if (pool_is_free_index (am->nd_events, pool_index))
+ return 1;
+
+ pool_put_index (am->nd_events, pool_index);
+ return 0;
+}
+
static void
vl_api_want_ip4_arp_events_t_handler (vl_api_want_ip4_arp_events_t * mp)
{
event->context = mp->context;
event->address = mp->address;
event->pid = mp->pid;
+ if (mp->address == 0)
+ event->mac_ip = 1;
rv = vnet_add_del_ip4_arp_change_event
(vnm, arp_change_data_callback,
REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY);
}
+static void
+vl_api_want_ip6_nd_events_t_handler (vl_api_want_ip6_nd_events_t * mp)
+{
+ vpe_api_main_t *am = &vpe_api_main;
+ vnet_main_t *vnm = vnet_get_main ();
+ vl_api_want_ip6_nd_events_reply_t *rmp;
+ vl_api_ip6_nd_event_t *event;
+ int rv;
+
+ if (mp->enable_disable)
+ {
+ pool_get (am->nd_events, event);
+ memset (event, 0, sizeof (*event));
+
+ event->_vl_msg_id = ntohs (VL_API_IP6_ND_EVENT);
+ event->client_index = mp->client_index;
+ event->context = mp->context;
+ clib_memcpy (event->address, mp->address, 16);
+ event->pid = mp->pid;
+ if (ip6_address_is_zero ((ip6_address_t *) mp->address))
+ event->mac_ip = 1;
+
+ rv = vnet_add_del_ip6_nd_change_event
+ (vnm, nd_change_data_callback,
+ mp->pid, mp->address /* addr, in net byte order */ ,
+ vpe_resolver_process_node.index,
+ IP6_ND_EVENT, event - am->nd_events, 1 /* is_add */ );
+ }
+ else
+ {
+ rv = vnet_add_del_ip6_nd_change_event
+ (vnm, nd_change_delete_callback,
+ mp->pid, mp->address /* addr, in net byte order */ ,
+ vpe_resolver_process_node.index,
+ IP6_ND_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
+ }
+ REPLY_MACRO (VL_API_WANT_IP6_ND_EVENTS_REPLY);
+}
+
static void vl_api_input_acl_set_interface_t_handler
(vl_api_input_acl_set_interface_t * mp)
{
/* *INDENT-ON* */
}
-static void vl_api_trace_profile_add_t_handler
- (vl_api_trace_profile_add_t * mp)
+static void
+vl_api_ioam_enable_t_handler (vl_api_ioam_enable_t * mp)
{
int rv = 0;
- vl_api_trace_profile_add_reply_t *rmp;
+ vl_api_ioam_enable_reply_t *rmp;
clib_error_t *error;
/* Ignoring the profile id as currently a single profile
* is supported */
- error = ip6_ioam_trace_profile_set (mp->trace_num_elt, mp->trace_type,
- ntohl (mp->node_id),
- ntohl (mp->trace_app_data),
- mp->pow_enable, mp->trace_tsp,
- mp->trace_ppc);
+ error = ip6_ioam_enable (mp->trace_enable, mp->pow_enable, mp->trace_ppc);
if (error)
{
clib_error_report (error);
rv = clib_error_get_code (error);
}
- REPLY_MACRO (VL_API_TRACE_PROFILE_ADD_REPLY);
-}
-
-static void vl_api_trace_profile_apply_t_handler
- (vl_api_trace_profile_apply_t * mp)
-{
- int rv = 0;
- vl_api_trace_profile_apply_reply_t *rmp;
-
- if (mp->enable != 0)
- {
- rv = ip6_ioam_set_destination ((ip6_address_t *) (&mp->dest_ipv6),
- ntohl (mp->prefix_length),
- ntohl (mp->vrf_id),
- mp->trace_op == IOAM_HBYH_ADD,
- mp->trace_op == IOAM_HBYH_POP,
- mp->trace_op == IOAM_HBYH_MOD);
- }
- else
- {
- //ip6_ioam_clear_destination(&ip6, mp->prefix_length, mp->vrf_id);
- }
- REPLY_MACRO (VL_API_TRACE_PROFILE_APPLY_REPLY);
+ REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
}
-static void vl_api_trace_profile_del_t_handler
- (vl_api_trace_profile_del_t * mp)
+static void
+vl_api_ioam_disable_t_handler (vl_api_ioam_disable_t * mp)
{
int rv = 0;
- vl_api_trace_profile_del_reply_t *rmp;
+ vl_api_ioam_disable_reply_t *rmp;
clib_error_t *error;
error = clear_ioam_rewrite_fn ();
rv = clib_error_get_code (error);
}
- REPLY_MACRO (VL_API_TRACE_PROFILE_DEL_REPLY);
+ REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
}
static void
REPLY_MACRO (VL_API_NETMAP_DELETE_REPLY);
}
-static void
-vl_api_mpls_gre_tunnel_details_t_handler (vl_api_mpls_gre_tunnel_details_t *
- mp)
-{
- clib_warning ("BUG");
-}
-
-static void
-send_mpls_gre_tunnel_entry (vpe_api_main_t * am,
- unix_shared_memory_queue_t * q,
- mpls_gre_tunnel_t * gt, u32 index, u32 context)
-{
- vl_api_mpls_gre_tunnel_details_t *mp;
- mpls_main_t *mm = &mpls_main;
- mpls_encap_t *e;
- int i;
- u32 nlabels;
-
- e = pool_elt_at_index (mm->encaps, gt->encap_index);
- nlabels = vec_len (e->labels);
-
- mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
- memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_MPLS_GRE_TUNNEL_DETAILS);
- mp->context = context;
-
- mp->tunnel_index = htonl (index);
- mp->tunnel_src = gt->tunnel_src.as_u32;
- mp->tunnel_dst = gt->tunnel_dst.as_u32;
- mp->intfc_address = gt->intfc_address.as_u32;
- mp->mask_width = htonl (gt->mask_width);
- mp->inner_fib_index = htonl (gt->inner_fib_index);
- mp->outer_fib_index = htonl (gt->outer_fib_index);
- mp->encap_index = htonl (gt->encap_index);
- mp->hw_if_index = htonl (gt->hw_if_index);
- mp->l2_only = htonl (gt->l2_only);
- mp->nlabels = htonl (nlabels);
-
- for (i = 0; i < nlabels; i++)
- {
- mp->labels[i] =
- htonl (vnet_mpls_uc_get_label
- (clib_host_to_net_u32 (e->labels[i].label_exp_s_ttl)));
- }
-
- vl_msg_api_send_shmem (q, (u8 *) & mp);
-}
-
-static void
-vl_api_mpls_gre_tunnel_dump_t_handler (vl_api_mpls_gre_tunnel_dump_t * mp)
-{
- vpe_api_main_t *am = &vpe_api_main;
- unix_shared_memory_queue_t *q;
- mpls_main_t *mm = &mpls_main;
- mpls_gre_tunnel_t *gt;
- u32 index = ntohl (mp->tunnel_index);
-
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
- return;
-
- if (index != ~0)
- {
- if (!pool_is_free_index (mm->gre_tunnels, index))
- {
- gt = pool_elt_at_index (mm->gre_tunnels, index);
- send_mpls_gre_tunnel_entry (am, q, gt, gt - mm->gre_tunnels,
- mp->context);
- }
- }
- else
- {
- /* *INDENT-OFF* */
- pool_foreach (gt, mm->gre_tunnels,
- ({
- send_mpls_gre_tunnel_entry (am, q, gt, gt - mm->gre_tunnels,
- mp->context);
- }));
- /* *INDENT-ON* */
- }
-}
-
static void
vl_api_mpls_eth_tunnel_details_t_handler (vl_api_mpls_eth_tunnel_details_t *
mp)
}
static void
-vl_api_mpls_fib_encap_details_t_handler (vl_api_mpls_fib_encap_details_t * mp)
+vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
{
clib_warning ("BUG");
}
static void
-send_mpls_fib_encap_details (vpe_api_main_t * am,
- unix_shared_memory_queue_t * q,
- show_mpls_fib_t * s, u32 context)
+send_mpls_fib_details (vpe_api_main_t * am,
+ unix_shared_memory_queue_t * q,
+ u32 table_id, u32 label, u32 eos, u32 context)
{
- vl_api_mpls_fib_encap_details_t *mp;
- mpls_main_t *mm = &mpls_main;
- mpls_encap_t *e;
- int i;
- u32 nlabels;
+ vl_api_mpls_fib_details_t *mp;
- e = pool_elt_at_index (mm->encaps, s->entry_index);
- nlabels = vec_len (e->labels);
-
- mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
+ mp = vl_msg_api_alloc (sizeof (*mp));
memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_ENCAP_DETAILS);
+ mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_DETAILS);
mp->context = context;
- mp->fib_index = htonl (s->fib_index);
- mp->entry_index = htonl (s->entry_index);
- mp->dest = s->dest;
- mp->s_bit = htonl (s->s_bit);
-
- mp->nlabels = htonl (nlabels);
-
- for (i = 0; i < nlabels; i++)
- {
- mp->labels[i] =
- htonl (vnet_mpls_uc_get_label
- (clib_host_to_net_u32 (e->labels[i].label_exp_s_ttl)));
- }
+ mp->table_id = htonl (table_id);
+ mp->eos_bit = eos;
+ mp->label = htonl (label);
vl_msg_api_send_shmem (q, (u8 *) & mp);
}
static void
-vl_api_mpls_fib_encap_dump_t_handler (vl_api_mpls_fib_encap_dump_t * mp)
+vl_api_mpls_fib_dump_t_handler (vl_api_mpls_fib_dump_t * mp)
{
vpe_api_main_t *am = &vpe_api_main;
unix_shared_memory_queue_t *q;
- vlib_main_t *vm = &vlib_global_main;
- u64 key;
- u32 value;
- show_mpls_fib_t *records = 0;
- show_mpls_fib_t *s;
mpls_main_t *mm = &mpls_main;
- ip4_main_t *im = &ip4_main;
- ip4_fib_t *rx_fib;
+ fib_table_t *fib_table;
+ fib_node_index_t lfei, *lfeip, *lfeis = NULL;
+ mpls_label_t key;
+ fib_prefix_t pfx;
+ u32 fib_index;
q = vl_api_client_index_to_input_queue (mp->client_index);
if (q == 0)
return;
/* *INDENT-OFF* */
- hash_foreach (key, value, mm->mpls_encap_by_fib_and_dest,
+ pool_foreach (fib_table, mm->fibs,
({
- vec_add2 (records, s, 1);
- s->fib_index = (u32)(key>>32);
- s->dest = (u32)(key & 0xFFFFFFFF);
- s->entry_index = (u32) value;
+ hash_foreach(key, lfei, fib_table->mpls.mf_entries,
+ ({
+ vec_add1(lfeis, lfei);
+ }));
}));
- /* *INDENT-ON* */
-
- if (0 == vec_len (records))
- {
- vlib_cli_output (vm, "MPLS encap table empty");
- goto out;
- }
+ vec_sort_with_function(lfeis, fib_entry_cmp_for_sort);
- /* sort output by dst address within fib */
- vec_sort_with_function (records, mpls_dest_cmp);
- vec_sort_with_function (records, mpls_fib_index_cmp);
- vlib_cli_output (vm, "MPLS encap table");
- vlib_cli_output (vm, "%=6s%=16s%=16s", "Table", "Dest address", "Labels");
- vec_foreach (s, records)
+ vec_foreach(lfeip, lfeis)
{
- rx_fib = vec_elt_at_index (im->fibs, s->fib_index);
- vlib_cli_output (vm, "%=6d%=16U%=16U", rx_fib->table_id,
- format_ip4_address, &s->dest, format_mpls_encap_index,
- mm, s->entry_index);
- send_mpls_fib_encap_details (am, q, s, mp->context);
+ fib_entry_get_prefix(*lfeip, &pfx);
+ fib_index = fib_entry_get_fib_index(*lfeip);
+
+ fib_table = fib_table_get(fib_index, pfx.fp_proto);
+
+ send_mpls_fib_details (am, q,
+ fib_table->ft_table_id,
+ pfx.fp_label,
+ pfx.fp_eos,
+ mp->context);
}
-out:
- vec_free (records);
+ vec_free (lfeis);
}
static void
-vl_api_mpls_fib_decap_details_t_handler (vl_api_mpls_fib_decap_details_t * mp)
+vl_api_mpls_fib_encap_details_t_handler (vl_api_mpls_fib_encap_details_t * mp)
{
clib_warning ("BUG");
}
static void
-send_mpls_fib_decap_details (vpe_api_main_t * am,
+send_mpls_fib_encap_details (vpe_api_main_t * am,
unix_shared_memory_queue_t * q,
- show_mpls_fib_t * s,
- u32 rx_table_id,
- u32 tx_table_id, char *swif_tag, u32 context)
+ show_mpls_fib_t * s, u32 context)
{
- vl_api_mpls_fib_decap_details_t *mp;
+ vl_api_mpls_fib_encap_details_t *mp;
+ mpls_main_t *mm = &mpls_main;
+ mpls_encap_t *e;
+ int i;
+ u32 nlabels;
- mp = vl_msg_api_alloc (sizeof (*mp));
+ e = pool_elt_at_index (mm->encaps, s->entry_index);
+ nlabels = vec_len (e->labels);
+
+ mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
memset (mp, 0, sizeof (*mp));
- mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_DECAP_DETAILS);
+ mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_ENCAP_DETAILS);
mp->context = context;
mp->fib_index = htonl (s->fib_index);
mp->entry_index = htonl (s->entry_index);
mp->dest = s->dest;
mp->s_bit = htonl (s->s_bit);
- mp->label = htonl (s->label);
- mp->rx_table_id = htonl (rx_table_id);
- mp->tx_table_id = htonl (tx_table_id);
- strncpy ((char *) mp->swif_tag,
- (char *) swif_tag, ARRAY_LEN (mp->swif_tag) - 1);
+
+ mp->nlabels = htonl (nlabels);
+
+ for (i = 0; i < nlabels; i++)
+ {
+ mp->labels[i] =
+ htonl (vnet_mpls_uc_get_label
+ (clib_host_to_net_u32 (e->labels[i].label_exp_s_ttl)));
+ }
vl_msg_api_send_shmem (q, (u8 *) & mp);
}
static void
-vl_api_mpls_fib_decap_dump_t_handler (vl_api_mpls_fib_decap_dump_t * mp)
+vl_api_mpls_fib_encap_dump_t_handler (vl_api_mpls_fib_encap_dump_t * mp)
{
vpe_api_main_t *am = &vpe_api_main;
unix_shared_memory_queue_t *q;
show_mpls_fib_t *records = 0;
show_mpls_fib_t *s;
mpls_main_t *mm = &mpls_main;
- ip4_main_t *im = &ip4_main;
ip4_fib_t *rx_fib;
- ip4_fib_t *tx_fib;
- u32 tx_table_id;
- char *swif_tag;
q = vl_api_client_index_to_input_queue (mp->client_index);
if (q == 0)
return;
/* *INDENT-OFF* */
- hash_foreach (key, value, mm->mpls_decap_by_rx_fib_and_label,
+ hash_foreach (key, value, mm->mpls_encap_by_fib_and_dest,
({
vec_add2 (records, s, 1);
s->fib_index = (u32)(key>>32);
+ s->dest = (u32)(key & 0xFFFFFFFF);
s->entry_index = (u32) value;
- s->label = ((u32) key)>>12;
- s->s_bit = (key & (1<<8)) != 0;
}));
/* *INDENT-ON* */
- if (!vec_len (records))
+ if (0 == vec_len (records))
{
- vlib_cli_output (vm, "MPLS decap table empty");
+ vlib_cli_output (vm, "MPLS encap table empty");
goto out;
}
- vec_sort_with_function (records, mpls_label_cmp);
- vlib_cli_output (vm, "MPLS decap table");
- vlib_cli_output (vm, "%=10s%=15s%=6s%=6s", "RX Table", "TX Table/Intfc",
- "Label", "S-bit");
+ /* sort output by dst address within fib */
+ vec_sort_with_function (records, mpls_dest_cmp);
+ vec_sort_with_function (records, mpls_fib_index_cmp);
+ vlib_cli_output (vm, "MPLS encap table");
+ vlib_cli_output (vm, "%=6s%=16s%=16s", "Table", "Dest address", "Labels");
vec_foreach (s, records)
{
- mpls_decap_t *d;
- d = pool_elt_at_index (mm->decaps, s->entry_index);
- if (d->next_index == MPLS_INPUT_NEXT_IP4_INPUT)
- {
- tx_fib = vec_elt_at_index (im->fibs, d->tx_fib_index);
- tx_table_id = tx_fib->table_id;
- swif_tag = " ";
- }
- else
- {
- tx_table_id = d->tx_fib_index;
- swif_tag = "(i) ";
- }
- rx_fib = vec_elt_at_index (im->fibs, s->fib_index);
-
- vlib_cli_output (vm, "%=10d%=10d%=5s%=6d%=6d", rx_fib->table_id,
- tx_table_id, swif_tag, s->label, s->s_bit);
-
- send_mpls_fib_decap_details (am, q, s, rx_fib->table_id,
- tx_table_id, swif_tag, mp->context);
+ rx_fib = ip4_fib_get (s->fib_index);
+ vlib_cli_output (vm, "%=6d%=16U%=16U", rx_fib->table_id,
+ format_ip4_address, &s->dest, format_mpls_encap_index,
+ mm, s->entry_index);
+ send_mpls_fib_encap_details (am, q, s, mp->context);
}
out:
vnet_classify_table_t *t;
q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (!q)
+ return;
/* *INDENT-OFF* */
pool_foreach (t, cm->tables,
}
static void
-vl_api_ipfix_enable_t_handler (vl_api_ipfix_enable_t * mp)
+vl_api_set_ipfix_exporter_t_handler (vl_api_set_ipfix_exporter_t * mp)
{
vlib_main_t *vm = vlib_get_main ();
flow_report_main_t *frm = &flow_report_main;
- vl_api_ipfix_enable_reply_t *rmp;
+ vl_api_set_ipfix_exporter_reply_t *rmp;
ip4_address_t collector, src;
u16 collector_port = UDP_DST_PORT_ipfix;
u32 path_mtu;
u32 template_interval;
+ u8 udp_checksum;
u32 fib_id;
u32 fib_index = ~0;
int rv = 0;
fib_id = ntohl (mp->vrf_id);
ip4_main_t *im = &ip4_main;
- uword *p = hash_get (im->fib_index_by_table_id, fib_id);
- if (!p)
+ if (fib_id == ~0)
{
- rv = VNET_API_ERROR_NO_SUCH_FIB;
- goto out;
+ fib_index = ~0;
+ }
+ else
+ {
+ uword *p = hash_get (im->fib_index_by_table_id, fib_id);
+ if (!p)
+ {
+ rv = VNET_API_ERROR_NO_SUCH_FIB;
+ goto out;
+ }
+ fib_index = p[0];
}
- fib_index = p[0];
path_mtu = ntohl (mp->path_mtu);
if (path_mtu == ~0)
template_interval = ntohl (mp->template_interval);
if (template_interval == ~0)
template_interval = 20;
+ udp_checksum = mp->udp_checksum;
if (collector.as_u32 == 0)
{
frm->fib_index = fib_index;
frm->path_mtu = path_mtu;
frm->template_interval = template_interval;
+ frm->udp_checksum = udp_checksum;
/* Turn on the flow reporting process */
vlib_process_signal_event (vm, flow_report_process_node.index, 1, 0);
out:
- REPLY_MACRO (VL_API_IPFIX_ENABLE_REPLY);
+ REPLY_MACRO (VL_API_SET_IPFIX_EXPORTER_REPLY);
}
static void
-vl_api_ipfix_dump_t_handler (vl_api_ipfix_dump_t * mp)
+vl_api_ipfix_exporter_dump_t_handler (vl_api_ipfix_exporter_dump_t * mp)
{
flow_report_main_t *frm = &flow_report_main;
unix_shared_memory_queue_t *q;
- vl_api_ipfix_details_t *rmp;
+ vl_api_ipfix_exporter_details_t *rmp;
+ ip4_main_t *im = &ip4_main;
+ u32 vrf_id;
q = vl_api_client_index_to_input_queue (mp->client_index);
if (!q)
rmp = vl_msg_api_alloc (sizeof (*rmp));
memset (rmp, 0, sizeof (*rmp));
- rmp->_vl_msg_id = ntohs (VL_API_IPFIX_DETAILS);
+ rmp->_vl_msg_id = ntohs (VL_API_IPFIX_EXPORTER_DETAILS);
rmp->context = mp->context;
memcpy (rmp->collector_address, frm->ipfix_collector.data,
sizeof (frm->ipfix_collector.data));
rmp->collector_port = htons (frm->collector_port);
memcpy (rmp->src_address, frm->src_address.data,
sizeof (frm->src_address.data));
- rmp->fib_index = htonl (frm->fib_index);
+ if (frm->fib_index == ~0)
+ vrf_id = ~0;
+ else
+ vrf_id = im->fibs[frm->fib_index].ft_table_id;
+ rmp->vrf_id = htonl (vrf_id);
rmp->path_mtu = htonl (frm->path_mtu);
rmp->template_interval = htonl (frm->template_interval);
+ rmp->udp_checksum = (frm->udp_checksum != 0);
+
+ vl_msg_api_send_shmem (q, (u8 *) & rmp);
+}
+
+static void
+ vl_api_set_ipfix_classify_stream_t_handler
+ (vl_api_set_ipfix_classify_stream_t * mp)
+{
+ vl_api_set_ipfix_classify_stream_reply_t *rmp;
+ flow_report_classify_main_t *fcm = &flow_report_classify_main;
+ flow_report_main_t *frm = &flow_report_main;
+ u32 domain_id = 0;
+ u32 src_port = UDP_DST_PORT_ipfix;
+ int rv = 0;
+
+ domain_id = ntohl (mp->domain_id);
+ src_port = ntohs (mp->src_port);
+
+ if (fcm->src_port != 0 &&
+ (fcm->domain_id != domain_id || fcm->src_port != (u16) src_port))
+ {
+ int rv = vnet_stream_change (frm, fcm->domain_id, fcm->src_port,
+ domain_id, (u16) src_port);
+ ASSERT (rv == 0);
+ }
+
+ fcm->domain_id = domain_id;
+ fcm->src_port = (u16) src_port;
+
+ REPLY_MACRO (VL_API_SET_IPFIX_CLASSIFY_STREAM_REPLY);
+}
+
+static void
+ vl_api_ipfix_classify_stream_dump_t_handler
+ (vl_api_ipfix_classify_stream_dump_t * mp)
+{
+ flow_report_classify_main_t *fcm = &flow_report_classify_main;
+ unix_shared_memory_queue_t *q;
+ vl_api_ipfix_classify_stream_details_t *rmp;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (!q)
+ return;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id = ntohs (VL_API_IPFIX_CLASSIFY_STREAM_DETAILS);
+ rmp->context = mp->context;
+ rmp->domain_id = htonl (fcm->domain_id);
+ rmp->src_port = htons (fcm->src_port);
vl_msg_api_send_shmem (q, (u8 *) & rmp);
}
+static void
+ vl_api_ipfix_classify_table_add_del_t_handler
+ (vl_api_ipfix_classify_table_add_del_t * mp)
+{
+ vl_api_ipfix_classify_table_add_del_reply_t *rmp;
+ flow_report_classify_main_t *fcm = &flow_report_classify_main;
+ flow_report_main_t *frm = &flow_report_main;
+ vnet_flow_report_add_del_args_t args;
+ ipfix_classify_table_t *table;
+ int is_add;
+ u32 classify_table_index;
+ u8 ip_version;
+ u8 transport_protocol;
+ int rv = 0;
+
+ classify_table_index = ntohl (mp->table_id);
+ ip_version = mp->ip_version;
+ transport_protocol = mp->transport_protocol;
+ is_add = mp->is_add;
+
+ if (fcm->src_port == 0)
+ {
+ /* call set_ipfix_classify_stream first */
+ rv = VNET_API_ERROR_UNSPECIFIED;
+ goto out;
+ }
+
+ memset (&args, 0, sizeof (args));
+
+ table = 0;
+ int i;
+ for (i = 0; i < vec_len (fcm->tables); i++)
+ if (ipfix_classify_table_index_valid (i))
+ if (fcm->tables[i].classify_table_index == classify_table_index)
+ {
+ table = &fcm->tables[i];
+ break;
+ }
+
+ if (is_add)
+ {
+ if (table)
+ {
+ rv = VNET_API_ERROR_VALUE_EXIST;
+ goto out;
+ }
+ table = ipfix_classify_add_table ();
+ table->classify_table_index = classify_table_index;
+ }
+ else
+ {
+ if (!table)
+ {
+ rv = VNET_API_ERROR_NO_SUCH_ENTRY;
+ goto out;
+ }
+ }
+
+ table->ip_version = ip_version;
+ table->transport_protocol = transport_protocol;
+
+ args.opaque.as_uword = table - fcm->tables;
+ args.rewrite_callback = ipfix_classify_template_rewrite;
+ args.flow_data_callback = ipfix_classify_send_flows;
+ args.is_add = is_add;
+ args.domain_id = fcm->domain_id;
+ args.src_port = fcm->src_port;
+
+ rv = vnet_flow_report_add_del (frm, &args);
+
+ /* If deleting, or add failed */
+ if (is_add == 0 || (rv && is_add))
+ ipfix_classify_delete_table (table - fcm->tables);
+
+out:
+ REPLY_MACRO (VL_API_SET_IPFIX_CLASSIFY_STREAM_REPLY);
+}
+
+static void
+send_ipfix_classify_table_details (u32 table_index,
+ unix_shared_memory_queue_t * q,
+ u32 context)
+{
+ flow_report_classify_main_t *fcm = &flow_report_classify_main;
+ vl_api_ipfix_classify_table_details_t *mp;
+
+ ipfix_classify_table_t *table = &fcm->tables[table_index];
+
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_IPFIX_CLASSIFY_TABLE_DETAILS);
+ mp->context = context;
+ mp->table_id = htonl (table->classify_table_index);
+ mp->ip_version = table->ip_version;
+ mp->transport_protocol = table->transport_protocol;
+
+ vl_msg_api_send_shmem (q, (u8 *) & mp);
+}
+
+static void
+ vl_api_ipfix_classify_table_dump_t_handler
+ (vl_api_ipfix_classify_table_dump_t * mp)
+{
+ flow_report_classify_main_t *fcm = &flow_report_classify_main;
+ unix_shared_memory_queue_t *q;
+ u32 i;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (!q)
+ return;
+
+ for (i = 0; i < vec_len (fcm->tables); i++)
+ if (ipfix_classify_table_index_valid (i))
+ send_ipfix_classify_table_details (i, q, mp->context);
+}
+
static void
vl_api_pg_create_interface_t_handler (vl_api_pg_create_interface_t * mp)
{
int rv = 0;
pg_main_t *pg = &pg_main;
- u32 sw_if_index = pg_interface_add_or_get (pg, ntohl (mp->interface_id));
+ u32 pg_if_id = pg_interface_add_or_get (pg, ntohl (mp->interface_id));
+ pg_interface_t *pi = pool_elt_at_index (pg->interfaces, pg_if_id);
/* *INDENT-OFF* */
REPLY_MACRO2(VL_API_PG_CREATE_INTERFACE_REPLY,
({
- rmp->sw_if_index = ntohl(sw_if_index);
+ rmp->sw_if_index = ntohl(pi->sw_if_index);
}));
/* *INDENT-ON* */
}
REPLY_MACRO (VL_API_DELETE_SUBIF_REPLY);
}
+static void
+ vl_api_l2_interface_pbb_tag_rewrite_t_handler
+ (vl_api_l2_interface_pbb_tag_rewrite_t * mp)
+{
+ vl_api_l2_interface_pbb_tag_rewrite_reply_t *rmp;
+ vnet_main_t *vnm = vnet_get_main ();
+ vlib_main_t *vm = vlib_get_main ();
+ u32 vtr_op;
+ int rv = 0;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ vtr_op = ntohl (mp->vtr_op);
+
+ switch (vtr_op)
+ {
+ case L2_VTR_DISABLED:
+ case L2_VTR_PUSH_2:
+ case L2_VTR_POP_2:
+ case L2_VTR_TRANSLATE_2_1:
+ break;
+
+ default:
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto bad_sw_if_index;
+ }
+
+ rv = l2pbb_configure (vm, vnm, ntohl (mp->sw_if_index), vtr_op,
+ mp->b_dmac, mp->b_smac, ntohs (mp->b_vlanid),
+ ntohl (mp->i_sid), ntohs (mp->outer_tag));
+
+ BAD_SW_IF_INDEX_LABEL;
+
+ 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) \
{
vl_api_ip4_arp_event_t *event = va_arg (*args, vl_api_ip4_arp_event_t *);
- s = format (s, "pid %d: %U", event->pid,
- format_ip4_address, &event->address);
+ s = format (s, "pid %d: ", event->pid);
+ if (event->mac_ip)
+ s = format (s, "bd mac/ip4 binding events");
+ else
+ s = format (s, "resolution for %U", format_ip4_address, &event->address);
+ return s;
+}
+
+static u8 *
+format_nd_event (u8 * s, va_list * args)
+{
+ vl_api_ip6_nd_event_t *event = va_arg (*args, vl_api_ip6_nd_event_t *);
+
+ s = format (s, "pid %d: ", event->pid);
+ if (event->mac_ip)
+ s = format (s, "bd mac/ip6 binding events");
+ else
+ s = format (s, "resolution for %U", format_ip6_address, event->address);
return s;
}
static clib_error_t *
-show_ip4_arp_events_fn (vlib_main_t * vm,
- unformat_input_t * input, vlib_cli_command_t * cmd)
+show_ip_arp_nd_events_fn (vlib_main_t * vm,
+ unformat_input_t * input, vlib_cli_command_t * cmd)
{
vpe_api_main_t *am = &vpe_api_main;
- vl_api_ip4_arp_event_t *event;
+ vl_api_ip4_arp_event_t *arp_event;
+ vl_api_ip6_nd_event_t *nd_event;
- if (pool_elts (am->arp_events) == 0)
+ if ((pool_elts (am->arp_events) == 0) && (pool_elts (am->nd_events) == 0))
{
- vlib_cli_output (vm, "No active arp event registrations");
+ vlib_cli_output (vm, "No active arp or nd event registrations");
return 0;
}
/* *INDENT-OFF* */
- pool_foreach (event, am->arp_events,
+ pool_foreach (arp_event, am->arp_events,
+ ({
+ vlib_cli_output (vm, "%U", format_arp_event, arp_event);
+ }));
+
+ pool_foreach (nd_event, am->nd_events,
({
- vlib_cli_output (vm, "%U", format_arp_event, event);
+ vlib_cli_output (vm, "%U", format_nd_event, nd_event);
}));
/* *INDENT-ON* */
}
/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (show_ip4_arp_events, static) = {
- .path = "show arp event registrations",
- .function = show_ip4_arp_events_fn,
- .short_help = "Show arp event registrations",
+VLIB_CLI_COMMAND (show_ip_arp_nd_events, static) = {
+ .path = "show arp-nd-event registrations",
+ .function = show_ip_arp_nd_events_fn,
+ .short_help = "Show ip4 arp and ip6 nd event registrations",
};
/* *INDENT-ON* */