2 *------------------------------------------------------------------
3 * api.c - message handler registration
5 * Copyright (c) 2010 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
23 #include <sys/types.h>
26 #include <netinet/in.h>
36 #include <vppinfra/clib.h>
37 #include <vppinfra/vec.h>
38 #include <vppinfra/hash.h>
39 #include <vppinfra/bitmap.h>
40 #include <vppinfra/fifo.h>
41 #include <vppinfra/time.h>
42 #include <vppinfra/mheap.h>
43 #include <vppinfra/heap.h>
44 #include <vppinfra/pool.h>
45 #include <vppinfra/format.h>
46 #include <vppinfra/error.h>
48 #include <vnet/api_errno.h>
49 #include <vnet/vnet.h>
50 #include <vnet/l2/l2_input.h>
51 #include <vnet/l2/l2_bd.h>
52 #include <vnet/l2tp/l2tp.h>
53 #include <vnet/ip/ip.h>
54 #include <vnet/unix/tuntap.h>
55 #include <vnet/unix/tapcli.h>
56 #include <vnet/mpls-gre/mpls.h>
57 #include <vnet/dhcp/proxy.h>
58 #include <vnet/dhcp/client.h>
60 #include <vnet/sr/sr.h>
62 #include <vnet/dhcpv6/proxy.h>
63 #include <vlib/vlib.h>
64 #include <vlib/unix/unix.h>
65 #include <vlibapi/api.h>
66 #include <vlibmemory/api.h>
67 #include <vnet/classify/vnet_classify.h>
68 #include <vnet/classify/input_acl.h>
69 #include <vnet/classify/policer_classify.h>
70 #include <vnet/l2/l2_classify.h>
71 #include <vnet/vxlan/vxlan.h>
72 #include <vnet/gre/gre.h>
73 #include <vnet/l2/l2_vtr.h>
74 #include <vnet/vxlan-gpe/vxlan_gpe.h>
75 #include <vnet/lisp-gpe/lisp_gpe.h>
76 #include <vnet/lisp-cp/control.h>
77 #include <vnet/map/map.h>
78 #include <vnet/cop/cop.h>
79 #include <vnet/ip/ip6_hop_by_hop.h>
80 #include <vnet/ip/ip_source_and_port_range_check.h>
81 #include <vnet/devices/af_packet/af_packet.h>
82 #include <vnet/policer/policer.h>
83 #include <vnet/devices/netmap/netmap.h>
84 #include <vnet/flow/flow_report.h>
85 #include <vnet/ipsec-gre/ipsec_gre.h>
88 #undef __included_bihash_template_h__
89 #include <vnet/l2/l2_fib.h>
92 #include <vnet/ipsec/ipsec.h>
93 #include <vnet/ipsec/ikev2.h>
95 #include <vnet/devices/virtio/vhost-user.h>
97 #include <stats/stats.h>
100 #include <vnet/ethernet/ethernet.h>
101 #include <vnet/ethernet/arp_packet.h>
102 #include <vnet/interface.h>
104 #include <vnet/l2/l2_fib.h>
105 #include <vnet/l2/l2_bd.h>
106 #include <vpp-api/vpe_msg_enum.h>
108 #define f64_endian(a)
109 #define f64_print(a,b)
111 #define vl_typedefs /* define message structures */
112 #include <vpp-api/vpe_all_api_h.h>
115 #define vl_endianfun /* define message structures */
116 #include <vpp-api/vpe_all_api_h.h>
119 /* instantiate all the print functions we know about */
120 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
122 #include <vpp-api/vpe_all_api_h.h>
125 #define REPLY_MACRO(t) \
127 unix_shared_memory_queue_t * q; \
128 rv = vl_msg_api_pd_handler (mp, rv); \
129 q = vl_api_client_index_to_input_queue (mp->client_index); \
133 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
134 rmp->_vl_msg_id = ntohs((t)); \
135 rmp->context = mp->context; \
136 rmp->retval = ntohl(rv); \
138 vl_msg_api_send_shmem (q, (u8 *)&rmp); \
141 #define REPLY_MACRO2(t, body) \
143 unix_shared_memory_queue_t * q; \
144 rv = vl_msg_api_pd_handler (mp, rv); \
145 q = vl_api_client_index_to_input_queue (mp->client_index); \
149 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
150 rmp->_vl_msg_id = ntohs((t)); \
151 rmp->context = mp->context; \
152 rmp->retval = ntohl(rv); \
153 do {body;} while (0); \
154 vl_msg_api_send_shmem (q, (u8 *)&rmp); \
157 #if (1 || CLIB_DEBUG > 0) /* "trust, but verify" */
159 #define VALIDATE_SW_IF_INDEX(mp) \
160 do { u32 __sw_if_index = ntohl(mp->sw_if_index); \
161 vnet_main_t *__vnm = vnet_get_main(); \
162 if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
164 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
165 goto bad_sw_if_index; \
169 #define BAD_SW_IF_INDEX_LABEL \
175 #define VALIDATE_RX_SW_IF_INDEX(mp) \
176 do { u32 __rx_sw_if_index = ntohl(mp->rx_sw_if_index); \
177 vnet_main_t *__vnm = vnet_get_main(); \
178 if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
179 __rx_sw_if_index)) { \
180 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
181 goto bad_rx_sw_if_index; \
185 #define BAD_RX_SW_IF_INDEX_LABEL \
187 bad_rx_sw_if_index: \
191 #define VALIDATE_TX_SW_IF_INDEX(mp) \
192 do { u32 __tx_sw_if_index = ntohl(mp->tx_sw_if_index); \
193 vnet_main_t *__vnm = vnet_get_main(); \
194 if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
195 __tx_sw_if_index)) { \
196 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
197 goto bad_tx_sw_if_index; \
201 #define BAD_TX_SW_IF_INDEX_LABEL \
203 bad_tx_sw_if_index: \
209 #define VALIDATE_SW_IF_INDEX(mp)
210 #define BAD_SW_IF_INDEX_LABEL
211 #define VALIDATE_RX_SW_IF_INDEX(mp)
212 #define BAD_RX_SW_IF_INDEX_LABEL
213 #define VALIDATE_TX_SW_IF_INDEX(mp)
214 #define BAD_TX_SW_IF_INDEX_LABEL
216 #endif /* CLIB_DEBUG > 0 */
218 #define foreach_vpe_api_msg \
219 _(WANT_INTERFACE_EVENTS, want_interface_events) \
220 _(WANT_OAM_EVENTS, want_oam_events) \
221 _(OAM_ADD_DEL, oam_add_del) \
222 _(SW_INTERFACE_DUMP, sw_interface_dump) \
223 _(SW_INTERFACE_DETAILS, sw_interface_details) \
224 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
225 _(IP_ADD_DEL_ROUTE, ip_add_del_route) \
226 _(IS_ADDRESS_REACHABLE, is_address_reachable) \
227 _(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address) \
228 _(SW_INTERFACE_SET_TABLE, sw_interface_set_table) \
229 _(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath) \
230 _(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect) \
231 _(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge) \
232 _(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del) \
233 _(BRIDGE_DOMAIN_DUMP, bridge_domain_dump) \
234 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
235 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
236 _(L2FIB_ADD_DEL, l2fib_add_del) \
237 _(L2_FLAGS, l2_flags) \
238 _(BRIDGE_FLAGS, bridge_flags) \
239 _(TAP_CONNECT, tap_connect) \
240 _(TAP_MODIFY, tap_modify) \
241 _(TAP_DELETE, tap_delete) \
242 _(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump) \
243 _(CREATE_VLAN_SUBIF, create_vlan_subif) \
244 _(CREATE_SUBIF, create_subif) \
245 _(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel) \
246 _(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel) \
247 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2) \
248 _(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap) \
249 _(MPLS_ADD_DEL_DECAP, mpls_add_del_decap) \
250 _(PROXY_ARP_ADD_DEL, proxy_arp_add_del) \
251 _(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable) \
252 _(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del) \
253 _(VNET_GET_SUMMARY_STATS, vnet_get_summary_stats) \
254 _(RESET_FIB, reset_fib) \
255 _(DHCP_PROXY_CONFIG,dhcp_proxy_config) \
256 _(DHCP_PROXY_CONFIG_2,dhcp_proxy_config_2) \
257 _(DHCP_PROXY_SET_VSS,dhcp_proxy_set_vss) \
258 _(DHCP_CLIENT_CONFIG, dhcp_client_config) \
259 _(SET_IP_FLOW_HASH,set_ip_flow_hash) \
260 _(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config) \
261 _(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix) \
262 _(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable ) \
263 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
264 sw_interface_ip6_set_link_local_address) \
265 _(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered) \
266 _(CREATE_LOOPBACK, create_loopback) \
267 _(CONTROL_PING, control_ping) \
268 _(NOPRINT_CONTROL_PING, noprint_control_ping) \
269 _(CLI_REQUEST, cli_request) \
270 _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \
271 _(L2_PATCH_ADD_DEL, l2_patch_add_del) \
272 _(CLASSIFY_ADD_DEL_TABLE, classify_add_del_table) \
273 _(CLASSIFY_ADD_DEL_SESSION, classify_add_del_session) \
274 _(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table) \
275 _(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables) \
276 _(GET_NODE_INDEX, get_node_index) \
277 _(ADD_NODE_NEXT, add_node_next) \
278 _(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel) \
279 _(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies) \
280 _(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable) \
281 _(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key) \
282 _(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump) \
283 _(VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel) \
284 _(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump) \
285 _(GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel) \
286 _(GRE_TUNNEL_DUMP, gre_tunnel_dump) \
287 _(L2_FIB_CLEAR_TABLE, l2_fib_clear_table) \
288 _(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter) \
289 _(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite) \
290 _(CREATE_VHOST_USER_IF, create_vhost_user_if) \
291 _(MODIFY_VHOST_USER_IF, modify_vhost_user_if) \
292 _(DELETE_VHOST_USER_IF, delete_vhost_user_if) \
293 _(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump) \
294 _(IP_ADDRESS_DUMP, ip_address_dump) \
295 _(IP_DUMP, ip_dump) \
296 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
297 _(SHOW_VERSION, show_version) \
298 _(L2_FIB_TABLE_DUMP, l2_fib_table_dump) \
299 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
300 _(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel) \
301 _(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump) \
302 _(INTERFACE_NAME_RENUMBER, interface_name_renumber) \
303 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events) \
304 _(INPUT_ACL_SET_INTERFACE, input_acl_set_interface) \
305 _(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
306 _(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
307 _(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry) \
308 _(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry) \
309 _(IPSEC_SA_SET_KEY, ipsec_sa_set_key) \
310 _(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del) \
311 _(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth) \
312 _(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id) \
313 _(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts) \
314 _(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key) \
315 _(DELETE_LOOPBACK, delete_loopback) \
316 _(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del) \
317 _(MAP_ADD_DOMAIN, map_add_domain) \
318 _(MAP_DEL_DOMAIN, map_del_domain) \
319 _(MAP_ADD_DEL_RULE, map_add_del_rule) \
320 _(MAP_DOMAIN_DUMP, map_domain_dump) \
321 _(MAP_RULE_DUMP, map_rule_dump) \
322 _(MAP_SUMMARY_STATS, map_summary_stats) \
323 _(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable) \
324 _(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable) \
325 _(GET_NODE_GRAPH, get_node_graph) \
326 _(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats) \
327 _(TRACE_PROFILE_ADD, trace_profile_add) \
328 _(TRACE_PROFILE_APPLY, trace_profile_apply) \
329 _(TRACE_PROFILE_DEL, trace_profile_del) \
330 _(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set) \
331 _(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator) \
332 _(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid) \
333 _(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry) \
334 _(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver) \
335 _(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable) \
336 _(LISP_ENABLE_DISABLE, lisp_enable_disable) \
337 _(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface) \
338 _(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping) \
339 _(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency) \
340 _(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set) \
341 _(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map) \
342 _(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump) \
343 _(LISP_LOCATOR_DUMP, lisp_locator_dump) \
344 _(LISP_EID_TABLE_DUMP, lisp_eid_table_dump) \
345 _(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump) \
346 _(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump) \
347 _(LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump) \
348 _(LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump) \
349 _(SHOW_LISP_STATUS, show_lisp_status) \
350 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, \
351 lisp_add_del_map_request_itr_rlocs) \
352 _(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs) \
353 _(SHOW_LISP_PITR, show_lisp_pitr) \
354 _(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del) \
355 _(AF_PACKET_CREATE, af_packet_create) \
356 _(AF_PACKET_DELETE, af_packet_delete) \
357 _(POLICER_ADD_DEL, policer_add_del) \
358 _(POLICER_DUMP, policer_dump) \
359 _(POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface) \
360 _(POLICER_CLASSIFY_DUMP, policer_classify_dump) \
361 _(NETMAP_CREATE, netmap_create) \
362 _(NETMAP_DELETE, netmap_delete) \
363 _(MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump) \
364 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details) \
365 _(MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump) \
366 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details) \
367 _(MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump) \
368 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details) \
369 _(MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump) \
370 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details) \
371 _(CLASSIFY_TABLE_IDS,classify_table_ids) \
372 _(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface) \
373 _(CLASSIFY_TABLE_INFO,classify_table_info) \
374 _(CLASSIFY_SESSION_DUMP,classify_session_dump) \
375 _(CLASSIFY_SESSION_DETAILS,classify_session_details) \
376 _(IPFIX_ENABLE,ipfix_enable) \
377 _(IPFIX_DUMP,ipfix_dump) \
378 _(GET_NEXT_INDEX, get_next_index) \
379 _(PG_CREATE_INTERFACE, pg_create_interface) \
380 _(PG_CAPTURE, pg_capture) \
381 _(PG_ENABLE_DISABLE, pg_enable_disable) \
382 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \
383 ip_source_and_port_range_check_add_del) \
384 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \
385 ip_source_and_port_range_check_interface_add_del) \
386 _(IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel) \
387 _(IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump)
390 #define QUOTE(x) QUOTE_(x)
392 #define foreach_registration_hash \
393 _(interface_events) \
394 _(to_netconf_server) \
395 _(from_netconf_server) \
396 _(to_netconf_client) \
397 _(from_netconf_client) \
402 RESOLVE_IP4_ADD_DEL_ROUTE = 1,
403 RESOLVE_IP6_ADD_DEL_ROUTE,
404 RESOLVE_MPLS_ETHERNET_ADD_DEL,
412 vl_api_ip_add_del_route_t r;
413 vl_api_mpls_ethernet_add_del_tunnel_2_t t;
420 #define _(a) uword *a##_registration_hash; \
421 vpe_client_registration_t * a##_registrations;
422 foreach_registration_hash
424 /* notifications happen really early in the game */
425 u8 link_state_process_up;
427 /* ip4 pending route adds */
428 pending_route_t *pending_routes;
430 /* ip4 arp event registration pool */
431 vl_api_ip4_arp_event_t *arp_events;
434 vlib_main_t *vlib_main;
435 vnet_main_t *vnet_main;
438 static vlib_node_registration_t vpe_resolver_process_node;
439 static vpe_api_main_t vpe_api_main;
441 static void send_sw_interface_flags (vpe_api_main_t * am,
442 unix_shared_memory_queue_t * q,
443 vnet_sw_interface_t * swif);
444 static void send_sw_interface_flags_deleted (vpe_api_main_t * am,
445 unix_shared_memory_queue_t * q,
448 static int arp_change_delete_callback (u32 pool_index, u8 * notused);
451 /* Clean up all registrations belonging to the indicated client */
453 vl_api_memclnt_delete_callback (u32 client_index)
455 vpe_api_main_t *vam = &vpe_api_main;
456 vpe_client_registration_t *rp;
458 int stats_memclnt_delete_callback (u32 client_index);
460 stats_memclnt_delete_callback (client_index);
463 p = hash_get (vam->a##_registration_hash, client_index); \
465 rp = pool_elt_at_index (vam->a##_registrations, p[0]); \
466 pool_put (vam->a##_registrations, rp); \
467 hash_unset (vam->a##_registration_hash, client_index); \
469 foreach_registration_hash;
474 #define API_LINK_STATE_EVENT 1
475 #define API_ADMIN_UP_DOWN_EVENT 2
478 event_data_cmp (void *a1, void *a2)
483 return (word) e1[0] - (word) e2[0];
487 link_state_process (vlib_main_t * vm,
488 vlib_node_runtime_t * rt, vlib_frame_t * f)
490 vpe_api_main_t *vam = &vpe_api_main;
491 vnet_main_t *vnm = vam->vnet_main;
492 vnet_sw_interface_t *swif;
493 uword *event_data = 0;
494 vpe_client_registration_t *reg;
496 u32 prev_sw_if_index;
497 unix_shared_memory_queue_t *q;
499 vam->link_state_process_up = 1;
503 vlib_process_wait_for_event (vm);
505 /* Unified list of changed link or admin state sw_if_indices */
506 vlib_process_get_events_with_type
507 (vm, &event_data, API_LINK_STATE_EVENT);
508 vlib_process_get_events_with_type
509 (vm, &event_data, API_ADMIN_UP_DOWN_EVENT);
511 /* Sort, so we can eliminate duplicates */
512 vec_sort_with_function (event_data, event_data_cmp);
514 prev_sw_if_index = ~0;
516 for (i = 0; i < vec_len (event_data); i++)
518 /* Only one message per swif */
519 if (prev_sw_if_index == event_data[i])
521 prev_sw_if_index = event_data[i];
524 pool_foreach(reg, vam->interface_events_registrations,
526 q = vl_api_client_index_to_input_queue (reg->client_index);
529 /* sw_interface may be deleted already */
530 if (!pool_is_free_index (vnm->interface_main.sw_interfaces,
533 swif = vnet_get_sw_interface (vnm, event_data[i]);
534 send_sw_interface_flags (vam, q, swif);
540 vec_reset_length (event_data);
546 static clib_error_t *link_up_down_function (vnet_main_t * vm, u32 hw_if_index,
548 static clib_error_t *admin_up_down_function (vnet_main_t * vm,
549 u32 hw_if_index, u32 flags);
552 VLIB_REGISTER_NODE (link_state_process_node,static) = {
553 .function = link_state_process,
554 .type = VLIB_NODE_TYPE_PROCESS,
555 .name = "vpe-link-state-process",
559 VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (admin_up_down_function);
560 VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (link_up_down_function);
562 static clib_error_t *
563 link_up_down_function (vnet_main_t * vm, u32 hw_if_index, u32 flags)
565 vpe_api_main_t *vam = &vpe_api_main;
566 vnet_hw_interface_t *hi = vnet_get_hw_interface (vm, hw_if_index);
568 if (vam->link_state_process_up)
569 vlib_process_signal_event (vam->vlib_main,
570 link_state_process_node.index,
571 API_LINK_STATE_EVENT, hi->sw_if_index);
575 static clib_error_t *
576 admin_up_down_function (vnet_main_t * vm, u32 sw_if_index, u32 flags)
578 vpe_api_main_t *vam = &vpe_api_main;
581 * Note: it's perfectly fair to set a subif admin up / admin down.
582 * Note the subtle distinction between this routine and the previous
585 if (vam->link_state_process_up)
586 vlib_process_signal_event (vam->vlib_main,
587 link_state_process_node.index,
588 API_ADMIN_UP_DOWN_EVENT, sw_if_index);
592 #define pub_sub_handler(lca,UCA) \
593 static void vl_api_want_##lca##_t_handler ( \
594 vl_api_want_##lca##_t *mp) \
596 vpe_api_main_t *vam = &vpe_api_main; \
597 vpe_client_registration_t *rp; \
598 vl_api_want_##lca##_reply_t *rmp; \
602 p = hash_get (vam->lca##_registration_hash, mp->client_index); \
604 if (mp->enable_disable) { \
605 clib_warning ("pid %d: already enabled...", mp->pid); \
606 rv = VNET_API_ERROR_INVALID_REGISTRATION; \
609 rp = pool_elt_at_index (vam->lca##_registrations, p[0]); \
610 pool_put (vam->lca##_registrations, rp); \
611 hash_unset (vam->lca##_registration_hash, \
616 if (mp->enable_disable == 0) { \
617 clib_warning ("pid %d: already disabled...", mp->pid); \
618 rv = VNET_API_ERROR_INVALID_REGISTRATION; \
621 pool_get (vam->lca##_registrations, rp); \
622 rp->client_index = mp->client_index; \
623 rp->client_pid = mp->pid; \
624 hash_set (vam->lca##_registration_hash, rp->client_index, \
625 rp - vam->lca##_registrations); \
628 REPLY_MACRO (VL_API_WANT_##UCA##_REPLY); \
631 pub_sub_handler (interface_events, INTERFACE_EVENTS)
632 pub_sub_handler (oam_events, OAM_EVENTS)
633 #define RESOLUTION_EVENT 1
634 #define RESOLUTION_PENDING_EVENT 2
635 #define IP4_ARP_EVENT 3
636 static int ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
637 static int ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
638 static int mpls_ethernet_add_del_tunnel_2_t_handler
639 (vl_api_mpls_ethernet_add_del_tunnel_2_t * mp);
641 void handle_ip4_arp_event (u32 pool_index)
643 vpe_api_main_t *vam = &vpe_api_main;
644 vnet_main_t *vnm = vam->vnet_main;
645 vlib_main_t *vm = vam->vlib_main;
646 vl_api_ip4_arp_event_t *event;
647 vl_api_ip4_arp_event_t *mp;
648 unix_shared_memory_queue_t *q;
650 /* Client can cancel, die, etc. */
651 if (pool_is_free_index (vam->arp_events, pool_index))
654 event = pool_elt_at_index (vam->arp_events, pool_index);
656 q = vl_api_client_index_to_input_queue (event->client_index);
659 (void) vnet_add_del_ip4_arp_change_event
660 (vnm, arp_change_delete_callback,
661 event->pid, &event->address,
662 vpe_resolver_process_node.index, IP4_ARP_EVENT,
663 ~0 /* pool index, notused */ , 0 /* is_add */ );
667 if (q->cursize < q->maxsize)
669 mp = vl_msg_api_alloc (sizeof (*mp));
670 clib_memcpy (mp, event, sizeof (*mp));
671 vl_msg_api_send_shmem (q, (u8 *) & mp);
675 static f64 last_time;
677 * Throttle syslog msgs.
678 * It's pretty tempting to just revoke the registration...
680 if (vlib_time_now (vm) > last_time + 10.0)
682 clib_warning ("arp event for %U to pid %d: queue stuffed!",
683 format_ip4_address, &event->address, event->pid);
684 last_time = vlib_time_now (vm);
690 resolver_process (vlib_main_t * vm,
691 vlib_node_runtime_t * rt, vlib_frame_t * f)
694 uword *event_data = 0;
696 vpe_api_main_t *vam = &vpe_api_main;
698 vl_api_ip_add_del_route_t *adr;
699 vl_api_mpls_ethernet_add_del_tunnel_2_t *pme;
700 u32 *resolution_failures = 0;
706 vlib_process_wait_for_event_or_clock (vm, timeout);
708 event_type = vlib_process_get_events (vm, &event_data);
712 case RESOLUTION_PENDING_EVENT:
716 case RESOLUTION_EVENT:
717 for (i = 0; i < vec_len (event_data); i++)
720 * Resolution events can occur long after the
721 * original request has timed out. $$$ add a cancel
724 if (pool_is_free_index (vam->pending_routes, event_data[i]))
727 pr = pool_elt_at_index (vam->pending_routes, event_data[i]);
731 switch (pr->resolve_type)
733 case RESOLVE_IP4_ADD_DEL_ROUTE:
734 rv = ip4_add_del_route_t_handler (adr);
735 clib_warning ("resolver: add %U/%d via %U %s",
737 (ip4_address_t *) & (adr->dst_address),
738 adr->dst_address_length,
740 (ip4_address_t *) & (adr->next_hop_address),
741 (rv >= 0) ? "succeeded" : "failed");
744 case RESOLVE_IP6_ADD_DEL_ROUTE:
745 rv = ip6_add_del_route_t_handler (adr);
746 clib_warning ("resolver: add %U/%d via %U %s",
748 (ip6_address_t *) & (adr->dst_address),
749 adr->dst_address_length,
751 (ip6_address_t *) & (adr->next_hop_address),
752 (rv >= 0) ? "succeeded" : "failed");
755 case RESOLVE_MPLS_ETHERNET_ADD_DEL:
756 rv = mpls_ethernet_add_del_tunnel_2_t_handler (pme);
757 clib_warning ("resolver: add mpls-o-e via %U %s",
760 (pme->next_hop_ip4_address_in_outer_vrf),
761 (rv >= 0) ? "succeeded" : "failed");
765 clib_warning ("resolver: BOGUS TYPE %d", pr->resolve_type);
767 pool_put (vam->pending_routes, pr);
772 for (i = 0; i < vec_len (event_data); i++)
773 handle_ip4_arp_event (event_data[i]);
776 case ~0: /* timeout, retry pending resolutions */
778 pool_foreach (pr, vam->pending_routes,
784 /* May fail, e.g. due to interface down */
785 switch (pr->resolve_type)
787 case RESOLVE_IP4_ADD_DEL_ROUTE:
788 e = ip4_probe_neighbor
789 (vm, (ip4_address_t *)&(adr->next_hop_address),
790 ntohl(adr->next_hop_sw_if_index));
793 case RESOLVE_IP6_ADD_DEL_ROUTE:
794 e = ip6_probe_neighbor
795 (vm, (ip6_address_t *)&(adr->next_hop_address),
796 ntohl(adr->next_hop_sw_if_index));
799 case RESOLVE_MPLS_ETHERNET_ADD_DEL:
801 e = ip4_probe_neighbor
803 (ip4_address_t *)&(pme->next_hop_ip4_address_in_outer_vrf),
804 pme->resolve_opaque);
808 e = clib_error_return (0, "resolver: BOGUS TYPE %d",
813 clib_error_report (e);
815 adr->resolve_attempts = 1;
817 pme->resolve_attempts = 1;
821 adr->resolve_attempts -= 1;
822 if (adr->resolve_attempts == 0)
823 vec_add1 (resolution_failures,
824 pr - vam->pending_routes);
828 pme->resolve_attempts -= 1;
829 if (pme->resolve_attempts == 0)
830 vec_add1 (resolution_failures,
831 pr - vam->pending_routes);
835 for (i = 0; i < vec_len (resolution_failures); i++)
837 pr = pool_elt_at_index (vam->pending_routes,
838 resolution_failures[i]);
842 switch (pr->resolve_type)
844 case RESOLVE_IP4_ADD_DEL_ROUTE:
845 clib_warning ("resolver: add %U/%d via %U retry failure",
847 (ip4_address_t *) & (adr->dst_address),
848 adr->dst_address_length,
850 (ip4_address_t *) & (adr->next_hop_address));
853 case RESOLVE_IP6_ADD_DEL_ROUTE:
854 clib_warning ("resolver: add %U/%d via %U retry failure",
856 (ip6_address_t *) & (adr->dst_address),
857 adr->dst_address_length,
859 (ip6_address_t *) & (adr->next_hop_address));
862 case RESOLVE_MPLS_ETHERNET_ADD_DEL:
863 clib_warning ("resolver: add mpls-o-e via %U retry failure",
866 (pme->next_hop_ip4_address_in_outer_vrf));
870 clib_warning ("BUG");
872 pool_put (vam->pending_routes, pr);
874 vec_reset_length (resolution_failures);
877 if (pool_elts (vam->pending_routes) == 0)
879 vec_reset_length (event_data);
881 return 0; /* or not */
885 VLIB_REGISTER_NODE (vpe_resolver_process_node,static) = {
886 .function = resolver_process,
887 .type = VLIB_NODE_TYPE_PROCESS,
888 .name = "vpe-route-resolver-process",
893 ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
895 ip4_main_t *im = &ip4_main;
896 ip_lookup_main_t *lm = &im->lookup_main;
897 vnet_classify_main_t *cm = &vnet_classify_main;
898 stats_main_t *sm = &stats_main;
899 ip4_add_del_route_args_t a;
900 ip4_address_t next_hop_address;
902 vpe_api_main_t *vam = &vpe_api_main;
903 vnet_main_t *vnm = vam->vnet_main;
904 vlib_main_t *vm = vlib_get_main ();
906 vl_api_ip_add_del_route_t *adr;
912 p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
915 if (mp->create_vrf_if_needed)
918 f = find_ip4_fib_by_table_index_or_id (im, ntohl (mp->vrf_id),
920 fib_index = f->index;
924 /* No such VRF, and we weren't asked to create one */
925 return VNET_API_ERROR_NO_SUCH_FIB;
933 if (~0 != mp->next_hop_sw_if_index &&
934 pool_is_free_index (vnm->interface_main.sw_interfaces,
935 ntohl (mp->next_hop_sw_if_index)))
936 return VNET_API_ERROR_NO_MATCHING_INTERFACE;
938 clib_memcpy (next_hop_address.data, mp->next_hop_address,
939 sizeof (next_hop_address.data));
941 /* Arp for the next_hop if necessary */
942 if (mp->is_add && mp->resolve_if_needed && ~0 != mp->next_hop_sw_if_index)
947 lookup_result = ip4_fib_lookup_with_table
948 (im, fib_index, &next_hop_address, 1 /* disable default route */ );
950 adj = ip_get_adjacency (lm, lookup_result);
952 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
954 pool_get (vam->pending_routes, pr);
955 pr->resolve_type = RESOLVE_IP4_ADD_DEL_ROUTE;
957 clib_memcpy (adr, mp, sizeof (*adr));
958 /* recursion block, "just in case" */
959 adr->resolve_if_needed = 0;
960 adr->resolve_attempts = ntohl (mp->resolve_attempts);
961 vnet_register_ip4_arp_resolution_event
962 (vnm, &next_hop_address, vpe_resolver_process_node.index,
963 RESOLUTION_EVENT, pr - vam->pending_routes);
965 vlib_process_signal_event
966 (vm, vpe_resolver_process_node.index,
967 RESOLUTION_PENDING_EVENT, 0 /* data */ );
969 /* The interface may be down, etc. */
970 e = ip4_probe_neighbor
971 (vm, (ip4_address_t *) & (mp->next_hop_address),
972 ntohl (mp->next_hop_sw_if_index));
975 clib_error_report (e);
977 return VNET_API_ERROR_IN_PROGRESS;
981 if (mp->is_multipath)
985 dslock (sm, 1 /* release hint */ , 10 /* tag */ );
988 flags = IP4_ROUTE_FLAG_ADD;
990 flags = IP4_ROUTE_FLAG_DEL;
993 flags |= IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP;
995 ip4_add_del_route_next_hop (im, flags,
996 (ip4_address_t *) mp->dst_address,
997 (u32) mp->dst_address_length,
998 (ip4_address_t *) mp->next_hop_address,
999 ntohl (mp->next_hop_sw_if_index),
1000 (u32) mp->next_hop_weight,
1001 ~0 /* adj_index */ ,
1007 memset (&a, 0, sizeof (a));
1008 clib_memcpy (a.dst_address.data, mp->dst_address,
1009 sizeof (a.dst_address.data));
1011 a.dst_address_length = mp->dst_address_length;
1013 a.flags = (mp->is_add ? IP4_ROUTE_FLAG_ADD : IP4_ROUTE_FLAG_DEL);
1014 a.flags |= IP4_ROUTE_FLAG_FIB_INDEX;
1015 a.table_index_or_table_id = fib_index;
1020 a.flags |= IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP;
1022 dslock (sm, 1 /* release hint */ , 2 /* tag */ );
1027 ai = lm->drop_adj_index;
1028 else if (mp->is_local)
1029 ai = lm->local_adj_index;
1030 else if (mp->is_classify)
1032 if (pool_is_free_index
1033 (cm->tables, ntohl (mp->classify_table_index)))
1036 return VNET_API_ERROR_NO_SUCH_TABLE;
1038 adj = ip_add_adjacency (lm,
1043 adj->lookup_next_index = IP_LOOKUP_NEXT_CLASSIFY;
1044 adj->classify.table_index = ntohl (mp->classify_table_index);
1046 else if (mp->lookup_in_vrf)
1048 p = hash_get (im->fib_index_by_table_id, ntohl (mp->lookup_in_vrf));
1051 adj = ip_add_adjacency (lm,
1055 adj->explicit_fib_index = p[0];
1060 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
1064 ai = ip4_route_get_next_hop_adj (im,
1067 ntohl (mp->next_hop_sw_if_index),
1070 if (ai == lm->miss_adj_index)
1073 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
1078 ip_adjacency_t *adj;
1079 int disable_default_route = 1;
1081 /* Trying to delete the default route? */
1082 if (a.dst_address.as_u32 == 0 && a.dst_address_length == 0)
1083 disable_default_route = 0;
1085 ai = ip4_fib_lookup_with_table
1086 (im, fib_index, &a.dst_address, disable_default_route);
1087 if (ai == lm->miss_adj_index)
1090 return VNET_API_ERROR_UNKNOWN_DESTINATION;
1093 adj = ip_get_adjacency (lm, ai);
1094 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
1097 return VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
1102 ip4_add_del_route (im, &a);
1109 ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
1111 ip6_main_t *im = &ip6_main;
1112 ip_lookup_main_t *lm = &im->lookup_main;
1113 vnet_main_t *vnm = vnet_get_main ();
1114 vlib_main_t *vm = vlib_get_main ();
1115 vpe_api_main_t *vam = &vpe_api_main;
1116 stats_main_t *sm = &stats_main;
1117 ip6_add_del_route_args_t a;
1118 ip6_address_t next_hop_address;
1119 pending_route_t *pr;
1120 vl_api_ip_add_del_route_t *adr;
1125 ip_adjacency_t *adj = 0;
1128 p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
1132 if (mp->create_vrf_if_needed)
1135 f = find_ip6_fib_by_table_index_or_id (im, ntohl (mp->vrf_id),
1137 fib_index = f->index;
1141 /* No such VRF, and we weren't asked to create one */
1142 return VNET_API_ERROR_NO_SUCH_FIB;
1150 if (~0 != mp->next_hop_sw_if_index &&
1151 pool_is_free_index (vnm->interface_main.sw_interfaces,
1152 ntohl (mp->next_hop_sw_if_index)))
1153 return VNET_API_ERROR_NO_MATCHING_INTERFACE;
1155 clib_memcpy (next_hop_address.as_u8, mp->next_hop_address,
1156 sizeof (next_hop_address.as_u8));
1158 /* Arp for the next_hop if necessary */
1159 if (mp->is_add && mp->resolve_if_needed && ~0 != mp->next_hop_sw_if_index)
1162 ip_adjacency_t *adj;
1164 lookup_result = ip6_fib_lookup_with_table
1165 (im, fib_index, &next_hop_address);
1167 adj = ip_get_adjacency (lm, lookup_result);
1169 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
1171 pool_get (vam->pending_routes, pr);
1173 pr->resolve_type = RESOLVE_IP6_ADD_DEL_ROUTE;
1174 clib_memcpy (adr, mp, sizeof (*adr));
1175 /* recursion block, "just in case" */
1176 adr->resolve_if_needed = 0;
1177 adr->resolve_attempts = ntohl (mp->resolve_attempts);
1178 vnet_register_ip6_neighbor_resolution_event
1179 (vnm, &next_hop_address, vpe_resolver_process_node.index,
1180 RESOLUTION_EVENT, pr - vam->pending_routes);
1182 vlib_process_signal_event
1183 (vm, vpe_resolver_process_node.index,
1184 RESOLUTION_PENDING_EVENT, 0 /* data */ );
1186 /* The interface may be down, etc. */
1187 e = ip6_probe_neighbor
1188 (vm, (ip6_address_t *) & (mp->next_hop_address),
1189 ntohl (mp->next_hop_sw_if_index));
1192 clib_error_report (e);
1194 return VNET_API_ERROR_IN_PROGRESS;
1198 if (mp->is_multipath)
1202 dslock (sm, 1 /* release hint */ , 11 /* tag */ );
1205 flags = IP6_ROUTE_FLAG_ADD;
1207 flags = IP6_ROUTE_FLAG_DEL;
1210 flags |= IP6_ROUTE_FLAG_NOT_LAST_IN_GROUP;
1212 ip6_add_del_route_next_hop (im, flags,
1213 (ip6_address_t *) mp->dst_address,
1214 (u32) mp->dst_address_length,
1215 (ip6_address_t *) mp->next_hop_address,
1216 ntohl (mp->next_hop_sw_if_index),
1217 (u32) mp->next_hop_weight,
1218 ~0 /* adj_index */ ,
1224 memset (&a, 0, sizeof (a));
1225 clib_memcpy (a.dst_address.as_u8, mp->dst_address,
1226 sizeof (a.dst_address.as_u8));
1228 a.dst_address_length = mp->dst_address_length;
1230 a.flags = (mp->is_add ? IP6_ROUTE_FLAG_ADD : IP6_ROUTE_FLAG_DEL);
1231 a.flags |= IP6_ROUTE_FLAG_FIB_INDEX;
1232 a.table_index_or_table_id = fib_index;
1237 a.flags |= IP6_ROUTE_FLAG_NOT_LAST_IN_GROUP;
1239 dslock (sm, 1 /* release hint */ , 3 /* tag */ );
1244 ai = lm->drop_adj_index;
1245 else if (mp->is_local)
1246 ai = lm->local_adj_index;
1247 else if (mp->lookup_in_vrf)
1249 p = hash_get (im->fib_index_by_table_id, ntohl (mp->lookup_in_vrf));
1252 adj = ip_add_adjacency (lm,
1256 adj->explicit_fib_index = p[0];
1261 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
1265 ai = ip6_route_get_next_hop_adj (im,
1268 ntohl (mp->next_hop_sw_if_index),
1270 if (ai == lm->miss_adj_index)
1273 return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
1278 ip_adjacency_t *adj;
1280 ai = ip6_fib_lookup_with_table (im, fib_index, &a.dst_address);
1281 if (ai == lm->miss_adj_index)
1284 return VNET_API_ERROR_UNKNOWN_DESTINATION;
1286 adj = ip_get_adjacency (lm, ai);
1287 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
1290 return VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
1295 ip6_add_del_route (im, &a);
1302 vl_api_ip_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
1304 vl_api_ip_add_del_route_reply_t *rmp;
1306 vnet_main_t *vnm = vnet_get_main ();
1311 rv = ip6_add_del_route_t_handler (mp);
1313 rv = ip4_add_del_route_t_handler (mp);
1315 rv = (rv == 0) ? vnm->api_errno : rv;
1317 REPLY_MACRO (VL_API_IP_ADD_DEL_ROUTE_REPLY);
1321 api_config_default_ip_route (u8 is_ipv6, u8 is_add, u32 vrf_id,
1322 u32 sw_if_index, u8 * next_hop_addr)
1324 vl_api_ip_add_del_route_t mp;
1327 memset (&mp, 0, sizeof (vl_api_ip_add_del_route_t));
1330 * Configure default IP route:
1331 * - ip route add 0.0.0.0/1 via <GW IP>
1332 * - ip route add 128.0.0.0/1 via <GW IP>
1334 mp.next_hop_sw_if_index = ntohl (sw_if_index);
1336 mp.resolve_attempts = ~0;
1337 mp.resolve_if_needed = 1;
1339 mp.is_ipv6 = is_ipv6;
1340 mp.next_hop_weight = 1;
1342 clib_memcpy (&mp.next_hop_address[0], next_hop_addr, 16);
1345 rv = ip6_add_del_route_t_handler (&mp);
1348 mp.dst_address_length = 1;
1350 mp.dst_address[0] = 0;
1351 rv = ip4_add_del_route_t_handler (&mp);
1353 mp.dst_address[0] = 128;
1354 rv |= ip4_add_del_route_t_handler (&mp);
1358 clib_error_return (0, "failed to config default IP route");
1363 vl_api_sw_interface_add_del_address_t_handler
1364 (vl_api_sw_interface_add_del_address_t * mp)
1366 vlib_main_t *vm = vlib_get_main ();
1367 vl_api_sw_interface_add_del_address_reply_t *rmp;
1371 VALIDATE_SW_IF_INDEX (mp);
1373 is_del = mp->is_add == 0;
1376 ip_del_all_interface_addresses (vm, ntohl (mp->sw_if_index));
1377 else if (mp->is_ipv6)
1378 ip6_add_del_interface_address (vm, ntohl (mp->sw_if_index),
1379 (void *) mp->address,
1380 mp->address_length, is_del);
1382 ip4_add_del_interface_address (vm, ntohl (mp->sw_if_index),
1383 (void *) mp->address,
1384 mp->address_length, is_del);
1386 BAD_SW_IF_INDEX_LABEL;
1388 REPLY_MACRO (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY);
1392 vl_api_sw_interface_set_table_t_handler (vl_api_sw_interface_set_table_t * mp)
1395 u32 table_id = ntohl (mp->vrf_id);
1396 u32 sw_if_index = ntohl (mp->sw_if_index);
1397 vl_api_sw_interface_set_table_reply_t *rmp;
1398 stats_main_t *sm = &stats_main;
1400 VALIDATE_SW_IF_INDEX (mp);
1402 dslock (sm, 1 /* release hint */ , 4 /* tag */ );
1406 ip6_main_t *im = &ip6_main;
1407 ip6_fib_t *fib = find_ip6_fib_by_table_index_or_id (im, table_id,
1408 IP6_ROUTE_FLAG_TABLE_ID);
1411 vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
1412 im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
1416 rv = VNET_API_ERROR_NO_SUCH_FIB;
1421 ip4_main_t *im = &ip4_main;
1422 ip4_fib_t *fib = find_ip4_fib_by_table_index_or_id
1423 (im, table_id, IP4_ROUTE_FLAG_TABLE_ID);
1425 /* Truthfully this can't fail */
1428 vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
1429 im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
1433 rv = VNET_API_ERROR_NO_SUCH_FIB;
1438 BAD_SW_IF_INDEX_LABEL;
1440 REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY);
1444 vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t * mp)
1446 vlib_main_t *vm = vlib_get_main ();
1447 ip4_main_t *im4 = &ip4_main;
1448 ip6_main_t *im6 = &ip6_main;
1449 vl_api_sw_interface_set_vpath_reply_t *rmp;
1452 u32 sw_if_index = ntohl (mp->sw_if_index);
1453 ip4_main_t *ip4m = &ip4_main;
1454 ip6_main_t *ip6m = &ip6_main;
1455 ip_lookup_main_t *ip4lm = &ip4m->lookup_main;
1456 ip_lookup_main_t *ip6lm = &ip6m->lookup_main;
1457 ip_config_main_t *rx_cm4u =
1458 &ip4lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT];
1459 ip_config_main_t *rx_cm4m =
1460 &ip4lm->feature_config_mains[VNET_IP_RX_MULTICAST_FEAT];
1461 ip_config_main_t *rx_cm6u =
1462 &ip6lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT];
1463 ip_config_main_t *rx_cm6m =
1464 &ip6lm->feature_config_mains[VNET_IP_RX_MULTICAST_FEAT];
1466 VALIDATE_SW_IF_INDEX (mp);
1468 l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_VPATH, mp->enable);
1471 ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast
1472 ci = vnet_config_add_feature (vm, &rx_cm4u->config_main,
1474 im4->ip4_unicast_rx_feature_vpath, 0, 0);
1475 rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci;
1476 ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast
1477 ci = vnet_config_add_feature (vm, &rx_cm4m->config_main,
1479 im4->ip4_multicast_rx_feature_vpath,
1481 rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci;
1482 ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast
1483 ci = vnet_config_add_feature (vm, &rx_cm6u->config_main,
1485 im6->ip6_unicast_rx_feature_vpath, 0, 0);
1486 rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci;
1487 ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast
1488 ci = vnet_config_add_feature (vm, &rx_cm6m->config_main,
1490 im6->ip6_multicast_rx_feature_vpath,
1492 rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci;
1496 ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast
1497 ci = vnet_config_del_feature (vm, &rx_cm4u->config_main,
1499 im4->ip4_unicast_rx_feature_vpath, 0, 0);
1500 rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci;
1501 ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast
1502 ci = vnet_config_del_feature (vm, &rx_cm4m->config_main,
1504 im4->ip4_multicast_rx_feature_vpath,
1506 rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci;
1507 ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast
1508 ci = vnet_config_del_feature (vm, &rx_cm6u->config_main,
1510 im6->ip6_unicast_rx_feature_vpath, 0, 0);
1511 rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci;
1512 ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast
1513 ci = vnet_config_del_feature (vm, &rx_cm6m->config_main,
1515 im6->ip6_multicast_rx_feature_vpath,
1517 rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci;
1520 BAD_SW_IF_INDEX_LABEL;
1522 REPLY_MACRO (VL_API_SW_INTERFACE_SET_VPATH_REPLY);
1526 vl_api_sw_interface_set_l2_xconnect_t_handler
1527 (vl_api_sw_interface_set_l2_xconnect_t * mp)
1529 vl_api_sw_interface_set_l2_xconnect_reply_t *rmp;
1531 u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
1532 u32 tx_sw_if_index = ntohl (mp->tx_sw_if_index);
1533 vlib_main_t *vm = vlib_get_main ();
1534 vnet_main_t *vnm = vnet_get_main ();
1536 VALIDATE_RX_SW_IF_INDEX (mp);
1540 VALIDATE_TX_SW_IF_INDEX (mp);
1541 rv = set_int_l2_mode (vm, vnm, MODE_L2_XC,
1542 rx_sw_if_index, 0, 0, 0, tx_sw_if_index);
1546 rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
1549 BAD_RX_SW_IF_INDEX_LABEL;
1550 BAD_TX_SW_IF_INDEX_LABEL;
1552 REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_XCONNECT_REPLY);
1556 vl_api_sw_interface_set_l2_bridge_t_handler
1557 (vl_api_sw_interface_set_l2_bridge_t * mp)
1559 bd_main_t *bdm = &bd_main;
1560 vl_api_sw_interface_set_l2_bridge_reply_t *rmp;
1562 u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
1563 u32 bd_id = ntohl (mp->bd_id);
1567 vlib_main_t *vm = vlib_get_main ();
1568 vnet_main_t *vnm = vnet_get_main ();
1570 VALIDATE_RX_SW_IF_INDEX (mp);
1572 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
1576 //VALIDATE_TX_SW_IF_INDEX(mp);
1577 rv = set_int_l2_mode (vm, vnm, MODE_L2_BRIDGE,
1578 rx_sw_if_index, bd_index, bvi, shg, 0);
1582 rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
1585 BAD_RX_SW_IF_INDEX_LABEL;
1587 REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_BRIDGE_REPLY);
1591 vl_api_bridge_domain_add_del_t_handler (vl_api_bridge_domain_add_del_t * mp)
1593 vlib_main_t *vm = vlib_get_main ();
1594 bd_main_t *bdm = &bd_main;
1595 vl_api_bridge_domain_add_del_reply_t *rmp;
1597 u32 enable_flags = 0, disable_flags = 0;
1598 u32 bd_id = ntohl (mp->bd_id);
1603 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
1606 enable_flags |= L2_FLOOD;
1608 disable_flags |= L2_FLOOD;
1611 enable_flags |= L2_UU_FLOOD;
1613 disable_flags |= L2_UU_FLOOD;
1616 enable_flags |= L2_FWD;
1618 disable_flags |= L2_FWD;
1621 enable_flags |= L2_ARP_TERM;
1623 disable_flags |= L2_ARP_TERM;
1626 enable_flags |= L2_LEARN;
1628 disable_flags |= L2_LEARN;
1631 bd_set_flags (vm, bd_index, enable_flags, 1 /* enable */ );
1634 bd_set_flags (vm, bd_index, disable_flags, 0 /* disable */ );
1638 rv = bd_delete_bd_index (bdm, bd_id);
1640 REPLY_MACRO (VL_API_BRIDGE_DOMAIN_ADD_DEL_REPLY);
1644 vl_api_bridge_domain_details_t_handler (vl_api_bridge_domain_details_t * mp)
1646 clib_warning ("BUG");
1650 vl_api_bridge_domain_sw_if_details_t_handler
1651 (vl_api_bridge_domain_sw_if_details_t * mp)
1653 clib_warning ("BUG");
1657 send_bridge_domain_details (unix_shared_memory_queue_t * q,
1658 l2_bridge_domain_t * bd_config,
1659 u32 n_sw_ifs, u32 context)
1661 vl_api_bridge_domain_details_t *mp;
1663 mp = vl_msg_api_alloc (sizeof (*mp));
1664 memset (mp, 0, sizeof (*mp));
1665 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_DETAILS);
1666 mp->bd_id = ntohl (bd_config->bd_id);
1667 mp->flood = bd_feature_flood (bd_config);
1668 mp->uu_flood = bd_feature_uu_flood (bd_config);
1669 mp->forward = bd_feature_forward (bd_config);
1670 mp->learn = bd_feature_learn (bd_config);
1671 mp->arp_term = bd_feature_arp_term (bd_config);
1672 mp->bvi_sw_if_index = ntohl (bd_config->bvi_sw_if_index);
1673 mp->n_sw_ifs = ntohl (n_sw_ifs);
1674 mp->context = context;
1676 vl_msg_api_send_shmem (q, (u8 *) & mp);
1680 send_bd_sw_if_details (l2input_main_t * l2im,
1681 unix_shared_memory_queue_t * q,
1682 l2_flood_member_t * member, u32 bd_id, u32 context)
1684 vl_api_bridge_domain_sw_if_details_t *mp;
1685 l2_input_config_t *input_cfg;
1687 mp = vl_msg_api_alloc (sizeof (*mp));
1688 memset (mp, 0, sizeof (*mp));
1689 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_SW_IF_DETAILS);
1690 mp->bd_id = ntohl (bd_id);
1691 mp->sw_if_index = ntohl (member->sw_if_index);
1692 input_cfg = vec_elt_at_index (l2im->configs, member->sw_if_index);
1693 mp->shg = input_cfg->shg;
1694 mp->context = context;
1696 vl_msg_api_send_shmem (q, (u8 *) & mp);
1700 vl_api_bridge_domain_dump_t_handler (vl_api_bridge_domain_dump_t * mp)
1702 bd_main_t *bdm = &bd_main;
1703 l2input_main_t *l2im = &l2input_main;
1704 unix_shared_memory_queue_t *q;
1705 l2_bridge_domain_t *bd_config;
1706 u32 bd_id, bd_index;
1709 q = vl_api_client_index_to_input_queue (mp->client_index);
1714 bd_id = ntohl (mp->bd_id);
1716 bd_index = (bd_id == ~0) ? 0 : bd_find_or_add_bd_index (bdm, bd_id);
1717 end = (bd_id == ~0) ? vec_len (l2im->bd_configs) : bd_index + 1;
1718 for (; bd_index < end; bd_index++)
1720 bd_config = l2input_bd_config_from_index (l2im, bd_index);
1721 /* skip dummy bd_id 0 */
1722 if (bd_config && (bd_config->bd_id > 0))
1725 l2_flood_member_t *m;
1727 n_sw_ifs = vec_len (bd_config->members);
1728 send_bridge_domain_details (q, bd_config, n_sw_ifs, mp->context);
1730 vec_foreach (m, bd_config->members)
1732 send_bd_sw_if_details (l2im, q, m, bd_config->bd_id, mp->context);
1739 vl_api_l2fib_add_del_t_handler (vl_api_l2fib_add_del_t * mp)
1741 bd_main_t *bdm = &bd_main;
1742 l2input_main_t *l2im = &l2input_main;
1743 vl_api_l2fib_add_del_reply_t *rmp;
1746 u32 sw_if_index = ntohl (mp->sw_if_index);
1747 u32 bd_id = ntohl (mp->bd_id);
1756 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1759 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1760 goto bad_sw_if_index;
1766 VALIDATE_SW_IF_INDEX (mp);
1767 if (vec_len (l2im->configs) <= sw_if_index)
1769 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1770 goto bad_sw_if_index;
1774 l2_input_config_t *config;
1775 config = vec_elt_at_index (l2im->configs, sw_if_index);
1776 if (config->bridge == 0)
1778 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1779 goto bad_sw_if_index;
1782 static_mac = mp->static_mac ? 1 : 0;
1783 filter_mac = mp->filter_mac ? 1 : 0;
1784 bvi_mac = mp->bvi_mac ? 1 : 0;
1785 l2fib_add_entry (mac, bd_index, sw_if_index, static_mac, filter_mac,
1790 l2fib_del_entry (mac, bd_index);
1793 BAD_SW_IF_INDEX_LABEL;
1795 REPLY_MACRO (VL_API_L2FIB_ADD_DEL_REPLY);
1799 vl_api_l2_flags_t_handler (vl_api_l2_flags_t * mp)
1801 vl_api_l2_flags_reply_t *rmp;
1803 u32 sw_if_index = ntohl (mp->sw_if_index);
1804 u32 flags = ntohl (mp->feature_bitmap);
1807 VALIDATE_SW_IF_INDEX (mp);
1810 if (flags & L2INPUT_FEAT_ ## a) \
1811 rbm = l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_ ## a, mp->is_set);
1812 foreach_l2input_feat;
1815 BAD_SW_IF_INDEX_LABEL;
1818 REPLY_MACRO2(VL_API_L2_FLAGS_REPLY,
1820 rmp->resulting_feature_bitmap = ntohl(rbm);
1826 vl_api_bridge_flags_t_handler (vl_api_bridge_flags_t * mp)
1828 vlib_main_t *vm = vlib_get_main ();
1829 bd_main_t *bdm = &bd_main;
1830 vl_api_bridge_flags_reply_t *rmp;
1832 u32 bd_id = ntohl (mp->bd_id);
1834 u32 flags = ntohl (mp->feature_bitmap);
1837 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1840 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1846 bd_set_flags (vm, bd_index, flags, mp->is_set);
1850 REPLY_MACRO2(VL_API_BRIDGE_FLAGS_REPLY,
1852 rmp->resulting_feature_bitmap = ntohl(flags);
1858 vl_api_bd_ip_mac_add_del_t_handler (vl_api_bd_ip_mac_add_del_t * mp)
1860 bd_main_t *bdm = &bd_main;
1861 vl_api_bd_ip_mac_add_del_reply_t *rmp;
1863 u32 bd_id = ntohl (mp->bd_id);
1867 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1870 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1875 if (bd_add_del_ip_mac (bd_index, mp->ip_address,
1876 mp->mac_address, mp->is_ipv6, mp->is_add))
1877 rv = VNET_API_ERROR_UNSPECIFIED;
1880 REPLY_MACRO (VL_API_BD_IP_MAC_ADD_DEL_REPLY);
1884 vl_api_tap_connect_t_handler (vl_api_tap_connect_t * mp, vlib_main_t * vm)
1887 vl_api_tap_connect_reply_t *rmp;
1888 unix_shared_memory_queue_t *q;
1889 u32 sw_if_index = (u32) ~ 0;
1891 rv = vnet_tap_connect_renumber (vm, mp->tap_name,
1892 mp->use_random_mac ? 0 : mp->mac_address,
1893 &sw_if_index, mp->renumber,
1894 ntohl (mp->custom_dev_instance));
1896 q = vl_api_client_index_to_input_queue (mp->client_index);
1900 rmp = vl_msg_api_alloc (sizeof (*rmp));
1901 rmp->_vl_msg_id = ntohs (VL_API_TAP_CONNECT_REPLY);
1902 rmp->context = mp->context;
1903 rmp->retval = ntohl (rv);
1904 rmp->sw_if_index = ntohl (sw_if_index);
1906 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1910 vl_api_tap_modify_t_handler (vl_api_tap_modify_t * mp, vlib_main_t * vm)
1913 vl_api_tap_modify_reply_t *rmp;
1914 unix_shared_memory_queue_t *q;
1915 u32 sw_if_index = (u32) ~ 0;
1917 rv = vnet_tap_modify (vm, ntohl (mp->sw_if_index), mp->tap_name,
1918 mp->use_random_mac ? 0 : mp->mac_address,
1919 &sw_if_index, mp->renumber,
1920 ntohl (mp->custom_dev_instance));
1922 q = vl_api_client_index_to_input_queue (mp->client_index);
1926 rmp = vl_msg_api_alloc (sizeof (*rmp));
1927 rmp->_vl_msg_id = ntohs (VL_API_TAP_MODIFY_REPLY);
1928 rmp->context = mp->context;
1929 rmp->retval = ntohl (rv);
1930 rmp->sw_if_index = ntohl (sw_if_index);
1932 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1936 vl_api_tap_delete_t_handler (vl_api_tap_delete_t * mp, vlib_main_t * vm)
1939 vpe_api_main_t *vam = &vpe_api_main;
1940 vl_api_tap_delete_reply_t *rmp;
1941 unix_shared_memory_queue_t *q;
1942 u32 sw_if_index = ntohl (mp->sw_if_index);
1944 rv = vnet_tap_delete (vm, sw_if_index);
1946 q = vl_api_client_index_to_input_queue (mp->client_index);
1950 rmp = vl_msg_api_alloc (sizeof (*rmp));
1951 rmp->_vl_msg_id = ntohs (VL_API_TAP_DELETE_REPLY);
1952 rmp->context = mp->context;
1953 rmp->retval = ntohl (rv);
1955 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1958 send_sw_interface_flags_deleted (vam, q, sw_if_index);
1962 vl_api_create_vlan_subif_t_handler (vl_api_create_vlan_subif_t * mp)
1964 vl_api_create_vlan_subif_reply_t *rmp;
1965 vnet_main_t *vnm = vnet_get_main ();
1966 u32 hw_if_index, sw_if_index = (u32) ~ 0;
1967 vnet_hw_interface_t *hi;
1970 vnet_sw_interface_t template;
1972 vnet_interface_main_t *im = &vnm->interface_main;
1973 u64 sup_and_sub_key;
1975 unix_shared_memory_queue_t *q;
1976 clib_error_t *error;
1978 VALIDATE_SW_IF_INDEX (mp);
1980 hw_if_index = ntohl (mp->sw_if_index);
1981 hi = vnet_get_hw_interface (vnm, hw_if_index);
1983 id = ntohl (mp->vlan_id);
1984 if (id == 0 || id > 4095)
1986 rv = VNET_API_ERROR_INVALID_VLAN;
1990 sup_and_sub_key = ((u64) (hi->sw_if_index) << 32) | (u64) id;
1992 p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1995 rv = VNET_API_ERROR_VLAN_ALREADY_EXISTS;
1999 kp = clib_mem_alloc (sizeof (*kp));
2000 *kp = sup_and_sub_key;
2002 memset (&template, 0, sizeof (template));
2003 template.type = VNET_SW_INTERFACE_TYPE_SUB;
2004 template.sup_sw_if_index = hi->sw_if_index;
2005 template.sub.id = id;
2006 template.sub.eth.raw_flags = 0;
2007 template.sub.eth.flags.one_tag = 1;
2008 template.sub.eth.outer_vlan_id = id;
2009 template.sub.eth.flags.exact_match = 1;
2011 error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
2014 clib_error_report (error);
2015 rv = VNET_API_ERROR_INVALID_REGISTRATION;
2018 hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
2019 hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
2021 BAD_SW_IF_INDEX_LABEL;
2024 q = vl_api_client_index_to_input_queue (mp->client_index);
2028 rmp = vl_msg_api_alloc (sizeof (*rmp));
2029 rmp->_vl_msg_id = ntohs (VL_API_CREATE_VLAN_SUBIF_REPLY);
2030 rmp->context = mp->context;
2031 rmp->retval = ntohl (rv);
2032 rmp->sw_if_index = ntohl (sw_if_index);
2033 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2037 vl_api_create_subif_t_handler (vl_api_create_subif_t * mp)
2039 vl_api_create_subif_reply_t *rmp;
2040 vnet_main_t *vnm = vnet_get_main ();
2041 u32 sw_if_index = ~0;
2044 vnet_sw_interface_t *si;
2045 vnet_hw_interface_t *hi;
2046 vnet_sw_interface_t template;
2048 vnet_interface_main_t *im = &vnm->interface_main;
2049 u64 sup_and_sub_key;
2051 clib_error_t *error;
2053 VALIDATE_SW_IF_INDEX (mp);
2055 si = vnet_get_sup_sw_interface (vnm, ntohl (mp->sw_if_index));
2056 hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
2058 if (hi->bond_info == VNET_HW_INTERFACE_BOND_INFO_SLAVE)
2060 rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
2064 sw_if_index = si->sw_if_index;
2065 sub_id = ntohl (mp->sub_id);
2067 sup_and_sub_key = ((u64) (sw_if_index) << 32) | (u64) sub_id;
2069 p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
2073 clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
2074 sw_if_index, sub_id);
2075 rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
2079 kp = clib_mem_alloc (sizeof (*kp));
2080 *kp = sup_and_sub_key;
2082 memset (&template, 0, sizeof (template));
2083 template.type = VNET_SW_INTERFACE_TYPE_SUB;
2084 template.sup_sw_if_index = sw_if_index;
2085 template.sub.id = sub_id;
2086 template.sub.eth.flags.no_tags = mp->no_tags;
2087 template.sub.eth.flags.one_tag = mp->one_tag;
2088 template.sub.eth.flags.two_tags = mp->two_tags;
2089 template.sub.eth.flags.dot1ad = mp->dot1ad;
2090 template.sub.eth.flags.exact_match = mp->exact_match;
2091 template.sub.eth.flags.default_sub = mp->default_sub;
2092 template.sub.eth.flags.outer_vlan_id_any = mp->outer_vlan_id_any;
2093 template.sub.eth.flags.inner_vlan_id_any = mp->inner_vlan_id_any;
2094 template.sub.eth.outer_vlan_id = ntohs (mp->outer_vlan_id);
2095 template.sub.eth.inner_vlan_id = ntohs (mp->inner_vlan_id);
2097 error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
2100 clib_error_report (error);
2101 rv = VNET_API_ERROR_SUBIF_CREATE_FAILED;
2105 hash_set (hi->sub_interface_sw_if_index_by_id, sub_id, sw_if_index);
2106 hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
2108 BAD_SW_IF_INDEX_LABEL;
2113 REPLY_MACRO2(VL_API_CREATE_SUBIF_REPLY,
2115 rmp->sw_if_index = ntohl(sw_if_index);
2121 vl_api_mpls_gre_add_del_tunnel_t_handler (vl_api_mpls_gre_add_del_tunnel_t *
2124 vl_api_mpls_gre_add_del_tunnel_reply_t *rmp;
2126 stats_main_t *sm = &stats_main;
2127 u32 tunnel_sw_if_index = ~0;
2129 dslock (sm, 1 /* release hint */ , 5 /* tag */ );
2131 rv = vnet_mpls_gre_add_del_tunnel ((ip4_address_t *) (mp->src_address),
2132 (ip4_address_t *) (mp->dst_address),
2133 (ip4_address_t *) (mp->intfc_address),
2134 (u32) (mp->intfc_address_length),
2135 ntohl (mp->inner_vrf_id),
2136 ntohl (mp->outer_vrf_id),
2137 &tunnel_sw_if_index,
2138 mp->l2_only, mp->is_add);
2142 REPLY_MACRO2(VL_API_MPLS_GRE_ADD_DEL_TUNNEL_REPLY,
2144 rmp->tunnel_sw_if_index = ntohl(tunnel_sw_if_index);
2150 vl_api_mpls_ethernet_add_del_tunnel_t_handler
2151 (vl_api_mpls_ethernet_add_del_tunnel_t * mp)
2153 vl_api_mpls_ethernet_add_del_tunnel_reply_t *rmp;
2155 stats_main_t *sm = &stats_main;
2156 u32 tunnel_sw_if_index;
2158 dslock (sm, 1 /* release hint */ , 5 /* tag */ );
2160 rv = vnet_mpls_ethernet_add_del_tunnel
2161 (mp->dst_mac_address, (ip4_address_t *) (mp->adj_address),
2162 (u32) (mp->adj_address_length), ntohl (mp->vrf_id),
2163 ntohl (mp->tx_sw_if_index),
2164 &tunnel_sw_if_index, mp->l2_only, mp->is_add);
2169 REPLY_MACRO2(VL_API_MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,
2171 rmp->tunnel_sw_if_index = ntohl(tunnel_sw_if_index);
2177 * This piece of misery brought to you because the control-plane
2178 * can't figure out the tx interface + dst-mac address all by itself
2180 static int mpls_ethernet_add_del_tunnel_2_t_handler
2181 (vl_api_mpls_ethernet_add_del_tunnel_2_t * mp)
2183 pending_route_t *pr;
2184 vl_api_mpls_ethernet_add_del_tunnel_2_t *pme;
2185 vnet_main_t *vnm = vnet_get_main ();
2186 vlib_main_t *vm = vlib_get_main ();
2187 stats_main_t *sm = &stats_main;
2188 vpe_api_main_t *vam = &vpe_api_main;
2189 u32 inner_fib_index, outer_fib_index;
2190 ip4_main_t *im = &ip4_main;
2191 ip_lookup_main_t *lm = &im->lookup_main;
2192 ip_adjacency_t *adj = 0;
2195 u8 *dst_mac_address;
2199 u32 tunnel_sw_if_index;
2201 p = hash_get (im->fib_index_by_table_id, ntohl (mp->outer_vrf_id));
2203 return VNET_API_ERROR_NO_SUCH_FIB;
2205 outer_fib_index = p[0];
2208 p = hash_get (im->fib_index_by_table_id, ntohl (mp->inner_vrf_id));
2210 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
2212 inner_fib_index = p[0];
2214 if (inner_fib_index == outer_fib_index)
2215 return VNET_API_ERROR_INVALID_VALUE;
2217 lookup_result = ip4_fib_lookup_with_table
2218 (im, outer_fib_index,
2219 (ip4_address_t *) mp->next_hop_ip4_address_in_outer_vrf,
2220 1 /* disable default route */ );
2222 adj = ip_get_adjacency (lm, lookup_result);
2223 tx_sw_if_index = adj->rewrite_header.sw_if_index;
2225 if (mp->is_add && mp->resolve_if_needed)
2227 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
2229 pool_get (vam->pending_routes, pr);
2230 pr->resolve_type = RESOLVE_MPLS_ETHERNET_ADD_DEL;
2232 clib_memcpy (pme, mp, sizeof (*pme));
2233 /* recursion block, "just in case" */
2234 pme->resolve_if_needed = 0;
2235 pme->resolve_attempts = ntohl (mp->resolve_attempts);
2236 pme->resolve_opaque = tx_sw_if_index;
2237 vnet_register_ip4_arp_resolution_event
2239 (ip4_address_t *) & (pme->next_hop_ip4_address_in_outer_vrf),
2240 vpe_resolver_process_node.index,
2241 RESOLUTION_EVENT, pr - vam->pending_routes);
2243 vlib_process_signal_event
2244 (vm, vpe_resolver_process_node.index,
2245 RESOLUTION_PENDING_EVENT, 0 /* data */ );
2247 /* The interface may be down, etc. */
2248 e = ip4_probe_neighbor
2249 (vm, (ip4_address_t *) & (mp->next_hop_ip4_address_in_outer_vrf),
2253 clib_error_report (e);
2255 return VNET_API_ERROR_IN_PROGRESS;
2259 if (adj->lookup_next_index != IP_LOOKUP_NEXT_REWRITE)
2260 return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
2263 vnet_rewrite_get_data_internal
2264 (&adj->rewrite_header, sizeof (adj->rewrite_data));
2266 dslock (sm, 1 /* release hint */ , 10 /* tag */ );
2268 rv = vnet_mpls_ethernet_add_del_tunnel
2269 (dst_mac_address, (ip4_address_t *) (mp->adj_address),
2270 (u32) (mp->adj_address_length), ntohl (mp->inner_vrf_id),
2271 tx_sw_if_index, &tunnel_sw_if_index, mp->l2_only, mp->is_add);
2279 vl_api_mpls_ethernet_add_del_tunnel_2_t_handler
2280 (vl_api_mpls_ethernet_add_del_tunnel_2_t * mp)
2282 vl_api_mpls_ethernet_add_del_tunnel_reply_t *rmp;
2285 rv = mpls_ethernet_add_del_tunnel_2_t_handler (mp);
2287 REPLY_MACRO (VL_API_MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY);
2292 vl_api_mpls_add_del_encap_t_handler (vl_api_mpls_add_del_encap_t * mp)
2294 vl_api_mpls_add_del_encap_reply_t *rmp;
2299 vec_reset_length (labels);
2301 for (i = 0; i < mp->nlabels; i++)
2302 vec_add1 (labels, ntohl (mp->labels[i]));
2305 rv = vnet_mpls_add_del_encap ((ip4_address_t *) mp->dst_address,
2306 ntohl (mp->vrf_id), labels,
2307 ~0 /* policy_tunnel_index */ ,
2308 0 /* no_dst_hash */ ,
2312 REPLY_MACRO (VL_API_MPLS_ADD_DEL_ENCAP_REPLY);
2316 vl_api_mpls_add_del_decap_t_handler (vl_api_mpls_add_del_decap_t * mp)
2318 vl_api_mpls_add_del_decap_reply_t *rmp;
2321 rv = vnet_mpls_add_del_decap (ntohl (mp->rx_vrf_id), ntohl (mp->tx_vrf_id),
2322 ntohl (mp->label), ntohl (mp->next_index),
2323 mp->s_bit, mp->is_add);
2325 REPLY_MACRO (VL_API_MPLS_ADD_DEL_DECAP_REPLY);
2329 vl_api_proxy_arp_add_del_t_handler (vl_api_proxy_arp_add_del_t * mp)
2331 vl_api_proxy_arp_add_del_reply_t *rmp;
2334 ip4_main_t *im = &ip4_main;
2335 stats_main_t *sm = &stats_main;
2336 int vnet_proxy_arp_add_del (ip4_address_t * lo_addr,
2337 ip4_address_t * hi_addr,
2338 u32 fib_index, int is_del);
2341 dslock (sm, 1 /* release hint */ , 6 /* tag */ );
2343 p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
2347 rv = VNET_API_ERROR_NO_SUCH_FIB;
2353 rv = vnet_proxy_arp_add_del ((ip4_address_t *) mp->low_address,
2354 (ip4_address_t *) mp->hi_address,
2355 fib_index, mp->is_add == 0);
2359 REPLY_MACRO (VL_API_PROXY_ARP_ADD_DEL_REPLY);
2363 vl_api_proxy_arp_intfc_enable_disable_t_handler
2364 (vl_api_proxy_arp_intfc_enable_disable_t * mp)
2367 vnet_main_t *vnm = vnet_get_main ();
2368 vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;
2369 vnet_sw_interface_t *si;
2372 VALIDATE_SW_IF_INDEX (mp);
2374 sw_if_index = ntohl (mp->sw_if_index);
2376 if (pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index))
2378 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
2382 si = vnet_get_sw_interface (vnm, sw_if_index);
2386 if (mp->enable_disable)
2387 si->flags |= VNET_SW_INTERFACE_FLAG_PROXY_ARP;
2389 si->flags &= ~VNET_SW_INTERFACE_FLAG_PROXY_ARP;
2391 BAD_SW_IF_INDEX_LABEL;
2394 REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
2398 vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
2401 vl_api_ip_neighbor_add_del_reply_t *rmp;
2402 vnet_main_t *vnm = vnet_get_main ();
2405 stats_main_t *sm = &stats_main;
2407 VALIDATE_SW_IF_INDEX (mp);
2409 dslock (sm, 1 /* release hint */ , 7 /* tag */ );
2414 rv = vnet_set_ip6_ethernet_neighbor
2415 (vm, ntohl (mp->sw_if_index),
2416 (ip6_address_t *) (mp->dst_address),
2417 mp->mac_address, sizeof (mp->mac_address), mp->is_static);
2419 rv = vnet_unset_ip6_ethernet_neighbor
2420 (vm, ntohl (mp->sw_if_index),
2421 (ip6_address_t *) (mp->dst_address),
2422 mp->mac_address, sizeof (mp->mac_address));
2426 ip4_main_t *im = &ip4_main;
2427 ip_lookup_main_t *lm = &im->lookup_main;
2428 ethernet_arp_ip4_over_ethernet_address_t a;
2430 ip_adjacency_t *nh_adj;
2432 uword *p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
2435 rv = VNET_API_ERROR_NO_SUCH_FIB;
2441 * Unfortunately, folks have a penchant for
2442 * adding interface addresses to the ARP cache, and
2443 * wondering why the forwarder eventually ASSERTs...
2445 ai = ip4_fib_lookup_with_table
2446 (im, fib_index, (ip4_address_t *) (mp->dst_address),
2447 1 /* disable default route */ );
2451 nh_adj = ip_get_adjacency (lm, ai);
2452 /* Never allow manipulation of a local adj! */
2453 if (nh_adj->lookup_next_index == IP_LOOKUP_NEXT_LOCAL)
2455 clib_warning ("%U matches local adj",
2457 (ip4_address_t *) (mp->dst_address));
2458 rv = VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
2463 clib_memcpy (&a.ethernet, mp->mac_address, 6);
2464 clib_memcpy (&a.ip4, mp->dst_address, 4);
2467 rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
2468 fib_index, &a, mp->is_static);
2470 rv = vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
2474 BAD_SW_IF_INDEX_LABEL;
2477 REPLY_MACRO (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY);
2481 vl_api_is_address_reachable_t_handler (vl_api_is_address_reachable_t * mp)
2484 vpe_main_t *rm = &vpe_main;
2485 ip4_main_t *im4 = &ip4_main;
2486 ip6_main_t *im6 = &ip6_main;
2487 ip_lookup_main_t *lm;
2493 u32 adj_index, sw_if_index;
2494 vl_api_is_address_reachable_t *rmp;
2495 ip_adjacency_t *adj;
2496 unix_shared_memory_queue_t *q;
2498 q = vl_api_client_index_to_input_queue (mp->client_index);
2501 increment_missing_api_client_counter (rm->vlib_main);
2505 rmp = vl_msg_api_alloc (sizeof (*rmp));
2506 clib_memcpy (rmp, mp, sizeof (*rmp));
2508 sw_if_index = mp->next_hop_sw_if_index;
2509 clib_memcpy (&addr, mp->address, sizeof (addr));
2512 lm = &im6->lookup_main;
2513 adj_index = ip6_fib_lookup (im6, sw_if_index, &addr.ip6);
2517 lm = &im4->lookup_main;
2518 adj_index = ip4_fib_lookup (im4, sw_if_index, &addr.ip4);
2520 if (adj_index == ~0)
2525 adj = ip_get_adjacency (lm, adj_index);
2527 if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE
2528 && adj->rewrite_header.sw_if_index == sw_if_index)
2534 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP
2535 && adj->rewrite_header.sw_if_index == sw_if_index)
2538 ip6_probe_neighbor (rm->vlib_main, &addr.ip6, sw_if_index);
2540 ip4_probe_neighbor (rm->vlib_main, &addr.ip4, sw_if_index);
2542 else if (adj->lookup_next_index == IP_LOOKUP_NEXT_DROP)
2551 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2556 vl_api_sw_interface_details_t_handler (vl_api_sw_interface_details_t * mp)
2558 clib_warning ("BUG");
2562 vl_api_sw_interface_set_flags_t_handler (vl_api_sw_interface_set_flags_t * mp)
2564 vl_api_sw_interface_set_flags_reply_t *rmp;
2565 vnet_main_t *vnm = vnet_get_main ();
2567 clib_error_t *error;
2570 VALIDATE_SW_IF_INDEX (mp);
2572 flags = mp->admin_up_down ? VNET_SW_INTERFACE_FLAG_ADMIN_UP : 0;
2574 error = vnet_sw_interface_set_flags (vnm, ntohl (mp->sw_if_index), flags);
2578 clib_error_report (error);
2581 BAD_SW_IF_INDEX_LABEL;
2582 REPLY_MACRO (VL_API_SW_INTERFACE_SET_FLAGS_REPLY);
2586 vl_api_sw_interface_clear_stats_t_handler (vl_api_sw_interface_clear_stats_t *
2589 vl_api_sw_interface_clear_stats_reply_t *rmp;
2591 vnet_main_t *vnm = vnet_get_main ();
2592 vnet_interface_main_t *im = &vnm->interface_main;
2593 vlib_simple_counter_main_t *sm;
2594 vlib_combined_counter_main_t *cm;
2595 static vnet_main_t **my_vnet_mains;
2596 int i, j, n_counters;
2599 if (mp->sw_if_index != ~0)
2600 VALIDATE_SW_IF_INDEX (mp);
2602 vec_reset_length (my_vnet_mains);
2604 for (i = 0; i < vec_len (vnet_mains); i++)
2607 vec_add1 (my_vnet_mains, vnet_mains[i]);
2610 if (vec_len (vnet_mains) == 0)
2611 vec_add1 (my_vnet_mains, vnm);
2613 n_counters = vec_len (im->combined_sw_if_counters);
2615 for (j = 0; j < n_counters; j++)
2617 for (i = 0; i < vec_len (my_vnet_mains); i++)
2619 im = &my_vnet_mains[i]->interface_main;
2620 cm = im->combined_sw_if_counters + j;
2621 if (mp->sw_if_index == (u32) ~ 0)
2622 vlib_clear_combined_counters (cm);
2624 vlib_zero_combined_counter (cm, ntohl (mp->sw_if_index));
2628 n_counters = vec_len (im->sw_if_counters);
2630 for (j = 0; j < n_counters; j++)
2632 for (i = 0; i < vec_len (my_vnet_mains); i++)
2634 im = &my_vnet_mains[i]->interface_main;
2635 sm = im->sw_if_counters + j;
2636 if (mp->sw_if_index == (u32) ~ 0)
2637 vlib_clear_simple_counters (sm);
2639 vlib_zero_simple_counter (sm, ntohl (mp->sw_if_index));
2643 BAD_SW_IF_INDEX_LABEL;
2645 REPLY_MACRO (VL_API_SW_INTERFACE_CLEAR_STATS_REPLY);
2649 send_sw_interface_details (vpe_api_main_t * am,
2650 unix_shared_memory_queue_t * q,
2651 vnet_sw_interface_t * swif,
2652 u8 * interface_name, u32 context)
2654 vl_api_sw_interface_details_t *mp;
2655 vnet_hw_interface_t *hi;
2657 hi = vnet_get_sup_hw_interface (am->vnet_main, swif->sw_if_index);
2659 mp = vl_msg_api_alloc (sizeof (*mp));
2660 memset (mp, 0, sizeof (*mp));
2661 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_DETAILS);
2662 mp->sw_if_index = ntohl (swif->sw_if_index);
2663 mp->sup_sw_if_index = ntohl (swif->sup_sw_if_index);
2664 mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0;
2665 mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0;
2666 mp->link_duplex = ((hi->flags & VNET_HW_INTERFACE_FLAG_DUPLEX_MASK) >>
2667 VNET_HW_INTERFACE_FLAG_DUPLEX_SHIFT);
2668 mp->link_speed = ((hi->flags & VNET_HW_INTERFACE_FLAG_SPEED_MASK) >>
2669 VNET_HW_INTERFACE_FLAG_SPEED_SHIFT);
2670 mp->link_mtu = ntohs (hi->max_packet_bytes);
2671 mp->context = context;
2673 strncpy ((char *) mp->interface_name,
2674 (char *) interface_name, ARRAY_LEN (mp->interface_name) - 1);
2676 /* Send the L2 address for ethernet physical intfcs */
2677 if (swif->sup_sw_if_index == swif->sw_if_index
2678 && hi->hw_class_index == ethernet_hw_interface_class.index)
2680 ethernet_main_t *em = ethernet_get_main (am->vlib_main);
2681 ethernet_interface_t *ei;
2683 ei = pool_elt_at_index (em->interfaces, hi->hw_instance);
2684 ASSERT (sizeof (mp->l2_address) >= sizeof (ei->address));
2685 clib_memcpy (mp->l2_address, ei->address, sizeof (ei->address));
2686 mp->l2_address_length = ntohl (sizeof (ei->address));
2688 else if (swif->sup_sw_if_index != swif->sw_if_index)
2690 vnet_sub_interface_t *sub = &swif->sub;
2691 mp->sub_id = ntohl (sub->id);
2692 mp->sub_dot1ad = sub->eth.flags.dot1ad;
2693 mp->sub_number_of_tags =
2694 sub->eth.flags.one_tag + sub->eth.flags.two_tags * 2;
2695 mp->sub_outer_vlan_id = ntohs (sub->eth.outer_vlan_id);
2696 mp->sub_inner_vlan_id = ntohs (sub->eth.inner_vlan_id);
2697 mp->sub_exact_match = sub->eth.flags.exact_match;
2698 mp->sub_default = sub->eth.flags.default_sub;
2699 mp->sub_outer_vlan_id_any = sub->eth.flags.outer_vlan_id_any;
2700 mp->sub_inner_vlan_id_any = sub->eth.flags.inner_vlan_id_any;
2702 /* vlan tag rewrite data */
2703 u32 vtr_op = L2_VTR_DISABLED;
2704 u32 vtr_push_dot1q = 0, vtr_tag1 = 0, vtr_tag2 = 0;
2706 if (l2vtr_get (am->vlib_main, am->vnet_main, swif->sw_if_index,
2707 &vtr_op, &vtr_push_dot1q, &vtr_tag1, &vtr_tag2) != 0)
2709 // error - default to disabled
2710 mp->vtr_op = ntohl (L2_VTR_DISABLED);
2711 clib_warning ("cannot get vlan tag rewrite for sw_if_index %d",
2716 mp->vtr_op = ntohl (vtr_op);
2717 mp->vtr_push_dot1q = ntohl (vtr_push_dot1q);
2718 mp->vtr_tag1 = ntohl (vtr_tag1);
2719 mp->vtr_tag2 = ntohl (vtr_tag2);
2723 vl_msg_api_send_shmem (q, (u8 *) & mp);
2727 send_sw_interface_flags (vpe_api_main_t * am,
2728 unix_shared_memory_queue_t * q,
2729 vnet_sw_interface_t * swif)
2731 vl_api_sw_interface_set_flags_t *mp;
2732 vnet_main_t *vnm = am->vnet_main;
2734 vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm,
2736 mp = vl_msg_api_alloc (sizeof (*mp));
2737 memset (mp, 0, sizeof (*mp));
2738 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SET_FLAGS);
2739 mp->sw_if_index = ntohl (swif->sw_if_index);
2741 mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0;
2742 mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0;
2743 vl_msg_api_send_shmem (q, (u8 *) & mp);
2746 static void send_sw_interface_flags_deleted (vpe_api_main_t * am,
2747 unix_shared_memory_queue_t * q,
2749 __attribute__ ((unused));
2752 send_sw_interface_flags_deleted (vpe_api_main_t * am,
2753 unix_shared_memory_queue_t * q,
2756 vl_api_sw_interface_set_flags_t *mp;
2758 mp = vl_msg_api_alloc (sizeof (*mp));
2759 memset (mp, 0, sizeof (*mp));
2760 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SET_FLAGS);
2761 mp->sw_if_index = ntohl (sw_if_index);
2763 mp->admin_up_down = 0;
2764 mp->link_up_down = 0;
2766 vl_msg_api_send_shmem (q, (u8 *) & mp);
2770 vl_api_sw_interface_dump_t_handler (vl_api_sw_interface_dump_t * mp)
2772 vpe_api_main_t *am = &vpe_api_main;
2773 vnet_sw_interface_t *swif;
2774 vnet_interface_main_t *im = &am->vnet_main->interface_main;
2775 u8 *filter_string = 0, *name_string = 0;
2776 unix_shared_memory_queue_t *q;
2777 char *strcasestr (char *, char *); /* lnx hdr file botch */
2779 q = vl_api_client_index_to_input_queue (mp->client_index);
2784 if (mp->name_filter_valid)
2786 mp->name_filter[ARRAY_LEN (mp->name_filter) - 1] = 0;
2787 filter_string = format (0, "%s%c", mp->name_filter, 0);
2791 pool_foreach (swif, im->sw_interfaces,
2793 name_string = format (name_string, "%U%c",
2794 format_vnet_sw_interface_name,
2795 am->vnet_main, swif, 0);
2797 if (mp->name_filter_valid == 0 ||
2798 strcasestr((char *) name_string, (char *) filter_string)) {
2800 send_sw_interface_details (am, q, swif, name_string, mp->context);
2802 _vec_len (name_string) = 0;
2806 vec_free (name_string);
2807 vec_free (filter_string);
2811 send_oam_event (oam_target_t * t)
2813 vpe_api_main_t *vam = &vpe_api_main;
2814 unix_shared_memory_queue_t *q;
2815 vpe_client_registration_t *reg;
2816 vl_api_oam_event_t *mp;
2819 pool_foreach(reg, vam->oam_events_registrations,
2821 q = vl_api_client_index_to_input_queue (reg->client_index);
2824 mp = vl_msg_api_alloc (sizeof (*mp));
2825 mp->_vl_msg_id = ntohs (VL_API_OAM_EVENT);
2826 clib_memcpy (mp->dst_address, &t->dst_address,
2827 sizeof (mp->dst_address));
2828 mp->state = t->state;
2829 vl_msg_api_send_shmem (q, (u8 *)&mp);
2836 vl_api_oam_add_del_t_handler (vl_api_oam_add_del_t * mp)
2838 vl_api_oam_add_del_reply_t *rmp;
2841 rv = vpe_oam_add_del_target ((ip4_address_t *) mp->src_address,
2842 (ip4_address_t *) mp->dst_address,
2843 ntohl (mp->vrf_id), (int) (mp->is_add));
2845 REPLY_MACRO (VL_API_OAM_ADD_DEL_REPLY);
2849 vl_api_vnet_get_summary_stats_t_handler (vl_api_vnet_get_summary_stats_t * mp)
2851 stats_main_t *sm = &stats_main;
2852 vnet_interface_main_t *im = sm->interface_main;
2853 vl_api_vnet_summary_stats_reply_t *rmp;
2854 vlib_combined_counter_main_t *cm;
2857 u64 total_pkts[VLIB_N_RX_TX];
2858 u64 total_bytes[VLIB_N_RX_TX];
2860 unix_shared_memory_queue_t *q =
2861 vl_api_client_index_to_input_queue (mp->client_index);
2866 rmp = vl_msg_api_alloc (sizeof (*rmp));
2867 rmp->_vl_msg_id = ntohs (VL_API_VNET_SUMMARY_STATS_REPLY);
2868 rmp->context = mp->context;
2871 memset (total_pkts, 0, sizeof (total_pkts));
2872 memset (total_bytes, 0, sizeof (total_bytes));
2874 vnet_interface_counter_lock (im);
2876 vec_foreach (cm, im->combined_sw_if_counters)
2878 which = cm - im->combined_sw_if_counters;
2880 for (i = 0; i < vec_len (cm->maxi); i++)
2882 vlib_get_combined_counter (cm, i, &v);
2883 total_pkts[which] += v.packets;
2884 total_bytes[which] += v.bytes;
2887 vnet_interface_counter_unlock (im);
2889 rmp->total_pkts[VLIB_RX] = clib_host_to_net_u64 (total_pkts[VLIB_RX]);
2890 rmp->total_bytes[VLIB_RX] = clib_host_to_net_u64 (total_bytes[VLIB_RX]);
2891 rmp->total_pkts[VLIB_TX] = clib_host_to_net_u64 (total_pkts[VLIB_TX]);
2892 rmp->total_bytes[VLIB_TX] = clib_host_to_net_u64 (total_bytes[VLIB_TX]);
2894 clib_host_to_net_u64 (vlib_last_vector_length_per_node (sm->vlib_main));
2896 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2900 typedef CLIB_PACKED (struct {
2901 ip4_address_t address;
2902 u32 address_length: 6;
2908 ip4_reset_fib_t_handler (vl_api_reset_fib_t * mp)
2910 vnet_main_t *vnm = vnet_get_main ();
2911 vnet_interface_main_t *im = &vnm->interface_main;
2912 ip4_main_t *im4 = &ip4_main;
2913 static ip4_route_t *routes;
2914 static u32 *sw_if_indices_to_shut;
2915 stats_main_t *sm = &stats_main;
2920 int rv = VNET_API_ERROR_NO_SUCH_FIB;
2921 u32 target_fib_id = ntohl (mp->vrf_id);
2923 dslock (sm, 1 /* release hint */ , 8 /* tag */ );
2925 vec_foreach (fib, im4->fibs)
2927 vnet_sw_interface_t *si;
2929 if (fib->table_id != target_fib_id)
2932 /* remove any mpls/gre tunnels in this fib */
2933 vnet_mpls_gre_delete_fib_tunnels (fib->table_id);
2935 /* remove any mpls encap/decap labels */
2936 mpls_fib_reset_labels (fib->table_id);
2938 /* remove any proxy arps in this fib */
2939 vnet_proxy_arp_fib_reset (fib->table_id);
2941 /* Set the flow hash for this fib to the default */
2942 vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
2944 vec_reset_length (sw_if_indices_to_shut);
2946 /* Shut down interfaces in this FIB / clean out intfc routes */
2948 pool_foreach (si, im->sw_interfaces,
2950 u32 sw_if_index = si->sw_if_index;
2952 if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
2953 && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
2955 vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
2959 for (i = 0; i < vec_len (sw_if_indices_to_shut); i++)
2961 sw_if_index = sw_if_indices_to_shut[i];
2962 // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
2964 u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
2965 flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
2966 vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
2969 vec_reset_length (routes);
2971 for (i = 0; i < ARRAY_LEN (fib->adj_index_by_dst_address); i++)
2973 uword *hash = fib->adj_index_by_dst_address[i];
2977 x.address_length = i;
2980 hash_foreach_pair (p, hash,
2982 x.address.data_u32 = p->key;
2983 vec_add1 (routes, x);
2988 vec_foreach (r, routes)
2990 ip4_add_del_route_args_t a;
2992 memset (&a, 0, sizeof (a));
2993 a.flags = IP4_ROUTE_FLAG_FIB_INDEX | IP4_ROUTE_FLAG_DEL;
2994 a.table_index_or_table_id = fib - im4->fibs;
2995 a.dst_address = r->address;
2996 a.dst_address_length = r->address_length;
2999 ip4_add_del_route (im4, &a);
3000 ip4_maybe_remap_adjacencies (im4, fib - im4->fibs,
3001 IP4_ROUTE_FLAG_FIB_INDEX);
3005 } /* vec_foreach (fib) */
3013 ip6_address_t address;
3021 ip6_route_t **routep;
3022 } add_routes_in_fib_arg_t;
3025 add_routes_in_fib (clib_bihash_kv_24_8_t * kvp, void *arg)
3027 add_routes_in_fib_arg_t *ap = arg;
3029 if (kvp->key[2] >> 32 == ap->fib_index)
3031 ip6_address_t *addr;
3033 addr = (ip6_address_t *) kvp;
3034 vec_add2 (*ap->routep, r, 1);
3035 r->address = addr[0];
3036 r->address_length = kvp->key[2] & 0xFF;
3037 r->index = kvp->value;
3042 ip6_reset_fib_t_handler (vl_api_reset_fib_t * mp)
3044 vnet_main_t *vnm = vnet_get_main ();
3045 vnet_interface_main_t *im = &vnm->interface_main;
3046 ip6_main_t *im6 = &ip6_main;
3047 stats_main_t *sm = &stats_main;
3048 static ip6_route_t *routes;
3049 static u32 *sw_if_indices_to_shut;
3054 int rv = VNET_API_ERROR_NO_SUCH_FIB;
3055 u32 target_fib_id = ntohl (mp->vrf_id);
3056 add_routes_in_fib_arg_t _a, *a = &_a;
3057 clib_bihash_24_8_t *h = &im6->ip6_lookup_table;
3059 dslock (sm, 1 /* release hint */ , 9 /* tag */ );
3061 vec_foreach (fib, im6->fibs)
3063 vnet_sw_interface_t *si;
3065 if (fib->table_id != target_fib_id)
3068 vec_reset_length (sw_if_indices_to_shut);
3070 /* Shut down interfaces in this FIB / clean out intfc routes */
3072 pool_foreach (si, im->sw_interfaces,
3074 if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
3076 vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
3080 for (i = 0; i < vec_len (sw_if_indices_to_shut); i++)
3082 sw_if_index = sw_if_indices_to_shut[i];
3083 // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
3085 u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
3086 flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
3087 vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
3090 vec_reset_length (routes);
3092 a->fib_index = fib - im6->fibs;
3093 a->routep = &routes;
3095 clib_bihash_foreach_key_value_pair_24_8 (h, add_routes_in_fib, a);
3097 vec_foreach (r, routes)
3099 ip6_add_del_route_args_t a;
3101 memset (&a, 0, sizeof (a));
3102 a.flags = IP6_ROUTE_FLAG_FIB_INDEX | IP6_ROUTE_FLAG_DEL;
3103 a.table_index_or_table_id = fib - im6->fibs;
3104 a.dst_address = r->address;
3105 a.dst_address_length = r->address_length;
3108 ip6_add_del_route (im6, &a);
3109 ip6_maybe_remap_adjacencies (im6, fib - im6->fibs,
3110 IP6_ROUTE_FLAG_FIB_INDEX);
3113 /* Reinstall the neighbor / router discovery routes */
3114 vnet_ip6_fib_init (im6, fib - im6->fibs);
3116 } /* vec_foreach (fib) */
3123 vl_api_reset_fib_t_handler (vl_api_reset_fib_t * mp)
3126 vl_api_reset_fib_reply_t *rmp;
3129 rv = ip6_reset_fib_t_handler (mp);
3131 rv = ip4_reset_fib_t_handler (mp);
3133 REPLY_MACRO (VL_API_RESET_FIB_REPLY);
3138 dhcpv4_proxy_config (vl_api_dhcp_proxy_config_t * mp)
3140 vl_api_dhcp_proxy_config_reply_t *rmp;
3143 rv = dhcp_proxy_set_server ((ip4_address_t *) (&mp->dhcp_server),
3144 (ip4_address_t *) (&mp->dhcp_src_address),
3145 (u32) ntohl (mp->vrf_id),
3146 (int) mp->insert_circuit_id,
3147 (int) (mp->is_add == 0));
3149 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_REPLY);
3154 dhcpv6_proxy_config (vl_api_dhcp_proxy_config_t * mp)
3156 vl_api_dhcp_proxy_config_reply_t *rmp;
3159 rv = dhcpv6_proxy_set_server ((ip6_address_t *) (&mp->dhcp_server),
3160 (ip6_address_t *) (&mp->dhcp_src_address),
3161 (u32) ntohl (mp->vrf_id),
3162 (int) mp->insert_circuit_id,
3163 (int) (mp->is_add == 0));
3165 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_REPLY);
3169 dhcpv4_proxy_config_2 (vl_api_dhcp_proxy_config_2_t * mp)
3171 vl_api_dhcp_proxy_config_reply_t *rmp;
3174 rv = dhcp_proxy_set_server_2 ((ip4_address_t *) (&mp->dhcp_server),
3175 (ip4_address_t *) (&mp->dhcp_src_address),
3176 (u32) ntohl (mp->rx_vrf_id),
3177 (u32) ntohl (mp->server_vrf_id),
3178 (int) mp->insert_circuit_id,
3179 (int) (mp->is_add == 0));
3181 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_2_REPLY);
3186 dhcpv6_proxy_config_2 (vl_api_dhcp_proxy_config_2_t * mp)
3188 vl_api_dhcp_proxy_config_reply_t *rmp;
3192 rv = dhcpv6_proxy_set_server_2 ((ip6_address_t *) (&mp->dhcp_server),
3193 (ip6_address_t *) (&mp->dhcp_src_address),
3194 (u32) ntohl (mp->rx_vrf_id),
3195 (u32) ntohl (mp->server_vrf_id),
3196 (int) mp->insert_circuit_id,
3197 (int) (mp->is_add == 0));
3199 rv = VNET_API_ERROR_UNIMPLEMENTED;
3202 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_2_REPLY);
3207 vl_api_dhcp_proxy_set_vss_t_handler (vl_api_dhcp_proxy_set_vss_t * mp)
3209 vl_api_dhcp_proxy_set_vss_reply_t *rmp;
3212 rv = dhcp_proxy_set_option82_vss (ntohl (mp->tbl_id),
3215 (int) mp->is_add == 0);
3217 rv = dhcpv6_proxy_set_vss (ntohl (mp->tbl_id),
3219 ntohl (mp->fib_id), (int) mp->is_add == 0);
3221 REPLY_MACRO (VL_API_DHCP_PROXY_SET_VSS_REPLY);
3225 static void vl_api_dhcp_proxy_config_t_handler
3226 (vl_api_dhcp_proxy_config_t * mp)
3228 if (mp->is_ipv6 == 0)
3229 dhcpv4_proxy_config (mp);
3231 dhcpv6_proxy_config (mp);
3234 static void vl_api_dhcp_proxy_config_2_t_handler
3235 (vl_api_dhcp_proxy_config_2_t * mp)
3237 if (mp->is_ipv6 == 0)
3238 dhcpv4_proxy_config_2 (mp);
3240 dhcpv6_proxy_config_2 (mp);
3244 dhcp_compl_event_callback (u32 client_index, u32 pid, u8 * hostname,
3245 u8 is_ipv6, u8 * host_address, u8 * router_address,
3248 unix_shared_memory_queue_t *q;
3249 vl_api_dhcp_compl_event_t *mp;
3251 q = vl_api_client_index_to_input_queue (client_index);
3255 mp = vl_msg_api_alloc (sizeof (*mp));
3256 mp->client_index = client_index;
3258 mp->is_ipv6 = is_ipv6;
3259 clib_memcpy (&mp->hostname, hostname, vec_len (hostname));
3260 mp->hostname[vec_len (hostname) + 1] = '\n';
3261 clib_memcpy (&mp->host_address[0], host_address, 16);
3262 clib_memcpy (&mp->router_address[0], router_address, 16);
3263 clib_memcpy (&mp->host_mac[0], host_mac, 6);
3265 mp->_vl_msg_id = ntohs (VL_API_DHCP_COMPL_EVENT);
3267 vl_msg_api_send_shmem (q, (u8 *) & mp);
3270 static void vl_api_dhcp_client_config_t_handler
3271 (vl_api_dhcp_client_config_t * mp)
3273 vlib_main_t *vm = vlib_get_main ();
3274 vl_api_dhcp_client_config_reply_t *rmp;
3277 VALIDATE_SW_IF_INDEX (mp);
3279 rv = dhcp_client_config (vm, ntohl (mp->sw_if_index),
3280 mp->hostname, mp->is_add, mp->client_index,
3281 mp->want_dhcp_event ? dhcp_compl_event_callback :
3284 BAD_SW_IF_INDEX_LABEL;
3286 REPLY_MACRO (VL_API_DHCP_CLIENT_CONFIG_REPLY);
3290 vl_api_sw_interface_ip6nd_ra_config_t_handler
3291 (vl_api_sw_interface_ip6nd_ra_config_t * mp, vlib_main_t * vm)
3293 vl_api_sw_interface_ip6nd_ra_config_reply_t *rmp;
3295 u8 is_no, suppress, managed, other, ll_option, send_unicast, cease,
3298 is_no = mp->is_no == 1;
3299 suppress = mp->suppress == 1;
3300 managed = mp->managed == 1;
3301 other = mp->other == 1;
3302 ll_option = mp->ll_option == 1;
3303 send_unicast = mp->send_unicast == 1;
3304 cease = mp->cease == 1;
3305 default_router = mp->default_router == 1;
3307 VALIDATE_SW_IF_INDEX (mp);
3309 rv = ip6_neighbor_ra_config (vm, ntohl (mp->sw_if_index),
3310 suppress, managed, other,
3311 ll_option, send_unicast, cease,
3312 default_router, ntohl (mp->lifetime),
3313 ntohl (mp->initial_count),
3314 ntohl (mp->initial_interval),
3315 ntohl (mp->max_interval),
3316 ntohl (mp->min_interval), is_no);
3318 BAD_SW_IF_INDEX_LABEL;
3320 REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
3324 vl_api_sw_interface_ip6nd_ra_prefix_t_handler
3325 (vl_api_sw_interface_ip6nd_ra_prefix_t * mp, vlib_main_t * vm)
3327 vl_api_sw_interface_ip6nd_ra_prefix_reply_t *rmp;
3329 u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
3331 VALIDATE_SW_IF_INDEX (mp);
3333 is_no = mp->is_no == 1;
3334 use_default = mp->use_default == 1;
3335 no_advertise = mp->no_advertise == 1;
3336 off_link = mp->off_link == 1;
3337 no_autoconfig = mp->no_autoconfig == 1;
3338 no_onlink = mp->no_onlink == 1;
3340 rv = ip6_neighbor_ra_prefix (vm, ntohl (mp->sw_if_index),
3341 (ip6_address_t *) mp->address,
3342 mp->address_length, use_default,
3343 ntohl (mp->val_lifetime),
3344 ntohl (mp->pref_lifetime), no_advertise,
3345 off_link, no_autoconfig, no_onlink, is_no);
3347 BAD_SW_IF_INDEX_LABEL;
3348 REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
3352 vl_api_sw_interface_ip6_enable_disable_t_handler
3353 (vl_api_sw_interface_ip6_enable_disable_t * mp, vlib_main_t * vm)
3355 vl_api_sw_interface_ip6_enable_disable_reply_t *rmp;
3356 vnet_main_t *vnm = vnet_get_main ();
3358 clib_error_t *error;
3362 VALIDATE_SW_IF_INDEX (mp);
3365 (mp->enable == 1) ? enable_ip6_interface (vm,
3366 ntohl (mp->sw_if_index)) :
3367 disable_ip6_interface (vm, ntohl (mp->sw_if_index));
3371 clib_error_report (error);
3372 rv = VNET_API_ERROR_UNSPECIFIED;
3376 rv = vnm->api_errno;
3379 BAD_SW_IF_INDEX_LABEL;
3381 REPLY_MACRO (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
3385 vl_api_sw_interface_ip6_set_link_local_address_t_handler
3386 (vl_api_sw_interface_ip6_set_link_local_address_t * mp, vlib_main_t * vm)
3388 vl_api_sw_interface_ip6_set_link_local_address_reply_t *rmp;
3390 clib_error_t *error;
3391 vnet_main_t *vnm = vnet_get_main ();
3395 VALIDATE_SW_IF_INDEX (mp);
3397 error = set_ip6_link_local_address (vm,
3398 ntohl (mp->sw_if_index),
3399 (ip6_address_t *) mp->address,
3400 mp->address_length);
3403 clib_error_report (error);
3404 rv = VNET_API_ERROR_UNSPECIFIED;
3408 rv = vnm->api_errno;
3411 BAD_SW_IF_INDEX_LABEL;
3413 REPLY_MACRO (VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY);
3417 set_ip6_flow_hash (vl_api_set_ip_flow_hash_t * mp)
3419 vl_api_set_ip_flow_hash_reply_t *rmp;
3420 int rv = VNET_API_ERROR_UNIMPLEMENTED;
3422 clib_warning ("unimplemented...");
3424 REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
3428 set_ip4_flow_hash (vl_api_set_ip_flow_hash_t * mp)
3430 vl_api_set_ip_flow_hash_reply_t *rmp;
3433 u32 flow_hash_config = 0;
3435 table_id = ntohl (mp->vrf_id);
3437 #define _(a,b) if (mp->a) flow_hash_config |= b;
3438 foreach_flow_hash_bit;
3441 rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config);
3443 REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
3448 vl_api_set_ip_flow_hash_t_handler (vl_api_set_ip_flow_hash_t * mp)
3450 if (mp->is_ipv6 == 0)
3451 set_ip4_flow_hash (mp);
3453 set_ip6_flow_hash (mp);
3456 static void vl_api_sw_interface_set_unnumbered_t_handler
3457 (vl_api_sw_interface_set_unnumbered_t * mp)
3459 vl_api_sw_interface_set_unnumbered_reply_t *rmp;
3461 vnet_sw_interface_t *si;
3462 vnet_main_t *vnm = vnet_get_main ();
3463 u32 sw_if_index, unnumbered_sw_if_index;
3465 sw_if_index = ntohl (mp->sw_if_index);
3466 unnumbered_sw_if_index = ntohl (mp->unnumbered_sw_if_index);
3469 * The API message field names are backwards from
3470 * the underlying data structure names.
3471 * It's not worth changing them now.
3473 if (pool_is_free_index (vnm->interface_main.sw_interfaces,
3474 unnumbered_sw_if_index))
3476 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
3480 /* Only check the "use loop0" field when setting the binding */
3482 pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index))
3484 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
3488 si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index);
3492 si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED;
3493 si->unnumbered_sw_if_index = sw_if_index;
3497 si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED);
3498 si->unnumbered_sw_if_index = (u32) ~ 0;
3502 REPLY_MACRO (VL_API_SW_INTERFACE_SET_UNNUMBERED_REPLY);
3506 vl_api_create_loopback_t_handler (vl_api_create_loopback_t * mp)
3508 vl_api_create_loopback_reply_t *rmp;
3512 rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address);
3515 REPLY_MACRO2(VL_API_CREATE_LOOPBACK_REPLY,
3517 rmp->sw_if_index = ntohl (sw_if_index);
3523 vl_api_delete_loopback_t_handler (vl_api_delete_loopback_t * mp)
3525 vl_api_delete_loopback_reply_t *rmp;
3529 sw_if_index = ntohl (mp->sw_if_index);
3530 rv = vnet_delete_loopback_interface (sw_if_index);
3532 REPLY_MACRO (VL_API_DELETE_LOOPBACK_REPLY);
3536 vl_api_control_ping_t_handler (vl_api_control_ping_t * mp)
3538 vl_api_control_ping_reply_t *rmp;
3542 REPLY_MACRO2(VL_API_CONTROL_PING_REPLY,
3544 rmp->vpe_pid = ntohl (getpid());
3549 static void vl_api_noprint_control_ping_t_handler
3550 (vl_api_noprint_control_ping_t * mp)
3552 vl_api_noprint_control_ping_reply_t *rmp;
3556 REPLY_MACRO2(VL_API_NOPRINT_CONTROL_PING_REPLY,
3558 rmp->vpe_pid = ntohl (getpid());
3564 shmem_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
3566 u8 **shmem_vecp = (u8 **) arg;
3569 api_main_t *am = &api_main;
3572 shmem_vec = *shmem_vecp;
3574 offset = vec_len (shmem_vec);
3576 pthread_mutex_lock (&am->vlib_rp->mutex);
3577 oldheap = svm_push_data_heap (am->vlib_rp);
3579 vec_validate (shmem_vec, offset + buffer_bytes - 1);
3581 clib_memcpy (shmem_vec + offset, buffer, buffer_bytes);
3583 svm_pop_heap (oldheap);
3584 pthread_mutex_unlock (&am->vlib_rp->mutex);
3586 *shmem_vecp = shmem_vec;
3591 vl_api_cli_request_t_handler (vl_api_cli_request_t * mp)
3593 vl_api_cli_reply_t *rp;
3594 unix_shared_memory_queue_t *q;
3595 vlib_main_t *vm = vlib_get_main ();
3596 api_main_t *am = &api_main;
3597 unformat_input_t input;
3601 q = vl_api_client_index_to_input_queue (mp->client_index);
3605 rp = vl_msg_api_alloc (sizeof (*rp));
3606 rp->_vl_msg_id = ntohs (VL_API_CLI_REPLY);
3607 rp->context = mp->context;
3609 unformat_init_vector (&input, (u8 *) (uword) mp->cmd_in_shmem);
3611 vlib_cli_input (vm, &input, shmem_cli_output, (uword) & shmem_vec);
3613 pthread_mutex_lock (&am->vlib_rp->mutex);
3614 oldheap = svm_push_data_heap (am->vlib_rp);
3616 vec_add1 (shmem_vec, 0);
3618 svm_pop_heap (oldheap);
3619 pthread_mutex_unlock (&am->vlib_rp->mutex);
3621 rp->reply_in_shmem = (uword) shmem_vec;
3623 vl_msg_api_send_shmem (q, (u8 *) & rp);
3627 vl_api_set_arp_neighbor_limit_t_handler (vl_api_set_arp_neighbor_limit_t * mp)
3630 vl_api_set_arp_neighbor_limit_reply_t *rmp;
3631 vnet_main_t *vnm = vnet_get_main ();
3632 clib_error_t *error;
3637 error = ip6_set_neighbor_limit (ntohl (mp->arp_neighbor_limit));
3639 error = ip4_set_arp_limit (ntohl (mp->arp_neighbor_limit));
3643 clib_error_report (error);
3644 rv = VNET_API_ERROR_UNSPECIFIED;
3648 rv = vnm->api_errno;
3651 REPLY_MACRO (VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
3654 static void vl_api_sr_tunnel_add_del_t_handler
3655 (vl_api_sr_tunnel_add_del_t * mp)
3658 clib_warning ("unimplemented");
3660 ip6_sr_add_del_tunnel_args_t _a, *a = &_a;
3662 vl_api_sr_tunnel_add_del_reply_t *rmp;
3663 ip6_address_t *segments = 0, *seg;
3664 ip6_address_t *tags = 0, *tag;
3665 ip6_address_t *this_address;
3668 if (mp->n_segments == 0)
3674 memset (a, 0, sizeof (*a));
3675 a->src_address = (ip6_address_t *) & mp->src_address;
3676 a->dst_address = (ip6_address_t *) & mp->dst_address;
3677 a->dst_mask_width = mp->dst_mask_width;
3678 a->flags_net_byte_order = mp->flags_net_byte_order;
3679 a->is_del = (mp->is_add == 0);
3680 a->rx_table_id = ntohl (mp->outer_vrf_id);
3681 a->tx_table_id = ntohl (mp->inner_vrf_id);
3683 a->name = format (0, "%s", mp->name);
3684 if (!(vec_len (a->name)))
3687 a->policy_name = format (0, "%s", mp->policy_name);
3688 if (!(vec_len (a->policy_name)))
3691 /* Yank segments and tags out of the API message */
3692 this_address = (ip6_address_t *) mp->segs_and_tags;
3693 for (i = 0; i < mp->n_segments; i++)
3695 vec_add2 (segments, seg, 1);
3696 clib_memcpy (seg->as_u8, this_address->as_u8, sizeof (*this_address));
3699 for (i = 0; i < mp->n_tags; i++)
3701 vec_add2 (tags, tag, 1);
3702 clib_memcpy (tag->as_u8, this_address->as_u8, sizeof (*this_address));
3706 a->segments = segments;
3709 rv = ip6_sr_add_del_tunnel (a);
3713 REPLY_MACRO (VL_API_SR_TUNNEL_ADD_DEL_REPLY);
3717 static void vl_api_sr_policy_add_del_t_handler
3718 (vl_api_sr_policy_add_del_t * mp)
3721 clib_warning ("unimplemented");
3723 ip6_sr_add_del_policy_args_t _a, *a = &_a;
3725 vl_api_sr_policy_add_del_reply_t *rmp;
3728 memset (a, 0, sizeof (*a));
3729 a->is_del = (mp->is_add == 0);
3731 a->name = format (0, "%s", mp->name);
3732 if (!(vec_len (a->name)))
3734 rv = VNET_API_ERROR_NO_SUCH_NODE2;
3738 if (!(mp->tunnel_names[0]))
3740 rv = VNET_API_ERROR_NO_SUCH_NODE2;
3744 // start deserializing tunnel_names
3745 int num_tunnels = mp->tunnel_names[0]; //number of tunnels
3746 u8 *deser_tun_names = mp->tunnel_names;
3747 deser_tun_names += 1; //moving along
3750 int tun_name_len = 0;
3752 for (i = 0; i < num_tunnels; i++)
3754 tun_name_len = *deser_tun_names;
3755 deser_tun_names += 1;
3756 vec_resize (tun_name, tun_name_len);
3757 memcpy (tun_name, deser_tun_names, tun_name_len);
3758 vec_add1 (a->tunnel_names, tun_name);
3759 deser_tun_names += tun_name_len;
3763 rv = ip6_sr_add_del_policy (a);
3767 REPLY_MACRO (VL_API_SR_POLICY_ADD_DEL_REPLY);
3771 static void vl_api_sr_multicast_map_add_del_t_handler
3772 (vl_api_sr_multicast_map_add_del_t * mp)
3775 clib_warning ("unimplemented");
3777 ip6_sr_add_del_multicastmap_args_t _a, *a = &_a;
3779 vl_api_sr_multicast_map_add_del_reply_t *rmp;
3781 memset (a, 0, sizeof (*a));
3782 a->is_del = (mp->is_add == 0);
3784 a->multicast_address = (ip6_address_t *) & mp->multicast_address;
3785 a->policy_name = format (0, "%s", mp->policy_name);
3787 if (a->multicast_address == 0)
3793 if (!(a->policy_name))
3799 #if DPDK > 0 /* Cannot call replicate without DPDK */
3800 rv = ip6_sr_add_del_multicastmap (a);
3802 clib_warning ("multicast replication without DPDK not implemented");
3803 rv = VNET_API_ERROR_UNIMPLEMENTED;
3808 REPLY_MACRO (VL_API_SR_MULTICAST_MAP_ADD_DEL_REPLY);
3812 #define foreach_classify_add_del_table_field \
3817 _(match_n_vectors) \
3818 _(next_table_index) \
3821 static void vl_api_classify_add_del_table_t_handler
3822 (vl_api_classify_add_del_table_t * mp)
3824 vl_api_classify_add_del_table_reply_t *rmp;
3825 vnet_classify_main_t *cm = &vnet_classify_main;
3826 vnet_classify_table_t *t;
3830 foreach_classify_add_del_table_field;
3833 #define _(a) a = ntohl(mp->a);
3834 foreach_classify_add_del_table_field;
3837 /* The underlying API fails silently, on purpose, so check here */
3838 if (mp->is_add == 0)
3839 if (pool_is_free_index (cm->tables, table_index))
3841 rv = VNET_API_ERROR_NO_SUCH_TABLE;
3845 rv = vnet_classify_add_del_table
3846 (cm, mp->mask, nbuckets, memory_size,
3847 skip_n_vectors, match_n_vectors,
3848 next_table_index, miss_next_index, &table_index, mp->is_add);
3852 REPLY_MACRO2(VL_API_CLASSIFY_ADD_DEL_TABLE_REPLY,
3854 if (rv == 0 && mp->is_add)
3856 t = pool_elt_at_index (cm->tables, table_index);
3857 rmp->skip_n_vectors = ntohl(t->skip_n_vectors);
3858 rmp->match_n_vectors = ntohl(t->match_n_vectors);
3859 rmp->new_table_index = ntohl(table_index);
3863 rmp->skip_n_vectors = ~0;
3864 rmp->match_n_vectors = ~0;
3865 rmp->new_table_index = ~0;
3871 static void vl_api_classify_add_del_session_t_handler
3872 (vl_api_classify_add_del_session_t * mp)
3874 vnet_classify_main_t *cm = &vnet_classify_main;
3875 vl_api_classify_add_del_session_reply_t *rmp;
3877 u32 table_index, hit_next_index, opaque_index;
3880 table_index = ntohl (mp->table_index);
3881 hit_next_index = ntohl (mp->hit_next_index);
3882 opaque_index = ntohl (mp->opaque_index);
3883 advance = ntohl (mp->advance);
3885 rv = vnet_classify_add_del_session
3886 (cm, table_index, mp->match, hit_next_index, opaque_index,
3887 advance, mp->is_add);
3889 REPLY_MACRO (VL_API_CLASSIFY_ADD_DEL_SESSION_REPLY);
3892 static void vl_api_classify_set_interface_ip_table_t_handler
3893 (vl_api_classify_set_interface_ip_table_t * mp)
3895 vlib_main_t *vm = vlib_get_main ();
3896 vl_api_classify_set_interface_ip_table_reply_t *rmp;
3898 u32 table_index, sw_if_index;
3900 table_index = ntohl (mp->table_index);
3901 sw_if_index = ntohl (mp->sw_if_index);
3903 VALIDATE_SW_IF_INDEX (mp);
3906 rv = vnet_set_ip6_classify_intfc (vm, sw_if_index, table_index);
3908 rv = vnet_set_ip4_classify_intfc (vm, sw_if_index, table_index);
3910 BAD_SW_IF_INDEX_LABEL;
3912 REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY);
3915 static void vl_api_classify_set_interface_l2_tables_t_handler
3916 (vl_api_classify_set_interface_l2_tables_t * mp)
3918 vl_api_classify_set_interface_l2_tables_reply_t *rmp;
3920 u32 sw_if_index, ip4_table_index, ip6_table_index, other_table_index;
3923 ip4_table_index = ntohl (mp->ip4_table_index);
3924 ip6_table_index = ntohl (mp->ip6_table_index);
3925 other_table_index = ntohl (mp->other_table_index);
3926 sw_if_index = ntohl (mp->sw_if_index);
3928 VALIDATE_SW_IF_INDEX (mp);
3930 rv = vnet_l2_classify_set_tables (sw_if_index, ip4_table_index,
3931 ip6_table_index, other_table_index);
3935 if (ip4_table_index != ~0 || ip6_table_index != ~0
3936 || other_table_index != ~0)
3941 vnet_l2_classify_enable_disable (sw_if_index, enable);
3944 BAD_SW_IF_INDEX_LABEL;
3946 REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY);
3950 vl_api_l2_fib_clear_table_t_handler (vl_api_l2_fib_clear_table_t * mp)
3953 vl_api_l2_fib_clear_table_reply_t *rmp;
3955 /* DAW-FIXME: This API should only clear non-static l2fib entries, but
3956 * that is not currently implemented. When that TODO is fixed
3957 * this call should be changed to pass 1 instead of 0.
3959 l2fib_clear_table (0);
3961 REPLY_MACRO (VL_API_L2_FIB_CLEAR_TABLE_REPLY);
3964 extern void l2_efp_filter_configure (vnet_main_t * vnet_main,
3965 u32 sw_if_index, u32 enable);
3968 vl_api_l2_interface_efp_filter_t_handler (vl_api_l2_interface_efp_filter_t *
3972 vl_api_l2_interface_efp_filter_reply_t *rmp;
3973 vnet_main_t *vnm = vnet_get_main ();
3975 // enable/disable the feature
3976 l2_efp_filter_configure (vnm, mp->sw_if_index, mp->enable_disable);
3977 rv = vnm->api_errno;
3979 REPLY_MACRO (VL_API_L2_INTERFACE_EFP_FILTER_REPLY);
3983 vl_api_l2_interface_vlan_tag_rewrite_t_handler
3984 (vl_api_l2_interface_vlan_tag_rewrite_t * mp)
3987 vl_api_l2_interface_vlan_tag_rewrite_reply_t *rmp;
3988 vnet_main_t *vnm = vnet_get_main ();
3989 vlib_main_t *vm = vlib_get_main ();
3992 VALIDATE_SW_IF_INDEX (mp);
3994 vtr_op = ntohl (mp->vtr_op);
3996 /* The L2 code is unsuspicious */
3999 case L2_VTR_DISABLED:
4004 case L2_VTR_TRANSLATE_1_1:
4005 case L2_VTR_TRANSLATE_1_2:
4006 case L2_VTR_TRANSLATE_2_1:
4007 case L2_VTR_TRANSLATE_2_2:
4011 rv = VNET_API_ERROR_INVALID_VALUE;
4012 goto bad_sw_if_index;
4015 rv = l2vtr_configure (vm, vnm, ntohl (mp->sw_if_index), vtr_op,
4016 ntohl (mp->push_dot1q), ntohl (mp->tag1),
4019 BAD_SW_IF_INDEX_LABEL;
4021 REPLY_MACRO (VL_API_L2_INTERFACE_VLAN_TAG_REWRITE_REPLY);
4025 vl_api_create_vhost_user_if_t_handler (vl_api_create_vhost_user_if_t * mp)
4028 vl_api_create_vhost_user_if_reply_t *rmp;
4029 u32 sw_if_index = (u32) ~ 0;
4031 vnet_main_t *vnm = vnet_get_main ();
4032 vlib_main_t *vm = vlib_get_main ();
4034 #if DPDK > 0 && DPDK_VHOST_USER
4035 rv = dpdk_vhost_user_create_if (
4037 rv = vhost_user_create_if (
4039 vnm, vm, (char *) mp->sock_filename,
4040 mp->is_server, &sw_if_index, (u64) ~ 0,
4041 mp->renumber, ntohl (mp->custom_dev_instance),
4042 (mp->use_custom_mac) ? mp->mac_address : NULL);
4045 REPLY_MACRO2(VL_API_CREATE_VHOST_USER_IF_REPLY,
4047 rmp->sw_if_index = ntohl (sw_if_index);
4053 vl_api_modify_vhost_user_if_t_handler (vl_api_modify_vhost_user_if_t * mp)
4056 vl_api_modify_vhost_user_if_reply_t *rmp;
4057 u32 sw_if_index = ntohl (mp->sw_if_index);
4059 vnet_main_t *vnm = vnet_get_main ();
4060 vlib_main_t *vm = vlib_get_main ();
4062 #if DPDK > 0 && DPDK_VHOST_USER
4063 rv = dpdk_vhost_user_modify_if (
4065 rv = vhost_user_modify_if (
4067 vnm, vm, (char *) mp->sock_filename,
4068 mp->is_server, sw_if_index, (u64) ~ 0,
4069 mp->renumber, ntohl (mp->custom_dev_instance));
4070 REPLY_MACRO (VL_API_MODIFY_VHOST_USER_IF_REPLY);
4074 vl_api_delete_vhost_user_if_t_handler (vl_api_delete_vhost_user_if_t * mp)
4077 vl_api_delete_vhost_user_if_reply_t *rmp;
4078 vpe_api_main_t *vam = &vpe_api_main;
4079 u32 sw_if_index = ntohl (mp->sw_if_index);
4081 vnet_main_t *vnm = vnet_get_main ();
4082 vlib_main_t *vm = vlib_get_main ();
4084 #if DPDK > 0 && DPDK_VHOST_USER
4085 rv = dpdk_vhost_user_delete_if (vnm, vm, sw_if_index);
4087 rv = vhost_user_delete_if (vnm, vm, sw_if_index);
4090 REPLY_MACRO (VL_API_DELETE_VHOST_USER_IF_REPLY);
4093 unix_shared_memory_queue_t *q =
4094 vl_api_client_index_to_input_queue (mp->client_index);
4098 send_sw_interface_flags_deleted (vam, q, sw_if_index);
4103 vl_api_sw_interface_vhost_user_details_t_handler
4104 (vl_api_sw_interface_vhost_user_details_t * mp)
4106 clib_warning ("BUG");
4110 send_sw_interface_vhost_user_details (vpe_api_main_t * am,
4111 unix_shared_memory_queue_t * q,
4112 vhost_user_intf_details_t * vui,
4115 vl_api_sw_interface_vhost_user_details_t *mp;
4117 mp = vl_msg_api_alloc (sizeof (*mp));
4118 memset (mp, 0, sizeof (*mp));
4119 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_VHOST_USER_DETAILS);
4120 mp->sw_if_index = ntohl (vui->sw_if_index);
4121 mp->virtio_net_hdr_sz = ntohl (vui->virtio_net_hdr_sz);
4122 mp->features = clib_net_to_host_u64 (vui->features);
4123 mp->is_server = vui->is_server;
4124 mp->num_regions = ntohl (vui->num_regions);
4125 mp->sock_errno = ntohl (vui->sock_errno);
4126 mp->context = context;
4128 strncpy ((char *) mp->sock_filename,
4129 (char *) vui->sock_filename, ARRAY_LEN (mp->sock_filename) - 1);
4130 strncpy ((char *) mp->interface_name,
4131 (char *) vui->if_name, ARRAY_LEN (mp->interface_name) - 1);
4133 vl_msg_api_send_shmem (q, (u8 *) & mp);
4137 vl_api_sw_interface_vhost_user_dump_t_handler
4138 (vl_api_sw_interface_vhost_user_dump_t * mp)
4141 vpe_api_main_t *am = &vpe_api_main;
4142 vnet_main_t *vnm = vnet_get_main ();
4143 vlib_main_t *vm = vlib_get_main ();
4144 vhost_user_intf_details_t *ifaces = NULL;
4145 vhost_user_intf_details_t *vuid = NULL;
4146 unix_shared_memory_queue_t *q;
4148 q = vl_api_client_index_to_input_queue (mp->client_index);
4152 #if DPDK > 0 && DPDK_VHOST_USER
4153 rv = dpdk_vhost_user_dump_ifs (vnm, vm, &ifaces);
4155 rv = vhost_user_dump_ifs (vnm, vm, &ifaces);
4160 vec_foreach (vuid, ifaces)
4162 send_sw_interface_vhost_user_details (am, q, vuid, mp->context);
4168 send_sw_if_l2tpv3_tunnel_details (vpe_api_main_t * am,
4169 unix_shared_memory_queue_t * q,
4171 l2t_main_t * lm, u32 context)
4173 vl_api_sw_if_l2tpv3_tunnel_details_t *mp;
4175 vnet_sw_interface_t *si = NULL;
4177 si = vnet_get_hw_sw_interface (lm->vnet_main, s->hw_if_index);
4179 if_name = format (if_name, "%U",
4180 format_vnet_sw_interface_name, lm->vnet_main, si);
4182 mp = vl_msg_api_alloc (sizeof (*mp));
4183 memset (mp, 0, sizeof (*mp));
4184 mp->_vl_msg_id = ntohs (VL_API_SW_IF_L2TPV3_TUNNEL_DETAILS);
4185 strncpy ((char *) mp->interface_name,
4186 (char *) if_name, ARRAY_LEN (mp->interface_name) - 1);
4187 mp->sw_if_index = ntohl (si->sw_if_index);
4188 mp->local_session_id = s->local_session_id;
4189 mp->remote_session_id = s->remote_session_id;
4190 mp->local_cookie[0] = s->local_cookie[0];
4191 mp->local_cookie[1] = s->local_cookie[1];
4192 mp->remote_cookie = s->remote_cookie;
4193 clib_memcpy (mp->client_address, &s->client_address,
4194 sizeof (s->client_address));
4195 clib_memcpy (mp->our_address, &s->our_address, sizeof (s->our_address));
4196 mp->l2_sublayer_present = s->l2_sublayer_present;
4197 mp->context = context;
4199 vl_msg_api_send_shmem (q, (u8 *) & mp);
4203 send_ip_address_details (vpe_api_main_t * am,
4204 unix_shared_memory_queue_t * q,
4205 u8 * ip, u16 prefix_length, u8 is_ipv6, u32 context)
4207 vl_api_ip_address_details_t *mp;
4209 mp = vl_msg_api_alloc (sizeof (*mp));
4210 memset (mp, 0, sizeof (*mp));
4211 mp->_vl_msg_id = ntohs (VL_API_IP_ADDRESS_DETAILS);
4215 clib_memcpy (&mp->ip, ip, sizeof (mp->ip));
4219 u32 *tp = (u32 *) mp->ip;
4220 *tp = ntohl (*(u32 *) ip);
4222 mp->prefix_length = prefix_length;
4223 mp->context = context;
4225 vl_msg_api_send_shmem (q, (u8 *) & mp);
4229 vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp)
4231 vpe_api_main_t *am = &vpe_api_main;
4232 unix_shared_memory_queue_t *q;
4235 ip6_main_t *im6 = &ip6_main;
4236 ip4_main_t *im4 = &ip4_main;
4237 ip_lookup_main_t *lm6 = &im6->lookup_main;
4238 ip_lookup_main_t *lm4 = &im4->lookup_main;
4239 ip_interface_address_t *ia = 0;
4240 u32 sw_if_index = ~0;
4241 int rv __attribute__ ((unused)) = 0;
4243 VALIDATE_SW_IF_INDEX (mp);
4245 sw_if_index = ntohl (mp->sw_if_index);
4247 q = vl_api_client_index_to_input_queue (mp->client_index);
4256 foreach_ip_interface_address (lm6, ia, sw_if_index,
4257 1 /* honor unnumbered */,
4259 r6 = ip_interface_address_get_address (lm6, ia);
4260 u16 prefix_length = ia->address_length;
4261 send_ip_address_details(am, q, (u8*)r6, prefix_length, 1, mp->context);
4268 foreach_ip_interface_address (lm4, ia, sw_if_index,
4269 1 /* honor unnumbered */,
4271 r4 = ip_interface_address_get_address (lm4, ia);
4272 u16 prefix_length = ia->address_length;
4273 send_ip_address_details(am, q, (u8*)r4, prefix_length, 0, mp->context);
4277 BAD_SW_IF_INDEX_LABEL;
4281 send_ip_details (vpe_api_main_t * am,
4282 unix_shared_memory_queue_t * q, u32 sw_if_index, u32 context)
4284 vl_api_ip_details_t *mp;
4286 mp = vl_msg_api_alloc (sizeof (*mp));
4287 memset (mp, 0, sizeof (*mp));
4288 mp->_vl_msg_id = ntohs (VL_API_IP_DETAILS);
4290 mp->sw_if_index = ntohl (sw_if_index);
4291 mp->context = context;
4293 vl_msg_api_send_shmem (q, (u8 *) & mp);
4297 vl_api_sw_if_l2tpv3_tunnel_dump_t_handler (vl_api_sw_if_l2tpv3_tunnel_dump_t *
4300 vpe_api_main_t *am = &vpe_api_main;
4301 l2t_main_t *lm = &l2t_main;
4302 unix_shared_memory_queue_t *q;
4303 l2t_session_t *session;
4305 q = vl_api_client_index_to_input_queue (mp->client_index);
4310 pool_foreach (session, lm->sessions,
4312 send_sw_if_l2tpv3_tunnel_details (am, q, session, lm, mp->context);
4319 send_sw_interface_tap_details (vpe_api_main_t * am,
4320 unix_shared_memory_queue_t * q,
4321 tapcli_interface_details_t * tap_if,
4324 vl_api_sw_interface_tap_details_t *mp;
4325 mp = vl_msg_api_alloc (sizeof (*mp));
4326 memset (mp, 0, sizeof (*mp));
4327 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_TAP_DETAILS);
4328 mp->sw_if_index = ntohl (tap_if->sw_if_index);
4329 strncpy ((char *) mp->dev_name,
4330 (char *) tap_if->dev_name, ARRAY_LEN (mp->dev_name) - 1);
4331 mp->context = context;
4333 vl_msg_api_send_shmem (q, (u8 *) & mp);
4337 vl_api_sw_interface_tap_dump_t_handler (vl_api_sw_interface_tap_dump_t * mp)
4340 vpe_api_main_t *am = &vpe_api_main;
4341 unix_shared_memory_queue_t *q;
4342 tapcli_interface_details_t *tapifs = NULL;
4343 tapcli_interface_details_t *tap_if = NULL;
4345 q = vl_api_client_index_to_input_queue (mp->client_index);
4349 rv = vnet_tap_dump_ifs (&tapifs);
4353 vec_foreach (tap_if, tapifs)
4355 send_sw_interface_tap_details (am, q, tap_if, mp->context);
4362 vl_api_ip_dump_t_handler (vl_api_ip_dump_t * mp)
4364 vpe_api_main_t *am = &vpe_api_main;
4365 vnet_main_t *vnm = vnet_get_main ();
4366 vlib_main_t *vm = vlib_get_main ();
4367 vnet_interface_main_t *im = &vnm->interface_main;
4368 unix_shared_memory_queue_t *q;
4369 vnet_sw_interface_t *si, *sorted_sis;
4370 u32 sw_if_index = ~0;
4372 q = vl_api_client_index_to_input_queue (mp->client_index);
4378 /* Gather interfaces. */
4379 sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
4380 _vec_len (sorted_sis) = 0;
4382 pool_foreach (si, im->sw_interfaces,
4384 vec_add1 (sorted_sis, si[0]);
4388 vec_foreach (si, sorted_sis)
4390 if (!(si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
4392 if (mp->is_ipv6 && !ip6_interface_enabled (vm, si->sw_if_index))
4396 sw_if_index = si->sw_if_index;
4397 send_ip_details (am, q, sw_if_index, mp->context);
4403 vl_api_l2_fib_table_entry_t_handler (vl_api_l2_fib_table_entry_t * mp)
4405 clib_warning ("BUG");
4409 send_l2fib_table_entry (vpe_api_main_t * am,
4410 unix_shared_memory_queue_t * q,
4411 l2fib_entry_key_t * l2fe_key,
4412 l2fib_entry_result_t * l2fe_res, u32 context)
4414 vl_api_l2_fib_table_entry_t *mp;
4416 mp = vl_msg_api_alloc (sizeof (*mp));
4417 memset (mp, 0, sizeof (*mp));
4418 mp->_vl_msg_id = ntohs (VL_API_L2_FIB_TABLE_ENTRY);
4421 ntohl (l2input_main.bd_configs[l2fe_key->fields.bd_index].bd_id);
4423 mp->mac = l2fib_make_key (l2fe_key->fields.mac, 0);
4424 mp->sw_if_index = ntohl (l2fe_res->fields.sw_if_index);
4425 mp->static_mac = l2fe_res->fields.static_mac;
4426 mp->filter_mac = l2fe_res->fields.filter;
4427 mp->bvi_mac = l2fe_res->fields.bvi;
4428 mp->context = context;
4430 vl_msg_api_send_shmem (q, (u8 *) & mp);
4434 vl_api_l2_fib_table_dump_t_handler (vl_api_l2_fib_table_dump_t * mp)
4436 vpe_api_main_t *am = &vpe_api_main;
4437 bd_main_t *bdm = &bd_main;
4438 l2fib_entry_key_t *l2fe_key = NULL;
4439 l2fib_entry_result_t *l2fe_res = NULL;
4440 u32 ni, bd_id = ntohl (mp->bd_id);
4442 unix_shared_memory_queue_t *q;
4445 q = vl_api_client_index_to_input_queue (mp->client_index);
4449 /* see l2fib_table_dump: ~0 means "any" */
4454 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
4461 l2fib_table_dump (bd_index, &l2fe_key, &l2fe_res);
4463 vec_foreach_index (ni, l2fe_key)
4465 send_l2fib_table_entry (am, q, vec_elt_at_index (l2fe_key, ni),
4466 vec_elt_at_index (l2fe_res, ni), mp->context);
4468 vec_free (l2fe_key);
4469 vec_free (l2fe_res);
4473 vl_api_show_version_t_handler (vl_api_show_version_t * mp)
4475 vl_api_show_version_reply_t *rmp;
4477 char *vpe_api_get_build_directory (void);
4478 char *vpe_api_get_version (void);
4479 char *vpe_api_get_build_date (void);
4481 unix_shared_memory_queue_t *q =
4482 vl_api_client_index_to_input_queue (mp->client_index);
4488 REPLY_MACRO2(VL_API_SHOW_VERSION_REPLY,
4490 strncpy ((char *) rmp->program, "vpe", ARRAY_LEN(rmp->program)-1);
4491 strncpy ((char *) rmp->build_directory, vpe_api_get_build_directory(),
4492 ARRAY_LEN(rmp->build_directory)-1);
4493 strncpy ((char *) rmp->version, vpe_api_get_version(),
4494 ARRAY_LEN(rmp->version)-1);
4495 strncpy ((char *) rmp->build_date, vpe_api_get_build_date(),
4496 ARRAY_LEN(rmp->build_date)-1);
4502 vl_api_get_node_index_t_handler (vl_api_get_node_index_t * mp)
4504 vlib_main_t *vm = vlib_get_main ();
4505 vl_api_get_node_index_reply_t *rmp;
4508 u32 node_index = ~0;
4510 n = vlib_get_node_by_name (vm, mp->node_name);
4513 rv = VNET_API_ERROR_NO_SUCH_NODE;
4515 node_index = n->index;
4518 REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
4520 rmp->node_index = ntohl(node_index);
4526 vl_api_get_next_index_t_handler (vl_api_get_next_index_t * mp)
4528 vlib_main_t *vm = vlib_get_main ();
4529 vl_api_get_next_index_reply_t *rmp;
4530 vlib_node_t *node, *next_node;
4532 u32 next_node_index = ~0, next_index = ~0;
4535 node = vlib_get_node_by_name (vm, mp->node_name);
4539 rv = VNET_API_ERROR_NO_SUCH_NODE;
4543 next_node = vlib_get_node_by_name (vm, mp->next_name);
4547 rv = VNET_API_ERROR_NO_SUCH_NODE2;
4551 next_node_index = next_node->index;
4553 p = hash_get (node->next_slot_by_node, next_node_index);
4557 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
4565 REPLY_MACRO2(VL_API_GET_NEXT_INDEX_REPLY,
4567 rmp->next_index = ntohl(next_index);
4573 vl_api_add_node_next_t_handler (vl_api_add_node_next_t * mp)
4575 vlib_main_t *vm = vlib_get_main ();
4576 vl_api_add_node_next_reply_t *rmp;
4577 vlib_node_t *n, *next;
4579 u32 next_index = ~0;
4581 n = vlib_get_node_by_name (vm, mp->node_name);
4585 rv = VNET_API_ERROR_NO_SUCH_NODE;
4589 next = vlib_get_node_by_name (vm, mp->next_name);
4592 rv = VNET_API_ERROR_NO_SUCH_NODE2;
4594 next_index = vlib_node_add_next (vm, n->index, next->index);
4598 REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
4600 rmp->next_index = ntohl(next_index);
4605 static void vl_api_l2tpv3_create_tunnel_t_handler
4606 (vl_api_l2tpv3_create_tunnel_t * mp)
4608 vl_api_l2tpv3_create_tunnel_reply_t *rmp;
4609 l2t_main_t *lm = &l2t_main;
4610 u32 sw_if_index = (u32) ~ 0;
4613 if (mp->is_ipv6 != 1)
4615 rv = VNET_API_ERROR_UNIMPLEMENTED;
4619 u32 encap_fib_index;
4621 if (mp->encap_vrf_id != ~0)
4624 ip6_main_t *im = &ip6_main;
4627 hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id))))
4629 rv = VNET_API_ERROR_NO_SUCH_FIB;
4632 encap_fib_index = p[0];
4636 encap_fib_index = ~0;
4639 rv = create_l2tpv3_ipv6_tunnel (lm,
4640 (ip6_address_t *) mp->client_address,
4641 (ip6_address_t *) mp->our_address,
4642 ntohl (mp->local_session_id),
4643 ntohl (mp->remote_session_id),
4644 clib_net_to_host_u64 (mp->local_cookie),
4645 clib_net_to_host_u64 (mp->remote_cookie),
4646 mp->l2_sublayer_present,
4647 encap_fib_index, &sw_if_index);
4651 REPLY_MACRO2(VL_API_L2TPV3_CREATE_TUNNEL_REPLY,
4653 rmp->sw_if_index = ntohl (sw_if_index);
4658 static void vl_api_l2tpv3_set_tunnel_cookies_t_handler
4659 (vl_api_l2tpv3_set_tunnel_cookies_t * mp)
4661 vl_api_l2tpv3_set_tunnel_cookies_reply_t *rmp;
4662 l2t_main_t *lm = &l2t_main;
4665 VALIDATE_SW_IF_INDEX (mp);
4667 rv = l2tpv3_set_tunnel_cookies (lm, ntohl (mp->sw_if_index),
4668 clib_net_to_host_u64 (mp->new_local_cookie),
4669 clib_net_to_host_u64
4670 (mp->new_remote_cookie));
4672 BAD_SW_IF_INDEX_LABEL;
4674 REPLY_MACRO (VL_API_L2TPV3_SET_TUNNEL_COOKIES_REPLY);
4677 static void vl_api_l2tpv3_interface_enable_disable_t_handler
4678 (vl_api_l2tpv3_interface_enable_disable_t * mp)
4681 vnet_main_t *vnm = vnet_get_main ();
4682 vl_api_l2tpv3_interface_enable_disable_reply_t *rmp;
4684 VALIDATE_SW_IF_INDEX (mp);
4686 rv = l2tpv3_interface_enable_disable
4687 (vnm, ntohl (mp->sw_if_index), mp->enable_disable);
4689 BAD_SW_IF_INDEX_LABEL;
4691 REPLY_MACRO (VL_API_L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY);
4694 static void vl_api_l2tpv3_set_lookup_key_t_handler
4695 (vl_api_l2tpv3_set_lookup_key_t * mp)
4698 l2t_main_t *lm = &l2t_main;
4699 vl_api_l2tpv3_set_lookup_key_reply_t *rmp;
4701 if (mp->key > L2T_LOOKUP_SESSION_ID)
4703 rv = VNET_API_ERROR_INVALID_VALUE;
4707 lm->lookup_type = mp->key;
4710 REPLY_MACRO (VL_API_L2TPV3_SET_LOOKUP_KEY_REPLY);
4713 static void vl_api_vxlan_add_del_tunnel_t_handler
4714 (vl_api_vxlan_add_del_tunnel_t * mp)
4716 vl_api_vxlan_add_del_tunnel_reply_t *rmp;
4718 vnet_vxlan_add_del_tunnel_args_t _a, *a = &_a;
4719 u32 encap_fib_index;
4721 ip4_main_t *im = &ip4_main;
4722 u32 sw_if_index = ~0;
4724 p = hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id));
4727 rv = VNET_API_ERROR_NO_SUCH_FIB;
4730 encap_fib_index = p[0];
4732 /* Check src & dst are different */
4733 if ((mp->is_ipv6 && memcmp (mp->src_address, mp->dst_address, 16) == 0) ||
4734 (!mp->is_ipv6 && memcmp (mp->src_address, mp->dst_address, 4) == 0))
4736 rv = VNET_API_ERROR_SAME_SRC_DST;
4739 memset (a, 0, sizeof (*a));
4741 a->is_add = mp->is_add;
4742 a->is_ip6 = mp->is_ipv6;
4744 /* ip addresses sent in network byte order */
4747 memcpy (&(a->src.ip6), mp->src_address, 16);
4748 memcpy (&(a->dst.ip6), mp->dst_address, 16);
4752 memcpy (&(a->src.ip4), mp->src_address, 4);
4753 memcpy (&(a->dst.ip4), mp->dst_address, 4);
4756 a->encap_fib_index = encap_fib_index;
4757 a->decap_next_index = ntohl (mp->decap_next_index);
4758 a->vni = ntohl (mp->vni);
4759 rv = vnet_vxlan_add_del_tunnel (a, &sw_if_index);
4763 REPLY_MACRO2(VL_API_VXLAN_ADD_DEL_TUNNEL_REPLY,
4765 rmp->sw_if_index = ntohl (sw_if_index);
4770 static void send_vxlan_tunnel_details
4771 (vxlan_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
4773 vl_api_vxlan_tunnel_details_t *rmp;
4774 ip4_main_t *im4 = &ip4_main;
4775 ip6_main_t *im6 = &ip6_main;
4776 u8 is_ipv6 = !(t->flags & VXLAN_TUNNEL_IS_IPV4);
4778 rmp = vl_msg_api_alloc (sizeof (*rmp));
4779 memset (rmp, 0, sizeof (*rmp));
4780 rmp->_vl_msg_id = ntohs (VL_API_VXLAN_TUNNEL_DETAILS);
4783 memcpy (rmp->src_address, &(t->src.ip6), 16);
4784 memcpy (rmp->dst_address, &(t->dst.ip6), 16);
4785 rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].table_id);
4789 memcpy (rmp->src_address, &(t->src.ip4), 4);
4790 memcpy (rmp->dst_address, &(t->dst.ip4), 4);
4791 rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].table_id);
4793 rmp->vni = htonl (t->vni);
4794 rmp->decap_next_index = htonl (t->decap_next_index);
4795 rmp->sw_if_index = htonl (t->sw_if_index);
4796 rmp->is_ipv6 = is_ipv6;
4797 rmp->context = context;
4799 vl_msg_api_send_shmem (q, (u8 *) & rmp);
4802 static void vl_api_vxlan_tunnel_dump_t_handler
4803 (vl_api_vxlan_tunnel_dump_t * mp)
4805 unix_shared_memory_queue_t *q;
4806 vxlan_main_t *vxm = &vxlan_main;
4810 q = vl_api_client_index_to_input_queue (mp->client_index);
4816 sw_if_index = ntohl (mp->sw_if_index);
4818 if (~0 == sw_if_index)
4821 pool_foreach (t, vxm->tunnels,
4823 send_vxlan_tunnel_details(t, q, mp->context);
4829 if ((sw_if_index >= vec_len (vxm->tunnel_index_by_sw_if_index)) ||
4830 (~0 == vxm->tunnel_index_by_sw_if_index[sw_if_index]))
4834 t = &vxm->tunnels[vxm->tunnel_index_by_sw_if_index[sw_if_index]];
4835 send_vxlan_tunnel_details (t, q, mp->context);
4839 static void vl_api_gre_add_del_tunnel_t_handler
4840 (vl_api_gre_add_del_tunnel_t * mp)
4842 vl_api_gre_add_del_tunnel_reply_t *rmp;
4844 vnet_gre_add_del_tunnel_args_t _a, *a = &_a;
4847 ip4_main_t *im = &ip4_main;
4848 u32 sw_if_index = ~0;
4850 p = hash_get (im->fib_index_by_table_id, ntohl (mp->outer_fib_id));
4853 rv = VNET_API_ERROR_NO_SUCH_FIB;
4856 outer_fib_id = p[0];
4858 /* Check src & dst are different */
4859 if ((mp->is_ipv6 && memcmp (mp->src_address, mp->dst_address, 16) == 0) ||
4860 (!mp->is_ipv6 && memcmp (mp->src_address, mp->dst_address, 4) == 0))
4862 rv = VNET_API_ERROR_SAME_SRC_DST;
4865 memset (a, 0, sizeof (*a));
4867 a->is_add = mp->is_add;
4869 /* ip addresses sent in network byte order */
4870 clib_memcpy (&(a->src), mp->src_address, 4);
4871 clib_memcpy (&(a->dst), mp->dst_address, 4);
4873 a->outer_fib_id = outer_fib_id;
4874 rv = vnet_gre_add_del_tunnel (a, &sw_if_index);
4878 REPLY_MACRO2(VL_API_GRE_ADD_DEL_TUNNEL_REPLY,
4880 rmp->sw_if_index = ntohl (sw_if_index);
4885 static void send_gre_tunnel_details
4886 (gre_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
4888 vl_api_gre_tunnel_details_t *rmp;
4889 ip4_main_t *im = &ip4_main;
4891 rmp = vl_msg_api_alloc (sizeof (*rmp));
4892 memset (rmp, 0, sizeof (*rmp));
4893 rmp->_vl_msg_id = ntohs (VL_API_GRE_TUNNEL_DETAILS);
4894 clib_memcpy (rmp->src_address, &(t->tunnel_src), 4);
4895 clib_memcpy (rmp->dst_address, &(t->tunnel_dst), 4);
4896 rmp->outer_fib_id = htonl (im->fibs[t->outer_fib_index].table_id);
4897 rmp->sw_if_index = htonl (t->sw_if_index);
4898 rmp->context = context;
4900 vl_msg_api_send_shmem (q, (u8 *) & rmp);
4904 vl_api_gre_tunnel_dump_t_handler (vl_api_gre_tunnel_dump_t * mp)
4906 unix_shared_memory_queue_t *q;
4907 gre_main_t *gm = &gre_main;
4911 q = vl_api_client_index_to_input_queue (mp->client_index);
4917 sw_if_index = ntohl (mp->sw_if_index);
4919 if (~0 == sw_if_index)
4922 pool_foreach (t, gm->tunnels,
4924 send_gre_tunnel_details(t, q, mp->context);
4930 if ((sw_if_index >= vec_len (gm->tunnel_index_by_sw_if_index)) ||
4931 (~0 == gm->tunnel_index_by_sw_if_index[sw_if_index]))
4935 t = &gm->tunnels[gm->tunnel_index_by_sw_if_index[sw_if_index]];
4936 send_gre_tunnel_details (t, q, mp->context);
4941 vl_api_l2_patch_add_del_t_handler (vl_api_l2_patch_add_del_t * mp)
4943 extern int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
4945 vl_api_l2_patch_add_del_reply_t *rmp;
4946 int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
4950 VALIDATE_RX_SW_IF_INDEX (mp);
4951 VALIDATE_TX_SW_IF_INDEX (mp);
4953 rv = vnet_l2_patch_add_del (ntohl (mp->rx_sw_if_index),
4954 ntohl (mp->tx_sw_if_index),
4955 (int) (mp->is_add != 0));
4957 BAD_RX_SW_IF_INDEX_LABEL;
4958 BAD_TX_SW_IF_INDEX_LABEL;
4960 REPLY_MACRO (VL_API_L2_PATCH_ADD_DEL_REPLY);
4964 vl_api_vxlan_gpe_add_del_tunnel_t_handler
4965 (vl_api_vxlan_gpe_add_del_tunnel_t * mp)
4967 vl_api_vxlan_gpe_add_del_tunnel_reply_t *rmp;
4969 vnet_vxlan_gpe_add_del_tunnel_args_t _a, *a = &_a;
4970 u32 encap_fib_index, decap_fib_index;
4973 ip4_main_t *im = &ip4_main;
4974 u32 sw_if_index = ~0;
4977 p = hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id));
4980 rv = VNET_API_ERROR_NO_SUCH_FIB;
4983 encap_fib_index = p[0];
4985 protocol = mp->protocol;
4987 /* Interpret decap_vrf_id as an opaque if sending to other-than-ip4-input */
4988 if (protocol == VXLAN_GPE_INPUT_NEXT_IP4_INPUT)
4990 p = hash_get (im->fib_index_by_table_id, ntohl (mp->decap_vrf_id));
4993 rv = VNET_API_ERROR_NO_SUCH_INNER_FIB;
4996 decap_fib_index = p[0];
5000 decap_fib_index = ntohl (mp->decap_vrf_id);
5003 /* Check src & dst are different */
5004 if ((mp->is_ipv6 && memcmp (mp->local, mp->remote, 16) == 0) ||
5005 (!mp->is_ipv6 && memcmp (mp->local, mp->remote, 4) == 0))
5007 rv = VNET_API_ERROR_SAME_SRC_DST;
5010 memset (a, 0, sizeof (*a));
5012 a->is_add = mp->is_add;
5013 a->is_ip6 = mp->is_ipv6;
5014 /* ip addresses sent in network byte order */
5017 clib_memcpy (&(a->local.ip6), mp->local, 16);
5018 clib_memcpy (&(a->remote.ip6), mp->remote, 16);
5022 clib_memcpy (&(a->local.ip4), mp->local, 4);
5023 clib_memcpy (&(a->remote.ip4), mp->remote, 4);
5025 a->encap_fib_index = encap_fib_index;
5026 a->decap_fib_index = decap_fib_index;
5027 a->protocol = protocol;
5028 a->vni = ntohl (mp->vni);
5029 rv = vnet_vxlan_gpe_add_del_tunnel (a, &sw_if_index);
5033 REPLY_MACRO2(VL_API_VXLAN_GPE_ADD_DEL_TUNNEL_REPLY,
5035 rmp->sw_if_index = ntohl (sw_if_index);
5040 static void send_vxlan_gpe_tunnel_details
5041 (vxlan_gpe_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
5043 vl_api_vxlan_gpe_tunnel_details_t *rmp;
5044 ip4_main_t *im4 = &ip4_main;
5045 ip6_main_t *im6 = &ip6_main;
5046 u8 is_ipv6 = !(t->flags & VXLAN_GPE_TUNNEL_IS_IPV4);
5048 rmp = vl_msg_api_alloc (sizeof (*rmp));
5049 memset (rmp, 0, sizeof (*rmp));
5050 rmp->_vl_msg_id = ntohs (VL_API_VXLAN_GPE_TUNNEL_DETAILS);
5053 memcpy (rmp->local, &(t->local.ip6), 16);
5054 memcpy (rmp->remote, &(t->remote.ip6), 16);
5055 rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].table_id);
5056 rmp->decap_vrf_id = htonl (im6->fibs[t->decap_fib_index].table_id);
5060 memcpy (rmp->local, &(t->local.ip4), 4);
5061 memcpy (rmp->remote, &(t->remote.ip4), 4);
5062 rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].table_id);
5063 rmp->decap_vrf_id = htonl (im4->fibs[t->decap_fib_index].table_id);
5065 rmp->vni = htonl (t->vni);
5066 rmp->protocol = t->protocol;
5067 rmp->sw_if_index = htonl (t->sw_if_index);
5068 rmp->is_ipv6 = is_ipv6;
5069 rmp->context = context;
5071 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5074 static void vl_api_vxlan_gpe_tunnel_dump_t_handler
5075 (vl_api_vxlan_gpe_tunnel_dump_t * mp)
5077 unix_shared_memory_queue_t *q;
5078 vxlan_gpe_main_t *vgm = &vxlan_gpe_main;
5079 vxlan_gpe_tunnel_t *t;
5082 q = vl_api_client_index_to_input_queue (mp->client_index);
5088 sw_if_index = ntohl (mp->sw_if_index);
5090 if (~0 == sw_if_index)
5093 pool_foreach (t, vgm->tunnels,
5095 send_vxlan_gpe_tunnel_details(t, q, mp->context);
5101 if ((sw_if_index >= vec_len (vgm->tunnel_index_by_sw_if_index)) ||
5102 (~0 == vgm->tunnel_index_by_sw_if_index[sw_if_index]))
5106 t = &vgm->tunnels[vgm->tunnel_index_by_sw_if_index[sw_if_index]];
5107 send_vxlan_gpe_tunnel_details (t, q, mp->context);
5111 /** Used for transferring locators via VPP API */
5113 typedef CLIB_PACKED (struct {
5114 u32 sw_if_index; /**< locator sw_if_index */
5115 u8 priority; /**< locator priority */
5116 u8 weight; /**< locator weight */
5121 vl_api_lisp_add_del_locator_set_t_handler (vl_api_lisp_add_del_locator_set_t *
5124 vl_api_lisp_add_del_locator_set_reply_t *rmp;
5126 vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
5128 ls_locator_t *ls_loc;
5130 u8 *locator_name = NULL;
5133 memset (a, 0, sizeof (a[0]));
5135 locator_name = format (0, "%s", mp->locator_set_name);
5137 a->name = locator_name;
5138 a->is_add = mp->is_add;
5141 memset (&locator, 0, sizeof (locator));
5142 for (i = 0; i < mp->locator_num; i++)
5144 ls_loc = &((ls_locator_t *) mp->locators)[i];
5145 VALIDATE_SW_IF_INDEX (ls_loc);
5147 locator.sw_if_index = htonl (ls_loc->sw_if_index);
5148 locator.priority = ls_loc->priority;
5149 locator.weight = ls_loc->weight;
5151 vec_add1 (a->locators, locator);
5154 rv = vnet_lisp_add_del_locator_set (a, &ls_index);
5156 BAD_SW_IF_INDEX_LABEL;
5158 vec_free (locator_name);
5159 vec_free (a->locators);
5162 REPLY_MACRO2 (VL_API_LISP_ADD_DEL_LOCATOR_SET_REPLY,
5164 rmp->ls_index = clib_host_to_net_u32 (ls_index);
5170 vl_api_lisp_add_del_locator_t_handler (vl_api_lisp_add_del_locator_t * mp)
5172 vl_api_lisp_add_del_locator_reply_t *rmp;
5174 locator_t locator, *locators = NULL;
5175 vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
5177 u8 *locator_name = NULL;
5179 memset (&locator, 0, sizeof (locator));
5180 memset (a, 0, sizeof (a[0]));
5182 locator.sw_if_index = ntohl (mp->sw_if_index);
5183 locator.priority = mp->priority;
5184 locator.weight = mp->weight;
5186 vec_add1 (locators, locator);
5188 locator_name = format (0, "%s", mp->locator_set_name);
5190 a->name = locator_name;
5191 a->locators = locators;
5192 a->is_add = mp->is_add;
5195 rv = vnet_lisp_add_del_locator (a, NULL, &ls_index);
5197 vec_free (locators);
5198 vec_free (locator_name);
5200 REPLY_MACRO (VL_API_LISP_ADD_DEL_LOCATOR_REPLY);
5204 unformat_lisp_eid_api (gid_address_t * dst, u32 vni, u8 type, void *src,
5210 gid_address_type (dst) = GID_ADDR_IP_PREFIX;
5211 gid_address_ip_set (dst, src, IP4);
5212 gid_address_ippref_len (dst) = len;
5213 ip_prefix_normalize (&gid_address_ippref (dst));
5216 gid_address_type (dst) = GID_ADDR_IP_PREFIX;
5217 gid_address_ip_set (dst, src, IP6);
5218 gid_address_ippref_len (dst) = len;
5219 ip_prefix_normalize (&gid_address_ippref (dst));
5221 case 2: /* l2 mac */
5222 gid_address_type (dst) = GID_ADDR_MAC;
5223 clib_memcpy (&gid_address_mac (dst), src, 6);
5227 return VNET_API_ERROR_INVALID_VALUE;
5230 gid_address_vni (dst) = vni;
5236 vl_api_lisp_add_del_local_eid_t_handler (vl_api_lisp_add_del_local_eid_t * mp)
5238 vl_api_lisp_add_del_local_eid_reply_t *rmp;
5239 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
5241 gid_address_t _eid, *eid = &_eid;
5243 u32 locator_set_index = ~0, map_index = ~0;
5244 vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
5246 memset (a, 0, sizeof (a[0]));
5247 memset (eid, 0, sizeof (eid[0]));
5249 rv = unformat_lisp_eid_api (eid, clib_net_to_host_u32 (mp->vni),
5250 mp->eid_type, mp->eid, mp->prefix_len);
5254 name = format (0, "%s", mp->locator_set_name);
5255 p = hash_get_mem (lcm->locator_set_index_by_name, name);
5258 rv = VNET_API_ERROR_INVALID_VALUE;
5261 locator_set_index = p[0];
5263 /* XXX treat batch configuration */
5264 a->is_add = mp->is_add;
5265 gid_address_copy (&a->eid, eid);
5266 a->locator_set_index = locator_set_index;
5268 rv = vnet_lisp_add_del_local_mapping (a, &map_index);
5272 gid_address_free (&a->eid);
5274 REPLY_MACRO (VL_API_LISP_ADD_DEL_LOCAL_EID_REPLY);
5278 vl_api_lisp_eid_table_add_del_map_t_handler
5279 (vl_api_lisp_eid_table_add_del_map_t * mp)
5281 vl_api_lisp_eid_table_add_del_map_reply_t *rmp;
5283 rv = vnet_lisp_eid_table_map (clib_net_to_host_u32 (mp->vni),
5284 clib_net_to_host_u32 (mp->dp_table),
5285 mp->is_l2, mp->is_add);
5286 REPLY_MACRO (VL_API_LISP_EID_TABLE_ADD_DEL_MAP_REPLY)}
5288 /** Used for transferring locators via VPP API */
5290 typedef CLIB_PACKED (struct {
5291 u8 is_ip4; /**< is locator an IPv4 address */
5292 u8 priority; /**< locator priority */
5293 u8 weight; /**< locator weight */
5294 u8 addr[16]; /**< IPv4/IPv6 address */
5298 static locator_pair_t *
5299 unformat_lisp_loc_pairs (void *lcl_locs, void *rmt_locs, u32 rloc_num)
5302 locator_pair_t *pairs = 0, pair;
5305 for (i = 0; i < rloc_num; i++)
5308 r = &((rloc_t *) lcl_locs)[i];
5309 memset (&pair.lcl_loc, 0, sizeof (pair.lcl_loc));
5310 ip_address_set (&pair.lcl_loc, &r->addr, r->is_ip4 ? IP4 : IP6);
5312 /* remote locators */
5313 r = &((rloc_t *) rmt_locs)[i];
5314 memset (&pair.rmt_loc, 0, sizeof (pair.rmt_loc));
5315 ip_address_set (&pair.rmt_loc, &r->addr, r->is_ip4 ? IP4 : IP6);
5317 pair.priority = r->priority;
5318 pair.weight = r->weight;
5320 vec_add1 (pairs, pair);
5326 unformat_lisp_locs (void *rmt_locs, u32 rloc_num)
5329 locator_t *locs = 0, loc;
5332 for (i = 0; i < rloc_num; i++)
5334 /* remote locators */
5335 r = &((rloc_t *) rmt_locs)[i];
5336 memset (&loc, 0, sizeof (loc));
5337 gid_address_ip_set (&loc.address, &r->addr, r->is_ip4 ? IP4 : IP6);
5339 loc.priority = r->priority;
5340 loc.weight = r->weight;
5342 vec_add1 (locs, loc);
5348 vl_api_lisp_gpe_add_del_fwd_entry_t_handler
5349 (vl_api_lisp_gpe_add_del_fwd_entry_t * mp)
5351 vl_api_lisp_gpe_add_del_fwd_entry_reply_t *rmp;
5352 vnet_lisp_gpe_add_del_fwd_entry_args_t _a, *a = &_a;
5353 locator_pair_t *pairs = 0;
5356 memset (a, 0, sizeof (a[0]));
5358 rv = unformat_lisp_eid_api (&a->rmt_eid, mp->vni, mp->eid_type,
5359 mp->rmt_eid, mp->rmt_len);
5360 rv |= unformat_lisp_eid_api (&a->lcl_eid, mp->vni, mp->eid_type,
5361 mp->lcl_eid, mp->lcl_len);
5363 pairs = unformat_lisp_loc_pairs (mp->lcl_locs, mp->rmt_locs, mp->loc_num);
5365 if (rv || 0 == pairs)
5368 a->is_add = mp->is_add;
5369 a->locator_pairs = pairs;
5370 a->dp_table = mp->dp_table;
5372 a->action = mp->action;
5374 rv = vnet_lisp_gpe_add_del_fwd_entry (a, 0);
5377 REPLY_MACRO (VL_API_LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY);
5381 vl_api_lisp_add_del_map_resolver_t_handler (vl_api_lisp_add_del_map_resolver_t
5384 vl_api_lisp_add_del_map_resolver_reply_t *rmp;
5386 vnet_lisp_add_del_map_resolver_args_t _a, *a = &_a;
5388 memset (a, 0, sizeof (a[0]));
5390 a->is_add = mp->is_add;
5391 ip_address_set (&a->address, mp->ip_address, mp->is_ipv6 ? IP6 : IP4);
5393 rv = vnet_lisp_add_del_map_resolver (a);
5395 REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_RESOLVER_REPLY);
5399 vl_api_lisp_gpe_enable_disable_t_handler (vl_api_lisp_gpe_enable_disable_t *
5402 vl_api_lisp_gpe_enable_disable_reply_t *rmp;
5404 vnet_lisp_gpe_enable_disable_args_t _a, *a = &_a;
5406 a->is_en = mp->is_en;
5407 vnet_lisp_gpe_enable_disable (a);
5409 REPLY_MACRO (VL_API_LISP_GPE_ENABLE_DISABLE_REPLY);
5413 vl_api_lisp_enable_disable_t_handler (vl_api_lisp_enable_disable_t * mp)
5415 vl_api_lisp_enable_disable_reply_t *rmp;
5418 vnet_lisp_enable_disable (mp->is_en);
5419 REPLY_MACRO (VL_API_LISP_ENABLE_DISABLE_REPLY);
5423 vl_api_lisp_gpe_add_del_iface_t_handler (vl_api_lisp_gpe_add_del_iface_t * mp)
5425 vl_api_lisp_gpe_add_del_iface_reply_t *rmp;
5427 vnet_lisp_gpe_add_del_iface_args_t _a, *a = &_a;
5429 a->is_add = mp->is_add;
5430 a->dp_table = mp->dp_table;
5432 a->is_l2 = mp->is_l2;
5433 rv = vnet_lisp_gpe_add_del_iface (a, 0);
5435 REPLY_MACRO (VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
5439 vl_api_lisp_pitr_set_locator_set_t_handler (vl_api_lisp_pitr_set_locator_set_t
5442 vl_api_lisp_pitr_set_locator_set_reply_t *rmp;
5446 ls_name = format (0, "%s", mp->ls_name);
5447 rv = vnet_lisp_pitr_set_locator_set (ls_name, mp->is_add);
5450 REPLY_MACRO (VL_API_LISP_PITR_SET_LOCATOR_SET_REPLY);
5454 vl_api_lisp_add_del_map_request_itr_rlocs_t_handler
5455 (vl_api_lisp_add_del_map_request_itr_rlocs_t * mp)
5457 vl_api_lisp_add_del_map_request_itr_rlocs_reply_t *rmp;
5459 u8 *locator_set_name = NULL;
5460 vnet_lisp_add_del_mreq_itr_rloc_args_t _a, *a = &_a;
5462 locator_set_name = format (0, "%s", mp->locator_set_name);
5464 a->is_add = mp->is_add;
5465 a->locator_set_name = locator_set_name;
5467 rv = vnet_lisp_add_del_mreq_itr_rlocs (a);
5469 vec_free (locator_set_name);
5471 REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY);
5475 vl_api_lisp_add_del_remote_mapping_t_handler
5476 (vl_api_lisp_add_del_remote_mapping_t * mp)
5478 locator_t *rlocs = 0;
5479 vl_api_lisp_add_del_remote_mapping_reply_t *rmp;
5481 gid_address_t _eid, *eid = &_eid;
5483 memset (eid, 0, sizeof (eid[0]));
5485 rv = unformat_lisp_eid_api (eid, clib_net_to_host_u32 (mp->vni),
5486 mp->eid_type, mp->eid, mp->eid_len);
5490 rlocs = unformat_lisp_locs (mp->rlocs, mp->rloc_num);
5496 vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
5497 gid_address_copy (&a->deid, eid);
5499 rv = vnet_lisp_add_del_adjacency (a);
5506 /* NOTE: for now this works as a static remote mapping, i.e.,
5507 * not authoritative and ttl infinite. */
5508 rv = vnet_lisp_add_del_mapping (eid, rlocs, mp->action, 0, ~0,
5509 mp->is_add, 1 /* is_static */ , 0);
5512 vnet_lisp_clear_all_remote_adjacencies ();
5517 REPLY_MACRO (VL_API_LISP_ADD_DEL_REMOTE_MAPPING_REPLY);
5521 vl_api_lisp_add_del_adjacency_t_handler (vl_api_lisp_add_del_adjacency_t * mp)
5523 vl_api_lisp_add_del_adjacency_reply_t *rmp;
5524 vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
5527 memset (a, 0, sizeof (a[0]));
5529 rv = unformat_lisp_eid_api (&a->seid, clib_net_to_host_u32 (mp->vni),
5530 mp->eid_type, mp->seid, mp->seid_len);
5531 rv |= unformat_lisp_eid_api (&a->deid, clib_net_to_host_u32 (mp->vni),
5532 mp->eid_type, mp->deid, mp->deid_len);
5537 a->is_add = mp->is_add;
5538 rv = vnet_lisp_add_del_adjacency (a);
5541 REPLY_MACRO (VL_API_LISP_ADD_DEL_ADJACENCY_REPLY);
5545 send_lisp_locator_details (lisp_cp_main_t * lcm,
5547 unix_shared_memory_queue_t * q, u32 context)
5549 vl_api_lisp_locator_details_t *rmp;
5551 rmp = vl_msg_api_alloc (sizeof (*rmp));
5552 memset (rmp, 0, sizeof (*rmp));
5553 rmp->_vl_msg_id = ntohs (VL_API_LISP_LOCATOR_DETAILS);
5554 rmp->context = context;
5556 rmp->local = loc->local;
5559 rmp->sw_if_index = ntohl (loc->sw_if_index);
5563 rmp->is_ipv6 = gid_address_ip_version (&loc->address);
5564 ip_address_copy_addr (rmp->ip_address, &gid_address_ip (&loc->address));
5566 rmp->priority = loc->priority;
5567 rmp->weight = loc->weight;
5569 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5573 vl_api_lisp_locator_dump_t_handler (vl_api_lisp_locator_dump_t * mp)
5575 unix_shared_memory_queue_t *q = 0;
5576 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
5577 locator_set_t *lsit = 0;
5579 u32 ls_index = ~0, *locit = 0;
5582 q = vl_api_client_index_to_input_queue (mp->client_index);
5588 ls_index = htonl (mp->locator_set_index);
5590 lsit = pool_elt_at_index (lcm->locator_set_pool, ls_index);
5592 filter = mp->filter;
5593 if (filter && !((1 == filter && lsit->local) ||
5594 (2 == filter && !lsit->local)))
5599 vec_foreach (locit, lsit->locator_indices)
5601 loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
5602 send_lisp_locator_details (lcm, loc, q, mp->context);
5607 send_lisp_locator_set_details (lisp_cp_main_t * lcm,
5608 locator_set_t * lsit,
5609 unix_shared_memory_queue_t * q,
5610 u32 context, u32 ls_index)
5612 vl_api_lisp_locator_set_details_t *rmp;
5615 rmp = vl_msg_api_alloc (sizeof (*rmp));
5616 memset (rmp, 0, sizeof (*rmp));
5617 rmp->_vl_msg_id = ntohs (VL_API_LISP_LOCATOR_SET_DETAILS);
5618 rmp->context = context;
5620 rmp->local = lsit->local;
5621 rmp->locator_set_index = htonl (ls_index);
5624 ASSERT (lsit->name != NULL);
5625 strncpy ((char *) rmp->locator_set_name,
5626 (char *) lsit->name, ARRAY_LEN (rmp->locator_set_name) - 1);
5630 str = format (0, "remote-%d", ls_index);
5631 strncpy ((char *) rmp->locator_set_name, (char *) str,
5632 ARRAY_LEN (rmp->locator_set_name) - 1);
5636 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5640 vl_api_lisp_locator_set_dump_t_handler (vl_api_lisp_locator_set_dump_t * mp)
5642 unix_shared_memory_queue_t *q = NULL;
5643 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
5644 locator_set_t *lsit = NULL;
5648 q = vl_api_client_index_to_input_queue (mp->client_index);
5654 filter = mp->filter;
5657 pool_foreach (lsit, lcm->locator_set_pool,
5659 if (filter && !((1 == filter && lsit->local) ||
5660 (2 == filter && !lsit->local))) {
5664 send_lisp_locator_set_details(lcm, lsit, q, mp->context, index++);
5670 send_lisp_eid_table_details (mapping_t * mapit,
5671 unix_shared_memory_queue_t * q,
5672 u32 context, u8 filter)
5674 vl_api_lisp_eid_table_details_t *rmp = NULL;
5675 gid_address_t *gid = NULL;
5677 ip_prefix_t *ip_prefix = NULL;
5681 case 0: /* all mappings */
5684 case 1: /* local only */
5688 case 2: /* remote only */
5693 clib_warning ("Filter error, unknown filter: %d", filter);
5698 ip_prefix = &gid_address_ippref (gid);
5699 mac = gid_address_mac (gid);
5701 rmp = vl_msg_api_alloc (sizeof (*rmp));
5702 memset (rmp, 0, sizeof (*rmp));
5703 rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_DETAILS);
5704 rmp->locator_set_index = mapit->locator_set_index;
5705 rmp->is_local = mapit->local;
5706 rmp->ttl = mapit->ttl;
5707 rmp->authoritative = mapit->authoritative;
5709 switch (gid_address_type (gid))
5711 case GID_ADDR_IP_PREFIX:
5712 rmp->eid_prefix_len = ip_prefix_len (ip_prefix);
5713 if (ip_prefix_version (ip_prefix) == IP4)
5715 rmp->eid_type = 0; /* ipv4 type */
5716 clib_memcpy (rmp->eid, &ip_prefix_v4 (ip_prefix),
5717 sizeof (ip_prefix_v4 (ip_prefix)));
5721 rmp->eid_type = 1; /* ipv6 type */
5722 clib_memcpy (rmp->eid, &ip_prefix_v6 (ip_prefix),
5723 sizeof (ip_prefix_v6 (ip_prefix)));
5727 rmp->eid_type = 2; /* l2 mac type */
5728 clib_memcpy (rmp->eid, mac, 6);
5733 rmp->context = context;
5734 rmp->vni = clib_host_to_net_u32 (gid_address_vni (gid));
5735 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5739 vl_api_lisp_eid_table_dump_t_handler (vl_api_lisp_eid_table_dump_t * mp)
5742 unix_shared_memory_queue_t *q = NULL;
5743 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
5744 mapping_t *mapit = NULL;
5745 gid_address_t _eid, *eid = &_eid;
5747 q = vl_api_client_index_to_input_queue (mp->client_index);
5755 memset (eid, 0, sizeof (*eid));
5757 unformat_lisp_eid_api (eid, clib_net_to_host_u32 (mp->vni),
5758 mp->eid_type, mp->eid, mp->prefix_length);
5760 mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, eid);
5761 if ((u32) ~ 0 == mi)
5764 mapit = pool_elt_at_index (lcm->mapping_pool, mi);
5765 send_lisp_eid_table_details (mapit, q, mp->context,
5766 0 /* ignore filter */ );
5771 pool_foreach (mapit, lcm->mapping_pool,
5773 send_lisp_eid_table_details(mapit, q, mp->context,
5781 send_lisp_gpe_tunnel_details (lisp_gpe_tunnel_t * tunnel,
5782 unix_shared_memory_queue_t * q, u32 context)
5784 vl_api_lisp_gpe_tunnel_details_t *rmp;
5785 lisp_gpe_main_t *lgm = &lisp_gpe_main;
5787 rmp = vl_msg_api_alloc (sizeof (*rmp));
5788 memset (rmp, 0, sizeof (*rmp));
5789 rmp->_vl_msg_id = ntohs (VL_API_LISP_GPE_TUNNEL_DETAILS);
5791 rmp->tunnels = tunnel - lgm->tunnels;
5793 rmp->is_ipv6 = ip_addr_version (&tunnel->src) == IP6 ? 1 : 0;
5794 ip_address_copy_addr (rmp->source_ip, &tunnel->src);
5795 ip_address_copy_addr (rmp->destination_ip, &tunnel->dst);
5797 rmp->encap_fib_id = htonl (tunnel->encap_fib_index);
5798 rmp->decap_fib_id = htonl (tunnel->decap_fib_index);
5799 rmp->dcap_next = htonl (tunnel->decap_next_index);
5800 rmp->lisp_ver = tunnel->ver_res;
5801 rmp->next_protocol = tunnel->next_protocol;
5802 rmp->flags = tunnel->flags;
5803 rmp->ver_res = tunnel->ver_res;
5804 rmp->res = tunnel->res;
5805 rmp->iid = htonl (tunnel->vni);
5806 rmp->context = context;
5808 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5812 vl_api_lisp_gpe_tunnel_dump_t_handler (vl_api_lisp_gpe_tunnel_dump_t * mp)
5814 unix_shared_memory_queue_t *q = NULL;
5815 lisp_gpe_main_t *lgm = &lisp_gpe_main;
5816 lisp_gpe_tunnel_t *tunnel = NULL;
5818 if (pool_elts (lgm->tunnels) == 0)
5823 q = vl_api_client_index_to_input_queue (mp->client_index);
5830 pool_foreach(tunnel, lgm->tunnels,
5832 send_lisp_gpe_tunnel_details(tunnel, q, mp->context);
5838 send_lisp_map_resolver_details (ip_address_t * ip,
5839 unix_shared_memory_queue_t * q, u32 context)
5841 vl_api_lisp_map_resolver_details_t *rmp = NULL;
5843 rmp = vl_msg_api_alloc (sizeof (*rmp));
5844 memset (rmp, 0, sizeof (*rmp));
5845 rmp->_vl_msg_id = ntohs (VL_API_LISP_MAP_RESOLVER_DETAILS);
5847 switch (ip_addr_version (ip))
5851 clib_memcpy (rmp->ip_address, &ip_addr_v4 (ip),
5852 sizeof (ip_addr_v4 (ip)));
5857 clib_memcpy (rmp->ip_address, &ip_addr_v6 (ip),
5858 sizeof (ip_addr_v6 (ip)));
5864 rmp->context = context;
5866 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5870 vl_api_lisp_map_resolver_dump_t_handler (vl_api_lisp_map_resolver_dump_t * mp)
5872 unix_shared_memory_queue_t *q = NULL;
5873 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
5876 q = vl_api_client_index_to_input_queue (mp->client_index);
5882 vec_foreach (mr, lcm->map_resolvers)
5884 send_lisp_map_resolver_details (&mr->address, q, mp->context);
5889 send_eid_table_map_pair (hash_pair_t * p,
5890 unix_shared_memory_queue_t * q, u32 context)
5892 vl_api_lisp_eid_table_map_details_t *rmp = NULL;
5894 rmp = vl_msg_api_alloc (sizeof (*rmp));
5895 memset (rmp, 0, sizeof (*rmp));
5896 rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_MAP_DETAILS);
5898 rmp->vni = clib_host_to_net_u32 (p->key);
5899 rmp->dp_table = clib_host_to_net_u32 (p->value[0]);
5900 rmp->context = context;
5901 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5905 vl_api_lisp_eid_table_map_dump_t_handler (vl_api_lisp_eid_table_map_dump_t *
5908 unix_shared_memory_queue_t *q = NULL;
5909 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
5911 uword *vni_table = 0;
5913 q = vl_api_client_index_to_input_queue (mp->client_index);
5921 vni_table = lcm->bd_id_by_vni;
5925 vni_table = lcm->table_id_by_vni;
5929 hash_foreach_pair (p, vni_table,
5931 send_eid_table_map_pair (p, q, mp->context);
5937 send_eid_table_vni (u32 vni, unix_shared_memory_queue_t * q, u32 context)
5939 vl_api_lisp_eid_table_vni_details_t *rmp = 0;
5941 rmp = vl_msg_api_alloc (sizeof (*rmp));
5942 memset (rmp, 0, sizeof (*rmp));
5943 rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_VNI_DETAILS);
5944 rmp->context = context;
5945 rmp->vni = clib_host_to_net_u32 (vni);
5946 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5950 vl_api_lisp_eid_table_vni_dump_t_handler (vl_api_lisp_eid_table_vni_dump_t *
5955 unix_shared_memory_queue_t *q = 0;
5956 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
5958 q = vl_api_client_index_to_input_queue (mp->client_index);
5965 hash_foreach_pair (p, lcm->table_id_by_vni,
5967 hash_set (vnis, p->key, 0);
5970 hash_foreach_pair (p, lcm->bd_id_by_vni,
5972 hash_set (vnis, p->key, 0);
5975 hash_foreach_pair (p, vnis,
5977 send_eid_table_vni (p->key, q, mp->context);
5985 vl_api_show_lisp_status_t_handler (vl_api_show_lisp_status_t * mp)
5987 unix_shared_memory_queue_t *q = NULL;
5988 vl_api_show_lisp_status_reply_t *rmp = NULL;
5991 q = vl_api_client_index_to_input_queue (mp->client_index);
5998 REPLY_MACRO2(VL_API_SHOW_LISP_STATUS_REPLY,
6000 rmp->gpe_status = vnet_lisp_gpe_enable_disable_status ();
6001 rmp->feature_status = vnet_lisp_enable_disable_status ();
6007 vl_api_lisp_get_map_request_itr_rlocs_t_handler
6008 (vl_api_lisp_get_map_request_itr_rlocs_t * mp)
6010 unix_shared_memory_queue_t *q = NULL;
6011 vl_api_lisp_get_map_request_itr_rlocs_reply_t *rmp = NULL;
6012 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
6013 locator_set_t *loc_set = 0;
6017 q = vl_api_client_index_to_input_queue (mp->client_index);
6023 if (~0 == lcm->mreq_itr_rlocs)
6025 tmp_str = format (0, " ");
6030 pool_elt_at_index (lcm->locator_set_pool, lcm->mreq_itr_rlocs);
6031 tmp_str = format (0, "%s", loc_set->name);
6035 REPLY_MACRO2(VL_API_LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,
6037 strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
6038 ARRAY_LEN(rmp->locator_set_name) - 1);
6046 vl_api_show_lisp_pitr_t_handler (vl_api_show_lisp_pitr_t * mp)
6048 unix_shared_memory_queue_t *q = NULL;
6049 vl_api_show_lisp_pitr_reply_t *rmp = NULL;
6050 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
6052 locator_set_t *ls = 0;
6056 q = vl_api_client_index_to_input_queue (mp->client_index);
6062 if (!lcm->lisp_pitr)
6064 tmp_str = format (0, "N/A");
6068 m = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
6069 if (~0 != m->locator_set_index)
6072 pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
6073 tmp_str = format (0, "%s", ls->name);
6077 tmp_str = format (0, "N/A");
6080 vec_add1 (tmp_str, 0);
6083 REPLY_MACRO2(VL_API_SHOW_LISP_PITR_REPLY,
6085 rmp->status = lcm->lisp_pitr;
6086 strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
6087 ARRAY_LEN(rmp->locator_set_name) - 1);
6093 vl_api_interface_name_renumber_t_handler (vl_api_interface_name_renumber_t *
6096 vl_api_interface_name_renumber_reply_t *rmp;
6099 VALIDATE_SW_IF_INDEX (mp);
6101 rv = vnet_interface_name_renumber
6102 (ntohl (mp->sw_if_index), ntohl (mp->new_show_dev_instance));
6104 BAD_SW_IF_INDEX_LABEL;
6106 REPLY_MACRO (VL_API_INTERFACE_NAME_RENUMBER_REPLY);
6110 arp_change_data_callback (u32 pool_index, u8 * new_mac,
6111 u32 sw_if_index, u32 address)
6113 vpe_api_main_t *am = &vpe_api_main;
6114 vlib_main_t *vm = am->vlib_main;
6115 vl_api_ip4_arp_event_t *event;
6116 static f64 arp_event_last_time;
6117 f64 now = vlib_time_now (vm);
6119 if (pool_is_free_index (am->arp_events, pool_index))
6122 event = pool_elt_at_index (am->arp_events, pool_index);
6123 if (memcmp (&event->new_mac, new_mac, sizeof (event->new_mac)))
6125 clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
6129 if ((sw_if_index == event->sw_if_index) && ((address == 0) ||
6130 /* for BD case, also check IP address with 10 sec timeout */
6131 ((address == event->address)
6134 arp_event_last_time) <
6139 arp_event_last_time = now;
6140 event->sw_if_index = sw_if_index;
6142 event->address = address;
6147 arp_change_delete_callback (u32 pool_index, u8 * notused)
6149 vpe_api_main_t *am = &vpe_api_main;
6151 if (pool_is_free_index (am->arp_events, pool_index))
6154 pool_put_index (am->arp_events, pool_index);
6159 vl_api_want_ip4_arp_events_t_handler (vl_api_want_ip4_arp_events_t * mp)
6161 vpe_api_main_t *am = &vpe_api_main;
6162 vnet_main_t *vnm = vnet_get_main ();
6163 vl_api_want_ip4_arp_events_reply_t *rmp;
6164 vl_api_ip4_arp_event_t *event;
6167 if (mp->enable_disable)
6169 pool_get (am->arp_events, event);
6170 memset (event, 0, sizeof (*event));
6172 event->_vl_msg_id = ntohs (VL_API_IP4_ARP_EVENT);
6173 event->client_index = mp->client_index;
6174 event->context = mp->context;
6175 event->address = mp->address;
6176 event->pid = mp->pid;
6178 rv = vnet_add_del_ip4_arp_change_event
6179 (vnm, arp_change_data_callback,
6180 mp->pid, &mp->address /* addr, in net byte order */ ,
6181 vpe_resolver_process_node.index,
6182 IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */ );
6186 rv = vnet_add_del_ip4_arp_change_event
6187 (vnm, arp_change_delete_callback,
6188 mp->pid, &mp->address /* addr, in net byte order */ ,
6189 vpe_resolver_process_node.index,
6190 IP4_ARP_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
6192 REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY);
6195 static void vl_api_input_acl_set_interface_t_handler
6196 (vl_api_input_acl_set_interface_t * mp)
6198 vlib_main_t *vm = vlib_get_main ();
6199 vl_api_input_acl_set_interface_reply_t *rmp;
6201 u32 sw_if_index, ip4_table_index, ip6_table_index, l2_table_index;
6203 ip4_table_index = ntohl (mp->ip4_table_index);
6204 ip6_table_index = ntohl (mp->ip6_table_index);
6205 l2_table_index = ntohl (mp->l2_table_index);
6206 sw_if_index = ntohl (mp->sw_if_index);
6208 VALIDATE_SW_IF_INDEX (mp);
6210 rv = vnet_set_input_acl_intfc (vm, sw_if_index, ip4_table_index,
6211 ip6_table_index, l2_table_index, mp->is_add);
6213 BAD_SW_IF_INDEX_LABEL;
6215 REPLY_MACRO (VL_API_INPUT_ACL_SET_INTERFACE_REPLY);
6218 static void vl_api_ipsec_spd_add_del_t_handler
6219 (vl_api_ipsec_spd_add_del_t * mp)
6222 clib_warning ("unimplemented");
6225 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
6226 vl_api_ipsec_spd_add_del_reply_t *rmp;
6230 rv = ipsec_add_del_spd (vm, ntohl (mp->spd_id), mp->is_add);
6232 rv = VNET_API_ERROR_UNIMPLEMENTED;
6235 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_REPLY);
6239 static void vl_api_ipsec_interface_add_del_spd_t_handler
6240 (vl_api_ipsec_interface_add_del_spd_t * mp)
6242 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
6243 vl_api_ipsec_interface_add_del_spd_reply_t *rmp;
6245 u32 sw_if_index __attribute__ ((unused));
6246 u32 spd_id __attribute__ ((unused));
6248 sw_if_index = ntohl (mp->sw_if_index);
6249 spd_id = ntohl (mp->spd_id);
6251 VALIDATE_SW_IF_INDEX (mp);
6254 rv = ipsec_set_interface_spd (vm, sw_if_index, spd_id, mp->is_add);
6256 rv = VNET_API_ERROR_UNIMPLEMENTED;
6259 BAD_SW_IF_INDEX_LABEL;
6261 REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY);
6264 static void vl_api_ipsec_spd_add_del_entry_t_handler
6265 (vl_api_ipsec_spd_add_del_entry_t * mp)
6267 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
6268 vl_api_ipsec_spd_add_del_entry_reply_t *rmp;
6274 memset (&p, 0, sizeof (p));
6276 p.id = ntohl (mp->spd_id);
6277 p.priority = ntohl (mp->priority);
6278 p.is_outbound = mp->is_outbound;
6279 p.is_ipv6 = mp->is_ipv6;
6281 if (mp->is_ipv6 || mp->is_ip_any)
6283 clib_memcpy (&p.raddr.start, mp->remote_address_start, 16);
6284 clib_memcpy (&p.raddr.stop, mp->remote_address_stop, 16);
6285 clib_memcpy (&p.laddr.start, mp->local_address_start, 16);
6286 clib_memcpy (&p.laddr.stop, mp->local_address_stop, 16);
6290 clib_memcpy (&p.raddr.start.ip4.data, mp->remote_address_start, 4);
6291 clib_memcpy (&p.raddr.stop.ip4.data, mp->remote_address_stop, 4);
6292 clib_memcpy (&p.laddr.start.ip4.data, mp->local_address_start, 4);
6293 clib_memcpy (&p.laddr.stop.ip4.data, mp->local_address_stop, 4);
6295 p.protocol = mp->protocol;
6296 p.rport.start = ntohs (mp->remote_port_start);
6297 p.rport.stop = ntohs (mp->remote_port_stop);
6298 p.lport.start = ntohs (mp->local_port_start);
6299 p.lport.stop = ntohs (mp->local_port_stop);
6300 /* policy action resolve unsupported */
6301 if (mp->policy == IPSEC_POLICY_ACTION_RESOLVE)
6303 clib_warning ("unsupported action: 'resolve'");
6304 rv = VNET_API_ERROR_UNIMPLEMENTED;
6307 p.policy = mp->policy;
6308 p.sa_id = ntohl (mp->sa_id);
6310 rv = ipsec_add_del_policy (vm, &p, mp->is_add);
6317 rv = ipsec_add_del_policy (vm, &p, mp->is_add);
6320 rv = VNET_API_ERROR_UNIMPLEMENTED;
6325 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_ENTRY_REPLY);
6328 static void vl_api_ipsec_sad_add_del_entry_t_handler
6329 (vl_api_ipsec_sad_add_del_entry_t * mp)
6331 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
6332 vl_api_ipsec_sad_add_del_entry_reply_t *rmp;
6337 memset (&sa, 0, sizeof (sa));
6339 sa.id = ntohl (mp->sad_id);
6340 sa.spi = ntohl (mp->spi);
6341 /* security protocol AH unsupported */
6342 if (mp->protocol == IPSEC_PROTOCOL_AH)
6344 clib_warning ("unsupported security protocol 'AH'");
6345 rv = VNET_API_ERROR_UNIMPLEMENTED;
6348 sa.protocol = mp->protocol;
6349 /* check for unsupported crypto-alg */
6350 if (mp->crypto_algorithm < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
6351 mp->crypto_algorithm > IPSEC_CRYPTO_ALG_AES_CBC_256)
6353 clib_warning ("unsupported crypto-alg: '%U'", format_ipsec_crypto_alg,
6354 mp->crypto_algorithm);
6355 rv = VNET_API_ERROR_UNIMPLEMENTED;
6358 sa.crypto_alg = mp->crypto_algorithm;
6359 sa.crypto_key_len = mp->crypto_key_length;
6360 clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key));
6361 /* check for unsupported integ-alg */
6362 if (mp->integrity_algorithm < IPSEC_INTEG_ALG_SHA1_96 ||
6363 mp->integrity_algorithm > IPSEC_INTEG_ALG_SHA_512_256)
6365 clib_warning ("unsupported integ-alg: '%U'", format_ipsec_integ_alg,
6366 mp->integrity_algorithm);
6367 rv = VNET_API_ERROR_UNIMPLEMENTED;
6370 sa.integ_alg = mp->integrity_algorithm;
6371 sa.integ_key_len = mp->integrity_key_length;
6372 clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key));
6373 sa.use_esn = mp->use_extended_sequence_number;
6374 sa.is_tunnel = mp->is_tunnel;
6375 sa.is_tunnel_ip6 = mp->is_tunnel_ipv6;
6376 if (sa.is_tunnel_ip6)
6378 clib_memcpy (&sa.tunnel_src_addr, mp->tunnel_src_address, 16);
6379 clib_memcpy (&sa.tunnel_dst_addr, mp->tunnel_dst_address, 16);
6383 clib_memcpy (&sa.tunnel_src_addr.ip4.data, mp->tunnel_src_address, 4);
6384 clib_memcpy (&sa.tunnel_dst_addr.ip4.data, mp->tunnel_dst_address, 4);
6387 rv = ipsec_add_del_sa (vm, &sa, mp->is_add);
6389 rv = VNET_API_ERROR_UNIMPLEMENTED;
6394 REPLY_MACRO (VL_API_IPSEC_SAD_ADD_DEL_ENTRY_REPLY);
6398 vl_api_ikev2_profile_add_del_t_handler (vl_api_ikev2_profile_add_del_t * mp)
6400 vl_api_ikev2_profile_add_del_reply_t *rmp;
6404 vlib_main_t *vm = vlib_get_main ();
6405 clib_error_t *error;
6406 u8 *tmp = format (0, "%s", mp->name);
6407 error = ikev2_add_del_profile (vm, tmp, mp->is_add);
6410 rv = VNET_API_ERROR_UNSPECIFIED;
6412 rv = VNET_API_ERROR_UNIMPLEMENTED;
6415 REPLY_MACRO (VL_API_IKEV2_PROFILE_ADD_DEL_REPLY);
6419 vl_api_ikev2_profile_set_auth_t_handler
6420 (vl_api_ikev2_profile_set_auth_t * mp)
6422 vl_api_ikev2_profile_set_auth_reply_t *rmp;
6426 vlib_main_t *vm = vlib_get_main ();
6427 clib_error_t *error;
6428 u8 *tmp = format (0, "%s", mp->name);
6429 u8 *data = vec_new (u8, mp->data_len);
6430 clib_memcpy (data, mp->data, mp->data_len);
6431 error = ikev2_set_profile_auth (vm, tmp, mp->auth_method, data, mp->is_hex);
6435 rv = VNET_API_ERROR_UNSPECIFIED;
6437 rv = VNET_API_ERROR_UNIMPLEMENTED;
6440 REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_AUTH_REPLY);
6444 vl_api_ikev2_profile_set_id_t_handler (vl_api_ikev2_profile_set_id_t * mp)
6446 vl_api_ikev2_profile_add_del_reply_t *rmp;
6450 vlib_main_t *vm = vlib_get_main ();
6451 clib_error_t *error;
6452 u8 *tmp = format (0, "%s", mp->name);
6453 u8 *data = vec_new (u8, mp->data_len);
6454 clib_memcpy (data, mp->data, mp->data_len);
6455 error = ikev2_set_profile_id (vm, tmp, mp->id_type, data, mp->is_local);
6459 rv = VNET_API_ERROR_UNSPECIFIED;
6461 rv = VNET_API_ERROR_UNIMPLEMENTED;
6464 REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_ID_REPLY);
6468 vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp)
6470 vl_api_ikev2_profile_set_ts_reply_t *rmp;
6474 vlib_main_t *vm = vlib_get_main ();
6475 clib_error_t *error;
6476 u8 *tmp = format (0, "%s", mp->name);
6477 error = ikev2_set_profile_ts (vm, tmp, mp->proto, mp->start_port,
6478 mp->end_port, (ip4_address_t) mp->start_addr,
6479 (ip4_address_t) mp->end_addr, mp->is_local);
6482 rv = VNET_API_ERROR_UNSPECIFIED;
6484 rv = VNET_API_ERROR_UNIMPLEMENTED;
6487 REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_TS_REPLY);
6491 vl_api_ikev2_set_local_key_t_handler (vl_api_ikev2_set_local_key_t * mp)
6493 vl_api_ikev2_profile_set_ts_reply_t *rmp;
6497 vlib_main_t *vm = vlib_get_main ();
6498 clib_error_t *error;
6500 error = ikev2_set_local_key (vm, mp->key_file);
6502 rv = VNET_API_ERROR_UNSPECIFIED;
6504 rv = VNET_API_ERROR_UNIMPLEMENTED;
6507 REPLY_MACRO (VL_API_IKEV2_SET_LOCAL_KEY_REPLY);
6511 vl_api_map_add_domain_t_handler (vl_api_map_add_domain_t * mp)
6513 vl_api_map_add_domain_reply_t *rmp;
6516 u8 flags = mp->is_translation ? MAP_DOMAIN_TRANSLATION : 0;
6518 map_create_domain ((ip4_address_t *) & mp->ip4_prefix, mp->ip4_prefix_len,
6519 (ip6_address_t *) & mp->ip6_prefix, mp->ip6_prefix_len,
6520 (ip6_address_t *) & mp->ip6_src,
6521 mp->ip6_src_prefix_len, mp->ea_bits_len,
6522 mp->psid_offset, mp->psid_length, &index,
6523 ntohs (mp->mtu), flags);
6526 REPLY_MACRO2(VL_API_MAP_ADD_DOMAIN_REPLY,
6528 rmp->index = ntohl(index);
6534 vl_api_map_del_domain_t_handler (vl_api_map_del_domain_t * mp)
6536 vl_api_map_del_domain_reply_t *rmp;
6539 rv = map_delete_domain (ntohl (mp->index));
6541 REPLY_MACRO (VL_API_MAP_DEL_DOMAIN_REPLY);
6545 vl_api_map_add_del_rule_t_handler (vl_api_map_add_del_rule_t * mp)
6547 vl_api_map_del_domain_reply_t *rmp;
6551 map_add_del_psid (ntohl (mp->index), ntohs (mp->psid),
6552 (ip6_address_t *) mp->ip6_dst, mp->is_add);
6554 REPLY_MACRO (VL_API_MAP_ADD_DEL_RULE_REPLY);
6558 vl_api_map_domain_dump_t_handler (vl_api_map_domain_dump_t * mp)
6560 vl_api_map_domain_details_t *rmp;
6561 map_main_t *mm = &map_main;
6563 unix_shared_memory_queue_t *q;
6565 if (pool_elts (mm->domains) == 0)
6568 q = vl_api_client_index_to_input_queue (mp->client_index);
6575 pool_foreach(d, mm->domains,
6577 /* Make sure every field is initiated (or don't skip the memset()) */
6578 rmp = vl_msg_api_alloc (sizeof (*rmp));
6579 rmp->_vl_msg_id = ntohs(VL_API_MAP_DOMAIN_DETAILS);
6580 rmp->domain_index = htonl(d - mm->domains);
6581 rmp->ea_bits_len = d->ea_bits_len;
6582 rmp->psid_offset = d->psid_offset;
6583 rmp->psid_length = d->psid_length;
6584 clib_memcpy(rmp->ip4_prefix, &d->ip4_prefix, sizeof(rmp->ip4_prefix));
6585 rmp->ip4_prefix_len = d->ip4_prefix_len;
6586 clib_memcpy(rmp->ip6_prefix, &d->ip6_prefix, sizeof(rmp->ip6_prefix));
6587 rmp->ip6_prefix_len = d->ip6_prefix_len;
6588 clib_memcpy(rmp->ip6_src, &d->ip6_src, sizeof(rmp->ip6_src));
6589 rmp->ip6_src_len = d->ip6_src_len;
6590 rmp->mtu = htons(d->mtu);
6591 rmp->is_translation = (d->flags & MAP_DOMAIN_TRANSLATION);
6592 rmp->context = mp->context;
6594 vl_msg_api_send_shmem (q, (u8 *)&rmp);
6600 vl_api_map_rule_dump_t_handler (vl_api_map_rule_dump_t * mp)
6602 unix_shared_memory_queue_t *q;
6605 vl_api_map_rule_details_t *rmp;
6606 map_main_t *mm = &map_main;
6607 u32 domain_index = ntohl (mp->domain_index);
6610 if (pool_elts (mm->domains) == 0)
6613 d = pool_elt_at_index (mm->domains, domain_index);
6614 if (!d || !d->rules)
6619 q = vl_api_client_index_to_input_queue (mp->client_index);
6625 for (i = 0; i < (0x1 << d->psid_length); i++)
6628 if (dst.as_u64[0] == 0 && dst.as_u64[1] == 0)
6632 rmp = vl_msg_api_alloc (sizeof (*rmp));
6633 memset (rmp, 0, sizeof (*rmp));
6634 rmp->_vl_msg_id = ntohs (VL_API_MAP_RULE_DETAILS);
6635 rmp->psid = htons (i);
6636 clib_memcpy (rmp->ip6_dst, &dst, sizeof (rmp->ip6_dst));
6637 rmp->context = mp->context;
6638 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6643 vl_api_map_summary_stats_t_handler (vl_api_map_summary_stats_t * mp)
6645 vl_api_map_summary_stats_reply_t *rmp;
6646 vlib_combined_counter_main_t *cm;
6649 u64 total_pkts[VLIB_N_RX_TX];
6650 u64 total_bytes[VLIB_N_RX_TX];
6651 map_main_t *mm = &map_main;
6652 unix_shared_memory_queue_t *q =
6653 vl_api_client_index_to_input_queue (mp->client_index);
6658 rmp = vl_msg_api_alloc (sizeof (*rmp));
6659 rmp->_vl_msg_id = ntohs (VL_API_MAP_SUMMARY_STATS_REPLY);
6660 rmp->context = mp->context;
6663 memset (total_pkts, 0, sizeof (total_pkts));
6664 memset (total_bytes, 0, sizeof (total_bytes));
6666 map_domain_counter_lock (mm);
6667 vec_foreach (cm, mm->domain_counters)
6669 which = cm - mm->domain_counters;
6671 for (i = 0; i < vec_len (cm->maxi); i++)
6673 vlib_get_combined_counter (cm, i, &v);
6674 total_pkts[which] += v.packets;
6675 total_bytes[which] += v.bytes;
6679 map_domain_counter_unlock (mm);
6681 /* Note: in network byte order! */
6682 rmp->total_pkts[MAP_DOMAIN_COUNTER_RX] =
6683 clib_host_to_net_u64 (total_pkts[MAP_DOMAIN_COUNTER_RX]);
6684 rmp->total_bytes[MAP_DOMAIN_COUNTER_RX] =
6685 clib_host_to_net_u64 (total_bytes[MAP_DOMAIN_COUNTER_RX]);
6686 rmp->total_pkts[MAP_DOMAIN_COUNTER_TX] =
6687 clib_host_to_net_u64 (total_pkts[MAP_DOMAIN_COUNTER_TX]);
6688 rmp->total_bytes[MAP_DOMAIN_COUNTER_TX] =
6689 clib_host_to_net_u64 (total_bytes[MAP_DOMAIN_COUNTER_TX]);
6690 rmp->total_bindings = clib_host_to_net_u64 (pool_elts (mm->domains));
6691 rmp->total_ip4_fragments = 0; // Not yet implemented. Should be a simple counter.
6692 rmp->total_security_check[MAP_DOMAIN_COUNTER_TX] =
6693 clib_host_to_net_u64 (map_error_counter_get
6694 (ip4_map_node.index, MAP_ERROR_ENCAP_SEC_CHECK));
6695 rmp->total_security_check[MAP_DOMAIN_COUNTER_RX] =
6696 clib_host_to_net_u64 (map_error_counter_get
6697 (ip4_map_node.index, MAP_ERROR_DECAP_SEC_CHECK));
6699 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6703 vl_api_ipsec_sa_set_key_t_handler (vl_api_ipsec_sa_set_key_t * mp)
6705 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
6706 vl_api_ipsec_sa_set_key_reply_t *rmp;
6710 sa.id = ntohl (mp->sa_id);
6711 sa.crypto_key_len = mp->crypto_key_length;
6712 clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key));
6713 sa.integ_key_len = mp->integrity_key_length;
6714 clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key));
6716 rv = ipsec_set_sa_key (vm, &sa);
6718 rv = VNET_API_ERROR_UNIMPLEMENTED;
6721 REPLY_MACRO (VL_API_IPSEC_SA_SET_KEY_REPLY);
6724 static void vl_api_cop_interface_enable_disable_t_handler
6725 (vl_api_cop_interface_enable_disable_t * mp)
6727 vl_api_cop_interface_enable_disable_reply_t *rmp;
6729 u32 sw_if_index = ntohl (mp->sw_if_index);
6732 VALIDATE_SW_IF_INDEX (mp);
6734 enable_disable = (int) mp->enable_disable;
6736 rv = cop_interface_enable_disable (sw_if_index, enable_disable);
6738 BAD_SW_IF_INDEX_LABEL;
6740 REPLY_MACRO (VL_API_COP_INTERFACE_ENABLE_DISABLE_REPLY);
6743 static void vl_api_cop_whitelist_enable_disable_t_handler
6744 (vl_api_cop_whitelist_enable_disable_t * mp)
6746 vl_api_cop_whitelist_enable_disable_reply_t *rmp;
6747 cop_whitelist_enable_disable_args_t _a, *a = &_a;
6748 u32 sw_if_index = ntohl (mp->sw_if_index);
6751 VALIDATE_SW_IF_INDEX (mp);
6753 a->sw_if_index = sw_if_index;
6756 a->default_cop = mp->default_cop;
6757 a->fib_id = ntohl (mp->fib_id);
6759 rv = cop_whitelist_enable_disable (a);
6761 BAD_SW_IF_INDEX_LABEL;
6763 REPLY_MACRO (VL_API_COP_WHITELIST_ENABLE_DISABLE_REPLY);
6767 vl_api_get_node_graph_t_handler (vl_api_get_node_graph_t * mp)
6771 api_main_t *am = &api_main;
6772 vlib_main_t *vm = vlib_get_main ();
6774 vl_api_get_node_graph_reply_t *rmp;
6776 pthread_mutex_lock (&am->vlib_rp->mutex);
6777 oldheap = svm_push_data_heap (am->vlib_rp);
6780 * Keep the number of memcpy ops to a minimum (e.g. 1).
6782 vec_validate (vector, 16384);
6783 vec_reset_length (vector);
6786 vector = vlib_node_serialize (&vm->node_main, vector,
6787 (u32) ~ 0 /* all threads */ ,
6788 1 /* include nexts */ ,
6789 1 /* include stats */ );
6791 svm_pop_heap (oldheap);
6792 pthread_mutex_unlock (&am->vlib_rp->mutex);
6795 REPLY_MACRO2(VL_API_GET_NODE_GRAPH_REPLY,
6797 rmp->reply_in_shmem = (uword) vector;
6802 static void vl_api_trace_profile_add_t_handler
6803 (vl_api_trace_profile_add_t * mp)
6806 vl_api_trace_profile_add_reply_t *rmp;
6807 clib_error_t *error;
6809 /* Ignoring the profile id as currently a single profile
6811 error = ip6_ioam_trace_profile_set (mp->trace_num_elt, mp->trace_type,
6812 ntohl (mp->node_id),
6813 ntohl (mp->trace_app_data),
6814 mp->pow_enable, mp->trace_tsp,
6818 clib_error_report (error);
6819 rv = clib_error_get_code (error);
6822 REPLY_MACRO (VL_API_TRACE_PROFILE_ADD_REPLY);
6825 static void vl_api_trace_profile_apply_t_handler
6826 (vl_api_trace_profile_apply_t * mp)
6829 vl_api_trace_profile_apply_reply_t *rmp;
6831 if (mp->enable != 0)
6833 rv = ip6_ioam_set_destination ((ip6_address_t *) (&mp->dest_ipv6),
6834 ntohl (mp->prefix_length),
6836 mp->trace_op == IOAM_HBYH_ADD,
6837 mp->trace_op == IOAM_HBYH_POP,
6838 mp->trace_op == IOAM_HBYH_MOD);
6842 //ip6_ioam_clear_destination(&ip6, mp->prefix_length, mp->vrf_id);
6844 REPLY_MACRO (VL_API_TRACE_PROFILE_APPLY_REPLY);
6847 static void vl_api_trace_profile_del_t_handler
6848 (vl_api_trace_profile_del_t * mp)
6851 vl_api_trace_profile_del_reply_t *rmp;
6852 clib_error_t *error;
6854 error = clear_ioam_rewrite_fn ();
6857 clib_error_report (error);
6858 rv = clib_error_get_code (error);
6861 REPLY_MACRO (VL_API_TRACE_PROFILE_DEL_REPLY);
6865 vl_api_af_packet_create_t_handler (vl_api_af_packet_create_t * mp)
6867 vlib_main_t *vm = vlib_get_main ();
6868 vl_api_af_packet_create_reply_t *rmp;
6870 u8 *host_if_name = NULL;
6873 host_if_name = format (0, "%s", mp->host_if_name);
6874 vec_add1 (host_if_name, 0);
6876 rv = af_packet_create_if (vm, host_if_name,
6877 mp->use_random_hw_addr ? 0 : mp->hw_addr,
6880 vec_free (host_if_name);
6883 REPLY_MACRO2(VL_API_AF_PACKET_CREATE_REPLY,
6885 rmp->sw_if_index = clib_host_to_net_u32(sw_if_index);
6891 vl_api_af_packet_delete_t_handler (vl_api_af_packet_delete_t * mp)
6893 vlib_main_t *vm = vlib_get_main ();
6894 vl_api_af_packet_delete_reply_t *rmp;
6896 u8 *host_if_name = NULL;
6898 host_if_name = format (0, "%s", mp->host_if_name);
6899 vec_add1 (host_if_name, 0);
6901 rv = af_packet_delete_if (vm, host_if_name);
6903 vec_free (host_if_name);
6905 REPLY_MACRO (VL_API_AF_PACKET_DELETE_REPLY);
6909 vl_api_policer_add_del_t_handler (vl_api_policer_add_del_t * mp)
6911 vlib_main_t *vm = vlib_get_main ();
6912 vl_api_policer_add_del_reply_t *rmp;
6915 sse2_qos_pol_cfg_params_st cfg;
6916 clib_error_t *error;
6919 name = format (0, "%s", mp->name);
6921 memset (&cfg, 0, sizeof (cfg));
6923 cfg.rnd_type = mp->round_type;
6924 cfg.rate_type = mp->rate_type;
6925 cfg.rb.kbps.cir_kbps = mp->cir;
6926 cfg.rb.kbps.eir_kbps = mp->eir;
6927 cfg.rb.kbps.cb_bytes = mp->cb;
6928 cfg.rb.kbps.eb_bytes = mp->eb;
6929 cfg.conform_action.action_type = mp->conform_action_type;
6930 cfg.conform_action.dscp = mp->conform_dscp;
6931 cfg.exceed_action.action_type = mp->exceed_action_type;
6932 cfg.exceed_action.dscp = mp->exceed_dscp;
6933 cfg.violate_action.action_type = mp->violate_action_type;
6934 cfg.violate_action.dscp = mp->violate_dscp;
6935 cfg.color_aware = mp->color_aware;
6937 error = policer_add_del (vm, name, &cfg, &policer_index, mp->is_add);
6940 rv = VNET_API_ERROR_UNSPECIFIED;
6943 REPLY_MACRO2(VL_API_POLICER_ADD_DEL_REPLY,
6945 if (rv == 0 && mp->is_add)
6946 rmp->policer_index = ntohl(policer_index);
6948 rmp->policer_index = ~0;
6954 send_policer_details (u8 * name,
6955 sse2_qos_pol_cfg_params_st * config,
6956 policer_read_response_type_st * templ,
6957 unix_shared_memory_queue_t * q, u32 context)
6959 vl_api_policer_details_t *mp;
6961 mp = vl_msg_api_alloc (sizeof (*mp));
6962 memset (mp, 0, sizeof (*mp));
6963 mp->_vl_msg_id = ntohs (VL_API_POLICER_DETAILS);
6964 mp->context = context;
6965 mp->cir = htonl (config->rb.kbps.cir_kbps);
6966 mp->eir = htonl (config->rb.kbps.eir_kbps);
6967 mp->cb = htonl (config->rb.kbps.cb_bytes);
6968 mp->eb = htonl (config->rb.kbps.eb_bytes);
6969 mp->rate_type = config->rate_type;
6970 mp->round_type = config->rnd_type;
6971 mp->type = config->rfc;
6972 mp->conform_action_type = config->conform_action.action_type;
6973 mp->conform_dscp = config->conform_action.dscp;
6974 mp->exceed_action_type = config->exceed_action.action_type;
6975 mp->exceed_dscp = config->exceed_action.dscp;
6976 mp->violate_action_type = config->violate_action.action_type;
6977 mp->violate_dscp = config->violate_action.dscp;
6978 mp->single_rate = templ->single_rate ? 1 : 0;
6979 mp->color_aware = templ->color_aware ? 1 : 0;
6980 mp->scale = htonl (templ->scale);
6981 mp->cir_tokens_per_period = htonl (templ->cir_tokens_per_period);
6982 mp->pir_tokens_per_period = htonl (templ->pir_tokens_per_period);
6983 mp->current_limit = htonl (templ->current_limit);
6984 mp->current_bucket = htonl (templ->current_bucket);
6985 mp->extended_limit = htonl (templ->extended_limit);
6986 mp->extended_bucket = htonl (templ->extended_bucket);
6987 mp->last_update_time = clib_host_to_net_u64 (templ->last_update_time);
6989 strncpy ((char *) mp->name, (char *) name, ARRAY_LEN (mp->name) - 1);
6991 vl_msg_api_send_shmem (q, (u8 *) & mp);
6995 vl_api_policer_dump_t_handler (vl_api_policer_dump_t * mp)
6997 unix_shared_memory_queue_t *q;
6998 vnet_policer_main_t *pm = &vnet_policer_main;
7004 sse2_qos_pol_cfg_params_st *config;
7005 policer_read_response_type_st *templ;
7007 q = vl_api_client_index_to_input_queue (mp->client_index);
7011 if (mp->match_name_valid)
7013 match_name = format (0, "%s%c", mp->match_name, 0);
7016 if (mp->match_name_valid)
7018 p = hash_get_mem (pm->policer_config_by_name, match_name);
7022 config = pool_elt_at_index (pm->configs, pool_index);
7023 templ = pool_elt_at_index (pm->policer_templates, pool_index);
7024 send_policer_details (match_name, config, templ, q, mp->context);
7030 hash_foreach_pair (hp, pm->policer_config_by_name,
7032 name = (u8 *) hp->key;
7033 pool_index = hp->value[0];
7034 config = pool_elt_at_index (pm->configs, pool_index);
7035 templ = pool_elt_at_index (pm->policer_templates, pool_index);
7036 send_policer_details(name, config, templ, q, mp->context);
7043 vl_api_policer_classify_set_interface_t_handler
7044 (vl_api_policer_classify_set_interface_t * mp)
7046 vlib_main_t *vm = vlib_get_main ();
7047 vl_api_policer_classify_set_interface_reply_t *rmp;
7049 u32 sw_if_index, ip4_table_index, ip6_table_index, l2_table_index;
7051 ip4_table_index = ntohl (mp->ip4_table_index);
7052 ip6_table_index = ntohl (mp->ip6_table_index);
7053 l2_table_index = ntohl (mp->l2_table_index);
7054 sw_if_index = ntohl (mp->sw_if_index);
7056 VALIDATE_SW_IF_INDEX (mp);
7058 rv = vnet_set_policer_classify_intfc (vm, sw_if_index, ip4_table_index,
7059 ip6_table_index, l2_table_index,
7062 BAD_SW_IF_INDEX_LABEL;
7064 REPLY_MACRO (VL_API_POLICER_CLASSIFY_SET_INTERFACE_REPLY);
7068 send_policer_classify_details (u32 sw_if_index,
7070 unix_shared_memory_queue_t * q, u32 context)
7072 vl_api_policer_classify_details_t *mp;
7074 mp = vl_msg_api_alloc (sizeof (*mp));
7075 memset (mp, 0, sizeof (*mp));
7076 mp->_vl_msg_id = ntohs (VL_API_POLICER_CLASSIFY_DETAILS);
7077 mp->context = context;
7078 mp->sw_if_index = htonl (sw_if_index);
7079 mp->table_index = htonl (table_index);
7081 vl_msg_api_send_shmem (q, (u8 *) & mp);
7085 vl_api_policer_classify_dump_t_handler (vl_api_policer_classify_dump_t * mp)
7087 unix_shared_memory_queue_t *q;
7088 policer_classify_main_t *pcm = &policer_classify_main;
7092 q = vl_api_client_index_to_input_queue (mp->client_index);
7096 vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type];
7098 if (vec_len (vec_tbl))
7100 for (i = 0; i < vec_len (vec_tbl); i++)
7102 if (vec_elt (vec_tbl, i) == ~0)
7105 send_policer_classify_details (i, vec_elt (vec_tbl, i), q,
7112 vl_api_netmap_create_t_handler (vl_api_netmap_create_t * mp)
7114 vlib_main_t *vm = vlib_get_main ();
7115 vl_api_netmap_create_reply_t *rmp;
7119 if_name = format (0, "%s", mp->netmap_if_name);
7120 vec_add1 (if_name, 0);
7123 netmap_create_if (vm, if_name, mp->use_random_hw_addr ? 0 : mp->hw_addr,
7124 mp->is_pipe, mp->is_master, 0);
7128 REPLY_MACRO (VL_API_NETMAP_CREATE_REPLY);
7132 vl_api_netmap_delete_t_handler (vl_api_netmap_delete_t * mp)
7134 vlib_main_t *vm = vlib_get_main ();
7135 vl_api_netmap_delete_reply_t *rmp;
7139 if_name = format (0, "%s", mp->netmap_if_name);
7140 vec_add1 (if_name, 0);
7142 rv = netmap_delete_if (vm, if_name);
7146 REPLY_MACRO (VL_API_NETMAP_DELETE_REPLY);
7150 vl_api_mpls_gre_tunnel_details_t_handler (vl_api_mpls_gre_tunnel_details_t *
7153 clib_warning ("BUG");
7157 send_mpls_gre_tunnel_entry (vpe_api_main_t * am,
7158 unix_shared_memory_queue_t * q,
7159 mpls_gre_tunnel_t * gt, u32 index, u32 context)
7161 vl_api_mpls_gre_tunnel_details_t *mp;
7162 mpls_main_t *mm = &mpls_main;
7167 e = pool_elt_at_index (mm->encaps, gt->encap_index);
7168 nlabels = vec_len (e->labels);
7170 mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
7171 memset (mp, 0, sizeof (*mp));
7172 mp->_vl_msg_id = ntohs (VL_API_MPLS_GRE_TUNNEL_DETAILS);
7173 mp->context = context;
7175 mp->tunnel_index = htonl (index);
7176 mp->tunnel_src = gt->tunnel_src.as_u32;
7177 mp->tunnel_dst = gt->tunnel_dst.as_u32;
7178 mp->intfc_address = gt->intfc_address.as_u32;
7179 mp->mask_width = htonl (gt->mask_width);
7180 mp->inner_fib_index = htonl (gt->inner_fib_index);
7181 mp->outer_fib_index = htonl (gt->outer_fib_index);
7182 mp->encap_index = htonl (gt->encap_index);
7183 mp->hw_if_index = htonl (gt->hw_if_index);
7184 mp->l2_only = htonl (gt->l2_only);
7185 mp->nlabels = htonl (nlabels);
7187 for (i = 0; i < nlabels; i++)
7190 htonl (vnet_mpls_uc_get_label
7191 (clib_host_to_net_u32 (e->labels[i].label_exp_s_ttl)));
7194 vl_msg_api_send_shmem (q, (u8 *) & mp);
7198 vl_api_mpls_gre_tunnel_dump_t_handler (vl_api_mpls_gre_tunnel_dump_t * mp)
7200 vpe_api_main_t *am = &vpe_api_main;
7201 unix_shared_memory_queue_t *q;
7202 mpls_main_t *mm = &mpls_main;
7203 mpls_gre_tunnel_t *gt;
7204 u32 index = ntohl (mp->tunnel_index);
7206 q = vl_api_client_index_to_input_queue (mp->client_index);
7212 if (!pool_is_free_index (mm->gre_tunnels, index))
7214 gt = pool_elt_at_index (mm->gre_tunnels, index);
7215 send_mpls_gre_tunnel_entry (am, q, gt, gt - mm->gre_tunnels,
7222 pool_foreach (gt, mm->gre_tunnels,
7224 send_mpls_gre_tunnel_entry (am, q, gt, gt - mm->gre_tunnels,
7232 vl_api_mpls_eth_tunnel_details_t_handler (vl_api_mpls_eth_tunnel_details_t *
7235 clib_warning ("BUG");
7239 send_mpls_eth_tunnel_entry (vpe_api_main_t * am,
7240 unix_shared_memory_queue_t * q,
7241 mpls_eth_tunnel_t * et, u32 index, u32 context)
7243 mpls_main_t *mm = &mpls_main;
7247 vl_api_mpls_eth_tunnel_details_t *mp;
7249 e = pool_elt_at_index (mm->encaps, et->encap_index);
7250 nlabels = vec_len (e->labels);
7252 mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
7253 memset (mp, 0, sizeof (*mp));
7254 mp->_vl_msg_id = ntohs (VL_API_MPLS_ETH_TUNNEL_DETAILS);
7255 mp->context = context;
7257 mp->tunnel_index = htonl (index);
7258 memcpy (mp->tunnel_dst_mac, et->tunnel_dst, 6);
7259 mp->intfc_address = et->intfc_address.as_u32;
7260 mp->tx_sw_if_index = htonl (et->tx_sw_if_index);
7261 mp->inner_fib_index = htonl (et->inner_fib_index);
7262 mp->mask_width = htonl (et->mask_width);
7263 mp->encap_index = htonl (et->encap_index);
7264 mp->hw_if_index = htonl (et->hw_if_index);
7265 mp->l2_only = htonl (et->l2_only);
7266 mp->nlabels = htonl (nlabels);
7268 for (i = 0; i < nlabels; i++)
7271 htonl (vnet_mpls_uc_get_label
7272 (clib_host_to_net_u32 (e->labels[i].label_exp_s_ttl)));
7275 vl_msg_api_send_shmem (q, (u8 *) & mp);
7279 vl_api_mpls_eth_tunnel_dump_t_handler (vl_api_mpls_eth_tunnel_dump_t * mp)
7281 vpe_api_main_t *am = &vpe_api_main;
7282 unix_shared_memory_queue_t *q;
7283 mpls_main_t *mm = &mpls_main;
7284 mpls_eth_tunnel_t *et;
7285 u32 index = ntohl (mp->tunnel_index);
7287 q = vl_api_client_index_to_input_queue (mp->client_index);
7293 if (!pool_is_free_index (mm->eth_tunnels, index))
7295 et = pool_elt_at_index (mm->eth_tunnels, index);
7296 send_mpls_eth_tunnel_entry (am, q, et, et - mm->eth_tunnels,
7303 pool_foreach (et, mm->eth_tunnels,
7305 send_mpls_eth_tunnel_entry (am, q, et, et - mm->eth_tunnels,
7313 vl_api_mpls_fib_encap_details_t_handler (vl_api_mpls_fib_encap_details_t * mp)
7315 clib_warning ("BUG");
7319 send_mpls_fib_encap_details (vpe_api_main_t * am,
7320 unix_shared_memory_queue_t * q,
7321 show_mpls_fib_t * s, u32 context)
7323 vl_api_mpls_fib_encap_details_t *mp;
7324 mpls_main_t *mm = &mpls_main;
7329 e = pool_elt_at_index (mm->encaps, s->entry_index);
7330 nlabels = vec_len (e->labels);
7332 mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
7333 memset (mp, 0, sizeof (*mp));
7334 mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_ENCAP_DETAILS);
7335 mp->context = context;
7337 mp->fib_index = htonl (s->fib_index);
7338 mp->entry_index = htonl (s->entry_index);
7340 mp->s_bit = htonl (s->s_bit);
7342 mp->nlabels = htonl (nlabels);
7344 for (i = 0; i < nlabels; i++)
7347 htonl (vnet_mpls_uc_get_label
7348 (clib_host_to_net_u32 (e->labels[i].label_exp_s_ttl)));
7351 vl_msg_api_send_shmem (q, (u8 *) & mp);
7355 vl_api_mpls_fib_encap_dump_t_handler (vl_api_mpls_fib_encap_dump_t * mp)
7357 vpe_api_main_t *am = &vpe_api_main;
7358 unix_shared_memory_queue_t *q;
7359 vlib_main_t *vm = &vlib_global_main;
7362 show_mpls_fib_t *records = 0;
7364 mpls_main_t *mm = &mpls_main;
7365 ip4_main_t *im = &ip4_main;
7368 q = vl_api_client_index_to_input_queue (mp->client_index);
7373 hash_foreach (key, value, mm->mpls_encap_by_fib_and_dest,
7375 vec_add2 (records, s, 1);
7376 s->fib_index = (u32)(key>>32);
7377 s->dest = (u32)(key & 0xFFFFFFFF);
7378 s->entry_index = (u32) value;
7382 if (0 == vec_len (records))
7384 vlib_cli_output (vm, "MPLS encap table empty");
7388 /* sort output by dst address within fib */
7389 vec_sort_with_function (records, mpls_dest_cmp);
7390 vec_sort_with_function (records, mpls_fib_index_cmp);
7391 vlib_cli_output (vm, "MPLS encap table");
7392 vlib_cli_output (vm, "%=6s%=16s%=16s", "Table", "Dest address", "Labels");
7393 vec_foreach (s, records)
7395 rx_fib = vec_elt_at_index (im->fibs, s->fib_index);
7396 vlib_cli_output (vm, "%=6d%=16U%=16U", rx_fib->table_id,
7397 format_ip4_address, &s->dest, format_mpls_encap_index,
7398 mm, s->entry_index);
7399 send_mpls_fib_encap_details (am, q, s, mp->context);
7407 vl_api_mpls_fib_decap_details_t_handler (vl_api_mpls_fib_decap_details_t * mp)
7409 clib_warning ("BUG");
7413 send_mpls_fib_decap_details (vpe_api_main_t * am,
7414 unix_shared_memory_queue_t * q,
7415 show_mpls_fib_t * s,
7417 u32 tx_table_id, char *swif_tag, u32 context)
7419 vl_api_mpls_fib_decap_details_t *mp;
7421 mp = vl_msg_api_alloc (sizeof (*mp));
7422 memset (mp, 0, sizeof (*mp));
7423 mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_DECAP_DETAILS);
7424 mp->context = context;
7426 mp->fib_index = htonl (s->fib_index);
7427 mp->entry_index = htonl (s->entry_index);
7429 mp->s_bit = htonl (s->s_bit);
7430 mp->label = htonl (s->label);
7431 mp->rx_table_id = htonl (rx_table_id);
7432 mp->tx_table_id = htonl (tx_table_id);
7433 strncpy ((char *) mp->swif_tag,
7434 (char *) swif_tag, ARRAY_LEN (mp->swif_tag) - 1);
7436 vl_msg_api_send_shmem (q, (u8 *) & mp);
7440 vl_api_mpls_fib_decap_dump_t_handler (vl_api_mpls_fib_decap_dump_t * mp)
7442 vpe_api_main_t *am = &vpe_api_main;
7443 unix_shared_memory_queue_t *q;
7444 vlib_main_t *vm = &vlib_global_main;
7447 show_mpls_fib_t *records = 0;
7449 mpls_main_t *mm = &mpls_main;
7450 ip4_main_t *im = &ip4_main;
7456 q = vl_api_client_index_to_input_queue (mp->client_index);
7461 hash_foreach (key, value, mm->mpls_decap_by_rx_fib_and_label,
7463 vec_add2 (records, s, 1);
7464 s->fib_index = (u32)(key>>32);
7465 s->entry_index = (u32) value;
7466 s->label = ((u32) key)>>12;
7467 s->s_bit = (key & (1<<8)) != 0;
7471 if (!vec_len (records))
7473 vlib_cli_output (vm, "MPLS decap table empty");
7477 vec_sort_with_function (records, mpls_label_cmp);
7478 vlib_cli_output (vm, "MPLS decap table");
7479 vlib_cli_output (vm, "%=10s%=15s%=6s%=6s", "RX Table", "TX Table/Intfc",
7481 vec_foreach (s, records)
7484 d = pool_elt_at_index (mm->decaps, s->entry_index);
7485 if (d->next_index == MPLS_INPUT_NEXT_IP4_INPUT)
7487 tx_fib = vec_elt_at_index (im->fibs, d->tx_fib_index);
7488 tx_table_id = tx_fib->table_id;
7493 tx_table_id = d->tx_fib_index;
7496 rx_fib = vec_elt_at_index (im->fibs, s->fib_index);
7498 vlib_cli_output (vm, "%=10d%=10d%=5s%=6d%=6d", rx_fib->table_id,
7499 tx_table_id, swif_tag, s->label, s->s_bit);
7501 send_mpls_fib_decap_details (am, q, s, rx_fib->table_id,
7502 tx_table_id, swif_tag, mp->context);
7510 vl_api_classify_table_ids_t_handler (vl_api_classify_table_ids_t * mp)
7512 unix_shared_memory_queue_t *q;
7514 q = vl_api_client_index_to_input_queue (mp->client_index);
7518 vnet_classify_main_t *cm = &vnet_classify_main;
7519 vnet_classify_table_t *t;
7524 pool_foreach (t, cm->tables,
7526 vec_add1 (table_ids, ntohl(t - cm->tables));
7529 count = vec_len (table_ids);
7531 vl_api_classify_table_ids_reply_t *rmp;
7532 rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp) + count * sizeof (u32));
7533 rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TABLE_IDS_REPLY);
7534 rmp->context = mp->context;
7535 rmp->count = ntohl (count);
7536 clib_memcpy (rmp->ids, table_ids, count * sizeof (u32));
7539 vl_msg_api_send_shmem (q, (u8 *) & rmp);
7541 vec_free (table_ids);
7545 vl_api_classify_table_by_interface_t_handler
7546 (vl_api_classify_table_by_interface_t * mp)
7548 vl_api_classify_table_by_interface_reply_t *rmp;
7551 u32 sw_if_index = ntohl (mp->sw_if_index);
7554 vec_validate (acl, INPUT_ACL_N_TABLES - 1);
7557 VALIDATE_SW_IF_INDEX (mp);
7559 input_acl_main_t *am = &input_acl_main;
7564 for (type = 0; type < INPUT_ACL_N_TABLES; type++)
7566 u32 *vec_tbl = am->classify_table_index_by_sw_if_index[type];
7567 if (vec_len (vec_tbl))
7569 for (if_idx = 0; if_idx < vec_len (vec_tbl); if_idx++)
7571 if (vec_elt (vec_tbl, if_idx) == ~0 || sw_if_index != if_idx)
7575 acl[type] = vec_elt (vec_tbl, if_idx);
7580 BAD_SW_IF_INDEX_LABEL;
7583 REPLY_MACRO2(VL_API_CLASSIFY_TABLE_BY_INTERFACE_REPLY,
7585 rmp->sw_if_index = ntohl(sw_if_index);
7586 rmp->l2_table_id = ntohl(acl[INPUT_ACL_TABLE_L2]);
7587 rmp->ip4_table_id = ntohl(acl[INPUT_ACL_TABLE_IP4]);
7588 rmp->ip6_table_id = ntohl(acl[INPUT_ACL_TABLE_IP6]);
7595 vl_api_classify_table_info_t_handler (vl_api_classify_table_info_t * mp)
7597 unix_shared_memory_queue_t *q;
7599 q = vl_api_client_index_to_input_queue (mp->client_index);
7603 vl_api_classify_table_info_reply_t *rmp = 0;
7605 vnet_classify_main_t *cm = &vnet_classify_main;
7606 u32 table_id = ntohl (mp->table_id);
7607 vnet_classify_table_t *t;
7610 pool_foreach (t, cm->tables,
7612 if (table_id == t - cm->tables)
7614 rmp = vl_msg_api_alloc_as_if_client
7615 (sizeof (*rmp) + t->match_n_vectors * sizeof (u32x4));
7616 rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TABLE_INFO_REPLY);
7617 rmp->context = mp->context;
7618 rmp->table_id = ntohl(table_id);
7619 rmp->nbuckets = ntohl(t->nbuckets);
7620 rmp->match_n_vectors = ntohl(t->match_n_vectors);
7621 rmp->skip_n_vectors = ntohl(t->skip_n_vectors);
7622 rmp->active_sessions = ntohl(t->active_elements);
7623 rmp->next_table_index = ntohl(t->next_table_index);
7624 rmp->miss_next_index = ntohl(t->miss_next_index);
7625 rmp->mask_length = ntohl(t->match_n_vectors * sizeof (u32x4));
7626 clib_memcpy(rmp->mask, t->mask, t->match_n_vectors * sizeof(u32x4));
7635 rmp = vl_msg_api_alloc (sizeof (*rmp));
7636 rmp->_vl_msg_id = ntohs ((VL_API_CLASSIFY_TABLE_INFO_REPLY));
7637 rmp->context = mp->context;
7638 rmp->retval = ntohl (VNET_API_ERROR_CLASSIFY_TABLE_NOT_FOUND);
7641 vl_msg_api_send_shmem (q, (u8 *) & rmp);
7645 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
7648 clib_warning ("BUG");
7652 send_classify_session_details (unix_shared_memory_queue_t * q,
7655 vnet_classify_entry_t * e, u32 context)
7657 vl_api_classify_session_details_t *rmp;
7659 rmp = vl_msg_api_alloc (sizeof (*rmp));
7660 memset (rmp, 0, sizeof (*rmp));
7661 rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_SESSION_DETAILS);
7662 rmp->context = context;
7663 rmp->table_id = ntohl (table_id);
7664 rmp->hit_next_index = ntohl (e->next_index);
7665 rmp->advance = ntohl (e->advance);
7666 rmp->opaque_index = ntohl (e->opaque_index);
7667 rmp->match_length = ntohl (match_length);
7668 clib_memcpy (rmp->match, e->key, match_length);
7670 vl_msg_api_send_shmem (q, (u8 *) & rmp);
7674 vl_api_classify_session_dump_t_handler (vl_api_classify_session_dump_t * mp)
7676 vnet_classify_main_t *cm = &vnet_classify_main;
7677 unix_shared_memory_queue_t *q;
7679 u32 table_id = ntohl (mp->table_id);
7680 vnet_classify_table_t *t;
7682 q = vl_api_client_index_to_input_queue (mp->client_index);
7685 pool_foreach (t, cm->tables,
7687 if (table_id == t - cm->tables)
7689 vnet_classify_bucket_t * b;
7690 vnet_classify_entry_t * v, * save_v;
7693 for (i = 0; i < t->nbuckets; i++)
7695 b = &t->buckets [i];
7699 save_v = vnet_classify_get_entry (t, b->offset);
7700 for (j = 0; j < (1<<b->log2_pages); j++)
7702 for (k = 0; k < t->entries_per_page; k++)
7704 v = vnet_classify_entry_at_index
7705 (t, save_v, j*t->entries_per_page + k);
7706 if (vnet_classify_entry_is_free (v))
7709 send_classify_session_details
7710 (q, table_id, t->match_n_vectors * sizeof (u32x4),
7722 vl_api_ipfix_enable_t_handler (vl_api_ipfix_enable_t * mp)
7724 vlib_main_t *vm = vlib_get_main ();
7725 flow_report_main_t *frm = &flow_report_main;
7726 vl_api_ipfix_enable_reply_t *rmp;
7727 ip4_address_t collector, src;
7728 u16 collector_port = UDP_DST_PORT_ipfix;
7730 u32 template_interval;
7735 memcpy (collector.data, mp->collector_address, sizeof (collector.data));
7736 collector_port = ntohs (mp->collector_port);
7737 if (collector_port == (u16) ~ 0)
7738 collector_port = UDP_DST_PORT_ipfix;
7739 memcpy (src.data, mp->src_address, sizeof (src.data));
7740 fib_id = ntohl (mp->vrf_id);
7742 ip4_main_t *im = &ip4_main;
7743 uword *p = hash_get (im->fib_index_by_table_id, fib_id);
7746 rv = VNET_API_ERROR_NO_SUCH_FIB;
7751 path_mtu = ntohl (mp->path_mtu);
7753 path_mtu = 512; // RFC 7011 section 10.3.3.
7754 template_interval = ntohl (mp->template_interval);
7755 if (template_interval == ~0)
7756 template_interval = 20;
7758 if (collector.as_u32 == 0)
7760 rv = VNET_API_ERROR_INVALID_VALUE;
7764 if (src.as_u32 == 0)
7766 rv = VNET_API_ERROR_INVALID_VALUE;
7770 if (path_mtu > 1450 /* vpp does not support fragmentation */ )
7772 rv = VNET_API_ERROR_INVALID_VALUE;
7778 rv = VNET_API_ERROR_INVALID_VALUE;
7782 /* Reset report streams if we are reconfiguring IP addresses */
7783 if (frm->ipfix_collector.as_u32 != collector.as_u32 ||
7784 frm->src_address.as_u32 != src.as_u32 ||
7785 frm->collector_port != collector_port)
7786 vnet_flow_reports_reset (frm);
7788 frm->ipfix_collector.as_u32 = collector.as_u32;
7789 frm->collector_port = collector_port;
7790 frm->src_address.as_u32 = src.as_u32;
7791 frm->fib_index = fib_index;
7792 frm->path_mtu = path_mtu;
7793 frm->template_interval = template_interval;
7795 /* Turn on the flow reporting process */
7796 vlib_process_signal_event (vm, flow_report_process_node.index, 1, 0);
7799 REPLY_MACRO (VL_API_IPFIX_ENABLE_REPLY);
7803 vl_api_ipfix_dump_t_handler (vl_api_ipfix_dump_t * mp)
7805 flow_report_main_t *frm = &flow_report_main;
7806 unix_shared_memory_queue_t *q;
7807 vl_api_ipfix_details_t *rmp;
7809 q = vl_api_client_index_to_input_queue (mp->client_index);
7813 rmp = vl_msg_api_alloc (sizeof (*rmp));
7814 memset (rmp, 0, sizeof (*rmp));
7815 rmp->_vl_msg_id = ntohs (VL_API_IPFIX_DETAILS);
7816 rmp->context = mp->context;
7817 memcpy (rmp->collector_address, frm->ipfix_collector.data,
7818 sizeof (frm->ipfix_collector.data));
7819 rmp->collector_port = htons (frm->collector_port);
7820 memcpy (rmp->src_address, frm->src_address.data,
7821 sizeof (frm->src_address.data));
7822 rmp->fib_index = htonl (frm->fib_index);
7823 rmp->path_mtu = htonl (frm->path_mtu);
7824 rmp->template_interval = htonl (frm->template_interval);
7826 vl_msg_api_send_shmem (q, (u8 *) & rmp);
7830 vl_api_pg_create_interface_t_handler (vl_api_pg_create_interface_t * mp)
7832 vl_api_pg_create_interface_reply_t *rmp;
7835 pg_main_t *pg = &pg_main;
7836 u32 sw_if_index = pg_interface_add_or_get (pg, ntohl (mp->interface_id));
7839 REPLY_MACRO2(VL_API_PG_CREATE_INTERFACE_REPLY,
7841 rmp->sw_if_index = ntohl(sw_if_index);
7847 vl_api_pg_capture_t_handler (vl_api_pg_capture_t * mp)
7849 vl_api_pg_capture_reply_t *rmp;
7852 vnet_main_t *vnm = vnet_get_main ();
7853 vnet_interface_main_t *im = &vnm->interface_main;
7854 vnet_hw_interface_t *hi = 0;
7856 u8 *intf_name = format (0, "pg%d", ntohl (mp->interface_id), 0);
7857 u32 hw_if_index = ~0;
7858 uword *p = hash_get_mem (im->hw_interface_by_name, intf_name);
7861 vec_free (intf_name);
7863 if (hw_if_index != ~0)
7865 pg_capture_args_t _a, *a = &_a;
7867 u32 len = ntohl (mp->pcap_name_length);
7868 u8 *pcap_file_name = vec_new (u8, len);
7869 clib_memcpy (pcap_file_name, mp->pcap_file_name, len);
7871 hi = vnet_get_sup_hw_interface (vnm, hw_if_index);
7872 a->hw_if_index = hw_if_index;
7873 a->dev_instance = hi->dev_instance;
7874 a->is_enabled = mp->is_enabled;
7875 a->pcap_file_name = pcap_file_name;
7876 a->count = ntohl (mp->count);
7878 clib_error_t *e = pg_capture (a);
7881 clib_error_report (e);
7882 rv = VNET_API_ERROR_CANNOT_CREATE_PCAP_FILE;
7885 vec_free (pcap_file_name);
7887 REPLY_MACRO (VL_API_PG_CAPTURE_REPLY);
7891 vl_api_pg_enable_disable_t_handler (vl_api_pg_enable_disable_t * mp)
7893 vl_api_pg_enable_disable_reply_t *rmp;
7896 pg_main_t *pg = &pg_main;
7897 u32 stream_index = ~0;
7899 int is_enable = mp->is_enabled != 0;
7900 u32 len = ntohl (mp->stream_name_length) - 1;
7904 u8 *stream_name = vec_new (u8, len);
7905 clib_memcpy (stream_name, mp->stream_name, len);
7906 uword *p = hash_get_mem (pg->stream_index_by_name, stream_name);
7909 vec_free (stream_name);
7912 pg_enable_disable (stream_index, is_enable);
7914 REPLY_MACRO (VL_API_PG_ENABLE_DISABLE_REPLY);
7918 vl_api_ip_source_and_port_range_check_add_del_t_handler
7919 (vl_api_ip_source_and_port_range_check_add_del_t * mp)
7921 vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
7924 u8 is_ipv6 = mp->is_ipv6;
7925 u8 is_add = mp->is_add;
7926 u8 mask_length = mp->mask_length;
7927 ip4_address_t ip4_addr;
7928 ip6_address_t ip6_addr;
7930 u16 *high_ports = 0;
7932 u16 tmp_low, tmp_high;
7936 // Validate port range
7937 num_ranges = mp->number_of_ranges;
7938 if (num_ranges > 32)
7939 { // This is size of array in VPE.API
7940 rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
7944 vec_reset_length (low_ports);
7945 vec_reset_length (high_ports);
7947 for (i = 0; i < num_ranges; i++)
7949 tmp_low = mp->low_ports[i];
7950 tmp_high = mp->high_ports[i];
7951 // If tmp_low <= tmp_high then only need to check tmp_low = 0
7952 // If tmp_low <= tmp_high then only need to check tmp_high > 65535
7953 if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535)
7955 rv = VNET_API_ERROR_INVALID_VALUE;
7958 vec_add1 (low_ports, tmp_low);
7959 vec_add1 (high_ports, tmp_high + 1);
7962 // Validate mask_length
7963 if ((is_ipv6 && mask_length > 128) || (!is_ipv6 && mask_length > 32))
7965 rv = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH;
7969 vrf_id = ntohl (mp->vrf_id);
7973 rv = VNET_API_ERROR_INVALID_VALUE;
7980 clib_memcpy (ip6_addr.as_u8, mp->address, sizeof (ip6_addr.as_u8));
7981 rv = ip6_source_and_port_range_check_add_del (&ip6_addr,
7985 high_ports, is_add);
7989 clib_memcpy (ip4_addr.data, mp->address, sizeof (ip4_addr));
7990 rv = ip4_source_and_port_range_check_add_del (&ip4_addr,
7994 high_ports, is_add);
7998 vec_free (low_ports);
7999 vec_free (high_ports);
8000 REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY);
8004 vl_api_ip_source_and_port_range_check_interface_add_del_t_handler
8005 (vl_api_ip_source_and_port_range_check_interface_add_del_t * mp)
8007 vlib_main_t *vm = vlib_get_main ();
8008 vl_api_ip_source_and_port_range_check_interface_add_del_reply_t *rmp;
8009 ip4_main_t *im = &ip4_main;
8012 u32 fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS];
8013 u32 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS];
8017 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT] =
8018 ntohl (mp->tcp_out_vrf_id);
8019 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT] =
8020 ntohl (mp->udp_out_vrf_id);
8021 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN] =
8022 ntohl (mp->tcp_in_vrf_id);
8023 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_IN] =
8024 ntohl (mp->udp_in_vrf_id);
8027 for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
8029 if (vrf_id[i] != 0 && vrf_id[i] != ~0)
8031 p = hash_get (im->fib_index_by_table_id, vrf_id[i]);
8035 rv = VNET_API_ERROR_INVALID_VALUE;
8039 fib_index[i] = p[0];
8044 sw_if_index = ntohl (mp->sw_if_index);
8046 VALIDATE_SW_IF_INDEX (mp);
8049 set_ip_source_and_port_range_check (vm, fib_index, sw_if_index,
8052 BAD_SW_IF_INDEX_LABEL;
8055 REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY);
8059 vl_api_ipsec_gre_add_del_tunnel_t_handler (vl_api_ipsec_gre_add_del_tunnel_t *
8062 vl_api_ipsec_gre_add_del_tunnel_reply_t *rmp;
8064 vnet_ipsec_gre_add_del_tunnel_args_t _a, *a = &_a;
8065 u32 sw_if_index = ~0;
8067 /* Check src & dst are different */
8068 if (memcmp (mp->src_address, mp->dst_address, 4) == 0)
8070 rv = VNET_API_ERROR_SAME_SRC_DST;
8074 memset (a, 0, sizeof (*a));
8076 /* ip addresses sent in network byte order */
8077 clib_memcpy (&(a->src), mp->src_address, 4);
8078 clib_memcpy (&(a->dst), mp->dst_address, 4);
8079 a->is_add = mp->is_add;
8080 a->lsa = ntohl (mp->local_sa_id);
8081 a->rsa = ntohl (mp->remote_sa_id);
8083 rv = vnet_ipsec_gre_add_del_tunnel (a, &sw_if_index);
8087 REPLY_MACRO2(VL_API_GRE_ADD_DEL_TUNNEL_REPLY,
8089 rmp->sw_if_index = ntohl (sw_if_index);
8094 static void send_ipsec_gre_tunnel_details
8095 (ipsec_gre_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
8097 vl_api_ipsec_gre_tunnel_details_t *rmp;
8099 rmp = vl_msg_api_alloc (sizeof (*rmp));
8100 memset (rmp, 0, sizeof (*rmp));
8101 rmp->_vl_msg_id = ntohs (VL_API_IPSEC_GRE_TUNNEL_DETAILS);
8102 clib_memcpy (rmp->src_address, &(t->tunnel_src), 4);
8103 clib_memcpy (rmp->dst_address, &(t->tunnel_dst), 4);
8104 rmp->sw_if_index = htonl (t->sw_if_index);
8105 rmp->local_sa_id = htonl (t->local_sa_id);
8106 rmp->remote_sa_id = htonl (t->remote_sa_id);
8107 rmp->context = context;
8109 vl_msg_api_send_shmem (q, (u8 *) & rmp);
8112 static void vl_api_ipsec_gre_tunnel_dump_t_handler
8113 (vl_api_ipsec_gre_tunnel_dump_t * mp)
8115 unix_shared_memory_queue_t *q;
8116 ipsec_gre_main_t *igm = &ipsec_gre_main;
8117 ipsec_gre_tunnel_t *t;
8120 q = vl_api_client_index_to_input_queue (mp->client_index);
8126 sw_if_index = ntohl (mp->sw_if_index);
8128 if (~0 == sw_if_index)
8131 pool_foreach (t, igm->tunnels,
8133 send_ipsec_gre_tunnel_details(t, q, mp->context);
8139 if ((sw_if_index >= vec_len (igm->tunnel_index_by_sw_if_index)) ||
8140 (~0 == igm->tunnel_index_by_sw_if_index[sw_if_index]))
8144 t = &igm->tunnels[igm->tunnel_index_by_sw_if_index[sw_if_index]];
8145 send_ipsec_gre_tunnel_details (t, q, mp->context);
8149 #define BOUNCE_HANDLER(nn) \
8150 static void vl_api_##nn##_t_handler ( \
8151 vl_api_##nn##_t *mp) \
8153 vpe_client_registration_t *reg; \
8154 vpe_api_main_t * vam = &vpe_api_main; \
8155 unix_shared_memory_queue_t * q; \
8157 /* One registration only... */ \
8158 pool_foreach(reg, vam->nn##_registrations, \
8160 q = vl_api_client_index_to_input_queue (reg->client_index); \
8163 * If the queue is stuffed, turf the msg and complain \
8164 * It's unlikely that the intended recipient is \
8165 * alive; avoid deadlock at all costs. \
8167 if (q->cursize == q->maxsize) { \
8168 clib_warning ("ERROR: receiver queue full, drop msg"); \
8169 vl_msg_api_free (mp); \
8172 vl_msg_api_send_shmem (q, (u8 *)&mp); \
8176 vl_msg_api_free (mp); \
8181 * Add vpe's API message handlers to the table.
8182 * vlib has alread mapped shared memory and
8183 * added the client registration handlers.
8184 * See .../open-repo/vlib/memclnt_vlib.c:memclnt_process()
8187 static clib_error_t *
8188 vpe_api_hookup (vlib_main_t * vm)
8190 api_main_t *am = &api_main;
8193 vl_msg_api_set_handlers(VL_API_##N, #n, \
8194 vl_api_##n##_t_handler, \
8196 vl_api_##n##_t_endian, \
8197 vl_api_##n##_t_print, \
8198 sizeof(vl_api_##n##_t), 1);
8199 foreach_vpe_api_msg;
8203 * Manually register the sr tunnel add del msg, so we trace
8204 * enough bytes to capture a typical segment list
8206 vl_msg_api_set_handlers (VL_API_SR_TUNNEL_ADD_DEL,
8207 "sr_tunnel_add_del",
8208 vl_api_sr_tunnel_add_del_t_handler,
8210 vl_api_sr_tunnel_add_del_t_endian,
8211 vl_api_sr_tunnel_add_del_t_print, 256, 1);
8215 * Manually register the sr policy add del msg, so we trace
8216 * enough bytes to capture a typical tunnel name list
8218 vl_msg_api_set_handlers (VL_API_SR_POLICY_ADD_DEL,
8219 "sr_policy_add_del",
8220 vl_api_sr_policy_add_del_t_handler,
8222 vl_api_sr_policy_add_del_t_endian,
8223 vl_api_sr_policy_add_del_t_print, 256, 1);
8226 * Trace space for 8 MPLS encap labels, classifier mask+match
8228 am->api_trace_cfg[VL_API_MPLS_ADD_DEL_ENCAP].size += 8 * sizeof (u32);
8229 am->api_trace_cfg[VL_API_CLASSIFY_ADD_DEL_TABLE].size += 5 * sizeof (u32x4);
8230 am->api_trace_cfg[VL_API_CLASSIFY_ADD_DEL_SESSION].size
8231 += 5 * sizeof (u32x4);
8232 am->api_trace_cfg[VL_API_VXLAN_ADD_DEL_TUNNEL].size += 16 * sizeof (u32);
8235 * Thread-safe API messages
8237 am->is_mp_safe[VL_API_IP_ADD_DEL_ROUTE] = 1;
8238 am->is_mp_safe[VL_API_GET_NODE_GRAPH] = 1;
8243 VLIB_API_INIT_FUNCTION (vpe_api_hookup);
8245 static clib_error_t *
8246 vpe_api_init (vlib_main_t * vm)
8248 vpe_api_main_t *am = &vpe_api_main;
8251 am->vnet_main = vnet_get_main ();
8252 am->interface_events_registration_hash = hash_create (0, sizeof (uword));
8253 am->to_netconf_server_registration_hash = hash_create (0, sizeof (uword));
8254 am->from_netconf_server_registration_hash = hash_create (0, sizeof (uword));
8255 am->to_netconf_client_registration_hash = hash_create (0, sizeof (uword));
8256 am->from_netconf_client_registration_hash = hash_create (0, sizeof (uword));
8257 am->oam_events_registration_hash = hash_create (0, sizeof (uword));
8260 vl_set_memory_region_name ("/vpe-api");
8261 vl_enable_disable_memory_api (vm, 1 /* enable it */ );
8266 VLIB_INIT_FUNCTION (vpe_api_init);
8269 static clib_error_t *
8270 api_segment_config (vlib_main_t * vm, unformat_input_t * input)
8273 u64 baseva, size, pvt_heap_size;
8275 const int max_buf_size = 4096;
8277 struct passwd _pw, *pw;
8278 struct group _grp, *grp;
8280 buf = vec_new (char, 128);
8281 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8283 if (unformat (input, "prefix %s", &chroot_path))
8285 vec_add1 (chroot_path, 0);
8286 vl_set_memory_root_path ((char *) chroot_path);
8288 else if (unformat (input, "uid %d", &uid))
8289 vl_set_memory_uid (uid);
8290 else if (unformat (input, "gid %d", &gid))
8291 vl_set_memory_gid (gid);
8292 else if (unformat (input, "baseva %llx", &baseva))
8293 vl_set_global_memory_baseva (baseva);
8294 else if (unformat (input, "global-size %lldM", &size))
8295 vl_set_global_memory_size (size * (1ULL << 20));
8296 else if (unformat (input, "global-size %lldG", &size))
8297 vl_set_global_memory_size (size * (1ULL << 30));
8298 else if (unformat (input, "global-size %lld", &size))
8299 vl_set_global_memory_size (size);
8300 else if (unformat (input, "global-pvt-heap-size %lldM", &pvt_heap_size))
8301 vl_set_global_pvt_heap_size (pvt_heap_size * (1ULL << 20));
8302 else if (unformat (input, "global-pvt-heap-size size %lld",
8304 vl_set_global_pvt_heap_size (pvt_heap_size);
8305 else if (unformat (input, "api-pvt-heap-size %lldM", &pvt_heap_size))
8306 vl_set_api_pvt_heap_size (pvt_heap_size * (1ULL << 20));
8307 else if (unformat (input, "api-pvt-heap-size size %lld",
8309 vl_set_api_pvt_heap_size (pvt_heap_size);
8310 else if (unformat (input, "api-size %lldM", &size))
8311 vl_set_api_memory_size (size * (1ULL << 20));
8312 else if (unformat (input, "api-size %lldG", &size))
8313 vl_set_api_memory_size (size * (1ULL << 30));
8314 else if (unformat (input, "api-size %lld", &size))
8315 vl_set_api_memory_size (size);
8316 else if (unformat (input, "uid %s", &s))
8318 /* lookup the username */
8321 getpwnam_r (s, &_pw, buf, vec_len (buf), &pw)) == ERANGE)
8322 && (vec_len (buf) <= max_buf_size))
8324 vec_resize (buf, vec_len (buf) * 2);
8328 e = clib_error_return_code (0, rv,
8329 CLIB_ERROR_ERRNO_VALID |
8331 "cannot fetch username %s", s);
8339 clib_error_return_fatal (0, "username %s does not exist", s);
8345 vl_set_memory_uid (pw->pw_uid);
8347 else if (unformat (input, "gid %s", &s))
8349 /* lookup the group name */
8352 getgrnam_r (s, &_grp, buf, vec_len (buf), &grp)) == ERANGE)
8353 && (vec_len (buf) <= max_buf_size))
8355 vec_resize (buf, vec_len (buf) * 2);
8359 e = clib_error_return_code (0, rv,
8360 CLIB_ERROR_ERRNO_VALID |
8362 "cannot fetch group %s", s);
8369 e = clib_error_return_fatal (0, "group %s does not exist", s);
8376 vl_set_memory_gid (grp->gr_gid);
8379 return clib_error_return (0, "unknown input `%U'",
8380 format_unformat_error, input);
8385 VLIB_EARLY_CONFIG_FUNCTION (api_segment_config, "api-segment");
8388 get_unformat_vnet_sw_interface (void)
8390 return (void *) &unformat_vnet_sw_interface;
8393 #undef vl_api_version
8394 #define vl_api_version(n,v) static u32 vpe_api_version = v;
8395 #include <vpp-api/vpe.api.h>
8396 #undef vl_api_version
8399 vl_msg_api_version_check (vl_api_memclnt_create_t * mp)
8401 if (clib_host_to_net_u32 (mp->api_versions[0]) != vpe_api_version)
8403 clib_warning ("vpe API mismatch: 0x%08x instead of 0x%08x",
8404 clib_host_to_net_u32 (mp->api_versions[0]),
8412 format_arp_event (u8 * s, va_list * args)
8414 vl_api_ip4_arp_event_t *event = va_arg (*args, vl_api_ip4_arp_event_t *);
8416 s = format (s, "pid %d: %U", event->pid,
8417 format_ip4_address, &event->address);
8421 static clib_error_t *
8422 show_ip4_arp_events_fn (vlib_main_t * vm,
8423 unformat_input_t * input, vlib_cli_command_t * cmd)
8425 vpe_api_main_t *am = &vpe_api_main;
8426 vl_api_ip4_arp_event_t *event;
8428 if (pool_elts (am->arp_events) == 0)
8430 vlib_cli_output (vm, "No active arp event registrations");
8435 pool_foreach (event, am->arp_events,
8437 vlib_cli_output (vm, "%U", format_arp_event, event);
8445 VLIB_CLI_COMMAND (show_ip4_arp_events, static) = {
8446 .path = "show arp event registrations",
8447 .function = show_ip4_arp_events_fn,
8448 .short_help = "Show arp event registrations",
8453 * fd.io coding-style-patch-verification: ON
8456 * eval: (c-set-style "gnu")