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> // alagalah TODO : committers please pay note, is this ok?
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/l2/l2_classify.h>
70 #include <vnet/vxlan/vxlan.h>
71 #include <vnet/gre/gre.h>
72 #include <vnet/l2/l2_vtr.h>
73 #include <vnet/vxlan-gpe/vxlan_gpe.h>
74 #include <vnet/lisp-gpe/lisp_gpe.h>
75 #include <vnet/lisp-cp/control.h>
76 #include <vnet/map/map.h>
77 #include <vnet/cop/cop.h>
78 #include <vnet/ip/ip6_hop_by_hop.h>
79 #include <vnet/devices/af_packet/af_packet.h>
80 #include <vnet/policer/policer.h>
81 #include <vnet/devices/netmap/netmap.h>
84 #undef __included_bihash_template_h__
85 #include <vnet/l2/l2_fib.h>
88 #include <vnet/ipsec/ipsec.h>
89 #include <vnet/ipsec/ikev2.h>
92 #include <vnet/devices/virtio/vhost-user.h>
95 #include <stats/stats.h>
98 #include <vnet/ethernet/ethernet.h>
99 #include <vnet/ethernet/arp_packet.h>
100 #include <vnet/interface.h>
102 #include <vnet/l2/l2_fib.h>
103 #include <vnet/l2/l2_bd.h>
104 #include <api/vpe_msg_enum.h>
106 #define f64_endian(a)
107 #define f64_print(a,b)
109 #define vl_typedefs /* define message structures */
110 #include <api/vpe_all_api_h.h>
113 #define vl_endianfun /* define message structures */
114 #include <api/vpe_all_api_h.h>
117 /* instantiate all the print functions we know about */
118 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
120 #include <api/vpe_all_api_h.h>
123 #define REPLY_MACRO(t) \
125 unix_shared_memory_queue_t * q; \
126 rv = vl_msg_api_pd_handler (mp, rv); \
127 q = vl_api_client_index_to_input_queue (mp->client_index); \
131 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
132 rmp->_vl_msg_id = ntohs((t)); \
133 rmp->context = mp->context; \
134 rmp->retval = ntohl(rv); \
136 vl_msg_api_send_shmem (q, (u8 *)&rmp); \
139 #define REPLY_MACRO2(t, body) \
141 unix_shared_memory_queue_t * q; \
142 rv = vl_msg_api_pd_handler (mp, rv); \
143 q = vl_api_client_index_to_input_queue (mp->client_index); \
147 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
148 rmp->_vl_msg_id = ntohs((t)); \
149 rmp->context = mp->context; \
150 rmp->retval = ntohl(rv); \
151 do {body;} while (0); \
152 vl_msg_api_send_shmem (q, (u8 *)&rmp); \
155 #if (1 || CLIB_DEBUG > 0) /* "trust, but verify" */
157 #define VALIDATE_SW_IF_INDEX(mp) \
158 do { u32 __sw_if_index = ntohl(mp->sw_if_index); \
159 vnet_main_t *__vnm = vnet_get_main(); \
160 if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
162 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
163 goto bad_sw_if_index; \
167 #define BAD_SW_IF_INDEX_LABEL \
173 #define VALIDATE_RX_SW_IF_INDEX(mp) \
174 do { u32 __rx_sw_if_index = ntohl(mp->rx_sw_if_index); \
175 vnet_main_t *__vnm = vnet_get_main(); \
176 if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
177 __rx_sw_if_index)) { \
178 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
179 goto bad_rx_sw_if_index; \
183 #define BAD_RX_SW_IF_INDEX_LABEL \
185 bad_rx_sw_if_index: \
189 #define VALIDATE_TX_SW_IF_INDEX(mp) \
190 do { u32 __tx_sw_if_index = ntohl(mp->tx_sw_if_index); \
191 vnet_main_t *__vnm = vnet_get_main(); \
192 if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
193 __tx_sw_if_index)) { \
194 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
195 goto bad_tx_sw_if_index; \
199 #define BAD_TX_SW_IF_INDEX_LABEL \
201 bad_tx_sw_if_index: \
207 #define VALIDATE_SW_IF_INDEX(mp)
208 #define BAD_SW_IF_INDEX_LABEL
209 #define VALIDATE_RX_SW_IF_INDEX(mp)
210 #define BAD_RX_SW_IF_INDEX_LABEL
211 #define VALIDATE_TX_SW_IF_INDEX(mp)
212 #define BAD_TX_SW_IF_INDEX_LABEL
214 #endif /* CLIB_DEBUG > 0 */
216 #define foreach_vpe_api_msg \
217 _(WANT_INTERFACE_EVENTS, want_interface_events) \
218 _(WANT_OAM_EVENTS, want_oam_events) \
219 _(OAM_ADD_DEL, oam_add_del) \
220 _(SW_INTERFACE_DUMP, sw_interface_dump) \
221 _(SW_INTERFACE_DETAILS, sw_interface_details) \
222 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
223 _(IP_ADD_DEL_ROUTE, ip_add_del_route) \
224 _(IS_ADDRESS_REACHABLE, is_address_reachable) \
225 _(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address) \
226 _(SW_INTERFACE_SET_TABLE, sw_interface_set_table) \
227 _(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath) \
228 _(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect) \
229 _(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge) \
230 _(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del) \
231 _(BRIDGE_DOMAIN_DUMP, bridge_domain_dump) \
232 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
233 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
234 _(L2FIB_ADD_DEL, l2fib_add_del) \
235 _(L2_FLAGS, l2_flags) \
236 _(BRIDGE_FLAGS, bridge_flags) \
237 _(TAP_CONNECT, tap_connect) \
238 _(TAP_MODIFY, tap_modify) \
239 _(TAP_DELETE, tap_delete) \
240 _(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump) \
241 _(CREATE_VLAN_SUBIF, create_vlan_subif) \
242 _(CREATE_SUBIF, create_subif) \
243 _(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel) \
244 _(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel) \
245 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2) \
246 _(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap) \
247 _(MPLS_ADD_DEL_DECAP, mpls_add_del_decap) \
248 _(PROXY_ARP_ADD_DEL, proxy_arp_add_del) \
249 _(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable) \
250 _(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del) \
251 _(VNET_GET_SUMMARY_STATS, vnet_get_summary_stats) \
252 _(RESET_FIB, reset_fib) \
253 _(DHCP_PROXY_CONFIG,dhcp_proxy_config) \
254 _(DHCP_PROXY_CONFIG_2,dhcp_proxy_config_2) \
255 _(DHCP_PROXY_SET_VSS,dhcp_proxy_set_vss) \
256 _(DHCP_CLIENT_CONFIG, dhcp_client_config) \
257 _(SET_IP_FLOW_HASH,set_ip_flow_hash) \
258 _(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config) \
259 _(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix) \
260 _(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable ) \
261 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
262 sw_interface_ip6_set_link_local_address) \
263 _(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered) \
264 _(CREATE_LOOPBACK, create_loopback) \
265 _(CONTROL_PING, control_ping) \
266 _(CLI_REQUEST, cli_request) \
267 _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \
268 _(L2_PATCH_ADD_DEL, l2_patch_add_del) \
269 _(CLASSIFY_ADD_DEL_TABLE, classify_add_del_table) \
270 _(CLASSIFY_ADD_DEL_SESSION, classify_add_del_session) \
271 _(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table) \
272 _(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables) \
273 _(GET_NODE_INDEX, get_node_index) \
274 _(ADD_NODE_NEXT, add_node_next) \
275 _(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel) \
276 _(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies) \
277 _(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable) \
278 _(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key) \
279 _(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump) \
280 _(VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel) \
281 _(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump) \
282 _(GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel) \
283 _(GRE_TUNNEL_DUMP, gre_tunnel_dump) \
284 _(L2_FIB_CLEAR_TABLE, l2_fib_clear_table) \
285 _(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter) \
286 _(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite) \
287 _(CREATE_VHOST_USER_IF, create_vhost_user_if) \
288 _(MODIFY_VHOST_USER_IF, modify_vhost_user_if) \
289 _(DELETE_VHOST_USER_IF, delete_vhost_user_if) \
290 _(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump) \
291 _(IP_ADDRESS_DUMP, ip_address_dump) \
292 _(IP_DUMP, ip_dump) \
293 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
294 _(SHOW_VERSION, show_version) \
295 _(L2_FIB_TABLE_DUMP, l2_fib_table_dump) \
296 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
297 _(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel) \
298 _(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump) \
299 _(INTERFACE_NAME_RENUMBER, interface_name_renumber) \
300 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events) \
301 _(INPUT_ACL_SET_INTERFACE, input_acl_set_interface) \
302 _(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
303 _(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
304 _(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry) \
305 _(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry) \
306 _(IPSEC_SA_SET_KEY, ipsec_sa_set_key) \
307 _(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del) \
308 _(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth) \
309 _(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id) \
310 _(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts) \
311 _(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key) \
312 _(DELETE_LOOPBACK, delete_loopback) \
313 _(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del) \
314 _(MAP_ADD_DOMAIN, map_add_domain) \
315 _(MAP_DEL_DOMAIN, map_del_domain) \
316 _(MAP_ADD_DEL_RULE, map_add_del_rule) \
317 _(MAP_DOMAIN_DUMP, map_domain_dump) \
318 _(MAP_RULE_DUMP, map_rule_dump) \
319 _(MAP_SUMMARY_STATS, map_summary_stats) \
320 _(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable) \
321 _(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable) \
322 _(GET_NODE_GRAPH, get_node_graph) \
323 _(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats) \
324 _(TRACE_PROFILE_ADD, trace_profile_add) \
325 _(TRACE_PROFILE_APPLY, trace_profile_apply) \
326 _(TRACE_PROFILE_DEL, trace_profile_del) \
327 _(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set) \
328 _(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator) \
329 _(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid) \
330 _(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry) \
331 _(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver) \
332 _(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable) \
333 _(LISP_ENABLE_DISABLE, lisp_enable_disable) \
334 _(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface) \
335 _(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping) \
336 _(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set) \
337 _(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump) \
338 _(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump) \
339 _(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump) \
340 _(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump) \
341 _(LISP_ENABLE_DISABLE_STATUS_DUMP, \
342 lisp_enable_disable_status_dump) \
343 _(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del) \
344 _(AF_PACKET_CREATE, af_packet_create) \
345 _(AF_PACKET_DELETE, af_packet_delete) \
346 _(POLICER_ADD_DEL, policer_add_del) \
347 _(POLICER_DUMP, policer_dump) \
348 _(NETMAP_CREATE, netmap_create) \
349 _(NETMAP_DELETE, netmap_delete)
352 #define QUOTE(x) QUOTE_(x)
354 #define foreach_registration_hash \
355 _(interface_events) \
356 _(to_netconf_server) \
357 _(from_netconf_server) \
358 _(to_netconf_client) \
359 _(from_netconf_client) \
363 RESOLVE_IP4_ADD_DEL_ROUTE=1,
364 RESOLVE_IP6_ADD_DEL_ROUTE,
365 RESOLVE_MPLS_ETHERNET_ADD_DEL,
371 vl_api_ip_add_del_route_t r;
372 vl_api_mpls_ethernet_add_del_tunnel_2_t t;
378 #define _(a) uword *a##_registration_hash; \
379 vpe_client_registration_t * a##_registrations;
380 foreach_registration_hash
383 /* notifications happen really early in the game */
384 u8 link_state_process_up;
386 /* ip4 pending route adds */
387 pending_route_t * pending_routes;
389 /* ip4 arp event registration pool */
390 vl_api_ip4_arp_event_t * arp_events;
393 vlib_main_t * vlib_main;
394 vnet_main_t * vnet_main;
397 static vlib_node_registration_t vpe_resolver_process_node;
398 static vpe_api_main_t vpe_api_main;
400 static void send_sw_interface_flags (vpe_api_main_t * am,
401 unix_shared_memory_queue_t *q,
402 vnet_sw_interface_t * swif);
403 static void send_sw_interface_flags_deleted (vpe_api_main_t * am,
404 unix_shared_memory_queue_t *q,
407 static int arp_change_delete_callback (u32 pool_index, u8 * notused);
410 /* Clean up all registrations belonging to the indicated client */
411 int vl_api_memclnt_delete_callback (u32 client_index)
413 vpe_api_main_t * vam = &vpe_api_main;
414 vpe_client_registration_t *rp;
416 int stats_memclnt_delete_callback (u32 client_index);
418 stats_memclnt_delete_callback (client_index);
421 p = hash_get (vam->a##_registration_hash, client_index); \
423 rp = pool_elt_at_index (vam->a##_registrations, p[0]); \
424 pool_put (vam->a##_registrations, rp); \
425 hash_unset (vam->a##_registration_hash, client_index); \
427 foreach_registration_hash;
432 #define API_LINK_STATE_EVENT 1
433 #define API_ADMIN_UP_DOWN_EVENT 2
436 event_data_cmp (void * a1, void * a2)
441 return (word) e1[0] - (word) e2[0];
445 link_state_process (vlib_main_t * vm,
446 vlib_node_runtime_t * rt,
449 vpe_api_main_t * vam = &vpe_api_main;
450 vnet_main_t * vnm = vam->vnet_main;
451 vnet_sw_interface_t * swif;
452 uword * event_data = 0;
453 vpe_client_registration_t *reg;
455 u32 prev_sw_if_index;
456 unix_shared_memory_queue_t * q;
458 vam->link_state_process_up = 1;
461 vlib_process_wait_for_event (vm);
463 /* Unified list of changed link or admin state sw_if_indices */
464 vlib_process_get_events_with_type
465 (vm, &event_data, API_LINK_STATE_EVENT);
466 vlib_process_get_events_with_type
467 (vm, &event_data, API_ADMIN_UP_DOWN_EVENT);
469 /* Sort, so we can eliminate duplicates */
470 vec_sort_with_function (event_data, event_data_cmp);
472 prev_sw_if_index = ~0;
474 for (i = 0; i < vec_len(event_data); i++) {
475 /* Only one message per swif */
476 if (prev_sw_if_index == event_data[i])
478 prev_sw_if_index = event_data[i];
480 pool_foreach(reg, vam->interface_events_registrations,
482 q = vl_api_client_index_to_input_queue (reg->client_index);
484 // sw_interface may be deleted already
485 if (!pool_is_free_index (vnm->interface_main.sw_interfaces,
488 swif = vnet_get_sw_interface (vnm, event_data[i]);
489 send_sw_interface_flags (vam, q, swif);
494 vec_reset_length (event_data);
500 static clib_error_t *
501 link_up_down_function (vnet_main_t *vm, u32 hw_if_index, u32 flags);
502 static clib_error_t *
503 admin_up_down_function (vnet_main_t *vm, u32 hw_if_index, u32 flags);
505 VLIB_REGISTER_NODE (link_state_process_node,static) = {
506 .function = link_state_process,
507 .type = VLIB_NODE_TYPE_PROCESS,
508 .name = "vpe-link-state-process",
511 VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (admin_up_down_function);
512 VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (link_up_down_function);
514 static clib_error_t *
515 link_up_down_function (vnet_main_t *vm, u32 hw_if_index, u32 flags)
517 vpe_api_main_t * vam = &vpe_api_main;
518 vnet_hw_interface_t *hi = vnet_get_hw_interface (vm, hw_if_index);
520 if (vam->link_state_process_up)
521 vlib_process_signal_event (vam->vlib_main,
522 link_state_process_node.index,
523 API_LINK_STATE_EVENT,
528 static clib_error_t *
529 admin_up_down_function (vnet_main_t *vm, u32 sw_if_index, u32 flags)
531 vpe_api_main_t * vam = &vpe_api_main;
534 * Note: it's perfectly fair to set a subif admin up / admin down.
535 * Note the subtle distinction between this routine and the previous
538 if (vam->link_state_process_up)
539 vlib_process_signal_event (vam->vlib_main,
540 link_state_process_node.index,
541 API_ADMIN_UP_DOWN_EVENT,
546 #define pub_sub_handler(lca,UCA) \
547 static void vl_api_want_##lca##_t_handler ( \
548 vl_api_want_##lca##_t *mp) \
550 vpe_api_main_t *vam = &vpe_api_main; \
551 vpe_client_registration_t *rp; \
552 vl_api_want_##lca##_reply_t *rmp; \
556 p = hash_get (vam->lca##_registration_hash, mp->client_index); \
558 if (mp->enable_disable) { \
559 clib_warning ("pid %d: already enabled...", mp->pid); \
560 rv = VNET_API_ERROR_INVALID_REGISTRATION; \
563 rp = pool_elt_at_index (vam->lca##_registrations, p[0]); \
564 pool_put (vam->lca##_registrations, rp); \
565 hash_unset (vam->lca##_registration_hash, \
570 if (mp->enable_disable == 0) { \
571 clib_warning ("pid %d: already disabled...", mp->pid); \
572 rv = VNET_API_ERROR_INVALID_REGISTRATION; \
575 pool_get (vam->lca##_registrations, rp); \
576 rp->client_index = mp->client_index; \
577 rp->client_pid = mp->pid; \
578 hash_set (vam->lca##_registration_hash, rp->client_index, \
579 rp - vam->lca##_registrations); \
582 REPLY_MACRO (VL_API_WANT_##UCA##_REPLY); \
585 pub_sub_handler (interface_events,INTERFACE_EVENTS)
586 pub_sub_handler (oam_events,OAM_EVENTS)
588 #define RESOLUTION_EVENT 1
589 #define RESOLUTION_PENDING_EVENT 2
590 #define IP4_ARP_EVENT 3
592 static int ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t *mp);
593 static int ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t *mp);
594 static int mpls_ethernet_add_del_tunnel_2_t_handler
595 (vl_api_mpls_ethernet_add_del_tunnel_2_t *mp);
597 void handle_ip4_arp_event (u32 pool_index)
599 vpe_api_main_t * vam = &vpe_api_main;
600 vnet_main_t * vnm = vam->vnet_main;
601 vlib_main_t * vm = vam->vlib_main;
602 vl_api_ip4_arp_event_t * event;
603 vl_api_ip4_arp_event_t * mp;
604 unix_shared_memory_queue_t * q;
606 /* Client can cancel, die, etc. */
607 if (pool_is_free_index (vam->arp_events, pool_index))
610 event = pool_elt_at_index (vam->arp_events, pool_index);
612 q = vl_api_client_index_to_input_queue (event->client_index);
614 (void) vnet_add_del_ip4_arp_change_event
615 (vnm, arp_change_delete_callback,
616 event->pid, &event->address,
617 vpe_resolver_process_node.index, IP4_ARP_EVENT,
618 ~0 /* pool index, notused */, 0 /* is_add */);
622 if (q->cursize < q->maxsize) {
623 mp = vl_msg_api_alloc (sizeof (*mp));
624 clib_memcpy (mp, event, sizeof (*mp));
625 vl_msg_api_send_shmem (q, (u8 *)&mp);
627 static f64 last_time;
629 * Throttle syslog msgs.
630 * It's pretty tempting to just revoke the registration...
632 if (vlib_time_now (vm) > last_time + 10.0) {
633 clib_warning ("arp event for %U to pid %d: queue stuffed!",
634 format_ip4_address, &event->address, event->pid);
635 last_time = vlib_time_now(vm);
641 resolver_process (vlib_main_t * vm,
642 vlib_node_runtime_t * rt,
646 uword *event_data = 0;
648 vpe_api_main_t * vam = &vpe_api_main;
649 pending_route_t * pr;
650 vl_api_ip_add_del_route_t * adr;
651 vl_api_mpls_ethernet_add_del_tunnel_2_t *pme;
652 u32 * resolution_failures = 0;
657 vlib_process_wait_for_event_or_clock (vm, timeout);
659 event_type = vlib_process_get_events (vm, &event_data);
661 switch (event_type) {
662 case RESOLUTION_PENDING_EVENT:
666 case RESOLUTION_EVENT:
667 for (i = 0; i < vec_len(event_data); i++) {
669 * Resolution events can occur long after the
670 * original request has timed out. $$$ add a cancel
673 if (pool_is_free_index (vam->pending_routes, event_data[i]))
676 pr = pool_elt_at_index (vam->pending_routes, event_data[i]);
680 switch (pr->resolve_type) {
681 case RESOLVE_IP4_ADD_DEL_ROUTE:
682 rv = ip4_add_del_route_t_handler (adr);
683 clib_warning ("resolver: add %U/%d via %U %s",
685 (ip4_address_t *)&(adr->dst_address),
686 adr->dst_address_length,
688 (ip4_address_t *)&(adr->next_hop_address),
689 (rv >= 0) ? "succeeded" : "failed");
692 case RESOLVE_IP6_ADD_DEL_ROUTE:
693 rv = ip6_add_del_route_t_handler (adr);
694 clib_warning ("resolver: add %U/%d via %U %s",
696 (ip6_address_t *)&(adr->dst_address),
697 adr->dst_address_length,
699 (ip6_address_t *)&(adr->next_hop_address),
700 (rv >= 0) ? "succeeded" : "failed");
703 case RESOLVE_MPLS_ETHERNET_ADD_DEL:
704 rv = mpls_ethernet_add_del_tunnel_2_t_handler (pme);
705 clib_warning ("resolver: add mpls-o-e via %U %s",
707 (ip4_address_t *)&(pme->next_hop_ip4_address_in_outer_vrf),
708 (rv >= 0) ? "succeeded" : "failed");
712 clib_warning ("resolver: BOGUS TYPE %d", pr->resolve_type);
714 pool_put (vam->pending_routes, pr);
719 for (i = 0; i < vec_len(event_data); i++)
720 handle_ip4_arp_event (event_data[i]);
723 case ~0: /* timeout, retry pending resolutions */
724 pool_foreach (pr, vam->pending_routes,
730 /* May fail, e.g. due to interface down */
731 switch (pr->resolve_type) {
732 case RESOLVE_IP4_ADD_DEL_ROUTE:
733 e = ip4_probe_neighbor
734 (vm, (ip4_address_t *)&(adr->next_hop_address),
735 ntohl(adr->next_hop_sw_if_index));
738 case RESOLVE_IP6_ADD_DEL_ROUTE:
739 e = ip6_probe_neighbor
740 (vm, (ip6_address_t *)&(adr->next_hop_address),
741 ntohl(adr->next_hop_sw_if_index));
744 case RESOLVE_MPLS_ETHERNET_ADD_DEL:
746 e = ip4_probe_neighbor
748 (ip4_address_t *)&(pme->next_hop_ip4_address_in_outer_vrf),
749 pme->resolve_opaque);
753 e = clib_error_return (0, "resolver: BOGUS TYPE %d",
757 clib_error_report (e);
759 adr->resolve_attempts = 1;
761 pme->resolve_attempts = 1;
765 adr->resolve_attempts -= 1;
766 if (adr->resolve_attempts == 0)
767 vec_add1 (resolution_failures,
768 pr - vam->pending_routes);
770 pme->resolve_attempts -= 1;
771 if (pme->resolve_attempts == 0)
772 vec_add1 (resolution_failures,
773 pr - vam->pending_routes);
777 for (i = 0; i < vec_len (resolution_failures); i++) {
778 pr = pool_elt_at_index (vam->pending_routes,
779 resolution_failures[i]);
783 switch (pr->resolve_type) {
784 case RESOLVE_IP4_ADD_DEL_ROUTE:
785 clib_warning ("resolver: add %U/%d via %U retry failure",
787 (ip4_address_t *)&(adr->dst_address),
788 adr->dst_address_length,
790 (ip4_address_t *)&(adr->next_hop_address));
793 case RESOLVE_IP6_ADD_DEL_ROUTE:
794 clib_warning ("resolver: add %U/%d via %U retry failure",
796 (ip6_address_t *)&(adr->dst_address),
797 adr->dst_address_length,
799 (ip6_address_t *)&(adr->next_hop_address));
802 case RESOLVE_MPLS_ETHERNET_ADD_DEL:
803 clib_warning ("resolver: add mpls-o-e via %U retry failure",
805 (ip4_address_t *)&(pme->next_hop_ip4_address_in_outer_vrf));
809 clib_warning ("BUG");
811 pool_put(vam->pending_routes, pr);
813 vec_reset_length (resolution_failures);
816 if (pool_elts (vam->pending_routes) == 0)
818 vec_reset_length (event_data);
820 return 0; /* or not */
823 VLIB_REGISTER_NODE (vpe_resolver_process_node,static) = {
824 .function = resolver_process,
825 .type = VLIB_NODE_TYPE_PROCESS,
826 .name = "vpe-route-resolver-process",
829 static int ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t *mp)
831 ip4_main_t * im = &ip4_main;
832 ip_lookup_main_t * lm = &im->lookup_main;
833 vnet_classify_main_t * cm = &vnet_classify_main;
834 stats_main_t * sm = &stats_main;
835 ip4_add_del_route_args_t a;
836 ip4_address_t next_hop_address;
838 vpe_api_main_t * vam = &vpe_api_main;
839 vnet_main_t * vnm = vam->vnet_main;
840 vlib_main_t * vm = vlib_get_main();
841 pending_route_t * pr;
842 vl_api_ip_add_del_route_t * adr;
846 ip_adjacency_t *nh_adj, *add_adj = 0;
848 p = hash_get (im->fib_index_by_table_id, ntohl(mp->vrf_id));
850 if (mp->create_vrf_if_needed) {
852 f = find_ip4_fib_by_table_index_or_id (im, ntohl(mp->vrf_id),
854 fib_index = f->index;
856 /* No such VRF, and we weren't asked to create one */
857 return VNET_API_ERROR_NO_SUCH_FIB;
863 if (pool_is_free_index (vnm->interface_main.sw_interfaces,
864 ntohl(mp->next_hop_sw_if_index)))
865 return VNET_API_ERROR_NO_MATCHING_INTERFACE;
867 clib_memcpy (next_hop_address.data, mp->next_hop_address,
868 sizeof (next_hop_address.data));
870 /* Arp for the next_hop if necessary */
871 if (mp->is_add && mp->resolve_if_needed) {
873 ip_adjacency_t * adj;
875 lookup_result = ip4_fib_lookup_with_table
876 (im, fib_index, &next_hop_address, 1 /* disable default route */);
878 adj = ip_get_adjacency (lm, lookup_result);
880 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP) {
881 pool_get (vam->pending_routes, pr);
882 pr->resolve_type = RESOLVE_IP4_ADD_DEL_ROUTE;
884 clib_memcpy (adr, mp, sizeof (*adr));
885 /* recursion block, "just in case" */
886 adr->resolve_if_needed = 0;
887 adr->resolve_attempts = ntohl(mp->resolve_attempts);
888 vnet_register_ip4_arp_resolution_event
889 (vnm, &next_hop_address, vpe_resolver_process_node.index,
890 RESOLUTION_EVENT, pr - vam->pending_routes);
892 vlib_process_signal_event
893 (vm, vpe_resolver_process_node.index,
894 RESOLUTION_PENDING_EVENT, 0 /* data */);
896 /* The interface may be down, etc. */
897 e = ip4_probe_neighbor
898 (vm, (ip4_address_t *)&(mp->next_hop_address),
899 ntohl(mp->next_hop_sw_if_index));
902 clib_error_report(e);
904 return VNET_API_ERROR_IN_PROGRESS;
908 if (mp->is_multipath) {
911 dslock (sm, 1 /* release hint */, 10 /* tag */);
914 flags = IP4_ROUTE_FLAG_ADD;
916 flags = IP4_ROUTE_FLAG_DEL;
919 flags |= IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP;
921 ip4_add_del_route_next_hop (im, flags,
922 (ip4_address_t *) mp->dst_address,
923 (u32) mp->dst_address_length,
924 (ip4_address_t *) mp->next_hop_address,
925 ntohl(mp->next_hop_sw_if_index),
926 (u32) mp->next_hop_weight,
933 memset (&a, 0, sizeof (a));
934 clib_memcpy (a.dst_address.data, mp->dst_address, sizeof (a.dst_address.data));
936 a.dst_address_length = mp->dst_address_length;
938 a.flags = (mp->is_add ? IP4_ROUTE_FLAG_ADD : IP4_ROUTE_FLAG_DEL);
939 a.flags |= IP4_ROUTE_FLAG_FIB_INDEX;
940 a.table_index_or_table_id = fib_index;
945 a.flags |= IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP;
947 dslock (sm, 1 /* release hint */, 2 /* tag */);
951 ai = lm->drop_adj_index;
952 else if (mp->is_local)
953 ai = lm->local_adj_index;
954 else if (mp->is_classify) {
956 memset(&cadj, 0, sizeof(cadj));
957 cadj.lookup_next_index = IP_LOOKUP_NEXT_CLASSIFY;
958 cadj.classify.table_index = ntohl(mp->classify_table_index);
959 if (pool_is_free_index (cm->tables, cadj.classify.table_index)) {
961 return VNET_API_ERROR_NO_SUCH_TABLE;
963 vec_add1 (add_adj, cadj);
967 ai = ip4_fib_lookup_with_table
968 (im, fib_index, &next_hop_address,
969 1 /* disable default route */);
970 if (ai == lm->miss_adj_index) {
972 return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
976 nh_adj = ip_get_adjacency (lm, ai);
977 if (nh_adj->lookup_next_index == IP_LOOKUP_NEXT_ARP &&
978 nh_adj->arp.next_hop.ip4.as_u32 == 0) {
979 /* the next-hop resovles via a glean adj. create and use
980 * a ARP adj for the next-hop */
981 a.adj_index = vnet_arp_glean_add(fib_index, &next_hop_address);
984 ip4_add_del_route (im, &a);
988 vec_add1 (add_adj, nh_adj[0]);
989 if (mp->lookup_in_vrf) {
990 p = hash_get (im->fib_index_by_table_id, ntohl(mp->lookup_in_vrf));
992 add_adj[0].explicit_fib_index = p[0];
996 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
1000 ip_adjacency_t * adj;
1001 int disable_default_route = 1;
1003 /* Trying to delete the default route? */
1004 if (a.dst_address.as_u32 == 0 &&
1005 a.dst_address_length == 0)
1006 disable_default_route = 0;
1008 ai = ip4_fib_lookup_with_table
1009 (im, fib_index, &a.dst_address, disable_default_route);
1010 if (ai == lm->miss_adj_index) {
1012 return VNET_API_ERROR_UNKNOWN_DESTINATION;
1015 adj = ip_get_adjacency (lm, ai);
1016 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP) {
1018 return VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
1024 a.add_adj = add_adj;
1025 a.n_add_adj = vec_len(add_adj);
1026 ip4_add_del_route (im, &a);
1035 static int ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t *mp)
1037 ip6_main_t * im = &ip6_main;
1038 ip_lookup_main_t * lm = &im->lookup_main;
1039 vnet_main_t * vnm = vnet_get_main();
1040 vlib_main_t * vm = vlib_get_main();
1041 vpe_api_main_t * vam = &vpe_api_main;
1042 stats_main_t * sm = &stats_main;
1043 ip6_add_del_route_args_t a;
1044 ip6_address_t next_hop_address;
1045 pending_route_t * pr;
1046 vl_api_ip_add_del_route_t * adr;
1051 ip_adjacency_t * nh_adj, * add_adj = 0;
1054 p = hash_get (im->fib_index_by_table_id, ntohl(mp->vrf_id));
1057 if (mp->create_vrf_if_needed) {
1059 f = find_ip6_fib_by_table_index_or_id (im, ntohl(mp->vrf_id),
1061 fib_index = f->index;
1063 /* No such VRF, and we weren't asked to create one */
1064 return VNET_API_ERROR_NO_SUCH_FIB;
1070 if (pool_is_free_index (vnm->interface_main.sw_interfaces,
1071 ntohl(mp->next_hop_sw_if_index)))
1072 return VNET_API_ERROR_NO_MATCHING_INTERFACE;
1074 clib_memcpy (next_hop_address.as_u8, mp->next_hop_address,
1075 sizeof (next_hop_address.as_u8));
1077 /* Arp for the next_hop if necessary */
1078 if (mp->is_add && mp->resolve_if_needed) {
1080 ip_adjacency_t * adj;
1082 lookup_result = ip6_fib_lookup_with_table
1083 (im, fib_index, &next_hop_address);
1085 adj = ip_get_adjacency (lm, lookup_result);
1087 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP) {
1088 pool_get (vam->pending_routes, pr);
1090 pr->resolve_type = RESOLVE_IP6_ADD_DEL_ROUTE;
1091 clib_memcpy (adr, mp, sizeof (*adr));
1092 /* recursion block, "just in case" */
1093 adr->resolve_if_needed = 0;
1094 adr->resolve_attempts = ntohl(mp->resolve_attempts);
1095 vnet_register_ip6_neighbor_resolution_event
1096 (vnm, &next_hop_address, vpe_resolver_process_node.index,
1097 RESOLUTION_EVENT, pr - vam->pending_routes);
1099 vlib_process_signal_event
1100 (vm, vpe_resolver_process_node.index,
1101 RESOLUTION_PENDING_EVENT, 0 /* data */);
1103 /* The interface may be down, etc. */
1104 e = ip6_probe_neighbor
1105 (vm, (ip6_address_t *)&(mp->next_hop_address),
1106 ntohl(mp->next_hop_sw_if_index));
1109 clib_error_report(e);
1111 return VNET_API_ERROR_IN_PROGRESS;
1115 if (mp->is_multipath) {
1118 dslock (sm, 1 /* release hint */, 11 /* tag */);
1121 flags = IP6_ROUTE_FLAG_ADD;
1123 flags = IP6_ROUTE_FLAG_DEL;
1126 flags |= IP6_ROUTE_FLAG_NOT_LAST_IN_GROUP;
1128 ip6_add_del_route_next_hop (im, flags, (ip6_address_t *)mp->dst_address,
1129 (u32) mp->dst_address_length,
1130 (ip6_address_t *)mp->next_hop_address,
1131 ntohl(mp->next_hop_sw_if_index),
1132 (u32) mp->next_hop_weight,
1139 memset (&a, 0, sizeof (a));
1140 clib_memcpy (a.dst_address.as_u8, mp->dst_address, sizeof (a.dst_address.as_u8));
1142 a.dst_address_length = mp->dst_address_length;
1144 a.flags = (mp->is_add ? IP6_ROUTE_FLAG_ADD : IP6_ROUTE_FLAG_DEL);
1145 a.flags |= IP6_ROUTE_FLAG_FIB_INDEX;
1146 a.table_index_or_table_id = fib_index;
1151 a.flags |= IP6_ROUTE_FLAG_NOT_LAST_IN_GROUP;
1153 dslock (sm, 1 /* release hint */, 3 /* tag */);
1157 ai = lm->drop_adj_index;
1158 else if (mp->is_local)
1159 ai = lm->local_adj_index;
1161 ai = ip6_fib_lookup_with_table
1162 (im, fib_index, &next_hop_address);
1163 if (ai == lm->miss_adj_index) {
1165 return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
1169 nh_adj = ip_get_adjacency (lm, ai);
1170 vec_add1 (add_adj, nh_adj[0]);
1171 if (mp->lookup_in_vrf) {
1172 p = hash_get (im->fib_index_by_table_id, ntohl(mp->lookup_in_vrf));
1174 add_adj[0].explicit_fib_index = p[0];
1178 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
1182 ip_adjacency_t * adj;
1184 ai = ip6_fib_lookup_with_table
1185 (im, fib_index, &a.dst_address);
1186 if (ai == lm->miss_adj_index) {
1188 return VNET_API_ERROR_UNKNOWN_DESTINATION;
1190 adj = ip_get_adjacency (lm, ai);
1191 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP) {
1193 return VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
1198 a.add_adj = add_adj;
1199 a.n_add_adj = vec_len(add_adj);
1200 ip6_add_del_route (im, &a);
1208 void vl_api_ip_add_del_route_t_handler (
1209 vl_api_ip_add_del_route_t *mp)
1211 vl_api_ip_add_del_route_reply_t * rmp;
1213 vnet_main_t * vnm = vnet_get_main();
1218 rv = ip6_add_del_route_t_handler (mp);
1220 rv = ip4_add_del_route_t_handler (mp);
1222 rv = (rv == 0) ? vnm->api_errno : rv;
1224 REPLY_MACRO(VL_API_IP_ADD_DEL_ROUTE_REPLY);
1227 void api_config_default_ip_route (u8 is_ipv6, u8 is_add, u32 vrf_id,
1228 u32 sw_if_index, u8 *next_hop_addr)
1230 vl_api_ip_add_del_route_t mp;
1233 memset (&mp, 0, sizeof(vl_api_ip_add_del_route_t));
1236 * Configure default IP route:
1237 * - ip route add 0.0.0.0/1 via <GW IP>
1238 * - ip route add 128.0.0.0/1 via <GW IP>
1240 mp.next_hop_sw_if_index = ntohl(sw_if_index);
1242 mp.resolve_attempts = ~0;
1243 mp.resolve_if_needed = 1;
1245 mp.is_ipv6 = is_ipv6;
1246 mp.next_hop_weight = 1;
1248 clib_memcpy (&mp.next_hop_address[0], next_hop_addr, 16);
1251 rv = ip6_add_del_route_t_handler (&mp);
1254 mp.dst_address_length = 1;
1256 mp.dst_address[0] = 0;
1257 rv = ip4_add_del_route_t_handler (&mp);
1259 mp.dst_address[0] = 128;
1260 rv |= ip4_add_del_route_t_handler (&mp);
1264 clib_error_return (0, "failed to config default IP route");
1269 vl_api_sw_interface_add_del_address_t_handler
1270 (vl_api_sw_interface_add_del_address_t *mp)
1272 vlib_main_t *vm = vlib_get_main();
1273 vl_api_sw_interface_add_del_address_reply_t * rmp;
1277 VALIDATE_SW_IF_INDEX(mp);
1279 is_del = mp->is_add == 0;
1282 ip_del_all_interface_addresses (vm, ntohl(mp->sw_if_index));
1283 else if (mp->is_ipv6)
1284 ip6_add_del_interface_address (vm, ntohl(mp->sw_if_index),
1285 (void *)mp->address,
1286 mp->address_length, is_del);
1288 ip4_add_del_interface_address (vm, ntohl(mp->sw_if_index),
1289 (void *) mp->address,
1290 mp->address_length, is_del);
1292 BAD_SW_IF_INDEX_LABEL;
1294 REPLY_MACRO(VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY);
1298 vl_api_sw_interface_set_table_t_handler (vl_api_sw_interface_set_table_t *mp)
1301 u32 table_id = ntohl(mp->vrf_id);
1302 u32 sw_if_index = ntohl(mp->sw_if_index);
1303 vl_api_sw_interface_set_table_reply_t * rmp;
1304 stats_main_t * sm = &stats_main;
1306 VALIDATE_SW_IF_INDEX(mp);
1308 dslock (sm, 1 /* release hint */, 4 /* tag */);
1311 ip6_main_t * im = &ip6_main;
1313 find_ip6_fib_by_table_index_or_id (im, table_id,
1314 IP6_ROUTE_FLAG_TABLE_ID);
1316 vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
1317 im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
1319 rv = VNET_API_ERROR_NO_SUCH_FIB;
1322 ip4_main_t * im = &ip4_main;
1323 ip4_fib_t * fib = find_ip4_fib_by_table_index_or_id
1324 (im, table_id, IP4_ROUTE_FLAG_TABLE_ID);
1326 /* Truthfully this can't fail */
1328 vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
1329 im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
1331 rv = VNET_API_ERROR_NO_SUCH_FIB;
1336 BAD_SW_IF_INDEX_LABEL;
1338 REPLY_MACRO(VL_API_SW_INTERFACE_SET_TABLE_REPLY);
1342 vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t *mp)
1344 vlib_main_t *vm = vlib_get_main();
1345 vl_api_sw_interface_set_vpath_reply_t * rmp;
1348 u32 sw_if_index = ntohl(mp->sw_if_index);
1349 ip4_main_t *ip4m = &ip4_main;
1350 ip6_main_t *ip6m = &ip6_main;
1351 ip_lookup_main_t *ip4lm = &ip4m->lookup_main;
1352 ip_lookup_main_t *ip6lm = &ip6m->lookup_main;
1353 ip_config_main_t *rx_cm4u = &ip4lm->rx_config_mains[VNET_UNICAST];
1354 ip_config_main_t *rx_cm4m = &ip4lm->rx_config_mains[VNET_MULTICAST];
1355 ip_config_main_t *rx_cm6u = &ip6lm->rx_config_mains[VNET_UNICAST];
1356 ip_config_main_t *rx_cm6m = &ip6lm->rx_config_mains[VNET_MULTICAST];
1358 VALIDATE_SW_IF_INDEX(mp);
1360 l2input_intf_bitmap_enable(sw_if_index, L2INPUT_FEAT_VPATH, mp->enable);
1362 ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast
1363 ci = vnet_config_add_feature(vm, &rx_cm4u->config_main,
1364 ci, IP4_RX_FEATURE_VPATH, 0, 0);
1365 rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci;
1366 ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast
1367 ci = vnet_config_add_feature(vm, &rx_cm4m->config_main,
1368 ci, IP4_RX_FEATURE_VPATH, 0, 0);
1369 rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci;
1370 ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast
1371 ci = vnet_config_add_feature(vm, &rx_cm6u->config_main,
1372 ci, IP6_RX_FEATURE_VPATH, 0, 0);
1373 rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci;
1374 ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast
1375 ci = vnet_config_add_feature(vm, &rx_cm6m->config_main,
1376 ci, IP6_RX_FEATURE_VPATH, 0, 0);
1377 rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci;
1379 ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast
1380 ci = vnet_config_del_feature(vm, &rx_cm4u->config_main,
1381 ci, IP4_RX_FEATURE_VPATH, 0, 0);
1382 rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci;
1383 ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast
1384 ci = vnet_config_del_feature(vm, &rx_cm4m->config_main,
1385 ci, IP4_RX_FEATURE_VPATH, 0, 0);
1386 rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci;
1387 ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast
1388 ci = vnet_config_del_feature(vm, &rx_cm6u->config_main,
1389 ci, IP6_RX_FEATURE_VPATH, 0, 0);
1390 rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci;
1391 ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast
1392 ci = vnet_config_del_feature(vm, &rx_cm6m->config_main,
1393 ci, IP6_RX_FEATURE_VPATH, 0, 0);
1394 rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci;
1397 BAD_SW_IF_INDEX_LABEL;
1399 REPLY_MACRO(VL_API_SW_INTERFACE_SET_VPATH_REPLY);
1403 vl_api_sw_interface_set_l2_xconnect_t_handler (
1404 vl_api_sw_interface_set_l2_xconnect_t *mp)
1406 vl_api_sw_interface_set_l2_xconnect_reply_t * rmp;
1408 u32 rx_sw_if_index = ntohl(mp->rx_sw_if_index);
1409 u32 tx_sw_if_index = ntohl(mp->tx_sw_if_index);
1410 vlib_main_t *vm = vlib_get_main();
1411 vnet_main_t *vnm = vnet_get_main();
1413 VALIDATE_RX_SW_IF_INDEX(mp);
1416 VALIDATE_TX_SW_IF_INDEX(mp);
1417 rv = set_int_l2_mode(vm, vnm, MODE_L2_XC,
1418 rx_sw_if_index, 0, 0, 0, tx_sw_if_index);
1420 rv = set_int_l2_mode(vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
1423 BAD_RX_SW_IF_INDEX_LABEL;
1424 BAD_TX_SW_IF_INDEX_LABEL;
1426 REPLY_MACRO(VL_API_SW_INTERFACE_SET_L2_XCONNECT_REPLY);
1430 vl_api_sw_interface_set_l2_bridge_t_handler (
1431 vl_api_sw_interface_set_l2_bridge_t *mp)
1433 bd_main_t * bdm = &bd_main;
1434 vl_api_sw_interface_set_l2_bridge_reply_t * rmp;
1436 u32 rx_sw_if_index = ntohl(mp->rx_sw_if_index);
1437 u32 bd_id = ntohl(mp->bd_id);
1441 vlib_main_t *vm = vlib_get_main();
1442 vnet_main_t *vnm = vnet_get_main();
1444 VALIDATE_RX_SW_IF_INDEX(mp);
1446 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
1449 //VALIDATE_TX_SW_IF_INDEX(mp);
1450 rv = set_int_l2_mode(vm, vnm, MODE_L2_BRIDGE,
1451 rx_sw_if_index, bd_index, bvi, shg, 0);
1453 rv = set_int_l2_mode(vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
1456 BAD_RX_SW_IF_INDEX_LABEL;
1458 REPLY_MACRO(VL_API_SW_INTERFACE_SET_L2_BRIDGE_REPLY);
1462 vl_api_bridge_domain_add_del_t_handler (
1463 vl_api_bridge_domain_add_del_t *mp)
1465 vlib_main_t * vm = vlib_get_main ();
1466 bd_main_t * bdm = &bd_main;
1467 vl_api_bridge_domain_add_del_reply_t * rmp;
1469 u32 enable_flags = 0, disable_flags = 0;
1470 u32 bd_id = ntohl(mp->bd_id);
1474 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
1477 enable_flags |= L2_FLOOD;
1479 disable_flags |= L2_FLOOD;
1482 enable_flags |= L2_UU_FLOOD;
1484 disable_flags |= L2_UU_FLOOD;
1487 enable_flags |= L2_FWD;
1489 disable_flags |= L2_FWD;
1492 enable_flags |= L2_ARP_TERM;
1494 disable_flags |= L2_ARP_TERM;
1497 enable_flags |= L2_LEARN;
1499 disable_flags |= L2_LEARN;
1502 bd_set_flags (vm, bd_index, enable_flags, 1 /* enable */);
1505 bd_set_flags (vm, bd_index, disable_flags, 0 /* disable */);
1508 rv = bd_delete_bd_index(bdm, bd_id);
1510 REPLY_MACRO(VL_API_BRIDGE_DOMAIN_ADD_DEL_REPLY);
1513 static void vl_api_bridge_domain_details_t_handler (
1514 vl_api_bridge_domain_details_t * mp)
1516 clib_warning ("BUG");
1519 static void vl_api_bridge_domain_sw_if_details_t_handler (
1520 vl_api_bridge_domain_sw_if_details_t * mp)
1522 clib_warning ("BUG");
1525 static void send_bridge_domain_details (unix_shared_memory_queue_t *q,
1526 l2_bridge_domain_t * bd_config,
1530 vl_api_bridge_domain_details_t * mp;
1532 mp = vl_msg_api_alloc (sizeof (*mp));
1533 memset (mp, 0, sizeof (*mp));
1534 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_DETAILS);
1535 mp->bd_id = ntohl (bd_config->bd_id);
1536 mp->flood = bd_feature_flood (bd_config);
1537 mp->uu_flood = bd_feature_uu_flood (bd_config);
1538 mp->forward = bd_feature_forward (bd_config);
1539 mp->learn = bd_feature_learn (bd_config);
1540 mp->arp_term = bd_feature_arp_term (bd_config);
1541 mp->bvi_sw_if_index = ntohl (bd_config->bvi_sw_if_index);
1542 mp->n_sw_ifs = ntohl (n_sw_ifs);
1543 mp->context = context;
1545 vl_msg_api_send_shmem (q, (u8 *)&mp);
1548 static void send_bd_sw_if_details (l2input_main_t * l2im,
1549 unix_shared_memory_queue_t *q,
1550 l2_flood_member_t * member, u32 bd_id,
1553 vl_api_bridge_domain_sw_if_details_t * mp;
1554 l2_input_config_t * input_cfg;
1556 mp = vl_msg_api_alloc (sizeof (*mp));
1557 memset (mp, 0, sizeof (*mp));
1558 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_SW_IF_DETAILS);
1559 mp->bd_id = ntohl (bd_id);
1560 mp->sw_if_index = ntohl (member->sw_if_index);
1561 input_cfg = vec_elt_at_index (l2im->configs, member->sw_if_index);
1562 mp->shg = input_cfg->shg;
1563 mp->context = context;
1565 vl_msg_api_send_shmem (q, (u8 *)&mp);
1568 static void vl_api_bridge_domain_dump_t_handler (
1569 vl_api_bridge_domain_dump_t *mp)
1571 bd_main_t * bdm = &bd_main;
1572 l2input_main_t * l2im = &l2input_main;
1573 unix_shared_memory_queue_t * q;
1574 l2_bridge_domain_t * bd_config;
1575 u32 bd_id, bd_index;
1578 q = vl_api_client_index_to_input_queue (mp->client_index);
1583 bd_id = ntohl(mp->bd_id);
1585 bd_index = (bd_id == ~0) ? 0 : bd_find_or_add_bd_index (bdm, bd_id);
1586 end = (bd_id == ~0) ? vec_len (l2im->bd_configs) : bd_index + 1;
1587 for (; bd_index < end; bd_index++) {
1588 bd_config = l2input_bd_config_from_index (l2im, bd_index);
1589 /* skip dummy bd_id 0 */
1590 if (bd_config && (bd_config->bd_id > 0)) {
1592 l2_flood_member_t * m;
1594 n_sw_ifs = vec_len (bd_config->members);
1595 send_bridge_domain_details (q, bd_config, n_sw_ifs, mp->context);
1597 vec_foreach (m, bd_config->members) {
1598 send_bd_sw_if_details (l2im, q, m, bd_config->bd_id, mp->context);
1605 vl_api_l2fib_add_del_t_handler (
1606 vl_api_l2fib_add_del_t *mp)
1608 bd_main_t * bdm = &bd_main;
1609 l2input_main_t * l2im = &l2input_main;
1610 vl_api_l2fib_add_del_reply_t * rmp;
1613 u32 sw_if_index = ntohl(mp->sw_if_index);
1614 u32 bd_id = ntohl(mp->bd_id);
1622 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1624 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1625 goto bad_sw_if_index;
1630 VALIDATE_SW_IF_INDEX(mp);
1631 if (vec_len(l2im->configs) <= sw_if_index) {
1632 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1633 goto bad_sw_if_index;
1635 l2_input_config_t * config;
1636 config = vec_elt_at_index(l2im->configs, sw_if_index);
1637 if (config->bridge == 0) {
1638 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1639 goto bad_sw_if_index;
1642 static_mac = mp->static_mac ? 1 : 0;
1643 filter_mac = mp->filter_mac ? 1 : 0;
1644 l2fib_add_entry(mac, bd_index, sw_if_index, static_mac, filter_mac,
1647 l2fib_del_entry(mac, bd_index);
1650 BAD_SW_IF_INDEX_LABEL;
1652 REPLY_MACRO(VL_API_L2FIB_ADD_DEL_REPLY);
1656 vl_api_l2_flags_t_handler (
1657 vl_api_l2_flags_t *mp)
1659 vl_api_l2_flags_reply_t * rmp;
1661 u32 sw_if_index = ntohl(mp->sw_if_index);
1662 u32 flags = ntohl(mp->feature_bitmap);
1665 VALIDATE_SW_IF_INDEX(mp);
1668 if (flags & L2INPUT_FEAT_ ## a) \
1669 rbm = l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_ ## a, mp->is_set);
1670 foreach_l2input_feat;
1673 BAD_SW_IF_INDEX_LABEL;
1675 REPLY_MACRO2(VL_API_L2_FLAGS_REPLY, rmp->resulting_feature_bitmap = ntohl(rbm));
1679 vl_api_bridge_flags_t_handler (
1680 vl_api_bridge_flags_t *mp)
1682 vlib_main_t *vm = vlib_get_main();
1683 bd_main_t * bdm = &bd_main;
1684 vl_api_bridge_flags_reply_t * rmp;
1686 u32 bd_id = ntohl(mp->bd_id);
1688 u32 flags = ntohl(mp->feature_bitmap);
1691 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1693 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1699 bd_set_flags(vm, bd_index, flags, mp->is_set);
1702 REPLY_MACRO2(VL_API_BRIDGE_FLAGS_REPLY,
1703 rmp->resulting_feature_bitmap = ntohl(flags));
1707 vl_api_bd_ip_mac_add_del_t_handler (
1708 vl_api_bd_ip_mac_add_del_t *mp)
1710 bd_main_t * bdm = &bd_main;
1711 vl_api_bd_ip_mac_add_del_reply_t * rmp;
1713 u32 bd_id = ntohl(mp->bd_id);
1717 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1719 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1724 if (bd_add_del_ip_mac(bd_index, mp->ip_address,
1725 mp->mac_address, mp->is_ipv6, mp->is_add))
1726 rv = VNET_API_ERROR_UNSPECIFIED;
1729 REPLY_MACRO(VL_API_BD_IP_MAC_ADD_DEL_REPLY);
1733 vl_api_tap_connect_t_handler (vl_api_tap_connect_t *mp, vlib_main_t *vm)
1736 vl_api_tap_connect_reply_t * rmp;
1737 unix_shared_memory_queue_t * q;
1738 u32 sw_if_index = (u32)~0;
1740 rv = vnet_tap_connect_renumber (vm, mp->tap_name,
1741 mp->use_random_mac ? 0 : mp->mac_address,
1742 &sw_if_index, mp->renumber,
1743 ntohl(mp->custom_dev_instance));
1745 q = vl_api_client_index_to_input_queue (mp->client_index);
1749 rmp = vl_msg_api_alloc (sizeof (*rmp));
1750 rmp->_vl_msg_id = ntohs(VL_API_TAP_CONNECT_REPLY);
1751 rmp->context = mp->context;
1752 rmp->retval = ntohl(rv);
1753 rmp->sw_if_index = ntohl(sw_if_index);
1755 vl_msg_api_send_shmem (q, (u8 *)&rmp);
1759 vl_api_tap_modify_t_handler (vl_api_tap_modify_t *mp, vlib_main_t *vm)
1762 vl_api_tap_modify_reply_t * rmp;
1763 unix_shared_memory_queue_t * q;
1764 u32 sw_if_index = (u32)~0;
1766 rv = vnet_tap_modify (vm, ntohl(mp->sw_if_index), mp->tap_name,
1767 mp->use_random_mac ? 0 : mp->mac_address,
1768 &sw_if_index, mp->renumber,
1769 ntohl(mp->custom_dev_instance));
1771 q = vl_api_client_index_to_input_queue (mp->client_index);
1775 rmp = vl_msg_api_alloc (sizeof (*rmp));
1776 rmp->_vl_msg_id = ntohs(VL_API_TAP_MODIFY_REPLY);
1777 rmp->context = mp->context;
1778 rmp->retval = ntohl(rv);
1779 rmp->sw_if_index = ntohl(sw_if_index);
1781 vl_msg_api_send_shmem (q, (u8 *)&rmp);
1785 vl_api_tap_delete_t_handler (vl_api_tap_delete_t *mp, vlib_main_t *vm)
1788 vpe_api_main_t * vam = &vpe_api_main;
1789 vl_api_tap_delete_reply_t * rmp;
1790 unix_shared_memory_queue_t * q;
1791 u32 sw_if_index = ntohl(mp->sw_if_index);
1793 rv = vnet_tap_delete (vm, sw_if_index);
1795 q = vl_api_client_index_to_input_queue (mp->client_index);
1799 rmp = vl_msg_api_alloc (sizeof (*rmp));
1800 rmp->_vl_msg_id = ntohs(VL_API_TAP_DELETE_REPLY);
1801 rmp->context = mp->context;
1802 rmp->retval = ntohl(rv);
1804 vl_msg_api_send_shmem (q, (u8 *)&rmp);
1807 send_sw_interface_flags_deleted (vam, q, sw_if_index);
1811 vl_api_create_vlan_subif_t_handler (vl_api_create_vlan_subif_t * mp)
1813 vl_api_create_vlan_subif_reply_t * rmp;
1814 vnet_main_t * vnm = vnet_get_main();
1815 u32 hw_if_index, sw_if_index = (u32)~0;
1816 vnet_hw_interface_t * hi;
1819 vnet_sw_interface_t template;
1821 vnet_interface_main_t * im = &vnm->interface_main;
1822 u64 sup_and_sub_key;
1824 unix_shared_memory_queue_t * q;
1825 clib_error_t * error;
1827 VALIDATE_SW_IF_INDEX(mp);
1829 hw_if_index = ntohl(mp->sw_if_index);
1830 hi = vnet_get_hw_interface (vnm, hw_if_index);
1832 id = ntohl(mp->vlan_id);
1833 if (id == 0 || id > 4095) {
1834 rv = VNET_API_ERROR_INVALID_VLAN;
1838 sup_and_sub_key = ((u64)(hi->sw_if_index) << 32) | (u64) id;
1840 p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1842 rv = VNET_API_ERROR_VLAN_ALREADY_EXISTS;
1846 kp = clib_mem_alloc (sizeof (*kp));
1847 *kp = sup_and_sub_key;
1849 memset (&template, 0, sizeof (template));
1850 template.type = VNET_SW_INTERFACE_TYPE_SUB;
1851 template.sup_sw_if_index = hi->sw_if_index;
1852 template.sub.id = id;
1853 template.sub.eth.raw_flags = 0;
1854 template.sub.eth.flags.one_tag = 1;
1855 template.sub.eth.outer_vlan_id = id;
1856 template.sub.eth.flags.exact_match = 1;
1858 error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1860 clib_error_report(error);
1861 rv = VNET_API_ERROR_INVALID_REGISTRATION;
1864 hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
1865 hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1867 BAD_SW_IF_INDEX_LABEL;
1870 q = vl_api_client_index_to_input_queue (mp->client_index);
1874 rmp = vl_msg_api_alloc (sizeof (*rmp));
1875 rmp->_vl_msg_id = ntohs(VL_API_CREATE_VLAN_SUBIF_REPLY);
1876 rmp->context = mp->context;
1877 rmp->retval = ntohl(rv);
1878 rmp->sw_if_index = ntohl(sw_if_index);
1879 vl_msg_api_send_shmem (q, (u8 *)&rmp);
1883 vl_api_create_subif_t_handler (vl_api_create_subif_t * mp)
1885 vl_api_create_subif_reply_t * rmp;
1886 vnet_main_t * vnm = vnet_get_main();
1887 u32 sw_if_index = ~0;
1890 vnet_sw_interface_t *si;
1891 vnet_hw_interface_t *hi;
1892 vnet_sw_interface_t template;
1894 vnet_interface_main_t * im = &vnm->interface_main;
1895 u64 sup_and_sub_key;
1897 clib_error_t * error;
1899 VALIDATE_SW_IF_INDEX(mp);
1901 si = vnet_get_sup_sw_interface (vnm, ntohl(mp->sw_if_index));
1902 hi = vnet_get_sup_hw_interface (vnm, ntohl(mp->sw_if_index));
1904 if (hi->bond_info == VNET_HW_INTERFACE_BOND_INFO_SLAVE) {
1905 rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
1909 sw_if_index = si->sw_if_index;
1910 sub_id = ntohl(mp->sub_id);
1912 sup_and_sub_key = ((u64)(sw_if_index) << 32) | (u64) sub_id;
1914 p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1917 clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
1918 sw_if_index, sub_id);
1919 rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
1923 kp = clib_mem_alloc (sizeof (*kp));
1924 *kp = sup_and_sub_key;
1926 memset (&template, 0, sizeof (template));
1927 template.type = VNET_SW_INTERFACE_TYPE_SUB;
1928 template.sup_sw_if_index = sw_if_index;
1929 template.sub.id = sub_id;
1930 template.sub.eth.flags.no_tags = mp->no_tags;
1931 template.sub.eth.flags.one_tag = mp->one_tag;
1932 template.sub.eth.flags.two_tags = mp->two_tags;
1933 template.sub.eth.flags.dot1ad = mp->dot1ad;
1934 template.sub.eth.flags.exact_match = mp->exact_match;
1935 template.sub.eth.flags.default_sub = mp->default_sub;
1936 template.sub.eth.flags.outer_vlan_id_any = mp->outer_vlan_id_any;
1937 template.sub.eth.flags.inner_vlan_id_any = mp->inner_vlan_id_any;
1938 template.sub.eth.outer_vlan_id = ntohs(mp->outer_vlan_id);
1939 template.sub.eth.inner_vlan_id = ntohs(mp->inner_vlan_id);
1941 error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1943 clib_error_report (error);
1944 rv = VNET_API_ERROR_SUBIF_CREATE_FAILED;
1948 hash_set (hi->sub_interface_sw_if_index_by_id, sub_id, sw_if_index);
1949 hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1951 BAD_SW_IF_INDEX_LABEL;
1955 REPLY_MACRO2(VL_API_CREATE_SUBIF_REPLY,
1957 rmp->sw_if_index = ntohl(sw_if_index);
1962 vl_api_mpls_gre_add_del_tunnel_t_handler (vl_api_mpls_gre_add_del_tunnel_t *mp)
1964 vl_api_mpls_gre_add_del_tunnel_reply_t * rmp;
1966 stats_main_t * sm = &stats_main;
1967 u32 tunnel_sw_if_index = ~0;
1969 dslock (sm, 1 /* release hint */, 5 /* tag */);
1971 rv = vnet_mpls_gre_add_del_tunnel ((ip4_address_t *)(mp->src_address),
1972 (ip4_address_t *)(mp->dst_address),
1973 (ip4_address_t *)(mp->intfc_address),
1974 (u32)(mp->intfc_address_length),
1975 ntohl(mp->inner_vrf_id),
1976 ntohl(mp->outer_vrf_id),
1977 &tunnel_sw_if_index,
1982 REPLY_MACRO2(VL_API_MPLS_GRE_ADD_DEL_TUNNEL_REPLY,
1984 rmp->tunnel_sw_if_index = ntohl(tunnel_sw_if_index);
1989 vl_api_mpls_ethernet_add_del_tunnel_t_handler
1990 (vl_api_mpls_ethernet_add_del_tunnel_t *mp)
1992 vl_api_mpls_ethernet_add_del_tunnel_reply_t * rmp;
1994 stats_main_t * sm = &stats_main;
1995 u32 tunnel_sw_if_index;
1997 dslock (sm, 1 /* release hint */, 5 /* tag */);
1999 rv = vnet_mpls_ethernet_add_del_tunnel
2000 (mp->dst_mac_address, (ip4_address_t *)(mp->adj_address),
2001 (u32)(mp->adj_address_length), ntohl(mp->vrf_id),
2002 ntohl(mp->tx_sw_if_index),
2003 &tunnel_sw_if_index,
2009 REPLY_MACRO2(VL_API_MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,
2011 rmp->tunnel_sw_if_index = ntohl(tunnel_sw_if_index);
2016 * This piece of misery brought to you because the control-plane
2017 * can't figure out the tx interface + dst-mac address all by itself
2019 static int mpls_ethernet_add_del_tunnel_2_t_handler
2020 (vl_api_mpls_ethernet_add_del_tunnel_2_t *mp)
2022 pending_route_t * pr;
2023 vl_api_mpls_ethernet_add_del_tunnel_2_t *pme;
2024 vnet_main_t * vnm = vnet_get_main();
2025 vlib_main_t * vm = vlib_get_main();
2026 stats_main_t * sm = &stats_main;
2027 vpe_api_main_t * vam = &vpe_api_main;
2028 u32 inner_fib_index, outer_fib_index;
2029 ip4_main_t * im = &ip4_main;
2030 ip_lookup_main_t * lm = &im->lookup_main;
2031 ip_adjacency_t * adj = 0;
2034 u8 * dst_mac_address;
2038 u32 tunnel_sw_if_index;
2040 p = hash_get (im->fib_index_by_table_id, ntohl(mp->outer_vrf_id));
2042 return VNET_API_ERROR_NO_SUCH_FIB;
2044 outer_fib_index = p[0];
2047 p = hash_get (im->fib_index_by_table_id, ntohl(mp->inner_vrf_id));
2049 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
2051 inner_fib_index = p[0];
2053 if (inner_fib_index == outer_fib_index)
2054 return VNET_API_ERROR_INVALID_VALUE;
2056 lookup_result = ip4_fib_lookup_with_table
2057 (im, outer_fib_index,
2058 (ip4_address_t *)mp->next_hop_ip4_address_in_outer_vrf,
2059 1 /* disable default route */);
2061 adj = ip_get_adjacency (lm, lookup_result);
2062 tx_sw_if_index = adj->rewrite_header.sw_if_index;
2064 if (mp->is_add && mp->resolve_if_needed) {
2065 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP) {
2066 pool_get (vam->pending_routes, pr);
2067 pr->resolve_type = RESOLVE_MPLS_ETHERNET_ADD_DEL;
2069 clib_memcpy (pme, mp, sizeof (*pme));
2070 /* recursion block, "just in case" */
2071 pme->resolve_if_needed = 0;
2072 pme->resolve_attempts = ntohl(mp->resolve_attempts);
2073 pme->resolve_opaque = tx_sw_if_index;
2074 vnet_register_ip4_arp_resolution_event
2076 (ip4_address_t *)&(pme->next_hop_ip4_address_in_outer_vrf),
2077 vpe_resolver_process_node.index,
2078 RESOLUTION_EVENT, pr - vam->pending_routes);
2080 vlib_process_signal_event
2081 (vm, vpe_resolver_process_node.index,
2082 RESOLUTION_PENDING_EVENT, 0 /* data */);
2084 /* The interface may be down, etc. */
2085 e = ip4_probe_neighbor
2086 (vm, (ip4_address_t *)&(mp->next_hop_ip4_address_in_outer_vrf),
2090 clib_error_report(e);
2092 return VNET_API_ERROR_IN_PROGRESS;
2096 if (adj->lookup_next_index != IP_LOOKUP_NEXT_REWRITE)
2097 return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
2100 vnet_rewrite_get_data_internal
2101 (&adj->rewrite_header, sizeof (adj->rewrite_data));
2103 dslock (sm, 1 /* release hint */, 10 /* tag */);
2105 rv = vnet_mpls_ethernet_add_del_tunnel
2106 (dst_mac_address, (ip4_address_t *)(mp->adj_address),
2107 (u32)(mp->adj_address_length), ntohl(mp->inner_vrf_id),
2108 tx_sw_if_index, &tunnel_sw_if_index, mp->l2_only, mp->is_add);
2116 vl_api_mpls_ethernet_add_del_tunnel_2_t_handler
2117 (vl_api_mpls_ethernet_add_del_tunnel_2_t *mp)
2119 vl_api_mpls_ethernet_add_del_tunnel_reply_t * rmp;
2122 rv = mpls_ethernet_add_del_tunnel_2_t_handler (mp);
2124 REPLY_MACRO(VL_API_MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY);
2129 vl_api_mpls_add_del_encap_t_handler (vl_api_mpls_add_del_encap_t *mp)
2131 vl_api_mpls_add_del_encap_reply_t * rmp;
2133 static u32 * labels;
2136 vec_reset_length (labels);
2138 for (i = 0; i < mp->nlabels; i++)
2139 vec_add1 (labels, ntohl(mp->labels[i]));
2142 rv = vnet_mpls_add_del_encap ((ip4_address_t *)mp->dst_address,
2143 ntohl(mp->vrf_id), labels,
2144 ~0 /* policy_tunnel_index */,
2145 0 /* no_dst_hash */,
2149 REPLY_MACRO(VL_API_MPLS_ADD_DEL_ENCAP_REPLY);
2153 vl_api_mpls_add_del_decap_t_handler
2154 (vl_api_mpls_add_del_decap_t *mp)
2156 vl_api_mpls_add_del_decap_reply_t * rmp;
2159 rv = vnet_mpls_add_del_decap (ntohl(mp->rx_vrf_id), ntohl(mp->tx_vrf_id),
2160 ntohl(mp->label), ntohl(mp->next_index),
2161 mp->s_bit, mp->is_add);
2163 REPLY_MACRO(VL_API_MPLS_ADD_DEL_DECAP_REPLY);
2167 vl_api_proxy_arp_add_del_t_handler (vl_api_proxy_arp_add_del_t *mp)
2169 vl_api_proxy_arp_add_del_reply_t * rmp;
2172 ip4_main_t * im = &ip4_main;
2173 stats_main_t * sm = &stats_main;
2174 int vnet_proxy_arp_add_del (ip4_address_t *lo_addr,
2175 ip4_address_t *hi_addr,
2176 u32 fib_index, int is_del);
2179 dslock (sm, 1 /* release hint */, 6 /* tag */);
2181 p = hash_get (im->fib_index_by_table_id, ntohl(mp->vrf_id));
2184 rv = VNET_API_ERROR_NO_SUCH_FIB;
2190 rv = vnet_proxy_arp_add_del ((ip4_address_t *)mp->low_address,
2191 (ip4_address_t *)mp->hi_address,
2192 fib_index, mp->is_add == 0);
2196 REPLY_MACRO(VL_API_PROXY_ARP_ADD_DEL_REPLY);
2200 vl_api_proxy_arp_intfc_enable_disable_t_handler
2201 (vl_api_proxy_arp_intfc_enable_disable_t *mp)
2204 vnet_main_t * vnm = vnet_get_main();
2205 vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;
2206 vnet_sw_interface_t * si;
2209 VALIDATE_SW_IF_INDEX(mp);
2211 sw_if_index = ntohl(mp->sw_if_index);
2213 if (pool_is_free_index (vnm->interface_main.sw_interfaces,
2215 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
2219 si = vnet_get_sw_interface (vnm, sw_if_index);
2223 if (mp->enable_disable)
2224 si->flags |= VNET_SW_INTERFACE_FLAG_PROXY_ARP;
2226 si->flags &= ~VNET_SW_INTERFACE_FLAG_PROXY_ARP;
2228 BAD_SW_IF_INDEX_LABEL;
2231 REPLY_MACRO(VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
2235 vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t *mp, vlib_main_t * vm)
2237 vl_api_ip_neighbor_add_del_reply_t * rmp;
2238 vnet_main_t * vnm = vnet_get_main();
2241 stats_main_t * sm = &stats_main;
2243 VALIDATE_SW_IF_INDEX(mp);
2245 dslock (sm, 1 /* release hint */, 7 /* tag */);
2249 rv = vnet_set_ip6_ethernet_neighbor
2250 (vm, ntohl(mp->sw_if_index),
2251 (ip6_address_t *)(mp->dst_address),
2252 mp->mac_address, sizeof (mp->mac_address), mp->is_static);
2254 rv = vnet_unset_ip6_ethernet_neighbor
2255 (vm, ntohl(mp->sw_if_index),
2256 (ip6_address_t *)(mp->dst_address),
2257 mp->mac_address, sizeof(mp->mac_address));
2259 ip4_main_t * im = &ip4_main;
2260 ip_lookup_main_t * lm = &im->lookup_main;
2261 ethernet_arp_ip4_over_ethernet_address_t a;
2263 ip_adjacency_t *nh_adj;
2265 uword * p = hash_get (im->fib_index_by_table_id, ntohl(mp->vrf_id));
2267 rv = VNET_API_ERROR_NO_SUCH_FIB;
2273 * Unfortunately, folks have a penchant for
2274 * adding interface addresses to the ARP cache, and
2275 * wondering why the forwarder eventually ASSERTs...
2277 ai = ip4_fib_lookup_with_table
2278 (im, fib_index, (ip4_address_t *)(mp->dst_address),
2279 1 /* disable default route */);
2282 nh_adj = ip_get_adjacency (lm, ai);
2283 /* Never allow manipulation of a local adj! */
2284 if (nh_adj->lookup_next_index == IP_LOOKUP_NEXT_LOCAL) {
2285 clib_warning("%U matches local adj",
2287 (ip4_address_t *)(mp->dst_address));
2288 rv = VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
2293 clib_memcpy (&a.ethernet, mp->mac_address, 6);
2294 clib_memcpy (&a.ip4, mp->dst_address, 4);
2297 rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl(mp->sw_if_index),
2298 fib_index, &a, mp->is_static);
2300 rv = vnet_arp_unset_ip4_over_ethernet (vnm, ntohl(mp->sw_if_index),
2304 BAD_SW_IF_INDEX_LABEL;
2307 REPLY_MACRO(VL_API_IP_NEIGHBOR_ADD_DEL_REPLY);
2311 vl_api_is_address_reachable_t_handler (vl_api_is_address_reachable_t *mp)
2314 vpe_main_t *rm = &vpe_main;
2315 ip4_main_t *im4 = &ip4_main;
2316 ip6_main_t *im6 = &ip6_main;
2317 ip_lookup_main_t * lm;
2322 u32 adj_index, sw_if_index;
2323 vl_api_is_address_reachable_t *rmp;
2324 ip_adjacency_t * adj;
2325 unix_shared_memory_queue_t *q;
2327 q = vl_api_client_index_to_input_queue (mp->client_index);
2329 increment_missing_api_client_counter (rm->vlib_main);
2333 rmp = vl_msg_api_alloc (sizeof (*rmp));
2334 clib_memcpy (rmp, mp, sizeof (*rmp));
2336 sw_if_index = mp->next_hop_sw_if_index;
2337 clib_memcpy (&addr, mp->address, sizeof (addr));
2339 lm = &im6->lookup_main;
2341 ip6_fib_lookup (im6, sw_if_index, &addr.ip6);
2343 lm = &im4->lookup_main;
2345 ip4_fib_lookup (im4, sw_if_index, &addr.ip4);
2347 if (adj_index == ~0) {
2351 adj = ip_get_adjacency (lm, adj_index);
2353 if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE
2354 && adj->rewrite_header.sw_if_index == sw_if_index) {
2357 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP
2358 && adj->rewrite_header.sw_if_index == sw_if_index) {
2360 ip6_probe_neighbor (rm->vlib_main, &addr.ip6, sw_if_index);
2362 ip4_probe_neighbor (rm->vlib_main, &addr.ip4, sw_if_index);
2363 } else if (adj->lookup_next_index == IP_LOOKUP_NEXT_DROP) {
2371 vl_msg_api_send_shmem (q, (u8 *)&rmp);
2375 static void vl_api_sw_interface_details_t_handler (
2376 vl_api_sw_interface_details_t * mp)
2378 clib_warning ("BUG");
2381 static void vl_api_sw_interface_set_flags_t_handler (
2382 vl_api_sw_interface_set_flags_t * mp)
2384 vl_api_sw_interface_set_flags_reply_t *rmp;
2385 vnet_main_t * vnm = vnet_get_main();
2387 clib_error_t * error;
2390 VALIDATE_SW_IF_INDEX(mp);
2392 flags = mp->admin_up_down ? VNET_SW_INTERFACE_FLAG_ADMIN_UP : 0;
2394 error = vnet_sw_interface_set_flags (vnm,
2395 ntohl(mp->sw_if_index),
2399 clib_error_report (error);
2402 BAD_SW_IF_INDEX_LABEL;
2403 REPLY_MACRO(VL_API_SW_INTERFACE_SET_FLAGS_REPLY);
2406 static void vl_api_sw_interface_clear_stats_t_handler (
2407 vl_api_sw_interface_clear_stats_t * mp)
2409 vl_api_sw_interface_clear_stats_reply_t *rmp;
2411 vnet_main_t * vnm = vnet_get_main();
2412 vnet_interface_main_t * im = &vnm->interface_main;
2413 vlib_simple_counter_main_t * sm;
2414 vlib_combined_counter_main_t * cm;
2415 static vnet_main_t ** my_vnet_mains;
2416 int i, j, n_counters;
2420 vec_reset_length (my_vnet_mains);
2422 for (i = 0; i < vec_len (vnet_mains); i++)
2425 vec_add1 (my_vnet_mains, vnet_mains[i]);
2428 if (vec_len (vnet_mains) == 0)
2429 vec_add1 (my_vnet_mains, vnm);
2431 n_counters = vec_len (im->combined_sw_if_counters);
2433 for (j = 0; j < n_counters; j++)
2435 for (i = 0; i < vec_len(my_vnet_mains); i++)
2437 im = &my_vnet_mains[i]->interface_main;
2438 cm = im->combined_sw_if_counters + j;
2439 if (mp->sw_if_index == (u32)~0)
2440 vlib_clear_combined_counters (cm);
2442 vlib_zero_combined_counter (cm, ntohl(mp->sw_if_index));
2446 n_counters = vec_len (im->sw_if_counters);
2448 for (j = 0; j < n_counters; j++)
2450 for (i = 0; i < vec_len(my_vnet_mains); i++)
2452 im = &my_vnet_mains[i]->interface_main;
2453 sm = im->sw_if_counters + j;
2454 if (mp->sw_if_index == (u32)~0)
2455 vlib_clear_simple_counters (sm);
2457 vlib_zero_simple_counter (sm, ntohl(mp->sw_if_index));
2461 REPLY_MACRO(VL_API_SW_INTERFACE_CLEAR_STATS_REPLY);
2464 static void send_sw_interface_details (vpe_api_main_t * am,
2465 unix_shared_memory_queue_t *q,
2466 vnet_sw_interface_t * swif,
2467 u8 * interface_name,
2470 vl_api_sw_interface_details_t * mp;
2471 vnet_hw_interface_t * hi;
2473 hi = vnet_get_sup_hw_interface (am->vnet_main, swif->sw_if_index);
2475 mp = vl_msg_api_alloc (sizeof (*mp));
2476 memset (mp, 0, sizeof (*mp));
2477 mp->_vl_msg_id = ntohs(VL_API_SW_INTERFACE_DETAILS);
2478 mp->sw_if_index = ntohl(swif->sw_if_index);
2479 mp->sup_sw_if_index = ntohl(swif->sup_sw_if_index);
2480 mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
2482 mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ?
2484 mp->link_duplex = ((hi->flags & VNET_HW_INTERFACE_FLAG_DUPLEX_MASK) >>
2485 VNET_HW_INTERFACE_FLAG_DUPLEX_SHIFT);
2486 mp->link_speed = ((hi->flags & VNET_HW_INTERFACE_FLAG_SPEED_MASK) >>
2487 VNET_HW_INTERFACE_FLAG_SPEED_SHIFT);
2488 mp->link_mtu = ntohs(hi->max_packet_bytes);
2489 mp->context = context;
2491 strncpy ((char *) mp->interface_name,
2492 (char *) interface_name, ARRAY_LEN(mp->interface_name)-1);
2494 /* Send the L2 address for ethernet physical intfcs */
2495 if (swif->sup_sw_if_index == swif->sw_if_index
2496 && hi->hw_class_index == ethernet_hw_interface_class.index) {
2497 ethernet_main_t *em = ethernet_get_main (am->vlib_main);
2498 ethernet_interface_t *ei;
2500 ei = pool_elt_at_index (em->interfaces, hi->hw_instance);
2501 ASSERT (sizeof (mp->l2_address) >= sizeof (ei->address));
2502 clib_memcpy (mp->l2_address, ei->address, sizeof (ei->address));
2503 mp->l2_address_length = ntohl(sizeof (ei->address));
2504 } else if (swif->sup_sw_if_index != swif->sw_if_index) {
2505 vnet_sub_interface_t *sub = &swif->sub;
2506 mp->sub_id = ntohl(sub->id);
2507 mp->sub_dot1ad = sub->eth.flags.dot1ad;
2508 mp->sub_number_of_tags = sub->eth.flags.one_tag + sub->eth.flags.two_tags*2;
2509 mp->sub_outer_vlan_id = ntohs(sub->eth.outer_vlan_id);
2510 mp->sub_inner_vlan_id = ntohs(sub->eth.inner_vlan_id);
2511 mp->sub_exact_match = sub->eth.flags.exact_match;
2512 mp->sub_default = sub->eth.flags.default_sub;
2513 mp->sub_outer_vlan_id_any = sub->eth.flags.outer_vlan_id_any;
2514 mp->sub_inner_vlan_id_any = sub->eth.flags.inner_vlan_id_any;
2516 /* vlan tag rewrite data */
2517 u32 vtr_op = L2_VTR_DISABLED;
2518 u32 vtr_push_dot1q = 0, vtr_tag1 = 0, vtr_tag2 = 0;
2520 if (l2vtr_get(am->vlib_main, am->vnet_main, swif->sw_if_index,
2521 &vtr_op, &vtr_push_dot1q, &vtr_tag1, &vtr_tag2) != 0) {
2522 // error - default to disabled
2523 mp->vtr_op = ntohl(L2_VTR_DISABLED);
2524 clib_warning("cannot get vlan tag rewrite for sw_if_index %d",
2527 mp->vtr_op = ntohl(vtr_op);
2528 mp->vtr_push_dot1q = ntohl(vtr_push_dot1q);
2529 mp->vtr_tag1 = ntohl(vtr_tag1);
2530 mp->vtr_tag2 = ntohl(vtr_tag2);
2534 vl_msg_api_send_shmem (q, (u8 *)&mp);
2537 static void send_sw_interface_flags (vpe_api_main_t * am,
2538 unix_shared_memory_queue_t *q,
2539 vnet_sw_interface_t * swif)
2541 vl_api_sw_interface_set_flags_t *mp;
2542 vnet_main_t * vnm = am->vnet_main;
2544 vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm,
2546 mp = vl_msg_api_alloc (sizeof (*mp));
2547 memset (mp, 0, sizeof (*mp));
2548 mp->_vl_msg_id = ntohs(VL_API_SW_INTERFACE_SET_FLAGS);
2549 mp->sw_if_index = ntohl(swif->sw_if_index);
2551 mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
2553 mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ?
2555 vl_msg_api_send_shmem (q, (u8 *)&mp);
2558 static void send_sw_interface_flags_deleted (vpe_api_main_t * am,
2559 unix_shared_memory_queue_t *q,
2561 __attribute__((unused));
2563 static void send_sw_interface_flags_deleted (vpe_api_main_t * am,
2564 unix_shared_memory_queue_t *q,
2567 vl_api_sw_interface_set_flags_t *mp;
2569 mp = vl_msg_api_alloc (sizeof (*mp));
2570 memset (mp, 0, sizeof (*mp));
2571 mp->_vl_msg_id = ntohs(VL_API_SW_INTERFACE_SET_FLAGS);
2572 mp->sw_if_index = ntohl(sw_if_index);
2574 mp->admin_up_down = 0;
2575 mp->link_up_down = 0;
2577 vl_msg_api_send_shmem (q, (u8 *)&mp);
2580 static void vl_api_sw_interface_dump_t_handler (
2581 vl_api_sw_interface_dump_t *mp)
2583 vpe_api_main_t * am = &vpe_api_main;
2584 vnet_sw_interface_t * swif;
2585 vnet_interface_main_t * im = &am->vnet_main->interface_main;
2586 u8 * filter_string = 0, * name_string = 0;
2587 unix_shared_memory_queue_t * q;
2588 char * strcasestr (char *, char *); /* lnx hdr file botch */
2590 q = vl_api_client_index_to_input_queue (mp->client_index);
2595 if (mp->name_filter_valid) {
2596 mp->name_filter [ARRAY_LEN(mp->name_filter)-1] = 0;
2597 filter_string = format (0, "%s%c", mp->name_filter, 0);
2600 pool_foreach (swif, im->sw_interfaces,
2602 name_string = format (name_string, "%U%c",
2603 format_vnet_sw_interface_name,
2604 am->vnet_main, swif, 0);
2606 if (mp->name_filter_valid == 0 ||
2607 strcasestr((char *) name_string, (char *) filter_string)) {
2609 send_sw_interface_details (am, q, swif, name_string, mp->context);
2611 _vec_len (name_string) = 0;
2614 vec_free (name_string);
2615 vec_free (filter_string);
2618 void send_oam_event (oam_target_t * t)
2620 vpe_api_main_t * vam = &vpe_api_main;
2621 unix_shared_memory_queue_t * q;
2622 vpe_client_registration_t *reg;
2623 vl_api_oam_event_t * mp;
2625 pool_foreach(reg, vam->oam_events_registrations,
2627 q = vl_api_client_index_to_input_queue (reg->client_index);
2629 mp = vl_msg_api_alloc (sizeof (*mp));
2630 mp->_vl_msg_id = ntohs (VL_API_OAM_EVENT);
2631 clib_memcpy (mp->dst_address, &t->dst_address, sizeof (mp->dst_address));
2632 mp->state = t->state;
2633 vl_msg_api_send_shmem (q, (u8 *)&mp);
2639 vl_api_oam_add_del_t_handler (vl_api_oam_add_del_t *mp)
2641 vl_api_oam_add_del_reply_t * rmp;
2644 rv = vpe_oam_add_del_target ((ip4_address_t *)mp->src_address,
2645 (ip4_address_t *)mp->dst_address,
2649 REPLY_MACRO(VL_API_OAM_ADD_DEL_REPLY);
2653 vl_api_vnet_get_summary_stats_t_handler (
2654 vl_api_vnet_get_summary_stats_t *mp)
2656 stats_main_t * sm = &stats_main;
2657 vnet_interface_main_t * im = sm->interface_main;
2658 vl_api_vnet_summary_stats_reply_t *rmp;
2659 vlib_combined_counter_main_t * cm;
2662 u64 total_pkts[VLIB_N_RX_TX];
2663 u64 total_bytes[VLIB_N_RX_TX];
2665 unix_shared_memory_queue_t * q =
2666 vl_api_client_index_to_input_queue (mp->client_index);
2671 rmp = vl_msg_api_alloc (sizeof (*rmp));
2672 rmp->_vl_msg_id = ntohs(VL_API_VNET_SUMMARY_STATS_REPLY);
2673 rmp->context = mp->context;
2676 memset (total_pkts, 0, sizeof (total_pkts));
2677 memset (total_bytes, 0, sizeof (total_bytes));
2679 vnet_interface_counter_lock (im);
2681 vec_foreach (cm, im->combined_sw_if_counters) {
2682 which = cm - im->combined_sw_if_counters;
2684 for (i = 0; i < vec_len (cm->maxi); i++) {
2685 vlib_get_combined_counter (cm, i, &v);
2686 total_pkts[which] += v.packets;
2687 total_bytes[which] += v.bytes;
2690 vnet_interface_counter_unlock (im);
2692 /* Note: in HOST byte order! */
2693 rmp->total_pkts[VLIB_RX] = total_pkts[VLIB_RX];
2694 rmp->total_bytes[VLIB_RX] = total_bytes[VLIB_RX];
2695 rmp->total_pkts[VLIB_TX] = total_pkts[VLIB_TX];
2696 rmp->total_bytes[VLIB_TX] = total_bytes[VLIB_TX];
2697 rmp->vector_rate = vlib_last_vector_length_per_node (sm->vlib_main);
2699 vl_msg_api_send_shmem (q, (u8 *)&rmp);
2702 typedef CLIB_PACKED (struct {
2703 ip4_address_t address;
2705 u32 address_length : 6;
2710 static int ip4_reset_fib_t_handler (vl_api_reset_fib_t *mp)
2712 vnet_main_t * vnm = vnet_get_main();
2713 vnet_interface_main_t * im = &vnm->interface_main;
2714 ip4_main_t * im4 = &ip4_main;
2715 static ip4_route_t * routes;
2716 static u32 * sw_if_indices_to_shut;
2717 stats_main_t * sm = &stats_main;
2722 int rv = VNET_API_ERROR_NO_SUCH_FIB;
2723 u32 target_fib_id = ntohl(mp->vrf_id);
2725 dslock (sm, 1 /* release hint */, 8 /* tag */);
2727 vec_foreach (fib, im4->fibs) {
2728 vnet_sw_interface_t * si;
2730 if (fib->table_id != target_fib_id)
2733 /* remove any mpls/gre tunnels in this fib */
2734 vnet_mpls_gre_delete_fib_tunnels (fib->table_id);
2736 /* remove any mpls encap/decap labels */
2737 mpls_fib_reset_labels (fib->table_id);
2739 /* remove any proxy arps in this fib */
2740 vnet_proxy_arp_fib_reset (fib->table_id);
2742 /* Set the flow hash for this fib to the default */
2743 vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
2745 vec_reset_length (sw_if_indices_to_shut);
2747 /* Shut down interfaces in this FIB / clean out intfc routes */
2748 pool_foreach (si, im->sw_interfaces,
2750 u32 sw_if_index = si->sw_if_index;
2752 if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
2753 && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
2755 vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
2758 for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
2759 sw_if_index = sw_if_indices_to_shut[i];
2760 // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
2762 u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
2763 flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
2764 vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
2767 vec_reset_length (routes);
2769 for (i = 0; i < ARRAY_LEN (fib->adj_index_by_dst_address); i++) {
2770 uword * hash = fib->adj_index_by_dst_address[i];
2774 x.address_length = i;
2776 hash_foreach_pair (p, hash,
2778 x.address.data_u32 = p->key;
2779 vec_add1 (routes, x);
2783 vec_foreach (r, routes) {
2784 ip4_add_del_route_args_t a;
2786 memset (&a, 0, sizeof (a));
2787 a.flags = IP4_ROUTE_FLAG_FIB_INDEX | IP4_ROUTE_FLAG_DEL;
2788 a.table_index_or_table_id = fib - im4->fibs;
2789 a.dst_address = r->address;
2790 a.dst_address_length = r->address_length;
2793 ip4_add_del_route (im4, &a);
2794 ip4_maybe_remap_adjacencies (im4, fib - im4->fibs,
2795 IP4_ROUTE_FLAG_FIB_INDEX);
2799 } /* vec_foreach (fib) */
2806 ip6_address_t address;
2813 ip6_route_t ** routep;
2814 } add_routes_in_fib_arg_t;
2816 static void add_routes_in_fib (clib_bihash_kv_24_8_t * kvp, void *arg)
2818 add_routes_in_fib_arg_t * ap = arg;
2820 if (kvp->key[2]>>32 == ap->fib_index)
2822 ip6_address_t *addr;
2824 addr = (ip6_address_t *) kvp;
2825 vec_add2 (*ap->routep, r, 1);
2826 r->address = addr[0];
2827 r->address_length = kvp->key[2] & 0xFF;
2828 r->index = kvp->value;
2832 static int ip6_reset_fib_t_handler (vl_api_reset_fib_t *mp)
2834 vnet_main_t * vnm = vnet_get_main();
2835 vnet_interface_main_t * im = &vnm->interface_main;
2836 ip6_main_t * im6 = &ip6_main;
2837 stats_main_t * sm = &stats_main;
2838 static ip6_route_t * routes;
2839 static u32 * sw_if_indices_to_shut;
2844 int rv = VNET_API_ERROR_NO_SUCH_FIB;
2845 u32 target_fib_id = ntohl(mp->vrf_id);
2846 add_routes_in_fib_arg_t _a, *a=&_a;
2847 clib_bihash_24_8_t * h = &im6->ip6_lookup_table;
2849 dslock (sm, 1 /* release hint */, 9 /* tag */);
2851 vec_foreach (fib, im6->fibs) {
2852 vnet_sw_interface_t * si;
2854 if (fib->table_id != target_fib_id)
2857 vec_reset_length (sw_if_indices_to_shut);
2859 /* Shut down interfaces in this FIB / clean out intfc routes */
2860 pool_foreach (si, im->sw_interfaces,
2862 if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
2864 vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
2867 for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
2868 sw_if_index = sw_if_indices_to_shut[i];
2869 // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
2871 u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
2872 flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
2873 vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
2876 vec_reset_length (routes);
2878 a->fib_index = fib - im6->fibs;
2879 a->routep = &routes;
2881 clib_bihash_foreach_key_value_pair_24_8 (h, add_routes_in_fib, a);
2883 vec_foreach (r, routes) {
2884 ip6_add_del_route_args_t a;
2886 memset (&a, 0, sizeof (a));
2887 a.flags = IP6_ROUTE_FLAG_FIB_INDEX | IP6_ROUTE_FLAG_DEL;
2888 a.table_index_or_table_id = fib - im6->fibs;
2889 a.dst_address = r->address;
2890 a.dst_address_length = r->address_length;
2893 ip6_add_del_route (im6, &a);
2894 ip6_maybe_remap_adjacencies (im6, fib - im6->fibs,
2895 IP6_ROUTE_FLAG_FIB_INDEX);
2898 /* Reinstall the neighbor / router discovery routes */
2899 vnet_ip6_fib_init (im6, fib - im6->fibs);
2901 } /* vec_foreach (fib) */
2907 static void vl_api_reset_fib_t_handler (vl_api_reset_fib_t *mp)
2910 vl_api_reset_fib_reply_t * rmp;
2913 rv = ip6_reset_fib_t_handler (mp);
2915 rv = ip4_reset_fib_t_handler (mp);
2917 REPLY_MACRO(VL_API_RESET_FIB_REPLY);
2922 dhcpv4_proxy_config (vl_api_dhcp_proxy_config_t *mp)
2924 vl_api_dhcp_proxy_config_reply_t * rmp;
2927 rv = dhcp_proxy_set_server ((ip4_address_t *)(&mp->dhcp_server),
2928 (ip4_address_t *)(&mp->dhcp_src_address),
2929 (u32) ntohl(mp->vrf_id),
2930 (int) mp->insert_circuit_id,
2931 (int) (mp->is_add == 0));
2933 REPLY_MACRO(VL_API_DHCP_PROXY_CONFIG_REPLY);
2938 dhcpv6_proxy_config (vl_api_dhcp_proxy_config_t *mp)
2940 vl_api_dhcp_proxy_config_reply_t * rmp;
2943 rv = dhcpv6_proxy_set_server ((ip6_address_t *)(&mp->dhcp_server),
2944 (ip6_address_t *)(&mp->dhcp_src_address),
2945 (u32) ntohl(mp->vrf_id),
2946 (int) mp->insert_circuit_id,
2947 (int) (mp->is_add == 0));
2949 REPLY_MACRO(VL_API_DHCP_PROXY_CONFIG_REPLY);
2953 dhcpv4_proxy_config_2 (vl_api_dhcp_proxy_config_2_t *mp)
2955 vl_api_dhcp_proxy_config_reply_t * rmp;
2958 rv = dhcp_proxy_set_server_2 ((ip4_address_t *)(&mp->dhcp_server),
2959 (ip4_address_t *)(&mp->dhcp_src_address),
2960 (u32) ntohl(mp->rx_vrf_id),
2961 (u32) ntohl(mp->server_vrf_id),
2962 (int) mp->insert_circuit_id,
2963 (int) (mp->is_add == 0));
2965 REPLY_MACRO(VL_API_DHCP_PROXY_CONFIG_2_REPLY);
2970 dhcpv6_proxy_config_2 (vl_api_dhcp_proxy_config_2_t *mp)
2972 vl_api_dhcp_proxy_config_reply_t * rmp;
2976 rv = dhcpv6_proxy_set_server_2 ((ip6_address_t *)(&mp->dhcp_server),
2977 (ip6_address_t *)(&mp->dhcp_src_address),
2978 (u32) ntohl(mp->rx_vrf_id),
2979 (u32) ntohl(mp->server_vrf_id),
2980 (int) mp->insert_circuit_id,
2981 (int) (mp->is_add == 0));
2983 rv = VNET_API_ERROR_UNIMPLEMENTED;
2986 REPLY_MACRO(VL_API_DHCP_PROXY_CONFIG_2_REPLY);
2991 vl_api_dhcp_proxy_set_vss_t_handler (vl_api_dhcp_proxy_set_vss_t *mp)
2993 vl_api_dhcp_proxy_set_vss_reply_t *rmp;
2996 rv = dhcp_proxy_set_option82_vss(ntohl(mp->tbl_id),
2999 (int)mp->is_add == 0);
3001 rv = dhcpv6_proxy_set_vss( ntohl(mp->tbl_id),
3004 (int)mp->is_add == 0);
3006 REPLY_MACRO(VL_API_DHCP_PROXY_SET_VSS_REPLY);
3010 static void vl_api_dhcp_proxy_config_t_handler
3011 (vl_api_dhcp_proxy_config_t *mp)
3013 if (mp->is_ipv6 == 0)
3014 dhcpv4_proxy_config (mp);
3016 dhcpv6_proxy_config (mp);
3019 static void vl_api_dhcp_proxy_config_2_t_handler
3020 (vl_api_dhcp_proxy_config_2_t *mp)
3022 if (mp->is_ipv6 == 0)
3023 dhcpv4_proxy_config_2 (mp);
3025 dhcpv6_proxy_config_2 (mp);
3028 void dhcp_compl_event_callback (u32 client_index, u32 pid, u8 * hostname,
3029 u8 is_ipv6, u8 * host_address, u8 * router_address, u8 * host_mac)
3031 unix_shared_memory_queue_t * q;
3032 vl_api_dhcp_compl_event_t * mp;
3034 q = vl_api_client_index_to_input_queue (client_index);
3038 mp = vl_msg_api_alloc (sizeof (*mp));
3039 mp->client_index = client_index;
3041 mp->is_ipv6 = is_ipv6;
3042 clib_memcpy (&mp->hostname, hostname, vec_len(hostname));
3043 mp->hostname[vec_len(hostname) + 1] = '\n';
3044 clib_memcpy (&mp->host_address[0], host_address, 16);
3045 clib_memcpy (&mp->router_address[0], router_address, 16);
3046 clib_memcpy (&mp->host_mac[0], host_mac, 6);
3048 mp->_vl_msg_id = ntohs (VL_API_DHCP_COMPL_EVENT);
3050 vl_msg_api_send_shmem (q, (u8 *)&mp);
3053 static void vl_api_dhcp_client_config_t_handler
3054 (vl_api_dhcp_client_config_t *mp)
3056 vlib_main_t *vm = vlib_get_main();
3057 vl_api_dhcp_client_config_reply_t * rmp;
3060 VALIDATE_SW_IF_INDEX(mp);
3062 rv = dhcp_client_config(vm, ntohl(mp->sw_if_index),
3063 mp->hostname, mp->is_add, mp->client_index,
3064 mp->want_dhcp_event ? dhcp_compl_event_callback : NULL,
3067 BAD_SW_IF_INDEX_LABEL;
3069 REPLY_MACRO(VL_API_DHCP_CLIENT_CONFIG_REPLY);
3073 vl_api_sw_interface_ip6nd_ra_config_t_handler
3074 (vl_api_sw_interface_ip6nd_ra_config_t *mp, vlib_main_t *vm)
3076 vl_api_sw_interface_ip6nd_ra_config_reply_t * rmp;
3078 u8 is_no, surpress, managed, other, ll_option, send_unicast, cease, default_router;
3080 is_no = mp->is_no == 1;
3081 surpress = mp->surpress == 1;
3082 managed = mp->managed == 1;
3083 other = mp->other == 1;
3084 ll_option = mp->ll_option == 1;
3085 send_unicast = mp->send_unicast == 1;
3086 cease = mp->cease == 1;
3087 default_router = mp->default_router == 1;
3089 VALIDATE_SW_IF_INDEX(mp);
3091 rv = ip6_neighbor_ra_config(vm, ntohl(mp->sw_if_index),
3092 surpress, managed, other,
3093 ll_option, send_unicast, cease,
3094 default_router, ntohl (mp->lifetime),
3095 ntohl(mp->initial_count), ntohl(mp->initial_interval),
3096 ntohl(mp->max_interval), ntohl( mp->min_interval),
3099 BAD_SW_IF_INDEX_LABEL;
3101 REPLY_MACRO(VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
3105 vl_api_sw_interface_ip6nd_ra_prefix_t_handler
3106 (vl_api_sw_interface_ip6nd_ra_prefix_t *mp, vlib_main_t *vm)
3108 vl_api_sw_interface_ip6nd_ra_prefix_reply_t * rmp;
3110 u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
3112 VALIDATE_SW_IF_INDEX(mp);
3114 is_no = mp->is_no == 1;
3115 use_default = mp->use_default == 1;
3116 no_advertise = mp->no_advertise == 1;
3117 off_link = mp->off_link == 1;
3118 no_autoconfig = mp->no_autoconfig == 1;
3119 no_onlink = mp->no_onlink == 1;
3121 rv = ip6_neighbor_ra_prefix(vm, ntohl(mp->sw_if_index),
3122 (ip6_address_t *)mp->address, mp->address_length,
3123 use_default, ntohl(mp->val_lifetime), ntohl(mp->pref_lifetime),
3124 no_advertise, off_link, no_autoconfig, no_onlink,
3127 BAD_SW_IF_INDEX_LABEL;
3128 REPLY_MACRO(VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
3132 vl_api_sw_interface_ip6_enable_disable_t_handler
3133 (vl_api_sw_interface_ip6_enable_disable_t *mp, vlib_main_t *vm)
3135 vl_api_sw_interface_ip6_enable_disable_reply_t * rmp;
3136 vnet_main_t * vnm = vnet_get_main();
3138 clib_error_t * error;
3142 VALIDATE_SW_IF_INDEX(mp);
3144 error = ( mp->enable == 1) ? enable_ip6_interface(vm,ntohl(mp->sw_if_index)) :
3145 disable_ip6_interface(vm,ntohl(mp->sw_if_index));
3148 clib_error_report(error);
3149 rv = VNET_API_ERROR_UNSPECIFIED;
3151 rv = vnm->api_errno;
3154 BAD_SW_IF_INDEX_LABEL;
3156 REPLY_MACRO(VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
3160 vl_api_sw_interface_ip6_set_link_local_address_t_handler
3161 (vl_api_sw_interface_ip6_set_link_local_address_t *mp, vlib_main_t *vm)
3163 vl_api_sw_interface_ip6_set_link_local_address_reply_t * rmp;
3165 clib_error_t * error;
3166 vnet_main_t * vnm = vnet_get_main();
3170 VALIDATE_SW_IF_INDEX(mp);
3172 error = set_ip6_link_local_address(vm,
3173 ntohl(mp->sw_if_index),
3174 (ip6_address_t *)mp->address,
3175 mp->address_length);
3177 clib_error_report(error);
3178 rv = VNET_API_ERROR_UNSPECIFIED;
3180 rv = vnm->api_errno;
3183 BAD_SW_IF_INDEX_LABEL;
3185 REPLY_MACRO(VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY);
3188 static void set_ip6_flow_hash (vl_api_set_ip_flow_hash_t *mp)
3190 vl_api_set_ip_flow_hash_reply_t *rmp;
3191 int rv = VNET_API_ERROR_UNIMPLEMENTED;
3193 clib_warning ("unimplemented...");
3195 REPLY_MACRO(VL_API_SET_IP_FLOW_HASH_REPLY);
3198 static void set_ip4_flow_hash (vl_api_set_ip_flow_hash_t *mp)
3200 vl_api_set_ip_flow_hash_reply_t *rmp;
3203 u32 flow_hash_config = 0;
3205 table_id = ntohl(mp->vrf_id);
3207 #define _(a,b) if (mp->a) flow_hash_config |= b;
3208 foreach_flow_hash_bit;
3211 rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config);
3213 REPLY_MACRO(VL_API_SET_IP_FLOW_HASH_REPLY);
3217 static void vl_api_set_ip_flow_hash_t_handler
3218 (vl_api_set_ip_flow_hash_t *mp)
3220 if (mp->is_ipv6 == 0)
3221 set_ip4_flow_hash (mp);
3223 set_ip6_flow_hash (mp);
3226 static void vl_api_sw_interface_set_unnumbered_t_handler
3227 (vl_api_sw_interface_set_unnumbered_t *mp)
3229 vl_api_sw_interface_set_unnumbered_reply_t * rmp;
3231 vnet_sw_interface_t * si;
3232 vnet_main_t *vnm = vnet_get_main();
3233 u32 sw_if_index, unnumbered_sw_if_index;
3235 sw_if_index = ntohl(mp->sw_if_index);
3236 unnumbered_sw_if_index = ntohl(mp->unnumbered_sw_if_index);
3239 * The API message field names are backwards from
3240 * the underlying data structure names.
3241 * It's not worth changing them now.
3243 if (pool_is_free_index (vnm->interface_main.sw_interfaces,
3244 unnumbered_sw_if_index)) {
3245 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
3249 /* Only check the "use loop0" field when setting the binding */
3251 pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index)) {
3252 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
3256 si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index);
3259 si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED;
3260 si->unnumbered_sw_if_index = sw_if_index;
3262 si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED);
3263 si->unnumbered_sw_if_index = (u32)~0;
3267 REPLY_MACRO(VL_API_SW_INTERFACE_SET_UNNUMBERED_REPLY);
3270 static void vl_api_create_loopback_t_handler
3271 (vl_api_create_loopback_t *mp)
3273 vl_api_create_loopback_reply_t * rmp;
3277 rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address);
3279 REPLY_MACRO2(VL_API_CREATE_LOOPBACK_REPLY,
3281 rmp->sw_if_index = ntohl (sw_if_index);
3285 static void vl_api_delete_loopback_t_handler
3286 (vl_api_delete_loopback_t *mp)
3288 vl_api_delete_loopback_reply_t * rmp;
3292 sw_if_index = ntohl (mp->sw_if_index);
3293 rv = vnet_delete_loopback_interface (sw_if_index);
3295 REPLY_MACRO(VL_API_DELETE_LOOPBACK_REPLY);
3298 static void vl_api_control_ping_t_handler
3299 (vl_api_control_ping_t *mp)
3301 vl_api_control_ping_reply_t * rmp;
3304 REPLY_MACRO2(VL_API_CONTROL_PING_REPLY,
3306 rmp->vpe_pid = ntohl (getpid());
3310 static void shmem_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
3312 u8 **shmem_vecp = (u8 **)arg;
3315 api_main_t * am = &api_main;
3318 shmem_vec = *shmem_vecp;
3320 offset = vec_len (shmem_vec);
3322 pthread_mutex_lock (&am->vlib_rp->mutex);
3323 oldheap = svm_push_data_heap (am->vlib_rp);
3325 vec_validate (shmem_vec, offset + buffer_bytes - 1);
3327 clib_memcpy (shmem_vec + offset, buffer, buffer_bytes);
3329 svm_pop_heap (oldheap);
3330 pthread_mutex_unlock (&am->vlib_rp->mutex);
3332 *shmem_vecp = shmem_vec;
3336 static void vl_api_cli_request_t_handler
3337 (vl_api_cli_request_t *mp)
3339 vl_api_cli_reply_t *rp;
3340 unix_shared_memory_queue_t *q;
3341 vlib_main_t * vm = vlib_get_main();
3342 api_main_t * am = &api_main;
3343 unformat_input_t input;
3347 q = vl_api_client_index_to_input_queue (mp->client_index);
3351 rp = vl_msg_api_alloc (sizeof (*rp));
3352 rp->_vl_msg_id = ntohs(VL_API_CLI_REPLY);
3353 rp->context = mp->context;
3355 unformat_init_vector (&input, (u8 *)(uword)mp->cmd_in_shmem);
3357 vlib_cli_input (vm, &input, shmem_cli_output,
3360 pthread_mutex_lock (&am->vlib_rp->mutex);
3361 oldheap = svm_push_data_heap (am->vlib_rp);
3363 vec_add1(shmem_vec, 0);
3365 svm_pop_heap (oldheap);
3366 pthread_mutex_unlock (&am->vlib_rp->mutex);
3368 rp->reply_in_shmem = (uword)shmem_vec;
3370 vl_msg_api_send_shmem (q, (u8 *)&rp);
3373 static void vl_api_set_arp_neighbor_limit_t_handler (vl_api_set_arp_neighbor_limit_t *mp)
3376 vl_api_set_arp_neighbor_limit_reply_t * rmp;
3377 vnet_main_t *vnm = vnet_get_main();
3378 clib_error_t * error;
3383 error = ip6_set_neighbor_limit (ntohl(mp->arp_neighbor_limit));
3385 error = ip4_set_arp_limit (ntohl(mp->arp_neighbor_limit));
3388 clib_error_report(error);
3389 rv = VNET_API_ERROR_UNSPECIFIED;
3391 rv = vnm->api_errno;
3394 REPLY_MACRO(VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
3397 static void vl_api_sr_tunnel_add_del_t_handler
3398 (vl_api_sr_tunnel_add_del_t *mp)
3401 clib_warning ("unimplemented");
3403 ip6_sr_add_del_tunnel_args_t _a, *a=&_a;
3405 vl_api_sr_tunnel_add_del_reply_t * rmp;
3406 ip6_address_t * segments = 0, * seg;
3407 ip6_address_t * tags = 0, *tag;
3408 ip6_address_t * this_address;
3411 if (mp->n_segments == 0) {
3416 memset (a, 0, sizeof (*a));
3417 a->src_address = (ip6_address_t *)&mp->src_address;
3418 a->dst_address = (ip6_address_t *)&mp->dst_address;
3419 a->dst_mask_width = mp->dst_mask_width;
3420 a->flags_net_byte_order = mp->flags_net_byte_order;
3421 a->is_del = (mp->is_add == 0);
3422 a->rx_table_id = ntohl(mp->outer_vrf_id);
3423 a->tx_table_id = ntohl(mp->inner_vrf_id);
3425 a->name = format(0, "%s", mp->name);
3426 if (!(vec_len(a->name)))
3429 a->policy_name = format(0, "%s", mp->policy_name);
3430 if (!(vec_len(a->policy_name)))
3433 /* Yank segments and tags out of the API message */
3434 this_address = (ip6_address_t *)mp->segs_and_tags;
3435 for (i = 0; i < mp->n_segments; i++) {
3436 vec_add2 (segments, seg, 1);
3437 clib_memcpy (seg->as_u8, this_address->as_u8, sizeof (*this_address));
3440 for (i = 0; i < mp->n_tags; i++) {
3441 vec_add2 (tags, tag, 1);
3442 clib_memcpy (tag->as_u8, this_address->as_u8, sizeof (*this_address));
3446 a->segments = segments;
3449 rv = ip6_sr_add_del_tunnel (a);
3453 REPLY_MACRO(VL_API_SR_TUNNEL_ADD_DEL_REPLY);
3457 static void vl_api_sr_policy_add_del_t_handler
3458 (vl_api_sr_policy_add_del_t *mp)
3461 clib_warning ("unimplemented");
3463 ip6_sr_add_del_policy_args_t _a, *a=&_a;
3465 vl_api_sr_policy_add_del_reply_t * rmp;
3468 memset (a, 0, sizeof (*a));
3469 a->is_del = (mp->is_add == 0);
3471 a->name = format(0, "%s", mp->name);
3472 if (!(vec_len(a->name)))
3474 rv = VNET_API_ERROR_NO_SUCH_NODE2;
3478 if (!(mp->tunnel_names[0]))
3480 rv = VNET_API_ERROR_NO_SUCH_NODE2;
3484 // start deserializing tunnel_names
3485 int num_tunnels = mp->tunnel_names[0]; //number of tunnels
3486 u8 * deser_tun_names = mp->tunnel_names;
3487 deser_tun_names += 1; //moving along
3490 int tun_name_len = 0;
3492 for (i=0; i < num_tunnels; i++)
3494 tun_name_len= *deser_tun_names;
3495 deser_tun_names += 1;
3496 vec_resize (tun_name, tun_name_len);
3497 memcpy(tun_name, deser_tun_names, tun_name_len);
3498 vec_add1 (a->tunnel_names, tun_name);
3499 deser_tun_names += tun_name_len;
3503 rv = ip6_sr_add_del_policy (a);
3507 REPLY_MACRO(VL_API_SR_POLICY_ADD_DEL_REPLY);
3511 static void vl_api_sr_multicast_map_add_del_t_handler
3512 (vl_api_sr_multicast_map_add_del_t *mp)
3515 clib_warning ("unimplemented");
3517 ip6_sr_add_del_multicastmap_args_t _a, *a=&_a;
3519 vl_api_sr_multicast_map_add_del_reply_t * rmp;
3521 memset (a, 0, sizeof (*a));
3522 a->is_del = (mp->is_add == 0);
3524 a->multicast_address = (ip6_address_t *)&mp->multicast_address;
3525 a->policy_name = format(0, "%s", mp->policy_name);
3527 if (a->multicast_address == 0)
3533 if (!(a->policy_name))
3539 #if DPDK > 0 /* Cannot call replicate without DPDK */
3540 rv = ip6_sr_add_del_multicastmap (a);
3542 clib_warning ("multicast replication without DPDK not implemented");
3543 rv = VNET_API_ERROR_UNIMPLEMENTED;
3548 REPLY_MACRO(VL_API_SR_MULTICAST_MAP_ADD_DEL_REPLY);
3552 #define foreach_classify_add_del_table_field \
3557 _(match_n_vectors) \
3558 _(next_table_index) \
3561 static void vl_api_classify_add_del_table_t_handler
3562 (vl_api_classify_add_del_table_t * mp)
3564 vl_api_classify_add_del_table_reply_t * rmp;
3565 vnet_classify_main_t * cm = &vnet_classify_main;
3566 vnet_classify_table_t * t;
3570 foreach_classify_add_del_table_field;
3573 #define _(a) a = ntohl(mp->a);
3574 foreach_classify_add_del_table_field;
3577 /* The underlying API fails silently, on purpose, so check here */
3578 if (mp->is_add == 0)
3579 if (pool_is_free_index (cm->tables, table_index)) {
3580 rv = VNET_API_ERROR_NO_SUCH_TABLE;
3584 rv = vnet_classify_add_del_table
3585 (cm, mp->mask, nbuckets, memory_size,
3586 skip_n_vectors, match_n_vectors,
3587 next_table_index, miss_next_index,
3588 &table_index, mp->is_add);
3591 REPLY_MACRO2(VL_API_CLASSIFY_ADD_DEL_TABLE_REPLY,
3593 if (rv == 0 && mp->is_add) {
3594 t = pool_elt_at_index (cm->tables, table_index);
3595 rmp->skip_n_vectors = ntohl(t->skip_n_vectors);
3596 rmp->match_n_vectors = ntohl(t->match_n_vectors);
3597 rmp->new_table_index = ntohl(table_index);
3599 rmp->skip_n_vectors = ~0;
3600 rmp->match_n_vectors = ~0;
3601 rmp->new_table_index = ~0;
3606 static void vl_api_classify_add_del_session_t_handler
3607 (vl_api_classify_add_del_session_t * mp)
3609 vnet_classify_main_t * cm = &vnet_classify_main;
3610 vl_api_classify_add_del_session_reply_t * rmp;
3612 u32 table_index, hit_next_index, opaque_index;
3615 table_index = ntohl (mp->table_index);
3616 hit_next_index = ntohl (mp->hit_next_index);
3617 opaque_index = ntohl (mp->opaque_index);
3618 advance = ntohl (mp->advance);
3620 rv = vnet_classify_add_del_session
3621 (cm, table_index, mp->match, hit_next_index, opaque_index,
3622 advance, mp->is_add);
3624 REPLY_MACRO(VL_API_CLASSIFY_ADD_DEL_SESSION_REPLY);
3627 static void vl_api_classify_set_interface_ip_table_t_handler
3628 (vl_api_classify_set_interface_ip_table_t * mp)
3630 vlib_main_t * vm = vlib_get_main();
3631 vl_api_classify_set_interface_ip_table_reply_t * rmp;
3633 u32 table_index, sw_if_index;
3635 table_index = ntohl (mp->table_index);
3636 sw_if_index = ntohl (mp->sw_if_index);
3638 VALIDATE_SW_IF_INDEX(mp);
3641 rv = vnet_set_ip6_classify_intfc (vm, sw_if_index, table_index);
3643 rv = vnet_set_ip4_classify_intfc (vm, sw_if_index, table_index);
3645 BAD_SW_IF_INDEX_LABEL;
3647 REPLY_MACRO(VL_API_CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY);
3650 static void vl_api_classify_set_interface_l2_tables_t_handler
3651 (vl_api_classify_set_interface_l2_tables_t * mp)
3653 vl_api_classify_set_interface_l2_tables_reply_t * rmp;
3655 u32 sw_if_index, ip4_table_index, ip6_table_index, other_table_index;
3658 ip4_table_index = ntohl(mp->ip4_table_index);
3659 ip6_table_index = ntohl(mp->ip6_table_index);
3660 other_table_index = ntohl(mp->other_table_index);
3661 sw_if_index = ntohl(mp->sw_if_index);
3663 VALIDATE_SW_IF_INDEX(mp);
3665 rv = vnet_l2_classify_set_tables (sw_if_index, ip4_table_index,
3666 ip6_table_index, other_table_index);
3669 if (ip4_table_index != ~0 || ip6_table_index != ~0
3670 || other_table_index != ~0)
3675 vnet_l2_classify_enable_disable (sw_if_index, enable);
3678 BAD_SW_IF_INDEX_LABEL;
3680 REPLY_MACRO(VL_API_CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY);
3684 vl_api_l2_fib_clear_table_t_handler (vl_api_l2_fib_clear_table_t *mp)
3687 vl_api_l2_fib_clear_table_reply_t * rmp;
3689 /* DAW-FIXME: This API should only clear non-static l2fib entries, but
3690 * that is not currently implemented. When that TODO is fixed
3691 * this call should be changed to pass 1 instead of 0.
3693 l2fib_clear_table (0);
3695 REPLY_MACRO(VL_API_L2_FIB_CLEAR_TABLE_REPLY);
3698 extern void l2_efp_filter_configure(vnet_main_t * vnet_main,
3703 vl_api_l2_interface_efp_filter_t_handler (vl_api_l2_interface_efp_filter_t *mp)
3706 vl_api_l2_interface_efp_filter_reply_t * rmp;
3707 vnet_main_t *vnm = vnet_get_main();
3709 // enable/disable the feature
3710 l2_efp_filter_configure (vnm, mp->sw_if_index, mp->enable_disable);
3711 rv = vnm->api_errno;
3713 REPLY_MACRO(VL_API_L2_INTERFACE_EFP_FILTER_REPLY);
3717 vl_api_l2_interface_vlan_tag_rewrite_t_handler (vl_api_l2_interface_vlan_tag_rewrite_t *mp)
3720 vl_api_l2_interface_vlan_tag_rewrite_reply_t * rmp;
3721 vnet_main_t * vnm = vnet_get_main();
3722 vlib_main_t * vm = vlib_get_main();
3725 VALIDATE_SW_IF_INDEX(mp);
3727 vtr_op = ntohl(mp->vtr_op);
3729 /* The L2 code is unsuspicious */
3731 case L2_VTR_DISABLED:
3736 case L2_VTR_TRANSLATE_1_1:
3737 case L2_VTR_TRANSLATE_1_2:
3738 case L2_VTR_TRANSLATE_2_1:
3739 case L2_VTR_TRANSLATE_2_2:
3743 rv = VNET_API_ERROR_INVALID_VALUE;
3744 goto bad_sw_if_index;
3747 rv = l2vtr_configure (vm, vnm, ntohl(mp->sw_if_index), vtr_op,
3748 ntohl(mp->push_dot1q), ntohl(mp->tag1),
3751 BAD_SW_IF_INDEX_LABEL;
3753 REPLY_MACRO(VL_API_L2_INTERFACE_VLAN_TAG_REWRITE_REPLY);
3757 vl_api_create_vhost_user_if_t_handler (vl_api_create_vhost_user_if_t *mp)
3761 vl_api_create_vhost_user_if_reply_t * rmp;
3762 u32 sw_if_index = (u32)~0;
3764 vnet_main_t * vnm = vnet_get_main();
3765 vlib_main_t * vm = vlib_get_main();
3767 rv = dpdk_vhost_user_create_if(vnm, vm, (char *)mp->sock_filename,
3768 mp->is_server, &sw_if_index, (u64)~0,
3769 mp->renumber, ntohl(mp->custom_dev_instance),
3770 (mp->use_custom_mac)?mp->mac_address:NULL);
3772 REPLY_MACRO2(VL_API_CREATE_VHOST_USER_IF_REPLY,
3774 rmp->sw_if_index = ntohl (sw_if_index);
3780 vl_api_modify_vhost_user_if_t_handler (vl_api_modify_vhost_user_if_t *mp)
3784 vl_api_modify_vhost_user_if_reply_t * rmp;
3785 u32 sw_if_index = ntohl(mp->sw_if_index);
3787 vnet_main_t * vnm = vnet_get_main();
3788 vlib_main_t * vm = vlib_get_main();
3790 rv = dpdk_vhost_user_modify_if(vnm, vm, (char *)mp->sock_filename,
3791 mp->is_server, sw_if_index, (u64)~0,
3792 mp->renumber, ntohl(mp->custom_dev_instance));
3794 REPLY_MACRO(VL_API_MODIFY_VHOST_USER_IF_REPLY);
3799 vl_api_delete_vhost_user_if_t_handler (vl_api_delete_vhost_user_if_t *mp)
3803 vpe_api_main_t * vam = &vpe_api_main;
3804 vl_api_delete_vhost_user_if_reply_t * rmp;
3805 u32 sw_if_index = ntohl(mp->sw_if_index);
3807 vnet_main_t * vnm = vnet_get_main();
3808 vlib_main_t * vm = vlib_get_main();
3810 rv = dpdk_vhost_user_delete_if(vnm, vm, sw_if_index);
3812 REPLY_MACRO(VL_API_DELETE_VHOST_USER_IF_REPLY);
3814 unix_shared_memory_queue_t * q =
3815 vl_api_client_index_to_input_queue (mp->client_index);
3819 send_sw_interface_flags_deleted (vam, q, sw_if_index);
3824 static void vl_api_sw_interface_vhost_user_details_t_handler (
3825 vl_api_sw_interface_vhost_user_details_t * mp)
3827 clib_warning ("BUG");
3831 static void send_sw_interface_vhost_user_details (vpe_api_main_t * am,
3832 unix_shared_memory_queue_t *q,
3833 vhost_user_intf_details_t * vui,
3836 vl_api_sw_interface_vhost_user_details_t * mp;
3838 mp = vl_msg_api_alloc (sizeof (*mp));
3839 memset (mp, 0, sizeof (*mp));
3840 mp->_vl_msg_id = ntohs(VL_API_SW_INTERFACE_VHOST_USER_DETAILS);
3841 mp->sw_if_index = ntohl(vui->sw_if_index);
3842 mp->virtio_net_hdr_sz = ntohl (vui->virtio_net_hdr_sz);
3843 mp->features = clib_net_to_host_u64 (vui->features);
3844 mp->is_server = vui->is_server;
3845 mp->num_regions = ntohl(vui->num_regions);
3846 mp->sock_errno = ntohl(vui->sock_errno);
3847 mp->context = context;
3849 strncpy ((char *) mp->sock_filename,
3850 (char *) vui->sock_filename, ARRAY_LEN(mp->sock_filename)-1);
3851 strncpy ((char *) mp->interface_name,
3852 (char *) vui->if_name, ARRAY_LEN(mp->interface_name)-1);
3854 vl_msg_api_send_shmem (q, (u8 *)&mp);
3859 vl_api_sw_interface_vhost_user_dump_t_handler (
3860 vl_api_sw_interface_vhost_user_dump_t *mp)
3864 vpe_api_main_t * am = &vpe_api_main;
3865 vnet_main_t * vnm = vnet_get_main();
3866 vlib_main_t * vm = vlib_get_main();
3867 vhost_user_intf_details_t *ifaces = NULL;
3868 vhost_user_intf_details_t *vuid = NULL;
3869 unix_shared_memory_queue_t * q;
3871 q = vl_api_client_index_to_input_queue (mp->client_index);
3875 rv = dpdk_vhost_user_dump_ifs(vnm, vm, &ifaces);
3879 vec_foreach (vuid, ifaces) {
3880 send_sw_interface_vhost_user_details (am, q, vuid, mp->context);
3886 static void send_sw_if_l2tpv3_tunnel_details (vpe_api_main_t * am,
3887 unix_shared_memory_queue_t *q,
3892 vl_api_sw_if_l2tpv3_tunnel_details_t * mp;
3893 u8 * if_name = NULL;
3894 vnet_sw_interface_t * si = NULL;
3896 si = vnet_get_hw_sw_interface (lm->vnet_main, s->hw_if_index);
3898 if_name = format(if_name, "%U",
3899 format_vnet_sw_interface_name, lm->vnet_main, si);
3901 mp = vl_msg_api_alloc (sizeof (*mp));
3902 memset (mp, 0, sizeof (*mp));
3903 mp->_vl_msg_id = ntohs(VL_API_SW_IF_L2TPV3_TUNNEL_DETAILS);
3904 strncpy((char *)mp->interface_name,
3905 (char *)if_name, ARRAY_LEN(mp->interface_name)-1);
3906 mp->sw_if_index = ntohl(si->sw_if_index);
3907 mp->local_session_id = s->local_session_id;
3908 mp->remote_session_id = s->remote_session_id;
3909 mp->local_cookie[0] = s->local_cookie[0];
3910 mp->local_cookie[1] = s->local_cookie[1];
3911 mp->remote_cookie = s->remote_cookie;
3912 clib_memcpy(mp->client_address, &s->client_address, sizeof(s->client_address));
3913 clib_memcpy(mp->our_address, &s->our_address, sizeof(s->our_address));
3914 mp->l2_sublayer_present = s->l2_sublayer_present;
3915 mp->context = context;
3917 vl_msg_api_send_shmem (q, (u8 *)&mp);
3920 static void send_ip_address_details (vpe_api_main_t * am,
3921 unix_shared_memory_queue_t * q,
3927 vl_api_ip_address_details_t * mp;
3929 mp = vl_msg_api_alloc (sizeof (*mp));
3930 memset (mp, 0, sizeof (*mp));
3931 mp->_vl_msg_id = ntohs(VL_API_IP_ADDRESS_DETAILS);
3934 clib_memcpy(&mp->ip, ip, sizeof(mp->ip));
3936 u32 * tp = (u32 *)mp->ip;
3937 *tp = ntohl(*(u32*)ip);
3939 mp->prefix_length = prefix_length;
3940 mp->context = context;
3942 vl_msg_api_send_shmem (q, (u8 *)&mp);
3946 vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t *mp)
3948 vpe_api_main_t * am = &vpe_api_main;
3949 unix_shared_memory_queue_t * q;
3952 ip6_main_t * im6 = &ip6_main;
3953 ip4_main_t * im4 = &ip4_main;
3954 ip_lookup_main_t * lm6 = &im6->lookup_main;
3955 ip_lookup_main_t * lm4 = &im4->lookup_main;
3956 ip_interface_address_t * ia = 0;
3957 u32 sw_if_index = ~0;
3958 int rv __attribute__ ((unused)) = 0;
3960 VALIDATE_SW_IF_INDEX(mp);
3962 sw_if_index = ntohl(mp->sw_if_index);
3964 q = vl_api_client_index_to_input_queue (mp->client_index);
3970 foreach_ip_interface_address (lm6, ia, sw_if_index,
3971 1 /* honor unnumbered */,
3973 r6 = ip_interface_address_get_address (lm6, ia);
3974 u16 prefix_length = ia->address_length;
3975 send_ip_address_details(am, q, (u8*)r6, prefix_length, 1, mp->context);
3978 foreach_ip_interface_address (lm4, ia, sw_if_index,
3979 1 /* honor unnumbered */,
3981 r4 = ip_interface_address_get_address (lm4, ia);
3982 u16 prefix_length = ia->address_length;
3983 send_ip_address_details(am, q, (u8*)r4, prefix_length, 0, mp->context);
3986 BAD_SW_IF_INDEX_LABEL;
3989 static void send_ip_details (vpe_api_main_t * am,
3990 unix_shared_memory_queue_t *q,
3994 vl_api_ip_details_t * mp;
3996 mp = vl_msg_api_alloc (sizeof (*mp));
3997 memset (mp, 0, sizeof (*mp));
3998 mp->_vl_msg_id = ntohs(VL_API_IP_DETAILS);
4000 mp->sw_if_index = ntohl(sw_if_index);
4001 mp->context = context;
4003 vl_msg_api_send_shmem (q, (u8 *)&mp);
4007 vl_api_sw_if_l2tpv3_tunnel_dump_t_handler (
4008 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp)
4010 vpe_api_main_t * am = &vpe_api_main;
4011 l2t_main_t * lm = &l2t_main;
4012 unix_shared_memory_queue_t * q;
4013 l2t_session_t *session;
4015 q = vl_api_client_index_to_input_queue (mp->client_index);
4019 pool_foreach (session, lm->sessions,
4021 send_sw_if_l2tpv3_tunnel_details (am, q, session, lm, mp->context);
4026 static void send_sw_interface_tap_details (vpe_api_main_t * am,
4027 unix_shared_memory_queue_t *q,
4028 tapcli_interface_details_t *tap_if,
4031 vl_api_sw_interface_tap_details_t * mp;
4032 mp = vl_msg_api_alloc (sizeof (*mp));
4033 memset (mp, 0, sizeof (*mp));
4034 mp->_vl_msg_id = ntohs(VL_API_SW_INTERFACE_TAP_DETAILS);
4035 mp->sw_if_index = ntohl(tap_if->sw_if_index);
4036 strncpy((char *)mp->dev_name,
4037 (char *)tap_if->dev_name, ARRAY_LEN(mp->dev_name)-1);
4038 mp->context = context;
4040 vl_msg_api_send_shmem (q, (u8 *)&mp);
4044 vl_api_sw_interface_tap_dump_t_handler (
4045 vl_api_sw_interface_tap_dump_t *mp)
4048 vpe_api_main_t * am = &vpe_api_main;
4049 unix_shared_memory_queue_t * q;
4050 tapcli_interface_details_t *tapifs = NULL;
4051 tapcli_interface_details_t *tap_if = NULL;
4053 q = vl_api_client_index_to_input_queue (mp->client_index);
4057 rv = vnet_tap_dump_ifs(&tapifs);
4061 vec_foreach(tap_if, tapifs) {
4062 send_sw_interface_tap_details(am, q, tap_if, mp->context);
4069 vl_api_ip_dump_t_handler (vl_api_ip_dump_t *mp)
4071 vpe_api_main_t * am = &vpe_api_main;
4072 vnet_main_t * vnm = vnet_get_main();
4073 vlib_main_t * vm = vlib_get_main();
4074 vnet_interface_main_t * im = &vnm->interface_main;
4075 unix_shared_memory_queue_t * q;
4076 vnet_sw_interface_t * si, * sorted_sis;
4077 u32 sw_if_index = ~0;
4079 q = vl_api_client_index_to_input_queue (mp->client_index);
4084 /* Gather interfaces. */
4085 sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
4086 _vec_len (sorted_sis) = 0;
4087 pool_foreach (si, im->sw_interfaces, ({ vec_add1 (sorted_sis, si[0]); }));
4089 vec_foreach (si, sorted_sis) {
4090 if (!(si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)) {
4091 if (mp->is_ipv6 && !ip6_interface_enabled(vm, si->sw_if_index)) {
4094 sw_if_index = si->sw_if_index;
4095 send_ip_details(am, q, sw_if_index, mp->context);
4100 static void vl_api_l2_fib_table_entry_t_handler (
4101 vl_api_l2_fib_table_entry_t * mp)
4103 clib_warning ("BUG");
4106 static void send_l2fib_table_entry (vpe_api_main_t * am,
4107 unix_shared_memory_queue_t *q,
4108 l2fib_entry_key_t * l2fe_key,
4109 l2fib_entry_result_t * l2fe_res,
4112 vl_api_l2_fib_table_entry_t * mp;
4114 mp = vl_msg_api_alloc (sizeof (*mp));
4115 memset (mp, 0, sizeof (*mp));
4116 mp->_vl_msg_id = ntohs(VL_API_L2_FIB_TABLE_ENTRY);
4118 mp->bd_id = ntohl(l2input_main.bd_configs[l2fe_key->fields.bd_index].bd_id);
4120 mp->mac = l2fib_make_key (l2fe_key->fields.mac, 0);
4121 mp->sw_if_index = ntohl(l2fe_res->fields.sw_if_index);
4122 mp->static_mac = l2fe_res->fields.static_mac;
4123 mp->filter_mac = l2fe_res->fields.filter;
4124 mp->bvi_mac = l2fe_res->fields.bvi;
4125 mp->context = context;
4127 vl_msg_api_send_shmem (q, (u8 *)&mp);
4131 vl_api_l2_fib_table_dump_t_handler (vl_api_l2_fib_table_dump_t *mp)
4133 vpe_api_main_t * am = &vpe_api_main;
4134 bd_main_t * bdm = &bd_main;
4135 l2fib_entry_key_t *l2fe_key = NULL;
4136 l2fib_entry_result_t *l2fe_res = NULL;
4137 u32 ni, bd_id = ntohl (mp->bd_id);
4139 unix_shared_memory_queue_t * q;
4142 q = vl_api_client_index_to_input_queue (mp->client_index);
4146 /* see l2fib_table_dump: ~0 means "any" */
4150 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
4157 l2fib_table_dump (bd_index, &l2fe_key, &l2fe_res);
4159 vec_foreach_index (ni, l2fe_key) {
4160 send_l2fib_table_entry (am, q, vec_elt_at_index(l2fe_key, ni),
4161 vec_elt_at_index(l2fe_res, ni), mp->context);
4168 vl_api_show_version_t_handler (vl_api_show_version_t *mp)
4170 vl_api_show_version_reply_t *rmp;
4172 char * vpe_api_get_build_directory(void);
4173 char * vpe_api_get_version(void);
4174 char * vpe_api_get_build_date(void);
4176 unix_shared_memory_queue_t * q =
4177 vl_api_client_index_to_input_queue (mp->client_index);
4182 REPLY_MACRO2(VL_API_SHOW_VERSION_REPLY,
4184 strncpy ((char *) rmp->program, "vpe", ARRAY_LEN(rmp->program)-1);
4185 strncpy ((char *) rmp->build_directory, vpe_api_get_build_directory(),
4186 ARRAY_LEN(rmp->build_directory)-1);
4187 strncpy ((char *) rmp->version, vpe_api_get_version(),
4188 ARRAY_LEN(rmp->version)-1);
4189 strncpy ((char *) rmp->build_date, vpe_api_get_build_date(),
4190 ARRAY_LEN(rmp->build_date)-1);
4194 static void vl_api_get_node_index_t_handler
4195 (vl_api_get_node_index_t * mp)
4197 vlib_main_t * vm = vlib_get_main();
4198 vl_api_get_node_index_reply_t * rmp;
4201 u32 node_index = ~0;
4203 n = vlib_get_node_by_name (vm, mp->node_name);
4206 rv = VNET_API_ERROR_NO_SUCH_NODE;
4208 node_index = n->index;
4210 REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
4212 rmp->node_index = ntohl(node_index);
4216 static void vl_api_add_node_next_t_handler
4217 (vl_api_add_node_next_t * mp)
4219 vlib_main_t * vm = vlib_get_main();
4220 vl_api_add_node_next_reply_t * rmp;
4221 vlib_node_t * n, * next;
4223 u32 next_index = ~0;
4225 n = vlib_get_node_by_name (vm, mp->node_name);
4228 rv = VNET_API_ERROR_NO_SUCH_NODE;
4232 next = vlib_get_node_by_name (vm, mp->next_name);
4235 rv = VNET_API_ERROR_NO_SUCH_NODE2;
4237 next_index = vlib_node_add_next (vm, n->index, next->index);
4240 REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
4242 rmp->next_index = ntohl(next_index);
4246 static void vl_api_l2tpv3_create_tunnel_t_handler
4247 (vl_api_l2tpv3_create_tunnel_t *mp)
4249 vl_api_l2tpv3_create_tunnel_reply_t * rmp;
4250 l2t_main_t *lm = &l2t_main;
4251 u32 sw_if_index = (u32)~0;
4254 if (mp->is_ipv6 != 1) {
4255 rv = VNET_API_ERROR_UNIMPLEMENTED;
4259 rv = create_l2tpv3_ipv6_tunnel (lm,
4260 (ip6_address_t *) mp->client_address,
4261 (ip6_address_t *) mp->our_address,
4262 ntohl(mp->local_session_id),
4263 ntohl(mp->remote_session_id),
4264 clib_net_to_host_u64(mp->local_cookie),
4265 clib_net_to_host_u64(mp->remote_cookie),
4266 mp->l2_sublayer_present,
4270 REPLY_MACRO2(VL_API_L2TPV3_CREATE_TUNNEL_REPLY,
4272 rmp->sw_if_index = ntohl (sw_if_index);
4276 static void vl_api_l2tpv3_set_tunnel_cookies_t_handler
4277 (vl_api_l2tpv3_set_tunnel_cookies_t *mp)
4279 vl_api_l2tpv3_set_tunnel_cookies_reply_t * rmp;
4280 l2t_main_t *lm = &l2t_main;
4283 VALIDATE_SW_IF_INDEX(mp);
4285 rv = l2tpv3_set_tunnel_cookies (lm, ntohl(mp->sw_if_index),
4286 clib_net_to_host_u64(mp->new_local_cookie),
4287 clib_net_to_host_u64(mp->new_remote_cookie));
4289 BAD_SW_IF_INDEX_LABEL;
4291 REPLY_MACRO (VL_API_L2TPV3_SET_TUNNEL_COOKIES_REPLY);
4294 static void vl_api_l2tpv3_interface_enable_disable_t_handler
4295 (vl_api_l2tpv3_interface_enable_disable_t * mp)
4298 vnet_main_t * vnm = vnet_get_main();
4299 vl_api_l2tpv3_interface_enable_disable_reply_t * rmp;
4301 VALIDATE_SW_IF_INDEX(mp);
4303 rv = l2tpv3_interface_enable_disable
4304 (vnm, ntohl(mp->sw_if_index), mp->enable_disable);
4306 BAD_SW_IF_INDEX_LABEL;
4308 REPLY_MACRO (VL_API_L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY);
4311 static void vl_api_l2tpv3_set_lookup_key_t_handler
4312 (vl_api_l2tpv3_set_lookup_key_t * mp)
4315 l2t_main_t *lm = &l2t_main;
4316 vl_api_l2tpv3_set_lookup_key_reply_t * rmp;
4318 if (mp->key > L2T_LOOKUP_SESSION_ID) {
4319 rv = VNET_API_ERROR_INVALID_VALUE;
4323 lm->lookup_type = mp->key;
4326 REPLY_MACRO (VL_API_L2TPV3_SET_LOOKUP_KEY_REPLY);
4329 static void vl_api_vxlan_add_del_tunnel_t_handler
4330 (vl_api_vxlan_add_del_tunnel_t * mp)
4332 vl_api_vxlan_add_del_tunnel_reply_t * rmp;
4334 vnet_vxlan_add_del_tunnel_args_t _a, *a = &_a;
4335 u32 encap_fib_index;
4337 ip4_main_t * im = &ip4_main;
4338 u32 sw_if_index = ~0;
4340 p = hash_get (im->fib_index_by_table_id, ntohl(mp->encap_vrf_id));
4342 rv = VNET_API_ERROR_NO_SUCH_FIB;
4345 encap_fib_index = p[0];
4347 /* Check src & dst are different */
4348 if ((mp->is_ipv6 && memcmp(mp->src_address, mp->dst_address, 16) == 0) ||
4349 (!mp->is_ipv6 && memcmp(mp->src_address, mp->dst_address, 4) == 0)) {
4350 rv = VNET_API_ERROR_SAME_SRC_DST;
4353 memset (a, 0, sizeof (*a));
4355 a->is_add = mp->is_add;
4356 a->is_ip6 = mp->is_ipv6;
4358 /* ip addresses sent in network byte order */
4360 memcpy(&(a->src.ip6), mp->src_address, 16);
4361 memcpy(&(a->dst.ip6), mp->dst_address, 16);
4363 memcpy(&(a->src.ip4), mp->src_address, 4);
4364 memcpy(&(a->dst.ip4), mp->dst_address, 4);
4367 a->encap_fib_index = encap_fib_index;
4368 a->decap_next_index = ntohl(mp->decap_next_index);
4369 a->vni = ntohl(mp->vni);
4370 rv = vnet_vxlan_add_del_tunnel (a, &sw_if_index);
4373 REPLY_MACRO2(VL_API_VXLAN_ADD_DEL_TUNNEL_REPLY,
4375 rmp->sw_if_index = ntohl (sw_if_index);
4379 static void send_vxlan_tunnel_details
4380 (vxlan_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
4382 vl_api_vxlan_tunnel_details_t * rmp;
4383 ip4_main_t * im4 = &ip4_main;
4384 ip6_main_t * im6 = &ip6_main;
4385 u8 is_ipv6 = !(t->flags & VXLAN_TUNNEL_IS_IPV4);
4387 rmp = vl_msg_api_alloc (sizeof (*rmp));
4388 memset (rmp, 0, sizeof (*rmp));
4389 rmp->_vl_msg_id = ntohs(VL_API_VXLAN_TUNNEL_DETAILS);
4391 memcpy(rmp->src_address, &(t->src.ip6), 16);
4392 memcpy(rmp->dst_address, &(t->dst.ip6), 16);
4393 rmp->encap_vrf_id = htonl(im6->fibs[t->encap_fib_index].table_id);
4395 memcpy(rmp->src_address, &(t->src.ip4), 4);
4396 memcpy(rmp->dst_address, &(t->dst.ip4), 4);
4397 rmp->encap_vrf_id = htonl(im4->fibs[t->encap_fib_index].table_id);
4399 rmp->vni = htonl(t->vni);
4400 rmp->decap_next_index = htonl(t->decap_next_index);
4401 rmp->sw_if_index = htonl(t->sw_if_index);
4402 rmp->is_ipv6 = is_ipv6;
4403 rmp->context = context;
4405 vl_msg_api_send_shmem (q, (u8 *)&rmp);
4408 static void vl_api_vxlan_tunnel_dump_t_handler
4409 (vl_api_vxlan_tunnel_dump_t * mp)
4411 unix_shared_memory_queue_t * q;
4412 vxlan_main_t * vxm = &vxlan_main;
4416 q = vl_api_client_index_to_input_queue (mp->client_index);
4421 sw_if_index = ntohl(mp->sw_if_index);
4423 if (~0 == sw_if_index) {
4424 pool_foreach (t, vxm->tunnels,
4426 send_vxlan_tunnel_details(t, q, mp->context);
4429 if ((sw_if_index >= vec_len(vxm->tunnel_index_by_sw_if_index)) ||
4430 (~0 == vxm->tunnel_index_by_sw_if_index[sw_if_index])) {
4433 t = &vxm->tunnels[vxm->tunnel_index_by_sw_if_index[sw_if_index]];
4434 send_vxlan_tunnel_details(t, q, mp->context);
4438 static void vl_api_gre_add_del_tunnel_t_handler
4439 (vl_api_gre_add_del_tunnel_t * mp)
4441 vl_api_gre_add_del_tunnel_reply_t * rmp;
4443 vnet_gre_add_del_tunnel_args_t _a, *a = &_a;
4446 ip4_main_t * im = &ip4_main;
4447 u32 sw_if_index = ~0;
4449 p = hash_get (im->fib_index_by_table_id, ntohl(mp->outer_table_id));
4451 rv = VNET_API_ERROR_NO_SUCH_FIB;
4454 outer_table_id = p[0];
4456 /* Check src & dst are different */
4457 if (memcmp(&mp->src_address, &mp->dst_address, 4) == 0) {
4458 rv = VNET_API_ERROR_SAME_SRC_DST;
4462 memset (a, 0, sizeof (*a));
4464 a->is_add = mp->is_add;
4466 /* ip addresses sent in network byte order */
4467 a->src.as_u32 = mp->src_address;
4468 a->dst.as_u32 = mp->dst_address;
4470 a->outer_table_id = outer_table_id;
4471 rv = vnet_gre_add_del_tunnel (a, &sw_if_index);
4474 REPLY_MACRO2(VL_API_GRE_ADD_DEL_TUNNEL_REPLY,
4476 rmp->sw_if_index = ntohl (sw_if_index);
4480 static void send_gre_tunnel_details
4481 (gre_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
4483 vl_api_gre_tunnel_details_t * rmp;
4484 ip4_main_t * im = &ip4_main;
4486 rmp = vl_msg_api_alloc (sizeof (*rmp));
4487 memset (rmp, 0, sizeof (*rmp));
4488 rmp->_vl_msg_id = ntohs(VL_API_GRE_TUNNEL_DETAILS);
4489 rmp->src_address = t->tunnel_src.data_u32;
4490 rmp->dst_address = t->tunnel_dst.data_u32;
4491 rmp->outer_table_id = htonl(im->fibs[t->outer_fib_index].table_id);
4492 rmp->sw_if_index = htonl(t->sw_if_index);
4493 rmp->context = context;
4495 vl_msg_api_send_shmem (q, (u8 *)&rmp);
4498 static void vl_api_gre_tunnel_dump_t_handler
4499 (vl_api_gre_tunnel_dump_t * mp)
4501 unix_shared_memory_queue_t * q;
4502 gre_main_t * gm = &gre_main;
4506 q = vl_api_client_index_to_input_queue (mp->client_index);
4511 sw_if_index = ntohl(mp->sw_if_index);
4513 if (~0 == sw_if_index) {
4514 pool_foreach (t, gm->tunnels,
4516 send_gre_tunnel_details(t, q, mp->context);
4519 if ((sw_if_index >= vec_len(gm->tunnel_index_by_sw_if_index)) ||
4520 (~0 == gm->tunnel_index_by_sw_if_index[sw_if_index])) {
4523 t = &gm->tunnels[gm->tunnel_index_by_sw_if_index[sw_if_index]];
4524 send_gre_tunnel_details(t, q, mp->context);
4529 vl_api_l2_patch_add_del_t_handler (vl_api_l2_patch_add_del_t *mp)
4531 extern int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
4533 vl_api_l2_patch_add_del_reply_t * rmp;
4534 int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
4538 VALIDATE_RX_SW_IF_INDEX(mp);
4539 VALIDATE_TX_SW_IF_INDEX(mp);
4541 rv = vnet_l2_patch_add_del (ntohl(mp->rx_sw_if_index),
4542 ntohl(mp->tx_sw_if_index),
4543 (int)(mp->is_add != 0));
4545 BAD_RX_SW_IF_INDEX_LABEL;
4546 BAD_TX_SW_IF_INDEX_LABEL;
4548 REPLY_MACRO(VL_API_L2_PATCH_ADD_DEL_REPLY);
4552 vl_api_vxlan_gpe_add_del_tunnel_t_handler
4553 (vl_api_vxlan_gpe_add_del_tunnel_t * mp)
4555 vl_api_vxlan_gpe_add_del_tunnel_reply_t * rmp;
4557 vnet_vxlan_gpe_add_del_tunnel_args_t _a, *a = &_a;
4558 u32 encap_fib_index, decap_fib_index;
4561 ip4_main_t * im = &ip4_main;
4562 u32 sw_if_index = ~0;
4565 p = hash_get (im->fib_index_by_table_id, ntohl(mp->encap_vrf_id));
4567 rv = VNET_API_ERROR_NO_SUCH_FIB;
4570 encap_fib_index = p[0];
4572 protocol = mp->protocol;
4574 /* Interpret decap_vrf_id as an opaque if sending to other-than-ip4-input */
4575 if (protocol == VXLAN_GPE_INPUT_NEXT_IP4_INPUT) {
4576 p = hash_get (im->fib_index_by_table_id, ntohl(mp->decap_vrf_id));
4578 rv = VNET_API_ERROR_NO_SUCH_INNER_FIB;
4581 decap_fib_index = p[0];
4583 decap_fib_index = ntohl(mp->decap_vrf_id);
4586 /* Check src & dst are different */
4587 if ((mp->is_ipv6 && memcmp(mp->local, mp->remote, 16) == 0) ||
4588 (!mp->is_ipv6 && memcmp(mp->local, mp->remote, 4) == 0)) {
4589 rv = VNET_API_ERROR_SAME_SRC_DST;
4592 memset (a, 0, sizeof (*a));
4594 a->is_add = mp->is_add;
4595 a->is_ip6 = mp->is_ipv6;
4596 /* ip addresses sent in network byte order */
4598 clib_memcpy(&(a->local.ip6), mp->local, 16);
4599 clib_memcpy(&(a->remote.ip6), mp->remote, 16);
4601 clib_memcpy(&(a->local.ip4), mp->local, 4);
4602 clib_memcpy(&(a->remote.ip4), mp->remote, 4);
4604 a->encap_fib_index = encap_fib_index;
4605 a->decap_fib_index = decap_fib_index;
4606 a->protocol = protocol;
4607 a->vni = ntohl(mp->vni);
4608 rv = vnet_vxlan_gpe_add_del_tunnel (a, &sw_if_index);
4611 REPLY_MACRO2(VL_API_VXLAN_GPE_ADD_DEL_TUNNEL_REPLY,
4613 rmp->sw_if_index = ntohl (sw_if_index);
4617 static void send_vxlan_gpe_tunnel_details
4618 (vxlan_gpe_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
4620 vl_api_vxlan_gpe_tunnel_details_t * rmp;
4621 ip4_main_t * im4 = &ip4_main;
4622 ip6_main_t * im6 = &ip6_main;
4623 u8 is_ipv6 = !(t->flags & VXLAN_GPE_TUNNEL_IS_IPV4);
4625 rmp = vl_msg_api_alloc (sizeof (*rmp));
4626 memset (rmp, 0, sizeof (*rmp));
4627 rmp->_vl_msg_id = ntohs(VL_API_VXLAN_GPE_TUNNEL_DETAILS);
4629 memcpy(rmp->local, &(t->local.ip6), 16);
4630 memcpy(rmp->remote, &(t->remote.ip6), 16);
4631 rmp->encap_vrf_id = htonl(im6->fibs[t->encap_fib_index].table_id);
4632 rmp->decap_vrf_id = htonl(im6->fibs[t->decap_fib_index].table_id);
4634 memcpy(rmp->local, &(t->local.ip4), 4);
4635 memcpy(rmp->remote, &(t->remote.ip4), 4);
4636 rmp->encap_vrf_id = htonl(im4->fibs[t->encap_fib_index].table_id);
4637 rmp->decap_vrf_id = htonl(im4->fibs[t->decap_fib_index].table_id);
4639 rmp->vni = htonl(t->vni);
4640 rmp->protocol = t->protocol;
4641 rmp->sw_if_index = htonl(t->sw_if_index);
4642 rmp->is_ipv6 = is_ipv6;
4643 rmp->context = context;
4645 vl_msg_api_send_shmem (q, (u8 *)&rmp);
4648 static void vl_api_vxlan_gpe_tunnel_dump_t_handler
4649 (vl_api_vxlan_gpe_tunnel_dump_t * mp)
4651 unix_shared_memory_queue_t * q;
4652 vxlan_gpe_main_t * vgm = &vxlan_gpe_main;
4653 vxlan_gpe_tunnel_t * t;
4656 q = vl_api_client_index_to_input_queue (mp->client_index);
4661 sw_if_index = ntohl(mp->sw_if_index);
4663 if (~0 == sw_if_index) {
4664 pool_foreach (t, vgm->tunnels,
4666 send_vxlan_gpe_tunnel_details(t, q, mp->context);
4669 if ((sw_if_index >= vec_len(vgm->tunnel_index_by_sw_if_index)) ||
4670 (~0 == vgm->tunnel_index_by_sw_if_index[sw_if_index])) {
4673 t = &vgm->tunnels[vgm->tunnel_index_by_sw_if_index[sw_if_index]];
4674 send_vxlan_gpe_tunnel_details(t, q, mp->context);
4679 vl_api_lisp_add_del_locator_set_t_handler(vl_api_lisp_add_del_locator_set_t *mp)
4681 vl_api_lisp_add_del_locator_set_reply_t *rmp;
4683 vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
4685 u8 *locator_name = NULL;
4687 memset(a, 0, sizeof(a[0]));
4689 locator_name = format(0, "%s", mp->locator_set_name);
4691 a->name = locator_name;
4693 a->is_add = mp->is_add;
4696 rv = vnet_lisp_add_del_locator_set(a, &ls_index);
4698 vec_free(locator_name);
4700 REPLY_MACRO(VL_API_LISP_ADD_DEL_LOCATOR_SET_REPLY);
4704 vl_api_lisp_add_del_locator_t_handler(
4705 vl_api_lisp_add_del_locator_t *mp)
4707 vl_api_lisp_add_del_locator_reply_t *rmp;
4709 locator_t locator, *locators = NULL;
4710 vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
4712 u8 *locator_name = NULL;
4714 memset(&locator, 0, sizeof(locator));
4715 memset(a, 0, sizeof(a[0]));
4717 locator.sw_if_index = ntohl(mp->sw_if_index);
4718 locator.priority = mp->priority;
4719 locator.weight = mp->weight;
4721 vec_add1(locators, locator);
4723 locator_name = format(0, "%s", mp->locator_set_name);
4725 a->name = locator_name;
4726 a->locators = locators;
4727 a->is_add = mp->is_add;
4730 rv = vnet_lisp_add_del_locator(a, NULL, &ls_index);
4733 vec_free(locator_name);
4735 REPLY_MACRO(VL_API_LISP_ADD_DEL_LOCATOR_REPLY);
4739 vl_api_lisp_add_del_local_eid_t_handler(
4740 vl_api_lisp_add_del_local_eid_t *mp)
4742 vl_api_lisp_add_del_local_eid_reply_t *rmp;
4743 lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
4745 ip_prefix_t *prefp = NULL;
4746 ip_address_t *ip_eid = NULL;
4749 u32 locator_set_index = ~0, map_index = ~0;
4750 vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
4753 prefp = &gid_address_ippref(&eid);
4754 ip_eid = &ip_prefix_addr(prefp);
4755 gid_address_type (&eid) = GID_ADDR_IP_PREFIX;
4758 clib_memcpy(&ip_addr_v6(ip_eid), mp->ip_address,
4759 sizeof(ip_addr_v6(ip_eid)));
4760 ip_addr_version(ip_eid) = IP6;
4762 clib_memcpy(&ip_addr_v4(ip_eid), mp->ip_address,
4763 sizeof(ip_addr_v4(ip_eid)));
4764 ip_addr_version(ip_eid) = IP4;
4766 ip_prefix_len(prefp) = mp->prefix_len;
4768 name = format(0, "%s", mp->locator_set_name);
4769 p = hash_get_mem(lcm->locator_set_index_by_name, name);
4771 rv = VNET_API_ERROR_INVALID_VALUE;
4774 locator_set_index = p[0];
4776 /* XXX treat batch configuration */
4777 a->is_add = mp->is_add;
4779 a->locator_set_index = locator_set_index;
4782 rv = vnet_lisp_add_del_local_mapping(a, &map_index);
4787 REPLY_MACRO(VL_API_LISP_ADD_DEL_LOCAL_EID_REPLY);
4791 lisp_gpe_add_del_fwd_entry_set_address(
4792 vl_api_lisp_gpe_add_del_fwd_entry_t *mp,
4793 ip_address_t *slocator,
4794 ip_address_t *dlocator,
4797 ip_address_t *ip_eid = NULL;
4798 ip_prefix_t *prefp = NULL;
4800 prefp = &gid_address_ippref(eid);
4801 ip_eid = &ip_prefix_addr(prefp);
4803 if (mp->eid_is_ipv6) {
4804 clib_memcpy(&ip_addr_v6(ip_eid), mp->eid_ip_address,
4805 sizeof(ip_addr_v6(ip_eid)));
4806 ip_addr_version(ip_eid) = IP6;
4808 clib_memcpy(&ip_addr_v4(ip_eid), mp->eid_ip_address,
4809 sizeof(ip_addr_v4(ip_eid)));
4810 ip_addr_version(ip_eid) = IP4;
4812 ip_prefix_len(prefp) = mp->eid_prefix_len;
4814 if (mp->address_is_ipv6) {
4815 clib_memcpy(&ip_addr_v6(slocator), mp->source_ip_address,
4816 sizeof(ip_addr_v6(slocator)));
4817 ip_addr_version(slocator) = IP6;
4818 clib_memcpy(&ip_addr_v6(dlocator), mp->destination_ip_address,
4819 sizeof(ip_addr_v6(dlocator)));
4820 ip_addr_version(dlocator) = IP6;
4822 clib_memcpy(&ip_addr_v4(slocator), mp->source_ip_address,
4823 sizeof(ip_addr_v4(slocator)));
4824 ip_addr_version(slocator) = IP4;
4825 clib_memcpy(&ip_addr_v4(dlocator), mp->destination_ip_address,
4826 sizeof(ip_addr_v4(dlocator)));
4827 ip_addr_version(dlocator) = IP4;
4832 vl_api_lisp_gpe_add_del_fwd_entry_t_handler(
4833 vl_api_lisp_gpe_add_del_fwd_entry_t *mp)
4835 vl_api_lisp_gpe_add_del_fwd_entry_reply_t *rmp;
4837 ip_address_t slocator, dlocator;
4839 vnet_lisp_gpe_add_del_fwd_entry_args_t a;
4841 lisp_gpe_add_del_fwd_entry_set_address(mp, &slocator, &dlocator, &eid);
4843 memset (&a, 0, sizeof(a));
4845 a.is_add = mp->is_add;
4847 a.slocator = slocator;
4848 a.dlocator = dlocator;
4849 rv = vnet_lisp_gpe_add_del_fwd_entry (&a, 0);
4851 REPLY_MACRO(VL_API_LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY);
4855 vl_api_lisp_add_del_map_resolver_t_handler(
4856 vl_api_lisp_add_del_map_resolver_t *mp)
4858 vl_api_lisp_add_del_map_resolver_reply_t *rmp;
4860 ip_address_t *ip_addr = NULL;
4861 vnet_lisp_add_del_map_resolver_args_t _a, * a = &_a;
4863 a->is_add = mp->is_add;
4864 ip_addr = &a->address;
4867 clib_memcpy(&ip_addr_v6(ip_addr), mp->ip_address,
4868 sizeof(ip_addr_v6(ip_addr)));
4869 ip_addr_version(ip_addr) = IP6;
4871 clib_memcpy(&ip_addr_v4(ip_addr), mp->ip_address,
4872 sizeof(ip_addr_v4(ip_addr)));
4873 ip_addr_version(ip_addr) = IP4;
4876 rv = vnet_lisp_add_del_map_resolver (a);
4878 REPLY_MACRO(VL_API_LISP_ADD_DEL_MAP_RESOLVER_REPLY);
4882 vl_api_lisp_gpe_enable_disable_t_handler(
4883 vl_api_lisp_gpe_enable_disable_t *mp)
4885 vl_api_lisp_gpe_enable_disable_reply_t *rmp;
4887 vnet_lisp_gpe_enable_disable_args_t _a, * a = &_a;
4889 a->is_en = mp->is_en;
4890 vnet_lisp_gpe_enable_disable (a);
4892 REPLY_MACRO(VL_API_LISP_GPE_ENABLE_DISABLE_REPLY);
4896 vl_api_lisp_enable_disable_t_handler(
4897 vl_api_lisp_enable_disable_t *mp)
4899 vl_api_lisp_enable_disable_reply_t *rmp;
4902 vnet_lisp_enable_disable (mp->is_en);
4903 REPLY_MACRO(VL_API_LISP_ENABLE_DISABLE_REPLY);
4907 vl_api_lisp_gpe_add_del_iface_t_handler(
4908 vl_api_lisp_gpe_add_del_iface_t *mp)
4910 vl_api_lisp_gpe_add_del_iface_reply_t *rmp;
4912 vnet_lisp_gpe_add_del_iface_args_t _a, * a = &_a;
4914 a->is_add = mp->is_add;
4915 a->table_id = mp->table_id;
4917 vnet_lisp_gpe_add_del_iface (a, 0);
4919 REPLY_MACRO(VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
4923 vl_api_lisp_pitr_set_locator_set_t_handler(
4924 vl_api_lisp_pitr_set_locator_set_t *mp)
4926 vl_api_lisp_pitr_set_locator_set_reply_t *rmp;
4930 ls_name = format (0, "%s", mp->ls_name);
4931 rv = vnet_lisp_pitr_set_locator_set (ls_name, mp->is_add);
4934 REPLY_MACRO(VL_API_LISP_PITR_SET_LOCATOR_SET_REPLY);
4937 /** Used for transferring locators via VPP API */
4938 typedef CLIB_PACKED(struct
4940 u8 is_ip4; /**< is locator an IPv4 address */
4941 u8 addr[16]; /**< IPv4/IPv6 address */
4945 send_lisp_locator_set_details_set_address
4946 (vl_api_lisp_locator_set_details_t *rmp,
4947 gid_address_t *gid_address)
4949 ip_prefix_t *ip_addr;
4951 if (gid_address_type(gid_address) != GID_ADDR_IP_PREFIX) {
4955 ip_addr = &gid_address_ippref(gid_address);
4956 rmp->prefix_len = ip_prefix_len(ip_addr);
4957 rmp->is_ipv6 = ip_prefix_version(ip_addr);
4958 ip_address_copy_addr(rmp->ip_address, &ip_prefix_addr(ip_addr));
4962 vl_api_lisp_add_del_remote_mapping_t_handler (
4963 vl_api_lisp_add_del_remote_mapping_t *mp)
4966 ip_address_t rloc, * rlocs = 0;
4967 vl_api_lisp_add_del_remote_mapping_reply_t * rmp;
4969 gid_address_t _seid, * seid = &_seid;
4970 gid_address_t _deid, * deid = &_deid;
4971 ip_prefix_t * seid_pref = &gid_address_ippref(seid);
4972 ip_prefix_t * deid_pref = &gid_address_ippref(deid);
4974 gid_address_type(seid) = GID_ADDR_IP_PREFIX;
4975 gid_address_type(deid) = GID_ADDR_IP_PREFIX;
4976 ip_address_t * seid_addr = &ip_prefix_addr(seid_pref);
4977 ip_address_t * deid_addr = &ip_prefix_addr(deid_pref);
4978 ip_prefix_len(seid_pref) = mp->seid_len;
4979 ip_prefix_len(deid_pref) = mp->deid_len;
4980 gid_address_set_vni (seid, ntohl (mp->vni));
4981 gid_address_set_vni (deid, ntohl (mp->vni));
4983 if (mp->eid_is_ip4) {
4984 ip_prefix_version(seid_pref) = IP4;
4985 ip_prefix_version(deid_pref) = IP4;
4986 clib_memcpy (&ip_addr_v4(seid_addr),
4987 mp->seid, sizeof (ip_addr_v4(seid_addr)));
4988 clib_memcpy (&ip_addr_v4(deid_addr),
4989 mp->deid, sizeof (ip_addr_v4(deid_addr)));
4991 ip_prefix_version(seid_pref) = IP6;
4992 ip_prefix_version(deid_pref) = IP6;
4993 clib_memcpy (&ip_addr_v6(seid_addr),
4994 mp->seid, sizeof (ip_addr_v6(seid_addr)));
4995 clib_memcpy (&ip_addr_v6(deid_addr),
4996 mp->deid, sizeof (ip_addr_v6(deid_addr)));
4999 for (i = 0; i < mp->rloc_num; i++) {
5000 rloc_t * r = &((rloc_t *) mp->rlocs)[i];
5002 clib_memcpy (&ip_addr_v4(&rloc), &r->addr, sizeof (rloc_t));
5003 ip_addr_version (&rloc) = IP4;
5005 clib_memcpy (&ip_addr_v6(&rloc), &r->addr, sizeof (rloc_t));
5006 ip_addr_version (&rloc) = IP6;
5008 vec_add1 (rlocs, rloc);
5011 rv = vnet_lisp_add_del_remote_mapping (deid, seid, rlocs, mp->action,
5012 mp->is_add, mp->del_all);
5014 REPLY_MACRO(VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
5018 send_lisp_locator_set_details (lisp_cp_main_t *lcm,
5019 locator_set_t *lsit,
5020 unix_shared_memory_queue_t *q,
5024 vl_api_lisp_locator_set_details_t *rmp;
5025 locator_t *loc = NULL;
5029 vec_foreach (locit, lsit->locator_indices) {
5030 loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
5031 rmp = vl_msg_api_alloc (sizeof (*rmp));
5032 memset (rmp, 0, sizeof (*rmp));
5033 rmp->_vl_msg_id = ntohs(VL_API_LISP_LOCATOR_SET_DETAILS);
5034 rmp->local = lsit->local;
5036 ASSERT(lsit->name != NULL);
5037 strncpy((char *) rmp->locator_set_name,
5038 (char *) lsit->name, ARRAY_LEN(rmp->locator_set_name) - 1);
5039 rmp->sw_if_index = htonl(loc->sw_if_index);
5041 str = format(0, "remote-%d", index);
5042 strncpy((char *) rmp->locator_set_name, (char *) str,
5043 ARRAY_LEN(rmp->locator_set_name) - 1);
5044 send_lisp_locator_set_details_set_address(rmp, &loc->address);
5048 rmp->priority = loc->priority;
5049 rmp->weight = loc->weight;
5050 rmp->context = context;
5052 vl_msg_api_send_shmem (q, (u8 *)&rmp);
5057 vl_api_lisp_locator_set_dump_t_handler (vl_api_lisp_locator_set_dump_t *mp)
5059 unix_shared_memory_queue_t * q = NULL;
5060 lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
5061 locator_set_t * lsit = NULL;
5064 q = vl_api_client_index_to_input_queue (mp->client_index);
5070 pool_foreach (lsit, lcm->locator_set_pool,
5072 send_lisp_locator_set_details(lcm, lsit, q, mp->context, index++);
5077 send_lisp_local_eid_table_details (mapping_t *mapit,
5078 unix_shared_memory_queue_t *q,
5081 vl_api_lisp_local_eid_table_details_t *rmp = NULL;
5082 lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
5083 locator_set_t *ls = NULL;
5084 gid_address_t *gid = NULL;
5085 ip_prefix_t *ip_prefix = NULL;
5089 ls = pool_elt_at_index (lcm->locator_set_pool,
5090 mapit->locator_set_index);
5093 type = gid_address_type(gid);
5095 if (type != GID_ADDR_IP_PREFIX) {
5099 ip_prefix = &gid_address_ippref(gid);
5101 rmp = vl_msg_api_alloc (sizeof (*rmp));
5102 memset (rmp, 0, sizeof (*rmp));
5103 rmp->_vl_msg_id = ntohs(VL_API_LISP_LOCAL_EID_TABLE_DETAILS);
5105 ASSERT(ls->name != NULL);
5106 strncpy((char *) rmp->locator_set_name,
5107 (char *) ls->name, ARRAY_LEN(rmp->locator_set_name) - 1);
5109 str = format(0, "remote-%d", mapit->locator_set_index);
5110 strncpy((char *) rmp->locator_set_name, (char *) str,
5111 ARRAY_LEN(rmp->locator_set_name) - 1);
5115 switch (ip_prefix_version(ip_prefix)) {
5117 rmp->eid_is_ipv6 = 0;
5118 clib_memcpy(rmp->eid_ip_address, &ip_prefix_v4(ip_prefix),
5119 sizeof(ip_prefix_v4(ip_prefix)));
5123 rmp->eid_is_ipv6 = 1;
5124 clib_memcpy(rmp->eid_ip_address, &ip_prefix_v6(ip_prefix),
5125 sizeof(ip_prefix_v6(ip_prefix)));
5131 rmp->eid_prefix_len = ip_prefix_len(ip_prefix);
5132 rmp->context = context;
5134 vl_msg_api_send_shmem (q, (u8 *)&rmp);
5138 vl_api_lisp_local_eid_table_dump_t_handler (
5139 vl_api_lisp_local_eid_table_dump_t *mp)
5141 unix_shared_memory_queue_t * q = NULL;
5142 lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
5143 mapping_t * mapit = NULL;
5145 q = vl_api_client_index_to_input_queue (mp->client_index);
5150 pool_foreach (mapit, lcm->mapping_pool,
5152 send_lisp_local_eid_table_details(mapit, q, mp->context);
5157 send_lisp_gpe_tunnel_details (lisp_gpe_tunnel_t *tunnel,
5158 unix_shared_memory_queue_t *q,
5161 vl_api_lisp_gpe_tunnel_details_t *rmp;
5162 lisp_gpe_main_t * lgm = &lisp_gpe_main;
5164 rmp = vl_msg_api_alloc (sizeof (*rmp));
5165 memset (rmp, 0, sizeof (*rmp));
5166 rmp->_vl_msg_id = ntohs(VL_API_LISP_GPE_TUNNEL_DETAILS);
5168 rmp->tunnels = tunnel - lgm->tunnels;
5170 rmp->is_ipv6 = ip_addr_version(&tunnel->src) == IP6 ? 1 : 0;
5171 ip_address_copy_addr(rmp->source_ip, &tunnel->src);
5172 ip_address_copy_addr(rmp->destination_ip, &tunnel->dst);
5174 rmp->encap_fib_id = htonl(tunnel->encap_fib_index);
5175 rmp->decap_fib_id = htonl(tunnel->decap_fib_index);
5176 rmp->dcap_next = htonl(tunnel->decap_next_index);
5177 rmp->lisp_ver = tunnel->ver_res;
5178 rmp->next_protocol = tunnel->next_protocol;
5179 rmp->flags = tunnel->flags;
5180 rmp->ver_res = tunnel->ver_res;
5181 rmp->res = tunnel->res;
5182 rmp->iid = htonl(tunnel->vni);
5183 rmp->context = context;
5185 vl_msg_api_send_shmem (q, (u8 *)&rmp);
5189 vl_api_lisp_gpe_tunnel_dump_t_handler (
5190 vl_api_lisp_local_eid_table_dump_t *mp)
5192 unix_shared_memory_queue_t * q = NULL;
5193 lisp_gpe_main_t * lgm = &lisp_gpe_main;
5194 lisp_gpe_tunnel_t * tunnel = NULL;
5196 if (pool_elts(lgm->tunnels) == 0) {
5200 q = vl_api_client_index_to_input_queue (mp->client_index);
5205 pool_foreach(tunnel, lgm->tunnels,
5207 send_lisp_gpe_tunnel_details(tunnel, q, mp->context);
5212 send_lisp_map_resolver_details (ip_address_t *ip,
5213 unix_shared_memory_queue_t *q,
5216 vl_api_lisp_map_resolver_details_t *rmp = NULL;
5218 rmp = vl_msg_api_alloc (sizeof (*rmp));
5219 memset (rmp, 0, sizeof (*rmp));
5220 rmp->_vl_msg_id = ntohs(VL_API_LISP_MAP_RESOLVER_DETAILS);
5222 switch (ip_addr_version(ip)) {
5225 clib_memcpy(rmp->ip_address, &ip_addr_v4(ip), sizeof(ip_addr_v4(ip)));
5230 clib_memcpy(rmp->ip_address, &ip_addr_v6(ip), sizeof(ip_addr_v6(ip)));
5236 rmp->context = context;
5238 vl_msg_api_send_shmem (q, (u8 *)&rmp);
5242 vl_api_lisp_map_resolver_dump_t_handler (
5243 vl_api_lisp_local_eid_table_dump_t *mp)
5245 unix_shared_memory_queue_t * q = NULL;
5246 lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
5247 ip_address_t *ip = NULL;
5249 q = vl_api_client_index_to_input_queue (mp->client_index);
5254 vec_foreach(ip, lcm->map_resolvers) {
5255 send_lisp_map_resolver_details(ip, q, mp->context);
5261 send_lisp_enable_disable_details (unix_shared_memory_queue_t *q,
5264 vl_api_lisp_enable_disable_status_details_t *rmp = NULL;
5266 rmp = vl_msg_api_alloc (sizeof (*rmp));
5267 memset (rmp, 0, sizeof (*rmp));
5268 rmp->_vl_msg_id = ntohs(VL_API_LISP_ENABLE_DISABLE_STATUS_DETAILS);
5270 rmp->gpe_status = vnet_lisp_gpe_enable_disable_status ();
5271 rmp->feature_status = vnet_lisp_enable_disable_status ();
5272 rmp->context = context;
5274 vl_msg_api_send_shmem (q, (u8 *)&rmp);
5278 vl_api_lisp_enable_disable_status_dump_t_handler
5279 (vl_api_lisp_enable_disable_status_dump_t *mp)
5281 unix_shared_memory_queue_t * q = NULL;
5283 q = vl_api_client_index_to_input_queue (mp->client_index);
5288 send_lisp_enable_disable_details(q, mp->context);
5292 vl_api_interface_name_renumber_t_handler (vl_api_interface_name_renumber_t *mp)
5294 vl_api_interface_name_renumber_reply_t * rmp;
5297 VALIDATE_SW_IF_INDEX(mp);
5299 rv = vnet_interface_name_renumber
5300 (ntohl(mp->sw_if_index), ntohl(mp->new_show_dev_instance));
5302 BAD_SW_IF_INDEX_LABEL;
5304 REPLY_MACRO(VL_API_INTERFACE_NAME_RENUMBER_REPLY);
5307 static int arp_change_data_callback (u32 pool_index, u8 * new_mac,
5308 u32 sw_if_index, u32 address)
5310 vpe_api_main_t * am = &vpe_api_main;
5311 vlib_main_t * vm = am->vlib_main;
5312 vl_api_ip4_arp_event_t * event;
5313 static f64 arp_event_last_time;
5314 f64 now = vlib_time_now (vm);
5316 if (pool_is_free_index (am->arp_events, pool_index))
5319 event = pool_elt_at_index (am->arp_events, pool_index);
5320 if (memcmp (&event->new_mac, new_mac, sizeof (event->new_mac))) {
5321 clib_memcpy (event->new_mac, new_mac, sizeof(event->new_mac));
5322 } else { /* same mac */
5323 if ((sw_if_index == event->sw_if_index) &&
5325 /* for BD case, also check IP address with 10 sec timeout */
5326 ((address == event->address) &&
5327 ((now - arp_event_last_time) < 10.0))))
5331 arp_event_last_time = now;
5332 event->sw_if_index = sw_if_index;
5333 if (address) event->address = address;
5337 static int arp_change_delete_callback (u32 pool_index, u8 * notused)
5339 vpe_api_main_t * am = &vpe_api_main;
5341 if (pool_is_free_index (am->arp_events, pool_index))
5344 pool_put_index (am->arp_events, pool_index);
5349 vl_api_want_ip4_arp_events_t_handler
5350 (vl_api_want_ip4_arp_events_t * mp)
5352 vpe_api_main_t * am = &vpe_api_main;
5353 vnet_main_t * vnm = vnet_get_main();
5354 vl_api_want_ip4_arp_events_reply_t *rmp;
5355 vl_api_ip4_arp_event_t * event;
5358 if (mp->enable_disable) {
5359 pool_get (am->arp_events, event);
5360 memset (event, 0, sizeof (*event));
5362 event->_vl_msg_id = ntohs(VL_API_IP4_ARP_EVENT);
5363 event->client_index = mp->client_index;
5364 event->context = mp->context;
5365 event->address = mp->address;
5366 event->pid = mp->pid;
5368 rv = vnet_add_del_ip4_arp_change_event
5369 (vnm, arp_change_data_callback,
5371 &mp->address /* addr, in net byte order */,
5372 vpe_resolver_process_node.index,
5373 IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */);
5375 rv = vnet_add_del_ip4_arp_change_event
5376 (vnm, arp_change_delete_callback,
5378 &mp->address /* addr, in net byte order */,
5379 vpe_resolver_process_node.index,
5380 IP4_ARP_EVENT, ~0 /* pool index */, 0 /* is_add */);
5382 REPLY_MACRO(VL_API_WANT_IP4_ARP_EVENTS_REPLY);
5385 static void vl_api_input_acl_set_interface_t_handler
5386 (vl_api_input_acl_set_interface_t * mp)
5388 vlib_main_t *vm = vlib_get_main();
5389 vl_api_input_acl_set_interface_reply_t * rmp;
5391 u32 sw_if_index, ip4_table_index, ip6_table_index, l2_table_index;
5393 ip4_table_index = ntohl(mp->ip4_table_index);
5394 ip6_table_index = ntohl(mp->ip6_table_index);
5395 l2_table_index = ntohl(mp->l2_table_index);
5396 sw_if_index = ntohl(mp->sw_if_index);
5398 VALIDATE_SW_IF_INDEX(mp);
5400 rv = vnet_set_input_acl_intfc (vm, sw_if_index, ip4_table_index,
5401 ip6_table_index, l2_table_index,
5404 BAD_SW_IF_INDEX_LABEL;
5406 REPLY_MACRO(VL_API_INPUT_ACL_SET_INTERFACE_REPLY);
5409 static void vl_api_ipsec_spd_add_del_t_handler
5410 (vl_api_ipsec_spd_add_del_t * mp)
5413 clib_warning ("unimplemented");
5416 vlib_main_t *vm __attribute__((unused)) = vlib_get_main();
5417 vl_api_ipsec_spd_add_del_reply_t * rmp;
5421 rv = ipsec_add_del_spd (vm, ntohl(mp->spd_id), mp->is_add);
5423 rv = VNET_API_ERROR_UNIMPLEMENTED;
5426 REPLY_MACRO(VL_API_IPSEC_SPD_ADD_DEL_REPLY);
5430 static void vl_api_ipsec_interface_add_del_spd_t_handler
5431 (vl_api_ipsec_interface_add_del_spd_t * mp)
5433 vlib_main_t *vm __attribute__((unused)) = vlib_get_main();
5434 vl_api_ipsec_interface_add_del_spd_reply_t * rmp;
5436 u32 sw_if_index __attribute__((unused));
5437 u32 spd_id __attribute__((unused));
5439 sw_if_index = ntohl(mp->sw_if_index);
5440 spd_id = ntohl(mp->spd_id);
5442 VALIDATE_SW_IF_INDEX(mp);
5445 rv = ipsec_set_interface_spd(vm, sw_if_index, spd_id, mp->is_add);
5447 rv = VNET_API_ERROR_UNIMPLEMENTED;
5450 BAD_SW_IF_INDEX_LABEL;
5452 REPLY_MACRO(VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY);
5455 static void vl_api_ipsec_spd_add_del_entry_t_handler
5456 (vl_api_ipsec_spd_add_del_entry_t * mp)
5458 vlib_main_t *vm __attribute__((unused)) = vlib_get_main();
5459 vl_api_ipsec_spd_add_del_entry_reply_t * rmp;
5465 memset(&p, 0, sizeof(p));
5467 p.id = ntohl(mp->spd_id);
5468 p.priority = ntohl(mp->priority);
5469 p.is_outbound = mp->is_outbound;
5470 p.is_ipv6 = mp->is_ipv6;
5472 clib_memcpy(&p.raddr.start, mp->remote_address_start, 16);
5473 clib_memcpy(&p.raddr.stop, mp->remote_address_stop, 16);
5474 clib_memcpy(&p.laddr.start, mp->local_address_start, 16);
5475 clib_memcpy(&p.laddr.stop, mp->local_address_stop, 16);
5477 p.protocol = mp->protocol;
5478 p.rport.start = ntohs(mp->remote_port_start);
5479 p.rport.stop = ntohs(mp->remote_port_stop);
5480 p.lport.start = ntohs(mp->local_port_start);
5481 p.lport.stop = ntohs(mp->local_port_stop);
5482 /* policy action resolve unsupported */
5483 if (mp->policy == IPSEC_POLICY_ACTION_RESOLVE) {
5484 clib_warning("unsupported action: 'resolve'");
5485 rv = VNET_API_ERROR_UNIMPLEMENTED;
5488 p.policy = mp->policy;
5489 p.sa_id = ntohl(mp->sa_id);
5491 rv = ipsec_add_del_policy(vm, &p, mp->is_add);
5495 if (mp->is_ip_any) {
5497 rv = ipsec_add_del_policy(vm, &p, mp->is_add);
5500 rv = VNET_API_ERROR_UNIMPLEMENTED;
5505 REPLY_MACRO(VL_API_IPSEC_SPD_ADD_DEL_ENTRY_REPLY);
5508 static void vl_api_ipsec_sad_add_del_entry_t_handler
5509 (vl_api_ipsec_sad_add_del_entry_t * mp)
5511 vlib_main_t *vm __attribute__((unused)) = vlib_get_main();
5512 vl_api_ipsec_sad_add_del_entry_reply_t * rmp;
5517 memset(&sa, 0, sizeof(sa));
5519 sa.id = ntohl(mp->sad_id);
5520 sa.spi = ntohl(mp->spi);
5521 /* security protocol AH unsupported */
5522 if (mp->protocol == IPSEC_PROTOCOL_AH) {
5523 clib_warning("unsupported security protocol 'AH'");
5524 rv = VNET_API_ERROR_UNIMPLEMENTED;
5527 sa.protocol = mp->protocol;
5528 /* check for unsupported crypto-alg */
5529 if (mp->crypto_algorithm < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
5530 mp->crypto_algorithm > IPSEC_CRYPTO_ALG_AES_CBC_256) {
5531 clib_warning("unsupported crypto-alg: '%U'", format_ipsec_crypto_alg,
5532 mp->crypto_algorithm);
5533 rv = VNET_API_ERROR_UNIMPLEMENTED;
5536 sa.crypto_alg = mp->crypto_algorithm;
5537 sa.crypto_key_len = mp->crypto_key_length;
5538 clib_memcpy(&sa.crypto_key, mp->crypto_key, sizeof(sa.crypto_key));
5539 /* check for unsupported integ-alg */
5540 if (mp->integrity_algorithm < IPSEC_INTEG_ALG_SHA1_96 ||
5541 mp->integrity_algorithm > IPSEC_INTEG_ALG_SHA_512_256) {
5542 clib_warning("unsupported integ-alg: '%U'", format_ipsec_integ_alg,
5543 mp->integrity_algorithm);
5544 rv = VNET_API_ERROR_UNIMPLEMENTED;
5547 sa.integ_alg = mp->integrity_algorithm;
5548 sa.integ_key_len = mp->integrity_key_length;
5549 clib_memcpy(&sa.integ_key, mp->integrity_key, sizeof(sa.integ_key));
5550 sa.use_esn = mp->use_extended_sequence_number;
5551 sa.is_tunnel = mp->is_tunnel;
5552 sa.is_tunnel_ip6 = mp->is_tunnel_ipv6;
5553 clib_memcpy(&sa.tunnel_src_addr, mp->tunnel_src_address, 16);
5554 clib_memcpy(&sa.tunnel_dst_addr, mp->tunnel_dst_address, 16);
5556 rv = ipsec_add_del_sa(vm, &sa, mp->is_add);
5558 rv = VNET_API_ERROR_UNIMPLEMENTED;
5563 REPLY_MACRO(VL_API_IPSEC_SAD_ADD_DEL_ENTRY_REPLY);
5567 vl_api_ikev2_profile_add_del_t_handler
5568 (vl_api_ikev2_profile_add_del_t * mp)
5570 vl_api_ikev2_profile_add_del_reply_t * rmp;
5574 vlib_main_t * vm = vlib_get_main();
5575 clib_error_t * error;
5576 u8 * tmp = format(0, "%s", mp->name);
5577 error = ikev2_add_del_profile(vm, tmp, mp->is_add);
5580 rv = VNET_API_ERROR_UNSPECIFIED;
5582 rv = VNET_API_ERROR_UNIMPLEMENTED;
5585 REPLY_MACRO(VL_API_IKEV2_PROFILE_ADD_DEL_REPLY);
5589 vl_api_ikev2_profile_set_auth_t_handler
5590 (vl_api_ikev2_profile_set_auth_t * mp)
5592 vl_api_ikev2_profile_set_auth_reply_t * rmp;
5596 vlib_main_t * vm = vlib_get_main();
5597 clib_error_t * error;
5598 u8 * tmp = format(0, "%s", mp->name);
5599 u8 * data = vec_new (u8, mp->data_len);
5600 clib_memcpy(data, mp->data, mp->data_len);
5601 error = ikev2_set_profile_auth(vm, tmp, mp->auth_method, data, mp->is_hex);
5605 rv = VNET_API_ERROR_UNSPECIFIED;
5607 rv = VNET_API_ERROR_UNIMPLEMENTED;
5610 REPLY_MACRO(VL_API_IKEV2_PROFILE_SET_AUTH_REPLY);
5614 vl_api_ikev2_profile_set_id_t_handler
5615 (vl_api_ikev2_profile_set_id_t * mp)
5617 vl_api_ikev2_profile_add_del_reply_t * rmp;
5621 vlib_main_t * vm = vlib_get_main();
5622 clib_error_t * error;
5623 u8 * tmp = format(0, "%s", mp->name);
5624 u8 * data = vec_new (u8, mp->data_len);
5625 clib_memcpy(data, mp->data, mp->data_len);
5626 error = ikev2_set_profile_id(vm, tmp, mp->id_type, data, mp->is_local);
5630 rv = VNET_API_ERROR_UNSPECIFIED;
5632 rv = VNET_API_ERROR_UNIMPLEMENTED;
5635 REPLY_MACRO(VL_API_IKEV2_PROFILE_SET_ID_REPLY);
5639 vl_api_ikev2_profile_set_ts_t_handler
5640 (vl_api_ikev2_profile_set_ts_t * mp)
5642 vl_api_ikev2_profile_set_ts_reply_t * rmp;
5646 vlib_main_t * vm = vlib_get_main();
5647 clib_error_t * error;
5648 u8 * tmp = format(0, "%s", mp->name);
5649 error = ikev2_set_profile_ts(vm, tmp, mp->proto, mp->start_port,
5650 mp->end_port, (ip4_address_t) mp->start_addr,
5651 (ip4_address_t) mp->end_addr, mp->is_local);
5654 rv = VNET_API_ERROR_UNSPECIFIED;
5656 rv = VNET_API_ERROR_UNIMPLEMENTED;
5659 REPLY_MACRO(VL_API_IKEV2_PROFILE_SET_TS_REPLY);
5663 vl_api_ikev2_set_local_key_t_handler
5664 (vl_api_ikev2_set_local_key_t * mp)
5666 vl_api_ikev2_profile_set_ts_reply_t * rmp;
5670 vlib_main_t * vm = vlib_get_main();
5671 clib_error_t * error;
5673 error = ikev2_set_local_key(vm, mp->key_file);
5675 rv = VNET_API_ERROR_UNSPECIFIED;
5677 rv = VNET_API_ERROR_UNIMPLEMENTED;
5680 REPLY_MACRO(VL_API_IKEV2_SET_LOCAL_KEY_REPLY);
5684 vl_api_map_add_domain_t_handler
5685 (vl_api_map_add_domain_t * mp)
5687 vl_api_map_add_domain_reply_t * rmp;
5690 u8 flags = mp->is_translation ? MAP_DOMAIN_TRANSLATION : 0;
5691 rv = map_create_domain((ip4_address_t *)&mp->ip4_prefix, mp->ip4_prefix_len,
5692 (ip6_address_t *)&mp->ip6_prefix, mp->ip6_prefix_len,
5693 (ip6_address_t *)&mp->ip6_src, mp->ip6_src_prefix_len,
5694 mp->ea_bits_len, mp->psid_offset, mp->psid_length, &index, ntohs(mp->mtu), flags);
5696 REPLY_MACRO2(VL_API_MAP_ADD_DOMAIN_REPLY,
5698 rmp->index = ntohl(index);
5703 vl_api_map_del_domain_t_handler
5704 (vl_api_map_del_domain_t * mp)
5706 vl_api_map_del_domain_reply_t * rmp;
5709 rv = map_delete_domain(ntohl(mp->index));
5711 REPLY_MACRO(VL_API_MAP_DEL_DOMAIN_REPLY);
5715 vl_api_map_add_del_rule_t_handler
5716 (vl_api_map_add_del_rule_t * mp)
5718 vl_api_map_del_domain_reply_t * rmp;
5721 rv = map_add_del_psid(ntohl(mp->index), ntohs(mp->psid), (ip6_address_t *)mp->ip6_dst, mp->is_add);
5723 REPLY_MACRO(VL_API_MAP_ADD_DEL_RULE_REPLY);
5727 vl_api_map_domain_dump_t_handler
5728 (vl_api_map_domain_dump_t * mp)
5730 vl_api_map_domain_details_t * rmp;
5731 map_main_t *mm = &map_main;
5733 unix_shared_memory_queue_t * q;
5735 if (pool_elts (mm->domains) == 0)
5738 q = vl_api_client_index_to_input_queue (mp->client_index);
5743 pool_foreach(d, mm->domains, ({
5744 /* Make sure every field is initiated (or don't skip the memset()) */
5745 rmp = vl_msg_api_alloc (sizeof (*rmp));
5746 rmp->_vl_msg_id = ntohs(VL_API_MAP_DOMAIN_DETAILS);
5747 rmp->domain_index = htonl(d - mm->domains);
5748 rmp->ea_bits_len = d->ea_bits_len;
5749 rmp->psid_offset = d->psid_offset;
5750 rmp->psid_length = d->psid_length;
5751 clib_memcpy(rmp->ip4_prefix, &d->ip4_prefix, sizeof(rmp->ip4_prefix));
5752 rmp->ip4_prefix_len = d->ip4_prefix_len;
5753 clib_memcpy(rmp->ip6_prefix, &d->ip6_prefix, sizeof(rmp->ip6_prefix));
5754 rmp->ip6_prefix_len = d->ip6_prefix_len;
5755 clib_memcpy(rmp->ip6_src, &d->ip6_src, sizeof(rmp->ip6_src));
5756 rmp->ip6_src_len = d->ip6_src_len;
5757 rmp->mtu = htons(d->mtu);
5758 rmp->is_translation = (d->flags & MAP_DOMAIN_TRANSLATION);
5759 rmp->context = mp->context;
5761 vl_msg_api_send_shmem (q, (u8 *)&rmp);
5766 vl_api_map_rule_dump_t_handler
5767 (vl_api_map_rule_dump_t * mp)
5769 unix_shared_memory_queue_t * q;
5772 vl_api_map_rule_details_t * rmp;
5773 map_main_t *mm = &map_main;
5774 u32 domain_index = ntohl(mp->domain_index);
5777 if (pool_elts (mm->domains) == 0)
5780 d = pool_elt_at_index(mm->domains, domain_index);
5781 if (!d || !d->rules) {
5785 q = vl_api_client_index_to_input_queue (mp->client_index);
5790 for (i = 0; i < (0x1 << d->psid_length); i++) {
5792 if (dst.as_u64[0] == 0 && dst.as_u64[1] == 0) {
5795 rmp = vl_msg_api_alloc(sizeof(*rmp));
5796 memset(rmp, 0, sizeof(*rmp));
5797 rmp->_vl_msg_id = ntohs(VL_API_MAP_RULE_DETAILS);
5798 rmp->psid = htons(i);
5799 clib_memcpy(rmp->ip6_dst, &dst, sizeof(rmp->ip6_dst));
5800 rmp->context = mp->context;
5801 vl_msg_api_send_shmem(q, (u8 *)&rmp);
5806 vl_api_map_summary_stats_t_handler (
5807 vl_api_map_summary_stats_t *mp)
5809 vl_api_map_summary_stats_reply_t *rmp;
5810 vlib_combined_counter_main_t *cm;
5813 u64 total_pkts[VLIB_N_RX_TX];
5814 u64 total_bytes[VLIB_N_RX_TX];
5815 map_main_t *mm = &map_main;
5816 unix_shared_memory_queue_t *q =
5817 vl_api_client_index_to_input_queue(mp->client_index);
5822 rmp = vl_msg_api_alloc (sizeof (*rmp));
5823 rmp->_vl_msg_id = ntohs(VL_API_MAP_SUMMARY_STATS_REPLY);
5824 rmp->context = mp->context;
5827 memset (total_pkts, 0, sizeof (total_pkts));
5828 memset (total_bytes, 0, sizeof (total_bytes));
5830 map_domain_counter_lock (mm);
5831 vec_foreach(cm, mm->domain_counters) {
5832 which = cm - mm->domain_counters;
5834 for (i = 0; i < vec_len(cm->maxi); i++) {
5835 vlib_get_combined_counter (cm, i, &v);
5836 total_pkts[which] += v.packets;
5837 total_bytes[which] += v.bytes;
5841 map_domain_counter_unlock (mm);
5843 /* Note: in network byte order! */
5844 rmp->total_pkts[MAP_DOMAIN_COUNTER_RX] = clib_host_to_net_u64(total_pkts[MAP_DOMAIN_COUNTER_RX]);
5845 rmp->total_bytes[MAP_DOMAIN_COUNTER_RX] = clib_host_to_net_u64(total_bytes[MAP_DOMAIN_COUNTER_RX]);
5846 rmp->total_pkts[MAP_DOMAIN_COUNTER_TX] = clib_host_to_net_u64(total_pkts[MAP_DOMAIN_COUNTER_TX]);
5847 rmp->total_bytes[MAP_DOMAIN_COUNTER_TX] = clib_host_to_net_u64(total_bytes[MAP_DOMAIN_COUNTER_TX]);
5848 rmp->total_bindings = clib_host_to_net_u64(pool_elts(mm->domains));
5849 rmp->total_ip4_fragments = 0; // Not yet implemented. Should be a simple counter.
5850 rmp->total_security_check[MAP_DOMAIN_COUNTER_TX] = clib_host_to_net_u64(map_error_counter_get(ip4_map_node.index, MAP_ERROR_ENCAP_SEC_CHECK));
5851 rmp->total_security_check[MAP_DOMAIN_COUNTER_RX] = clib_host_to_net_u64(map_error_counter_get(ip4_map_node.index, MAP_ERROR_DECAP_SEC_CHECK));
5853 vl_msg_api_send_shmem(q, (u8 *)&rmp);
5856 static void vl_api_ipsec_sa_set_key_t_handler
5857 (vl_api_ipsec_sa_set_key_t * mp)
5859 vlib_main_t *vm __attribute__((unused)) = vlib_get_main();
5860 vl_api_ipsec_sa_set_key_reply_t *rmp;
5864 sa.id = ntohl(mp->sa_id);
5865 sa.crypto_key_len = mp->crypto_key_length;
5866 clib_memcpy(&sa.crypto_key, mp->crypto_key, sizeof(sa.crypto_key));
5867 sa.integ_key_len = mp->integrity_key_length;
5868 clib_memcpy(&sa.integ_key, mp->integrity_key, sizeof(sa.integ_key));
5870 rv = ipsec_set_sa_key(vm, &sa);
5872 rv = VNET_API_ERROR_UNIMPLEMENTED;
5875 REPLY_MACRO(VL_API_IPSEC_SA_SET_KEY_REPLY);
5878 static void vl_api_cop_interface_enable_disable_t_handler
5879 (vl_api_cop_interface_enable_disable_t * mp)
5881 vl_api_cop_interface_enable_disable_reply_t * rmp;
5883 u32 sw_if_index = ntohl(mp->sw_if_index);
5886 VALIDATE_SW_IF_INDEX(mp);
5888 enable_disable = (int) mp->enable_disable;
5890 rv = cop_interface_enable_disable (sw_if_index, enable_disable);
5892 BAD_SW_IF_INDEX_LABEL;
5894 REPLY_MACRO(VL_API_COP_INTERFACE_ENABLE_DISABLE_REPLY);
5897 static void vl_api_cop_whitelist_enable_disable_t_handler
5898 (vl_api_cop_whitelist_enable_disable_t * mp)
5900 vl_api_cop_whitelist_enable_disable_reply_t * rmp;
5901 cop_whitelist_enable_disable_args_t _a, *a=&_a;
5902 u32 sw_if_index = ntohl(mp->sw_if_index);
5905 VALIDATE_SW_IF_INDEX(mp);
5907 a->sw_if_index = sw_if_index;
5910 a->default_cop = mp->default_cop;
5911 a->fib_id = ntohl(mp->fib_id);
5913 rv = cop_whitelist_enable_disable (a);
5915 BAD_SW_IF_INDEX_LABEL;
5917 REPLY_MACRO(VL_API_COP_WHITELIST_ENABLE_DISABLE_REPLY);
5920 static void vl_api_get_node_graph_t_handler
5921 (vl_api_get_node_graph_t * mp)
5925 api_main_t * am = &api_main;
5926 vlib_main_t * vm = vlib_get_main();
5928 vl_api_get_node_graph_reply_t * rmp;
5930 pthread_mutex_lock (&am->vlib_rp->mutex);
5931 oldheap = svm_push_data_heap (am->vlib_rp);
5934 * Keep the number of memcpy ops to a minimum (e.g. 1).
5936 vec_validate (vector, 16384);
5937 vec_reset_length (vector);
5940 vector = vlib_node_serialize (&vm->node_main, vector,
5941 (u32)~0 /* all threads */,
5942 1 /* include nexts */,
5943 1 /* include stats */);
5945 svm_pop_heap (oldheap);
5946 pthread_mutex_unlock (&am->vlib_rp->mutex);
5948 REPLY_MACRO2(VL_API_GET_NODE_GRAPH_REPLY,
5949 rmp->reply_in_shmem = (uword) vector);
5952 static void vl_api_trace_profile_add_t_handler
5953 (vl_api_trace_profile_add_t *mp)
5956 vl_api_trace_profile_add_reply_t * rmp;
5957 clib_error_t *error;
5959 /* Ignoring the profile id as currently a single profile
5961 error = ip6_ioam_trace_profile_set(mp->trace_num_elt, mp->trace_type,
5962 ntohl(mp->node_id), ntohl(mp->trace_app_data),
5963 mp->pow_enable, mp->trace_tsp,
5966 clib_error_report(error);
5967 rv = clib_error_get_code(error);
5970 REPLY_MACRO(VL_API_TRACE_PROFILE_ADD_REPLY);
5973 static void vl_api_trace_profile_apply_t_handler
5974 (vl_api_trace_profile_apply_t *mp)
5977 vl_api_trace_profile_apply_reply_t * rmp;
5979 if (mp->enable != 0) {
5980 rv = ip6_ioam_set_destination ((ip6_address_t *)(&mp->dest_ipv6),
5981 ntohl(mp->prefix_length),
5983 mp->trace_op == IOAM_HBYH_ADD,
5984 mp->trace_op == IOAM_HBYH_POP,
5985 mp->trace_op == IOAM_HBYH_MOD);
5987 //ip6_ioam_clear_destination(&ip6, mp->prefix_length, mp->vrf_id);
5989 REPLY_MACRO(VL_API_TRACE_PROFILE_APPLY_REPLY);
5992 static void vl_api_trace_profile_del_t_handler
5993 (vl_api_trace_profile_del_t *mp)
5996 vl_api_trace_profile_del_reply_t * rmp;
5997 clib_error_t *error;
5999 error = clear_ioam_rewrite_fn();
6001 clib_error_report(error);
6002 rv = clib_error_get_code(error);
6005 REPLY_MACRO(VL_API_TRACE_PROFILE_DEL_REPLY);
6009 vl_api_af_packet_create_t_handler
6010 (vl_api_af_packet_create_t *mp)
6012 vlib_main_t *vm = vlib_get_main();
6013 vl_api_af_packet_create_reply_t *rmp;
6015 u8 *host_if_name = NULL;
6018 host_if_name = format(0, "%s", mp->host_if_name);
6019 vec_add1 (host_if_name, 0);
6021 rv = af_packet_create_if(vm, host_if_name,
6022 mp->use_random_hw_addr ? 0 : mp->hw_addr, &sw_if_index);
6024 vec_free(host_if_name);
6026 REPLY_MACRO2(VL_API_AF_PACKET_CREATE_REPLY,
6027 rmp->sw_if_index = clib_host_to_net_u32(sw_if_index));
6031 vl_api_af_packet_delete_t_handler
6032 (vl_api_af_packet_delete_t *mp)
6034 vlib_main_t * vm = vlib_get_main();
6035 vl_api_af_packet_delete_reply_t *rmp;
6037 u8 *host_if_name = NULL;
6039 host_if_name = format(0, "%s", mp->host_if_name);
6040 vec_add1 (host_if_name, 0);
6042 rv = af_packet_delete_if(vm, host_if_name);
6044 vec_free(host_if_name);
6046 REPLY_MACRO(VL_API_AF_PACKET_DELETE_REPLY);
6050 vl_api_policer_add_del_t_handler
6051 (vl_api_policer_add_del_t *mp)
6053 vlib_main_t * vm = vlib_get_main();
6054 vl_api_policer_add_del_reply_t *rmp;
6057 sse2_qos_pol_cfg_params_st cfg;
6058 clib_error_t * error;
6060 name = format(0, "%s", mp->name);
6062 memset (&cfg, 0, sizeof (cfg));
6064 cfg.rnd_type = mp->round_type;
6065 cfg.rate_type = mp->rate_type;
6066 cfg.rb.kbps.cir_kbps = mp->cir;
6067 cfg.rb.kbps.eir_kbps = mp->eir;
6068 cfg.rb.kbps.cb_bytes = mp->cb;
6069 cfg.rb.kbps.eb_bytes = mp->eb;
6071 error = policer_add_del(vm, name, &cfg, mp->is_add);
6074 rv = VNET_API_ERROR_UNSPECIFIED;
6076 REPLY_MACRO(VL_API_POLICER_ADD_DEL_REPLY);
6080 send_policer_details (u8 *name,
6081 sse2_qos_pol_cfg_params_st *config,
6082 policer_read_response_type_st *templ,
6083 unix_shared_memory_queue_t *q,
6086 vl_api_policer_details_t * mp;
6088 mp = vl_msg_api_alloc (sizeof (*mp));
6089 memset (mp, 0, sizeof (*mp));
6090 mp->_vl_msg_id = ntohs (VL_API_POLICER_DETAILS);
6091 mp->context = context;
6092 mp->cir = htonl(config->rb.kbps.cir_kbps);
6093 mp->eir = htonl(config->rb.kbps.eir_kbps);
6094 mp->cb = htonl(config->rb.kbps.cb_bytes);
6095 mp->eb = htonl(config->rb.kbps.eb_bytes);
6096 mp->rate_type = config->rate_type;
6097 mp->round_type = config->rnd_type;
6098 mp->type = config->rfc;
6099 mp->single_rate = templ->single_rate ? 1 : 0;
6100 mp->color_aware = templ->color_aware ? 1 : 0;
6101 mp->scale = htonl(templ->scale);
6102 mp->cir_tokens_per_period = htonl(templ->cir_tokens_per_period);
6103 mp->pir_tokens_per_period = htonl(templ->pir_tokens_per_period);
6104 mp->current_limit = htonl(templ->current_limit);
6105 mp->current_bucket = htonl(templ->current_bucket);
6106 mp->extended_limit = htonl(templ->extended_limit);
6107 mp->extended_bucket = htonl(templ->extended_bucket);
6108 mp->last_update_time = clib_host_to_net_u64(templ->last_update_time);
6110 strncpy ((char *) mp->name, (char *) name, ARRAY_LEN(mp->name) - 1);
6112 vl_msg_api_send_shmem (q, (u8 *)&mp);
6116 vl_api_policer_dump_t_handler
6117 (vl_api_policer_dump_t *mp)
6119 unix_shared_memory_queue_t * q;
6120 vnet_policer_main_t * pm = &vnet_policer_main;
6124 u8 * match_name = 0;
6126 sse2_qos_pol_cfg_params_st *config;
6127 policer_read_response_type_st *templ;
6129 q = vl_api_client_index_to_input_queue (mp->client_index);
6133 if (mp->match_name_valid) {
6134 match_name = format(0, "%s%c", mp->match_name, 0);
6137 if (mp->match_name_valid) {
6138 p = hash_get_mem (pm->policer_config_by_name, match_name);
6141 config = pool_elt_at_index (pm->configs, pool_index);
6142 templ = pool_elt_at_index (pm->policer_templates, pool_index);
6143 send_policer_details(match_name, config, templ, q, mp->context);
6146 hash_foreach_pair (hp, pm->policer_config_by_name,
6148 name = (u8 *) hp->key;
6149 pool_index = hp->value[0];
6150 config = pool_elt_at_index (pm->configs, pool_index);
6151 templ = pool_elt_at_index (pm->policer_templates, pool_index);
6152 send_policer_details(name, config, templ, q, mp->context);
6158 vl_api_netmap_create_t_handler
6159 (vl_api_netmap_create_t *mp)
6161 vlib_main_t *vm = vlib_get_main();
6162 vl_api_netmap_create_reply_t *rmp;
6166 if_name = format(0, "%s", mp->netmap_if_name);
6167 vec_add1 (if_name, 0);
6169 rv = netmap_create_if(vm, if_name, mp->use_random_hw_addr ? 0 : mp->hw_addr,
6170 mp->is_pipe, mp->is_master, 0);
6174 REPLY_MACRO(VL_API_NETMAP_CREATE_REPLY);
6178 vl_api_netmap_delete_t_handler
6179 (vl_api_netmap_delete_t *mp)
6181 vlib_main_t * vm = vlib_get_main();
6182 vl_api_netmap_delete_reply_t *rmp;
6186 if_name = format(0, "%s", mp->netmap_if_name);
6187 vec_add1 (if_name, 0);
6189 rv = netmap_delete_if(vm, if_name);
6193 REPLY_MACRO(VL_API_NETMAP_DELETE_REPLY);
6196 #define BOUNCE_HANDLER(nn) \
6197 static void vl_api_##nn##_t_handler ( \
6198 vl_api_##nn##_t *mp) \
6200 vpe_client_registration_t *reg; \
6201 vpe_api_main_t * vam = &vpe_api_main; \
6202 unix_shared_memory_queue_t * q; \
6204 /* One registration only... */ \
6205 pool_foreach(reg, vam->nn##_registrations, \
6207 q = vl_api_client_index_to_input_queue (reg->client_index); \
6210 * If the queue is stuffed, turf the msg and complain \
6211 * It's unlikely that the intended recipient is \
6212 * alive; avoid deadlock at all costs. \
6214 if (q->cursize == q->maxsize) { \
6215 clib_warning ("ERROR: receiver queue full, drop msg"); \
6216 vl_msg_api_free (mp); \
6219 vl_msg_api_send_shmem (q, (u8 *)&mp); \
6223 vl_msg_api_free (mp); \
6228 * Add vpe's API message handlers to the table.
6229 * vlib has alread mapped shared memory and
6230 * added the client registration handlers.
6231 * See .../open-repo/vlib/memclnt_vlib.c:memclnt_process()
6234 static clib_error_t *
6235 vpe_api_hookup (vlib_main_t *vm)
6237 api_main_t * am = &api_main;
6240 vl_msg_api_set_handlers(VL_API_##N, #n, \
6241 vl_api_##n##_t_handler, \
6243 vl_api_##n##_t_endian, \
6244 vl_api_##n##_t_print, \
6245 sizeof(vl_api_##n##_t), 1);
6246 foreach_vpe_api_msg;
6250 * Manually register the sr tunnel add del msg, so we trace
6251 * enough bytes to capture a typical segment list
6253 vl_msg_api_set_handlers (VL_API_SR_TUNNEL_ADD_DEL,
6254 "sr_tunnel_add_del",
6255 vl_api_sr_tunnel_add_del_t_handler,
6257 vl_api_sr_tunnel_add_del_t_endian,
6258 vl_api_sr_tunnel_add_del_t_print,
6263 * Manually register the sr policy add del msg, so we trace
6264 * enough bytes to capture a typical tunnel name list
6266 vl_msg_api_set_handlers (VL_API_SR_POLICY_ADD_DEL,
6267 "sr_policy_add_del",
6268 vl_api_sr_policy_add_del_t_handler,
6270 vl_api_sr_policy_add_del_t_endian,
6271 vl_api_sr_policy_add_del_t_print,
6275 * Trace space for 8 MPLS encap labels, classifier mask+match
6277 am->api_trace_cfg [VL_API_MPLS_ADD_DEL_ENCAP].size += 8 * sizeof(u32);
6278 am->api_trace_cfg [VL_API_CLASSIFY_ADD_DEL_TABLE].size
6279 += 5 * sizeof (u32x4);
6280 am->api_trace_cfg [VL_API_CLASSIFY_ADD_DEL_SESSION].size
6281 += 5 * sizeof (u32x4);
6282 am->api_trace_cfg [VL_API_VXLAN_ADD_DEL_TUNNEL].size
6283 += 16 * sizeof (u32);
6286 * Thread-safe API messages
6288 am->is_mp_safe [VL_API_IP_ADD_DEL_ROUTE] = 1;
6289 am->is_mp_safe [VL_API_GET_NODE_GRAPH] = 1;
6294 VLIB_API_INIT_FUNCTION(vpe_api_hookup);
6296 static clib_error_t *
6297 vpe_api_init (vlib_main_t *vm)
6299 vpe_api_main_t *am = &vpe_api_main;
6302 am->vnet_main = vnet_get_main();
6303 am->interface_events_registration_hash = hash_create (0, sizeof (uword));
6304 am->to_netconf_server_registration_hash = hash_create (0, sizeof (uword));
6305 am->from_netconf_server_registration_hash = hash_create (0, sizeof (uword));
6306 am->to_netconf_client_registration_hash = hash_create (0, sizeof (uword));
6307 am->from_netconf_client_registration_hash = hash_create (0, sizeof (uword));
6308 am->oam_events_registration_hash = hash_create (0, sizeof (uword));
6311 vl_set_memory_region_name ("/vpe-api");
6312 vl_enable_disable_memory_api (vm, 1 /* enable it */);
6317 VLIB_INIT_FUNCTION(vpe_api_init);
6320 static clib_error_t *
6321 api_segment_config (vlib_main_t * vm, unformat_input_t * input)
6326 struct passwd _pw, *pw;
6327 struct group _grp, *grp;
6330 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6332 if (unformat (input, "prefix %s", &chroot_path))
6334 vec_add1 (chroot_path, 0);
6335 vl_set_memory_root_path ((char *)chroot_path);
6337 else if (unformat (input, "uid %d", &uid))
6338 vl_set_memory_uid (uid);
6339 else if (unformat (input, "gid %d", &gid))
6340 vl_set_memory_gid (gid);
6341 else if (unformat (input, "uid %s", &s))
6343 /* lookup the username */
6345 rv = getpwnam_r(s, &_pw, buf, sizeof(buf), &pw);
6348 e = clib_error_return_code(0, rv,
6349 CLIB_ERROR_ERRNO_VALID | CLIB_ERROR_FATAL,
6350 "cannot fetch username %s", s);
6356 e = clib_error_return_fatal(0, "username %s does not exist", s);
6361 vl_set_memory_uid (pw->pw_uid);
6363 else if (unformat (input, "gid %s", &s))
6365 /* lookup the group name */
6367 rv = getgrnam_r(s, &_grp, buf, sizeof(buf), &grp);
6370 e = clib_error_return_code(0, rv,
6371 CLIB_ERROR_ERRNO_VALID | CLIB_ERROR_FATAL,
6372 "cannot fetch group %s", s);
6378 e = clib_error_return_fatal(0, "group %s does not exist", s);
6383 vl_set_memory_gid (grp->gr_gid);
6386 return clib_error_return (0, "unknown input `%U'",
6387 format_unformat_error, input);
6391 VLIB_EARLY_CONFIG_FUNCTION (api_segment_config, "api-segment");
6393 void * get_unformat_vnet_sw_interface (void)
6395 return (void *) &unformat_vnet_sw_interface;
6398 #undef vl_api_version
6399 #define vl_api_version(n,v) static u32 vpe_api_version = v;
6400 #include <api/vpe.api.h>
6401 #undef vl_api_version
6403 int vl_msg_api_version_check (vl_api_memclnt_create_t * mp)
6405 if (clib_host_to_net_u32(mp->api_versions[0]) != vpe_api_version) {
6406 clib_warning ("vpe API mismatch: 0x%08x instead of 0x%08x",
6407 clib_host_to_net_u32 (mp->api_versions[0]),
6414 static u8 * format_arp_event (u8 * s, va_list * args)
6416 vl_api_ip4_arp_event_t * event = va_arg (*args, vl_api_ip4_arp_event_t *);
6418 s = format (s, "pid %d: %U", event->pid,
6419 format_ip4_address, &event->address);
6423 static clib_error_t *
6424 show_ip4_arp_events_fn (vlib_main_t * vm,
6425 unformat_input_t * input,
6426 vlib_cli_command_t * cmd)
6428 vpe_api_main_t * am = &vpe_api_main;
6429 vl_api_ip4_arp_event_t * event;
6431 if (pool_elts (am->arp_events) == 0) {
6432 vlib_cli_output (vm, "No active arp event registrations");
6436 pool_foreach (event, am->arp_events,
6438 vlib_cli_output (vm, "%U", format_arp_event, event);
6444 VLIB_CLI_COMMAND (show_ip4_arp_events, static) = {
6445 .path = "show arp event registrations",
6446 .function = show_ip4_arp_events_fn,
6447 .short_help = "Show arp event registrations",