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 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, \
344 lisp_add_del_map_request_itr_rlocs) \
345 _(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs) \
346 _(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del) \
347 _(AF_PACKET_CREATE, af_packet_create) \
348 _(AF_PACKET_DELETE, af_packet_delete) \
349 _(POLICER_ADD_DEL, policer_add_del) \
350 _(POLICER_DUMP, policer_dump) \
351 _(NETMAP_CREATE, netmap_create) \
352 _(NETMAP_DELETE, netmap_delete)
355 #define QUOTE(x) QUOTE_(x)
357 #define foreach_registration_hash \
358 _(interface_events) \
359 _(to_netconf_server) \
360 _(from_netconf_server) \
361 _(to_netconf_client) \
362 _(from_netconf_client) \
366 RESOLVE_IP4_ADD_DEL_ROUTE=1,
367 RESOLVE_IP6_ADD_DEL_ROUTE,
368 RESOLVE_MPLS_ETHERNET_ADD_DEL,
374 vl_api_ip_add_del_route_t r;
375 vl_api_mpls_ethernet_add_del_tunnel_2_t t;
381 #define _(a) uword *a##_registration_hash; \
382 vpe_client_registration_t * a##_registrations;
383 foreach_registration_hash
386 /* notifications happen really early in the game */
387 u8 link_state_process_up;
389 /* ip4 pending route adds */
390 pending_route_t * pending_routes;
392 /* ip4 arp event registration pool */
393 vl_api_ip4_arp_event_t * arp_events;
396 vlib_main_t * vlib_main;
397 vnet_main_t * vnet_main;
400 static vlib_node_registration_t vpe_resolver_process_node;
401 static vpe_api_main_t vpe_api_main;
403 static void send_sw_interface_flags (vpe_api_main_t * am,
404 unix_shared_memory_queue_t *q,
405 vnet_sw_interface_t * swif);
406 static void send_sw_interface_flags_deleted (vpe_api_main_t * am,
407 unix_shared_memory_queue_t *q,
410 static int arp_change_delete_callback (u32 pool_index, u8 * notused);
413 /* Clean up all registrations belonging to the indicated client */
414 int vl_api_memclnt_delete_callback (u32 client_index)
416 vpe_api_main_t * vam = &vpe_api_main;
417 vpe_client_registration_t *rp;
419 int stats_memclnt_delete_callback (u32 client_index);
421 stats_memclnt_delete_callback (client_index);
424 p = hash_get (vam->a##_registration_hash, client_index); \
426 rp = pool_elt_at_index (vam->a##_registrations, p[0]); \
427 pool_put (vam->a##_registrations, rp); \
428 hash_unset (vam->a##_registration_hash, client_index); \
430 foreach_registration_hash;
435 #define API_LINK_STATE_EVENT 1
436 #define API_ADMIN_UP_DOWN_EVENT 2
439 event_data_cmp (void * a1, void * a2)
444 return (word) e1[0] - (word) e2[0];
448 link_state_process (vlib_main_t * vm,
449 vlib_node_runtime_t * rt,
452 vpe_api_main_t * vam = &vpe_api_main;
453 vnet_main_t * vnm = vam->vnet_main;
454 vnet_sw_interface_t * swif;
455 uword * event_data = 0;
456 vpe_client_registration_t *reg;
458 u32 prev_sw_if_index;
459 unix_shared_memory_queue_t * q;
461 vam->link_state_process_up = 1;
464 vlib_process_wait_for_event (vm);
466 /* Unified list of changed link or admin state sw_if_indices */
467 vlib_process_get_events_with_type
468 (vm, &event_data, API_LINK_STATE_EVENT);
469 vlib_process_get_events_with_type
470 (vm, &event_data, API_ADMIN_UP_DOWN_EVENT);
472 /* Sort, so we can eliminate duplicates */
473 vec_sort_with_function (event_data, event_data_cmp);
475 prev_sw_if_index = ~0;
477 for (i = 0; i < vec_len(event_data); i++) {
478 /* Only one message per swif */
479 if (prev_sw_if_index == event_data[i])
481 prev_sw_if_index = event_data[i];
483 pool_foreach(reg, vam->interface_events_registrations,
485 q = vl_api_client_index_to_input_queue (reg->client_index);
487 // sw_interface may be deleted already
488 if (!pool_is_free_index (vnm->interface_main.sw_interfaces,
491 swif = vnet_get_sw_interface (vnm, event_data[i]);
492 send_sw_interface_flags (vam, q, swif);
497 vec_reset_length (event_data);
503 static clib_error_t *
504 link_up_down_function (vnet_main_t *vm, u32 hw_if_index, u32 flags);
505 static clib_error_t *
506 admin_up_down_function (vnet_main_t *vm, u32 hw_if_index, u32 flags);
508 VLIB_REGISTER_NODE (link_state_process_node,static) = {
509 .function = link_state_process,
510 .type = VLIB_NODE_TYPE_PROCESS,
511 .name = "vpe-link-state-process",
514 VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (admin_up_down_function);
515 VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (link_up_down_function);
517 static clib_error_t *
518 link_up_down_function (vnet_main_t *vm, u32 hw_if_index, u32 flags)
520 vpe_api_main_t * vam = &vpe_api_main;
521 vnet_hw_interface_t *hi = vnet_get_hw_interface (vm, hw_if_index);
523 if (vam->link_state_process_up)
524 vlib_process_signal_event (vam->vlib_main,
525 link_state_process_node.index,
526 API_LINK_STATE_EVENT,
531 static clib_error_t *
532 admin_up_down_function (vnet_main_t *vm, u32 sw_if_index, u32 flags)
534 vpe_api_main_t * vam = &vpe_api_main;
537 * Note: it's perfectly fair to set a subif admin up / admin down.
538 * Note the subtle distinction between this routine and the previous
541 if (vam->link_state_process_up)
542 vlib_process_signal_event (vam->vlib_main,
543 link_state_process_node.index,
544 API_ADMIN_UP_DOWN_EVENT,
549 #define pub_sub_handler(lca,UCA) \
550 static void vl_api_want_##lca##_t_handler ( \
551 vl_api_want_##lca##_t *mp) \
553 vpe_api_main_t *vam = &vpe_api_main; \
554 vpe_client_registration_t *rp; \
555 vl_api_want_##lca##_reply_t *rmp; \
559 p = hash_get (vam->lca##_registration_hash, mp->client_index); \
561 if (mp->enable_disable) { \
562 clib_warning ("pid %d: already enabled...", mp->pid); \
563 rv = VNET_API_ERROR_INVALID_REGISTRATION; \
566 rp = pool_elt_at_index (vam->lca##_registrations, p[0]); \
567 pool_put (vam->lca##_registrations, rp); \
568 hash_unset (vam->lca##_registration_hash, \
573 if (mp->enable_disable == 0) { \
574 clib_warning ("pid %d: already disabled...", mp->pid); \
575 rv = VNET_API_ERROR_INVALID_REGISTRATION; \
578 pool_get (vam->lca##_registrations, rp); \
579 rp->client_index = mp->client_index; \
580 rp->client_pid = mp->pid; \
581 hash_set (vam->lca##_registration_hash, rp->client_index, \
582 rp - vam->lca##_registrations); \
585 REPLY_MACRO (VL_API_WANT_##UCA##_REPLY); \
588 pub_sub_handler (interface_events,INTERFACE_EVENTS)
589 pub_sub_handler (oam_events,OAM_EVENTS)
591 #define RESOLUTION_EVENT 1
592 #define RESOLUTION_PENDING_EVENT 2
593 #define IP4_ARP_EVENT 3
595 static int ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t *mp);
596 static int ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t *mp);
597 static int mpls_ethernet_add_del_tunnel_2_t_handler
598 (vl_api_mpls_ethernet_add_del_tunnel_2_t *mp);
600 void handle_ip4_arp_event (u32 pool_index)
602 vpe_api_main_t * vam = &vpe_api_main;
603 vnet_main_t * vnm = vam->vnet_main;
604 vlib_main_t * vm = vam->vlib_main;
605 vl_api_ip4_arp_event_t * event;
606 vl_api_ip4_arp_event_t * mp;
607 unix_shared_memory_queue_t * q;
609 /* Client can cancel, die, etc. */
610 if (pool_is_free_index (vam->arp_events, pool_index))
613 event = pool_elt_at_index (vam->arp_events, pool_index);
615 q = vl_api_client_index_to_input_queue (event->client_index);
617 (void) vnet_add_del_ip4_arp_change_event
618 (vnm, arp_change_delete_callback,
619 event->pid, &event->address,
620 vpe_resolver_process_node.index, IP4_ARP_EVENT,
621 ~0 /* pool index, notused */, 0 /* is_add */);
625 if (q->cursize < q->maxsize) {
626 mp = vl_msg_api_alloc (sizeof (*mp));
627 clib_memcpy (mp, event, sizeof (*mp));
628 vl_msg_api_send_shmem (q, (u8 *)&mp);
630 static f64 last_time;
632 * Throttle syslog msgs.
633 * It's pretty tempting to just revoke the registration...
635 if (vlib_time_now (vm) > last_time + 10.0) {
636 clib_warning ("arp event for %U to pid %d: queue stuffed!",
637 format_ip4_address, &event->address, event->pid);
638 last_time = vlib_time_now(vm);
644 resolver_process (vlib_main_t * vm,
645 vlib_node_runtime_t * rt,
649 uword *event_data = 0;
651 vpe_api_main_t * vam = &vpe_api_main;
652 pending_route_t * pr;
653 vl_api_ip_add_del_route_t * adr;
654 vl_api_mpls_ethernet_add_del_tunnel_2_t *pme;
655 u32 * resolution_failures = 0;
660 vlib_process_wait_for_event_or_clock (vm, timeout);
662 event_type = vlib_process_get_events (vm, &event_data);
664 switch (event_type) {
665 case RESOLUTION_PENDING_EVENT:
669 case RESOLUTION_EVENT:
670 for (i = 0; i < vec_len(event_data); i++) {
672 * Resolution events can occur long after the
673 * original request has timed out. $$$ add a cancel
676 if (pool_is_free_index (vam->pending_routes, event_data[i]))
679 pr = pool_elt_at_index (vam->pending_routes, event_data[i]);
683 switch (pr->resolve_type) {
684 case RESOLVE_IP4_ADD_DEL_ROUTE:
685 rv = ip4_add_del_route_t_handler (adr);
686 clib_warning ("resolver: add %U/%d via %U %s",
688 (ip4_address_t *)&(adr->dst_address),
689 adr->dst_address_length,
691 (ip4_address_t *)&(adr->next_hop_address),
692 (rv >= 0) ? "succeeded" : "failed");
695 case RESOLVE_IP6_ADD_DEL_ROUTE:
696 rv = ip6_add_del_route_t_handler (adr);
697 clib_warning ("resolver: add %U/%d via %U %s",
699 (ip6_address_t *)&(adr->dst_address),
700 adr->dst_address_length,
702 (ip6_address_t *)&(adr->next_hop_address),
703 (rv >= 0) ? "succeeded" : "failed");
706 case RESOLVE_MPLS_ETHERNET_ADD_DEL:
707 rv = mpls_ethernet_add_del_tunnel_2_t_handler (pme);
708 clib_warning ("resolver: add mpls-o-e via %U %s",
710 (ip4_address_t *)&(pme->next_hop_ip4_address_in_outer_vrf),
711 (rv >= 0) ? "succeeded" : "failed");
715 clib_warning ("resolver: BOGUS TYPE %d", pr->resolve_type);
717 pool_put (vam->pending_routes, pr);
722 for (i = 0; i < vec_len(event_data); i++)
723 handle_ip4_arp_event (event_data[i]);
726 case ~0: /* timeout, retry pending resolutions */
727 pool_foreach (pr, vam->pending_routes,
733 /* May fail, e.g. due to interface down */
734 switch (pr->resolve_type) {
735 case RESOLVE_IP4_ADD_DEL_ROUTE:
736 e = ip4_probe_neighbor
737 (vm, (ip4_address_t *)&(adr->next_hop_address),
738 ntohl(adr->next_hop_sw_if_index));
741 case RESOLVE_IP6_ADD_DEL_ROUTE:
742 e = ip6_probe_neighbor
743 (vm, (ip6_address_t *)&(adr->next_hop_address),
744 ntohl(adr->next_hop_sw_if_index));
747 case RESOLVE_MPLS_ETHERNET_ADD_DEL:
749 e = ip4_probe_neighbor
751 (ip4_address_t *)&(pme->next_hop_ip4_address_in_outer_vrf),
752 pme->resolve_opaque);
756 e = clib_error_return (0, "resolver: BOGUS TYPE %d",
760 clib_error_report (e);
762 adr->resolve_attempts = 1;
764 pme->resolve_attempts = 1;
768 adr->resolve_attempts -= 1;
769 if (adr->resolve_attempts == 0)
770 vec_add1 (resolution_failures,
771 pr - vam->pending_routes);
773 pme->resolve_attempts -= 1;
774 if (pme->resolve_attempts == 0)
775 vec_add1 (resolution_failures,
776 pr - vam->pending_routes);
780 for (i = 0; i < vec_len (resolution_failures); i++) {
781 pr = pool_elt_at_index (vam->pending_routes,
782 resolution_failures[i]);
786 switch (pr->resolve_type) {
787 case RESOLVE_IP4_ADD_DEL_ROUTE:
788 clib_warning ("resolver: add %U/%d via %U retry failure",
790 (ip4_address_t *)&(adr->dst_address),
791 adr->dst_address_length,
793 (ip4_address_t *)&(adr->next_hop_address));
796 case RESOLVE_IP6_ADD_DEL_ROUTE:
797 clib_warning ("resolver: add %U/%d via %U retry failure",
799 (ip6_address_t *)&(adr->dst_address),
800 adr->dst_address_length,
802 (ip6_address_t *)&(adr->next_hop_address));
805 case RESOLVE_MPLS_ETHERNET_ADD_DEL:
806 clib_warning ("resolver: add mpls-o-e via %U retry failure",
808 (ip4_address_t *)&(pme->next_hop_ip4_address_in_outer_vrf));
812 clib_warning ("BUG");
814 pool_put(vam->pending_routes, pr);
816 vec_reset_length (resolution_failures);
819 if (pool_elts (vam->pending_routes) == 0)
821 vec_reset_length (event_data);
823 return 0; /* or not */
826 VLIB_REGISTER_NODE (vpe_resolver_process_node,static) = {
827 .function = resolver_process,
828 .type = VLIB_NODE_TYPE_PROCESS,
829 .name = "vpe-route-resolver-process",
832 static int ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t *mp)
834 ip4_main_t * im = &ip4_main;
835 ip_lookup_main_t * lm = &im->lookup_main;
836 vnet_classify_main_t * cm = &vnet_classify_main;
837 stats_main_t * sm = &stats_main;
838 ip4_add_del_route_args_t a;
839 ip4_address_t next_hop_address;
841 vpe_api_main_t * vam = &vpe_api_main;
842 vnet_main_t * vnm = vam->vnet_main;
843 vlib_main_t * vm = vlib_get_main();
844 pending_route_t * pr;
845 vl_api_ip_add_del_route_t * adr;
849 ip_adjacency_t *nh_adj, *add_adj = 0;
851 p = hash_get (im->fib_index_by_table_id, ntohl(mp->vrf_id));
853 if (mp->create_vrf_if_needed) {
855 f = find_ip4_fib_by_table_index_or_id (im, ntohl(mp->vrf_id),
857 fib_index = f->index;
859 /* No such VRF, and we weren't asked to create one */
860 return VNET_API_ERROR_NO_SUCH_FIB;
866 if (pool_is_free_index (vnm->interface_main.sw_interfaces,
867 ntohl(mp->next_hop_sw_if_index)))
868 return VNET_API_ERROR_NO_MATCHING_INTERFACE;
870 clib_memcpy (next_hop_address.data, mp->next_hop_address,
871 sizeof (next_hop_address.data));
873 /* Arp for the next_hop if necessary */
874 if (mp->is_add && mp->resolve_if_needed) {
876 ip_adjacency_t * adj;
878 lookup_result = ip4_fib_lookup_with_table
879 (im, fib_index, &next_hop_address, 1 /* disable default route */);
881 adj = ip_get_adjacency (lm, lookup_result);
883 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP) {
884 pool_get (vam->pending_routes, pr);
885 pr->resolve_type = RESOLVE_IP4_ADD_DEL_ROUTE;
887 clib_memcpy (adr, mp, sizeof (*adr));
888 /* recursion block, "just in case" */
889 adr->resolve_if_needed = 0;
890 adr->resolve_attempts = ntohl(mp->resolve_attempts);
891 vnet_register_ip4_arp_resolution_event
892 (vnm, &next_hop_address, vpe_resolver_process_node.index,
893 RESOLUTION_EVENT, pr - vam->pending_routes);
895 vlib_process_signal_event
896 (vm, vpe_resolver_process_node.index,
897 RESOLUTION_PENDING_EVENT, 0 /* data */);
899 /* The interface may be down, etc. */
900 e = ip4_probe_neighbor
901 (vm, (ip4_address_t *)&(mp->next_hop_address),
902 ntohl(mp->next_hop_sw_if_index));
905 clib_error_report(e);
907 return VNET_API_ERROR_IN_PROGRESS;
911 if (mp->is_multipath) {
914 dslock (sm, 1 /* release hint */, 10 /* tag */);
917 flags = IP4_ROUTE_FLAG_ADD;
919 flags = IP4_ROUTE_FLAG_DEL;
922 flags |= IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP;
924 ip4_add_del_route_next_hop (im, flags,
925 (ip4_address_t *) mp->dst_address,
926 (u32) mp->dst_address_length,
927 (ip4_address_t *) mp->next_hop_address,
928 ntohl(mp->next_hop_sw_if_index),
929 (u32) mp->next_hop_weight,
936 memset (&a, 0, sizeof (a));
937 clib_memcpy (a.dst_address.data, mp->dst_address, sizeof (a.dst_address.data));
939 a.dst_address_length = mp->dst_address_length;
941 a.flags = (mp->is_add ? IP4_ROUTE_FLAG_ADD : IP4_ROUTE_FLAG_DEL);
942 a.flags |= IP4_ROUTE_FLAG_FIB_INDEX;
943 a.table_index_or_table_id = fib_index;
948 a.flags |= IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP;
950 dslock (sm, 1 /* release hint */, 2 /* tag */);
954 ai = lm->drop_adj_index;
955 else if (mp->is_local)
956 ai = lm->local_adj_index;
957 else if (mp->is_classify) {
959 memset(&cadj, 0, sizeof(cadj));
960 cadj.lookup_next_index = IP_LOOKUP_NEXT_CLASSIFY;
961 cadj.classify.table_index = ntohl(mp->classify_table_index);
962 if (pool_is_free_index (cm->tables, cadj.classify.table_index)) {
964 return VNET_API_ERROR_NO_SUCH_TABLE;
966 vec_add1 (add_adj, cadj);
970 ai = ip4_fib_lookup_with_table
971 (im, fib_index, &next_hop_address,
972 1 /* disable default route */);
973 if (ai == lm->miss_adj_index) {
975 return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
979 nh_adj = ip_get_adjacency (lm, ai);
980 if (nh_adj->lookup_next_index == IP_LOOKUP_NEXT_ARP &&
981 nh_adj->arp.next_hop.ip4.as_u32 == 0) {
982 /* the next-hop resovles via a glean adj. create and use
983 * a ARP adj for the next-hop */
984 a.adj_index = vnet_arp_glean_add(fib_index, &next_hop_address);
987 ip4_add_del_route (im, &a);
991 vec_add1 (add_adj, nh_adj[0]);
992 if (mp->lookup_in_vrf) {
993 p = hash_get (im->fib_index_by_table_id, ntohl(mp->lookup_in_vrf));
995 add_adj[0].explicit_fib_index = p[0];
999 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
1003 ip_adjacency_t * adj;
1004 int disable_default_route = 1;
1006 /* Trying to delete the default route? */
1007 if (a.dst_address.as_u32 == 0 &&
1008 a.dst_address_length == 0)
1009 disable_default_route = 0;
1011 ai = ip4_fib_lookup_with_table
1012 (im, fib_index, &a.dst_address, disable_default_route);
1013 if (ai == lm->miss_adj_index) {
1015 return VNET_API_ERROR_UNKNOWN_DESTINATION;
1018 adj = ip_get_adjacency (lm, ai);
1019 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP) {
1021 return VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
1027 a.add_adj = add_adj;
1028 a.n_add_adj = vec_len(add_adj);
1029 ip4_add_del_route (im, &a);
1038 static int ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t *mp)
1040 ip6_main_t * im = &ip6_main;
1041 ip_lookup_main_t * lm = &im->lookup_main;
1042 vnet_main_t * vnm = vnet_get_main();
1043 vlib_main_t * vm = vlib_get_main();
1044 vpe_api_main_t * vam = &vpe_api_main;
1045 stats_main_t * sm = &stats_main;
1046 ip6_add_del_route_args_t a;
1047 ip6_address_t next_hop_address;
1048 pending_route_t * pr;
1049 vl_api_ip_add_del_route_t * adr;
1054 ip_adjacency_t * nh_adj, * add_adj = 0;
1057 p = hash_get (im->fib_index_by_table_id, ntohl(mp->vrf_id));
1060 if (mp->create_vrf_if_needed) {
1062 f = find_ip6_fib_by_table_index_or_id (im, ntohl(mp->vrf_id),
1064 fib_index = f->index;
1066 /* No such VRF, and we weren't asked to create one */
1067 return VNET_API_ERROR_NO_SUCH_FIB;
1073 if (pool_is_free_index (vnm->interface_main.sw_interfaces,
1074 ntohl(mp->next_hop_sw_if_index)))
1075 return VNET_API_ERROR_NO_MATCHING_INTERFACE;
1077 clib_memcpy (next_hop_address.as_u8, mp->next_hop_address,
1078 sizeof (next_hop_address.as_u8));
1080 /* Arp for the next_hop if necessary */
1081 if (mp->is_add && mp->resolve_if_needed) {
1083 ip_adjacency_t * adj;
1085 lookup_result = ip6_fib_lookup_with_table
1086 (im, fib_index, &next_hop_address);
1088 adj = ip_get_adjacency (lm, lookup_result);
1090 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP) {
1091 pool_get (vam->pending_routes, pr);
1093 pr->resolve_type = RESOLVE_IP6_ADD_DEL_ROUTE;
1094 clib_memcpy (adr, mp, sizeof (*adr));
1095 /* recursion block, "just in case" */
1096 adr->resolve_if_needed = 0;
1097 adr->resolve_attempts = ntohl(mp->resolve_attempts);
1098 vnet_register_ip6_neighbor_resolution_event
1099 (vnm, &next_hop_address, vpe_resolver_process_node.index,
1100 RESOLUTION_EVENT, pr - vam->pending_routes);
1102 vlib_process_signal_event
1103 (vm, vpe_resolver_process_node.index,
1104 RESOLUTION_PENDING_EVENT, 0 /* data */);
1106 /* The interface may be down, etc. */
1107 e = ip6_probe_neighbor
1108 (vm, (ip6_address_t *)&(mp->next_hop_address),
1109 ntohl(mp->next_hop_sw_if_index));
1112 clib_error_report(e);
1114 return VNET_API_ERROR_IN_PROGRESS;
1118 if (mp->is_multipath) {
1121 dslock (sm, 1 /* release hint */, 11 /* tag */);
1124 flags = IP6_ROUTE_FLAG_ADD;
1126 flags = IP6_ROUTE_FLAG_DEL;
1129 flags |= IP6_ROUTE_FLAG_NOT_LAST_IN_GROUP;
1131 ip6_add_del_route_next_hop (im, flags, (ip6_address_t *)mp->dst_address,
1132 (u32) mp->dst_address_length,
1133 (ip6_address_t *)mp->next_hop_address,
1134 ntohl(mp->next_hop_sw_if_index),
1135 (u32) mp->next_hop_weight,
1142 memset (&a, 0, sizeof (a));
1143 clib_memcpy (a.dst_address.as_u8, mp->dst_address, sizeof (a.dst_address.as_u8));
1145 a.dst_address_length = mp->dst_address_length;
1147 a.flags = (mp->is_add ? IP6_ROUTE_FLAG_ADD : IP6_ROUTE_FLAG_DEL);
1148 a.flags |= IP6_ROUTE_FLAG_FIB_INDEX;
1149 a.table_index_or_table_id = fib_index;
1154 a.flags |= IP6_ROUTE_FLAG_NOT_LAST_IN_GROUP;
1156 dslock (sm, 1 /* release hint */, 3 /* tag */);
1160 ai = lm->drop_adj_index;
1161 else if (mp->is_local)
1162 ai = lm->local_adj_index;
1164 ai = ip6_fib_lookup_with_table
1165 (im, fib_index, &next_hop_address);
1166 if (ai == lm->miss_adj_index) {
1168 return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
1172 nh_adj = ip_get_adjacency (lm, ai);
1173 vec_add1 (add_adj, nh_adj[0]);
1174 if (mp->lookup_in_vrf) {
1175 p = hash_get (im->fib_index_by_table_id, ntohl(mp->lookup_in_vrf));
1177 add_adj[0].explicit_fib_index = p[0];
1181 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
1185 ip_adjacency_t * adj;
1187 ai = ip6_fib_lookup_with_table
1188 (im, fib_index, &a.dst_address);
1189 if (ai == lm->miss_adj_index) {
1191 return VNET_API_ERROR_UNKNOWN_DESTINATION;
1193 adj = ip_get_adjacency (lm, ai);
1194 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP) {
1196 return VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
1201 a.add_adj = add_adj;
1202 a.n_add_adj = vec_len(add_adj);
1203 ip6_add_del_route (im, &a);
1211 void vl_api_ip_add_del_route_t_handler (
1212 vl_api_ip_add_del_route_t *mp)
1214 vl_api_ip_add_del_route_reply_t * rmp;
1216 vnet_main_t * vnm = vnet_get_main();
1221 rv = ip6_add_del_route_t_handler (mp);
1223 rv = ip4_add_del_route_t_handler (mp);
1225 rv = (rv == 0) ? vnm->api_errno : rv;
1227 REPLY_MACRO(VL_API_IP_ADD_DEL_ROUTE_REPLY);
1230 void api_config_default_ip_route (u8 is_ipv6, u8 is_add, u32 vrf_id,
1231 u32 sw_if_index, u8 *next_hop_addr)
1233 vl_api_ip_add_del_route_t mp;
1236 memset (&mp, 0, sizeof(vl_api_ip_add_del_route_t));
1239 * Configure default IP route:
1240 * - ip route add 0.0.0.0/1 via <GW IP>
1241 * - ip route add 128.0.0.0/1 via <GW IP>
1243 mp.next_hop_sw_if_index = ntohl(sw_if_index);
1245 mp.resolve_attempts = ~0;
1246 mp.resolve_if_needed = 1;
1248 mp.is_ipv6 = is_ipv6;
1249 mp.next_hop_weight = 1;
1251 clib_memcpy (&mp.next_hop_address[0], next_hop_addr, 16);
1254 rv = ip6_add_del_route_t_handler (&mp);
1257 mp.dst_address_length = 1;
1259 mp.dst_address[0] = 0;
1260 rv = ip4_add_del_route_t_handler (&mp);
1262 mp.dst_address[0] = 128;
1263 rv |= ip4_add_del_route_t_handler (&mp);
1267 clib_error_return (0, "failed to config default IP route");
1272 vl_api_sw_interface_add_del_address_t_handler
1273 (vl_api_sw_interface_add_del_address_t *mp)
1275 vlib_main_t *vm = vlib_get_main();
1276 vl_api_sw_interface_add_del_address_reply_t * rmp;
1280 VALIDATE_SW_IF_INDEX(mp);
1282 is_del = mp->is_add == 0;
1285 ip_del_all_interface_addresses (vm, ntohl(mp->sw_if_index));
1286 else if (mp->is_ipv6)
1287 ip6_add_del_interface_address (vm, ntohl(mp->sw_if_index),
1288 (void *)mp->address,
1289 mp->address_length, is_del);
1291 ip4_add_del_interface_address (vm, ntohl(mp->sw_if_index),
1292 (void *) mp->address,
1293 mp->address_length, is_del);
1295 BAD_SW_IF_INDEX_LABEL;
1297 REPLY_MACRO(VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY);
1301 vl_api_sw_interface_set_table_t_handler (vl_api_sw_interface_set_table_t *mp)
1304 u32 table_id = ntohl(mp->vrf_id);
1305 u32 sw_if_index = ntohl(mp->sw_if_index);
1306 vl_api_sw_interface_set_table_reply_t * rmp;
1307 stats_main_t * sm = &stats_main;
1309 VALIDATE_SW_IF_INDEX(mp);
1311 dslock (sm, 1 /* release hint */, 4 /* tag */);
1314 ip6_main_t * im = &ip6_main;
1316 find_ip6_fib_by_table_index_or_id (im, table_id,
1317 IP6_ROUTE_FLAG_TABLE_ID);
1319 vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
1320 im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
1322 rv = VNET_API_ERROR_NO_SUCH_FIB;
1325 ip4_main_t * im = &ip4_main;
1326 ip4_fib_t * fib = find_ip4_fib_by_table_index_or_id
1327 (im, table_id, IP4_ROUTE_FLAG_TABLE_ID);
1329 /* Truthfully this can't fail */
1331 vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
1332 im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
1334 rv = VNET_API_ERROR_NO_SUCH_FIB;
1339 BAD_SW_IF_INDEX_LABEL;
1341 REPLY_MACRO(VL_API_SW_INTERFACE_SET_TABLE_REPLY);
1345 vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t *mp)
1347 vlib_main_t *vm = vlib_get_main();
1348 ip4_main_t * im4 = &ip4_main;
1349 ip6_main_t * im6 = &ip6_main;
1350 vl_api_sw_interface_set_vpath_reply_t * rmp;
1353 u32 sw_if_index = ntohl(mp->sw_if_index);
1354 ip4_main_t *ip4m = &ip4_main;
1355 ip6_main_t *ip6m = &ip6_main;
1356 ip_lookup_main_t *ip4lm = &ip4m->lookup_main;
1357 ip_lookup_main_t *ip6lm = &ip6m->lookup_main;
1358 ip_config_main_t *rx_cm4u = &ip4lm->rx_config_mains[VNET_UNICAST];
1359 ip_config_main_t *rx_cm4m = &ip4lm->rx_config_mains[VNET_MULTICAST];
1360 ip_config_main_t *rx_cm6u = &ip6lm->rx_config_mains[VNET_UNICAST];
1361 ip_config_main_t *rx_cm6m = &ip6lm->rx_config_mains[VNET_MULTICAST];
1363 VALIDATE_SW_IF_INDEX(mp);
1365 l2input_intf_bitmap_enable(sw_if_index, L2INPUT_FEAT_VPATH, mp->enable);
1367 ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast
1368 ci = vnet_config_add_feature(vm, &rx_cm4u->config_main,
1370 im4->ip4_unicast_rx_feature_vpath,
1372 rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci;
1373 ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast
1374 ci = vnet_config_add_feature(vm, &rx_cm4m->config_main,
1376 im4->ip4_multicast_rx_feature_vpath,
1378 rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci;
1379 ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast
1380 ci = vnet_config_add_feature(vm, &rx_cm6u->config_main,
1382 im6->ip6_unicast_rx_feature_vpath,
1384 rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci;
1385 ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast
1386 ci = vnet_config_add_feature(vm, &rx_cm6m->config_main,
1388 im6->ip6_multicast_rx_feature_vpath,
1390 rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci;
1392 ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast
1393 ci = vnet_config_del_feature(vm, &rx_cm4u->config_main,
1395 im4->ip4_unicast_rx_feature_vpath,
1397 rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci;
1398 ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast
1399 ci = vnet_config_del_feature(vm, &rx_cm4m->config_main,
1401 im4->ip4_multicast_rx_feature_vpath,
1403 rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci;
1404 ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast
1405 ci = vnet_config_del_feature(vm, &rx_cm6u->config_main,
1407 im6->ip6_unicast_rx_feature_vpath,
1409 rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci;
1410 ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast
1411 ci = vnet_config_del_feature(vm, &rx_cm6m->config_main,
1413 im6->ip6_multicast_rx_feature_vpath,
1415 rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci;
1418 BAD_SW_IF_INDEX_LABEL;
1420 REPLY_MACRO(VL_API_SW_INTERFACE_SET_VPATH_REPLY);
1424 vl_api_sw_interface_set_l2_xconnect_t_handler (
1425 vl_api_sw_interface_set_l2_xconnect_t *mp)
1427 vl_api_sw_interface_set_l2_xconnect_reply_t * rmp;
1429 u32 rx_sw_if_index = ntohl(mp->rx_sw_if_index);
1430 u32 tx_sw_if_index = ntohl(mp->tx_sw_if_index);
1431 vlib_main_t *vm = vlib_get_main();
1432 vnet_main_t *vnm = vnet_get_main();
1434 VALIDATE_RX_SW_IF_INDEX(mp);
1437 VALIDATE_TX_SW_IF_INDEX(mp);
1438 rv = set_int_l2_mode(vm, vnm, MODE_L2_XC,
1439 rx_sw_if_index, 0, 0, 0, tx_sw_if_index);
1441 rv = set_int_l2_mode(vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
1444 BAD_RX_SW_IF_INDEX_LABEL;
1445 BAD_TX_SW_IF_INDEX_LABEL;
1447 REPLY_MACRO(VL_API_SW_INTERFACE_SET_L2_XCONNECT_REPLY);
1451 vl_api_sw_interface_set_l2_bridge_t_handler (
1452 vl_api_sw_interface_set_l2_bridge_t *mp)
1454 bd_main_t * bdm = &bd_main;
1455 vl_api_sw_interface_set_l2_bridge_reply_t * rmp;
1457 u32 rx_sw_if_index = ntohl(mp->rx_sw_if_index);
1458 u32 bd_id = ntohl(mp->bd_id);
1462 vlib_main_t *vm = vlib_get_main();
1463 vnet_main_t *vnm = vnet_get_main();
1465 VALIDATE_RX_SW_IF_INDEX(mp);
1467 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
1470 //VALIDATE_TX_SW_IF_INDEX(mp);
1471 rv = set_int_l2_mode(vm, vnm, MODE_L2_BRIDGE,
1472 rx_sw_if_index, bd_index, bvi, shg, 0);
1474 rv = set_int_l2_mode(vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
1477 BAD_RX_SW_IF_INDEX_LABEL;
1479 REPLY_MACRO(VL_API_SW_INTERFACE_SET_L2_BRIDGE_REPLY);
1483 vl_api_bridge_domain_add_del_t_handler (
1484 vl_api_bridge_domain_add_del_t *mp)
1486 vlib_main_t * vm = vlib_get_main ();
1487 bd_main_t * bdm = &bd_main;
1488 vl_api_bridge_domain_add_del_reply_t * rmp;
1490 u32 enable_flags = 0, disable_flags = 0;
1491 u32 bd_id = ntohl(mp->bd_id);
1495 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
1498 enable_flags |= L2_FLOOD;
1500 disable_flags |= L2_FLOOD;
1503 enable_flags |= L2_UU_FLOOD;
1505 disable_flags |= L2_UU_FLOOD;
1508 enable_flags |= L2_FWD;
1510 disable_flags |= L2_FWD;
1513 enable_flags |= L2_ARP_TERM;
1515 disable_flags |= L2_ARP_TERM;
1518 enable_flags |= L2_LEARN;
1520 disable_flags |= L2_LEARN;
1523 bd_set_flags (vm, bd_index, enable_flags, 1 /* enable */);
1526 bd_set_flags (vm, bd_index, disable_flags, 0 /* disable */);
1529 rv = bd_delete_bd_index(bdm, bd_id);
1531 REPLY_MACRO(VL_API_BRIDGE_DOMAIN_ADD_DEL_REPLY);
1534 static void vl_api_bridge_domain_details_t_handler (
1535 vl_api_bridge_domain_details_t * mp)
1537 clib_warning ("BUG");
1540 static void vl_api_bridge_domain_sw_if_details_t_handler (
1541 vl_api_bridge_domain_sw_if_details_t * mp)
1543 clib_warning ("BUG");
1546 static void send_bridge_domain_details (unix_shared_memory_queue_t *q,
1547 l2_bridge_domain_t * bd_config,
1551 vl_api_bridge_domain_details_t * mp;
1553 mp = vl_msg_api_alloc (sizeof (*mp));
1554 memset (mp, 0, sizeof (*mp));
1555 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_DETAILS);
1556 mp->bd_id = ntohl (bd_config->bd_id);
1557 mp->flood = bd_feature_flood (bd_config);
1558 mp->uu_flood = bd_feature_uu_flood (bd_config);
1559 mp->forward = bd_feature_forward (bd_config);
1560 mp->learn = bd_feature_learn (bd_config);
1561 mp->arp_term = bd_feature_arp_term (bd_config);
1562 mp->bvi_sw_if_index = ntohl (bd_config->bvi_sw_if_index);
1563 mp->n_sw_ifs = ntohl (n_sw_ifs);
1564 mp->context = context;
1566 vl_msg_api_send_shmem (q, (u8 *)&mp);
1569 static void send_bd_sw_if_details (l2input_main_t * l2im,
1570 unix_shared_memory_queue_t *q,
1571 l2_flood_member_t * member, u32 bd_id,
1574 vl_api_bridge_domain_sw_if_details_t * mp;
1575 l2_input_config_t * input_cfg;
1577 mp = vl_msg_api_alloc (sizeof (*mp));
1578 memset (mp, 0, sizeof (*mp));
1579 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_SW_IF_DETAILS);
1580 mp->bd_id = ntohl (bd_id);
1581 mp->sw_if_index = ntohl (member->sw_if_index);
1582 input_cfg = vec_elt_at_index (l2im->configs, member->sw_if_index);
1583 mp->shg = input_cfg->shg;
1584 mp->context = context;
1586 vl_msg_api_send_shmem (q, (u8 *)&mp);
1589 static void vl_api_bridge_domain_dump_t_handler (
1590 vl_api_bridge_domain_dump_t *mp)
1592 bd_main_t * bdm = &bd_main;
1593 l2input_main_t * l2im = &l2input_main;
1594 unix_shared_memory_queue_t * q;
1595 l2_bridge_domain_t * bd_config;
1596 u32 bd_id, bd_index;
1599 q = vl_api_client_index_to_input_queue (mp->client_index);
1604 bd_id = ntohl(mp->bd_id);
1606 bd_index = (bd_id == ~0) ? 0 : bd_find_or_add_bd_index (bdm, bd_id);
1607 end = (bd_id == ~0) ? vec_len (l2im->bd_configs) : bd_index + 1;
1608 for (; bd_index < end; bd_index++) {
1609 bd_config = l2input_bd_config_from_index (l2im, bd_index);
1610 /* skip dummy bd_id 0 */
1611 if (bd_config && (bd_config->bd_id > 0)) {
1613 l2_flood_member_t * m;
1615 n_sw_ifs = vec_len (bd_config->members);
1616 send_bridge_domain_details (q, bd_config, n_sw_ifs, mp->context);
1618 vec_foreach (m, bd_config->members) {
1619 send_bd_sw_if_details (l2im, q, m, bd_config->bd_id, mp->context);
1626 vl_api_l2fib_add_del_t_handler (
1627 vl_api_l2fib_add_del_t *mp)
1629 bd_main_t * bdm = &bd_main;
1630 l2input_main_t * l2im = &l2input_main;
1631 vl_api_l2fib_add_del_reply_t * rmp;
1634 u32 sw_if_index = ntohl(mp->sw_if_index);
1635 u32 bd_id = ntohl(mp->bd_id);
1643 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1645 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1646 goto bad_sw_if_index;
1651 VALIDATE_SW_IF_INDEX(mp);
1652 if (vec_len(l2im->configs) <= sw_if_index) {
1653 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1654 goto bad_sw_if_index;
1656 l2_input_config_t * config;
1657 config = vec_elt_at_index(l2im->configs, sw_if_index);
1658 if (config->bridge == 0) {
1659 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1660 goto bad_sw_if_index;
1663 static_mac = mp->static_mac ? 1 : 0;
1664 filter_mac = mp->filter_mac ? 1 : 0;
1665 l2fib_add_entry(mac, bd_index, sw_if_index, static_mac, filter_mac,
1668 l2fib_del_entry(mac, bd_index);
1671 BAD_SW_IF_INDEX_LABEL;
1673 REPLY_MACRO(VL_API_L2FIB_ADD_DEL_REPLY);
1677 vl_api_l2_flags_t_handler (
1678 vl_api_l2_flags_t *mp)
1680 vl_api_l2_flags_reply_t * rmp;
1682 u32 sw_if_index = ntohl(mp->sw_if_index);
1683 u32 flags = ntohl(mp->feature_bitmap);
1686 VALIDATE_SW_IF_INDEX(mp);
1689 if (flags & L2INPUT_FEAT_ ## a) \
1690 rbm = l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_ ## a, mp->is_set);
1691 foreach_l2input_feat;
1694 BAD_SW_IF_INDEX_LABEL;
1696 REPLY_MACRO2(VL_API_L2_FLAGS_REPLY, rmp->resulting_feature_bitmap = ntohl(rbm));
1700 vl_api_bridge_flags_t_handler (
1701 vl_api_bridge_flags_t *mp)
1703 vlib_main_t *vm = vlib_get_main();
1704 bd_main_t * bdm = &bd_main;
1705 vl_api_bridge_flags_reply_t * rmp;
1707 u32 bd_id = ntohl(mp->bd_id);
1709 u32 flags = ntohl(mp->feature_bitmap);
1712 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1714 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1720 bd_set_flags(vm, bd_index, flags, mp->is_set);
1723 REPLY_MACRO2(VL_API_BRIDGE_FLAGS_REPLY,
1724 rmp->resulting_feature_bitmap = ntohl(flags));
1728 vl_api_bd_ip_mac_add_del_t_handler (
1729 vl_api_bd_ip_mac_add_del_t *mp)
1731 bd_main_t * bdm = &bd_main;
1732 vl_api_bd_ip_mac_add_del_reply_t * rmp;
1734 u32 bd_id = ntohl(mp->bd_id);
1738 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1740 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1745 if (bd_add_del_ip_mac(bd_index, mp->ip_address,
1746 mp->mac_address, mp->is_ipv6, mp->is_add))
1747 rv = VNET_API_ERROR_UNSPECIFIED;
1750 REPLY_MACRO(VL_API_BD_IP_MAC_ADD_DEL_REPLY);
1754 vl_api_tap_connect_t_handler (vl_api_tap_connect_t *mp, vlib_main_t *vm)
1757 vl_api_tap_connect_reply_t * rmp;
1758 unix_shared_memory_queue_t * q;
1759 u32 sw_if_index = (u32)~0;
1761 rv = vnet_tap_connect_renumber (vm, mp->tap_name,
1762 mp->use_random_mac ? 0 : mp->mac_address,
1763 &sw_if_index, mp->renumber,
1764 ntohl(mp->custom_dev_instance));
1766 q = vl_api_client_index_to_input_queue (mp->client_index);
1770 rmp = vl_msg_api_alloc (sizeof (*rmp));
1771 rmp->_vl_msg_id = ntohs(VL_API_TAP_CONNECT_REPLY);
1772 rmp->context = mp->context;
1773 rmp->retval = ntohl(rv);
1774 rmp->sw_if_index = ntohl(sw_if_index);
1776 vl_msg_api_send_shmem (q, (u8 *)&rmp);
1780 vl_api_tap_modify_t_handler (vl_api_tap_modify_t *mp, vlib_main_t *vm)
1783 vl_api_tap_modify_reply_t * rmp;
1784 unix_shared_memory_queue_t * q;
1785 u32 sw_if_index = (u32)~0;
1787 rv = vnet_tap_modify (vm, ntohl(mp->sw_if_index), mp->tap_name,
1788 mp->use_random_mac ? 0 : mp->mac_address,
1789 &sw_if_index, mp->renumber,
1790 ntohl(mp->custom_dev_instance));
1792 q = vl_api_client_index_to_input_queue (mp->client_index);
1796 rmp = vl_msg_api_alloc (sizeof (*rmp));
1797 rmp->_vl_msg_id = ntohs(VL_API_TAP_MODIFY_REPLY);
1798 rmp->context = mp->context;
1799 rmp->retval = ntohl(rv);
1800 rmp->sw_if_index = ntohl(sw_if_index);
1802 vl_msg_api_send_shmem (q, (u8 *)&rmp);
1806 vl_api_tap_delete_t_handler (vl_api_tap_delete_t *mp, vlib_main_t *vm)
1809 vpe_api_main_t * vam = &vpe_api_main;
1810 vl_api_tap_delete_reply_t * rmp;
1811 unix_shared_memory_queue_t * q;
1812 u32 sw_if_index = ntohl(mp->sw_if_index);
1814 rv = vnet_tap_delete (vm, sw_if_index);
1816 q = vl_api_client_index_to_input_queue (mp->client_index);
1820 rmp = vl_msg_api_alloc (sizeof (*rmp));
1821 rmp->_vl_msg_id = ntohs(VL_API_TAP_DELETE_REPLY);
1822 rmp->context = mp->context;
1823 rmp->retval = ntohl(rv);
1825 vl_msg_api_send_shmem (q, (u8 *)&rmp);
1828 send_sw_interface_flags_deleted (vam, q, sw_if_index);
1832 vl_api_create_vlan_subif_t_handler (vl_api_create_vlan_subif_t * mp)
1834 vl_api_create_vlan_subif_reply_t * rmp;
1835 vnet_main_t * vnm = vnet_get_main();
1836 u32 hw_if_index, sw_if_index = (u32)~0;
1837 vnet_hw_interface_t * hi;
1840 vnet_sw_interface_t template;
1842 vnet_interface_main_t * im = &vnm->interface_main;
1843 u64 sup_and_sub_key;
1845 unix_shared_memory_queue_t * q;
1846 clib_error_t * error;
1848 VALIDATE_SW_IF_INDEX(mp);
1850 hw_if_index = ntohl(mp->sw_if_index);
1851 hi = vnet_get_hw_interface (vnm, hw_if_index);
1853 id = ntohl(mp->vlan_id);
1854 if (id == 0 || id > 4095) {
1855 rv = VNET_API_ERROR_INVALID_VLAN;
1859 sup_and_sub_key = ((u64)(hi->sw_if_index) << 32) | (u64) id;
1861 p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1863 rv = VNET_API_ERROR_VLAN_ALREADY_EXISTS;
1867 kp = clib_mem_alloc (sizeof (*kp));
1868 *kp = sup_and_sub_key;
1870 memset (&template, 0, sizeof (template));
1871 template.type = VNET_SW_INTERFACE_TYPE_SUB;
1872 template.sup_sw_if_index = hi->sw_if_index;
1873 template.sub.id = id;
1874 template.sub.eth.raw_flags = 0;
1875 template.sub.eth.flags.one_tag = 1;
1876 template.sub.eth.outer_vlan_id = id;
1877 template.sub.eth.flags.exact_match = 1;
1879 error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1881 clib_error_report(error);
1882 rv = VNET_API_ERROR_INVALID_REGISTRATION;
1885 hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
1886 hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1888 BAD_SW_IF_INDEX_LABEL;
1891 q = vl_api_client_index_to_input_queue (mp->client_index);
1895 rmp = vl_msg_api_alloc (sizeof (*rmp));
1896 rmp->_vl_msg_id = ntohs(VL_API_CREATE_VLAN_SUBIF_REPLY);
1897 rmp->context = mp->context;
1898 rmp->retval = ntohl(rv);
1899 rmp->sw_if_index = ntohl(sw_if_index);
1900 vl_msg_api_send_shmem (q, (u8 *)&rmp);
1904 vl_api_create_subif_t_handler (vl_api_create_subif_t * mp)
1906 vl_api_create_subif_reply_t * rmp;
1907 vnet_main_t * vnm = vnet_get_main();
1908 u32 sw_if_index = ~0;
1911 vnet_sw_interface_t *si;
1912 vnet_hw_interface_t *hi;
1913 vnet_sw_interface_t template;
1915 vnet_interface_main_t * im = &vnm->interface_main;
1916 u64 sup_and_sub_key;
1918 clib_error_t * error;
1920 VALIDATE_SW_IF_INDEX(mp);
1922 si = vnet_get_sup_sw_interface (vnm, ntohl(mp->sw_if_index));
1923 hi = vnet_get_sup_hw_interface (vnm, ntohl(mp->sw_if_index));
1925 if (hi->bond_info == VNET_HW_INTERFACE_BOND_INFO_SLAVE) {
1926 rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
1930 sw_if_index = si->sw_if_index;
1931 sub_id = ntohl(mp->sub_id);
1933 sup_and_sub_key = ((u64)(sw_if_index) << 32) | (u64) sub_id;
1935 p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1938 clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
1939 sw_if_index, sub_id);
1940 rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
1944 kp = clib_mem_alloc (sizeof (*kp));
1945 *kp = sup_and_sub_key;
1947 memset (&template, 0, sizeof (template));
1948 template.type = VNET_SW_INTERFACE_TYPE_SUB;
1949 template.sup_sw_if_index = sw_if_index;
1950 template.sub.id = sub_id;
1951 template.sub.eth.flags.no_tags = mp->no_tags;
1952 template.sub.eth.flags.one_tag = mp->one_tag;
1953 template.sub.eth.flags.two_tags = mp->two_tags;
1954 template.sub.eth.flags.dot1ad = mp->dot1ad;
1955 template.sub.eth.flags.exact_match = mp->exact_match;
1956 template.sub.eth.flags.default_sub = mp->default_sub;
1957 template.sub.eth.flags.outer_vlan_id_any = mp->outer_vlan_id_any;
1958 template.sub.eth.flags.inner_vlan_id_any = mp->inner_vlan_id_any;
1959 template.sub.eth.outer_vlan_id = ntohs(mp->outer_vlan_id);
1960 template.sub.eth.inner_vlan_id = ntohs(mp->inner_vlan_id);
1962 error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1964 clib_error_report (error);
1965 rv = VNET_API_ERROR_SUBIF_CREATE_FAILED;
1969 hash_set (hi->sub_interface_sw_if_index_by_id, sub_id, sw_if_index);
1970 hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1972 BAD_SW_IF_INDEX_LABEL;
1976 REPLY_MACRO2(VL_API_CREATE_SUBIF_REPLY,
1978 rmp->sw_if_index = ntohl(sw_if_index);
1983 vl_api_mpls_gre_add_del_tunnel_t_handler (vl_api_mpls_gre_add_del_tunnel_t *mp)
1985 vl_api_mpls_gre_add_del_tunnel_reply_t * rmp;
1987 stats_main_t * sm = &stats_main;
1988 u32 tunnel_sw_if_index = ~0;
1990 dslock (sm, 1 /* release hint */, 5 /* tag */);
1992 rv = vnet_mpls_gre_add_del_tunnel ((ip4_address_t *)(mp->src_address),
1993 (ip4_address_t *)(mp->dst_address),
1994 (ip4_address_t *)(mp->intfc_address),
1995 (u32)(mp->intfc_address_length),
1996 ntohl(mp->inner_vrf_id),
1997 ntohl(mp->outer_vrf_id),
1998 &tunnel_sw_if_index,
2003 REPLY_MACRO2(VL_API_MPLS_GRE_ADD_DEL_TUNNEL_REPLY,
2005 rmp->tunnel_sw_if_index = ntohl(tunnel_sw_if_index);
2010 vl_api_mpls_ethernet_add_del_tunnel_t_handler
2011 (vl_api_mpls_ethernet_add_del_tunnel_t *mp)
2013 vl_api_mpls_ethernet_add_del_tunnel_reply_t * rmp;
2015 stats_main_t * sm = &stats_main;
2016 u32 tunnel_sw_if_index;
2018 dslock (sm, 1 /* release hint */, 5 /* tag */);
2020 rv = vnet_mpls_ethernet_add_del_tunnel
2021 (mp->dst_mac_address, (ip4_address_t *)(mp->adj_address),
2022 (u32)(mp->adj_address_length), ntohl(mp->vrf_id),
2023 ntohl(mp->tx_sw_if_index),
2024 &tunnel_sw_if_index,
2030 REPLY_MACRO2(VL_API_MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,
2032 rmp->tunnel_sw_if_index = ntohl(tunnel_sw_if_index);
2037 * This piece of misery brought to you because the control-plane
2038 * can't figure out the tx interface + dst-mac address all by itself
2040 static int mpls_ethernet_add_del_tunnel_2_t_handler
2041 (vl_api_mpls_ethernet_add_del_tunnel_2_t *mp)
2043 pending_route_t * pr;
2044 vl_api_mpls_ethernet_add_del_tunnel_2_t *pme;
2045 vnet_main_t * vnm = vnet_get_main();
2046 vlib_main_t * vm = vlib_get_main();
2047 stats_main_t * sm = &stats_main;
2048 vpe_api_main_t * vam = &vpe_api_main;
2049 u32 inner_fib_index, outer_fib_index;
2050 ip4_main_t * im = &ip4_main;
2051 ip_lookup_main_t * lm = &im->lookup_main;
2052 ip_adjacency_t * adj = 0;
2055 u8 * dst_mac_address;
2059 u32 tunnel_sw_if_index;
2061 p = hash_get (im->fib_index_by_table_id, ntohl(mp->outer_vrf_id));
2063 return VNET_API_ERROR_NO_SUCH_FIB;
2065 outer_fib_index = p[0];
2068 p = hash_get (im->fib_index_by_table_id, ntohl(mp->inner_vrf_id));
2070 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
2072 inner_fib_index = p[0];
2074 if (inner_fib_index == outer_fib_index)
2075 return VNET_API_ERROR_INVALID_VALUE;
2077 lookup_result = ip4_fib_lookup_with_table
2078 (im, outer_fib_index,
2079 (ip4_address_t *)mp->next_hop_ip4_address_in_outer_vrf,
2080 1 /* disable default route */);
2082 adj = ip_get_adjacency (lm, lookup_result);
2083 tx_sw_if_index = adj->rewrite_header.sw_if_index;
2085 if (mp->is_add && mp->resolve_if_needed) {
2086 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP) {
2087 pool_get (vam->pending_routes, pr);
2088 pr->resolve_type = RESOLVE_MPLS_ETHERNET_ADD_DEL;
2090 clib_memcpy (pme, mp, sizeof (*pme));
2091 /* recursion block, "just in case" */
2092 pme->resolve_if_needed = 0;
2093 pme->resolve_attempts = ntohl(mp->resolve_attempts);
2094 pme->resolve_opaque = tx_sw_if_index;
2095 vnet_register_ip4_arp_resolution_event
2097 (ip4_address_t *)&(pme->next_hop_ip4_address_in_outer_vrf),
2098 vpe_resolver_process_node.index,
2099 RESOLUTION_EVENT, pr - vam->pending_routes);
2101 vlib_process_signal_event
2102 (vm, vpe_resolver_process_node.index,
2103 RESOLUTION_PENDING_EVENT, 0 /* data */);
2105 /* The interface may be down, etc. */
2106 e = ip4_probe_neighbor
2107 (vm, (ip4_address_t *)&(mp->next_hop_ip4_address_in_outer_vrf),
2111 clib_error_report(e);
2113 return VNET_API_ERROR_IN_PROGRESS;
2117 if (adj->lookup_next_index != IP_LOOKUP_NEXT_REWRITE)
2118 return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
2121 vnet_rewrite_get_data_internal
2122 (&adj->rewrite_header, sizeof (adj->rewrite_data));
2124 dslock (sm, 1 /* release hint */, 10 /* tag */);
2126 rv = vnet_mpls_ethernet_add_del_tunnel
2127 (dst_mac_address, (ip4_address_t *)(mp->adj_address),
2128 (u32)(mp->adj_address_length), ntohl(mp->inner_vrf_id),
2129 tx_sw_if_index, &tunnel_sw_if_index, mp->l2_only, mp->is_add);
2137 vl_api_mpls_ethernet_add_del_tunnel_2_t_handler
2138 (vl_api_mpls_ethernet_add_del_tunnel_2_t *mp)
2140 vl_api_mpls_ethernet_add_del_tunnel_reply_t * rmp;
2143 rv = mpls_ethernet_add_del_tunnel_2_t_handler (mp);
2145 REPLY_MACRO(VL_API_MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY);
2150 vl_api_mpls_add_del_encap_t_handler (vl_api_mpls_add_del_encap_t *mp)
2152 vl_api_mpls_add_del_encap_reply_t * rmp;
2154 static u32 * labels;
2157 vec_reset_length (labels);
2159 for (i = 0; i < mp->nlabels; i++)
2160 vec_add1 (labels, ntohl(mp->labels[i]));
2163 rv = vnet_mpls_add_del_encap ((ip4_address_t *)mp->dst_address,
2164 ntohl(mp->vrf_id), labels,
2165 ~0 /* policy_tunnel_index */,
2166 0 /* no_dst_hash */,
2170 REPLY_MACRO(VL_API_MPLS_ADD_DEL_ENCAP_REPLY);
2174 vl_api_mpls_add_del_decap_t_handler
2175 (vl_api_mpls_add_del_decap_t *mp)
2177 vl_api_mpls_add_del_decap_reply_t * rmp;
2180 rv = vnet_mpls_add_del_decap (ntohl(mp->rx_vrf_id), ntohl(mp->tx_vrf_id),
2181 ntohl(mp->label), ntohl(mp->next_index),
2182 mp->s_bit, mp->is_add);
2184 REPLY_MACRO(VL_API_MPLS_ADD_DEL_DECAP_REPLY);
2188 vl_api_proxy_arp_add_del_t_handler (vl_api_proxy_arp_add_del_t *mp)
2190 vl_api_proxy_arp_add_del_reply_t * rmp;
2193 ip4_main_t * im = &ip4_main;
2194 stats_main_t * sm = &stats_main;
2195 int vnet_proxy_arp_add_del (ip4_address_t *lo_addr,
2196 ip4_address_t *hi_addr,
2197 u32 fib_index, int is_del);
2200 dslock (sm, 1 /* release hint */, 6 /* tag */);
2202 p = hash_get (im->fib_index_by_table_id, ntohl(mp->vrf_id));
2205 rv = VNET_API_ERROR_NO_SUCH_FIB;
2211 rv = vnet_proxy_arp_add_del ((ip4_address_t *)mp->low_address,
2212 (ip4_address_t *)mp->hi_address,
2213 fib_index, mp->is_add == 0);
2217 REPLY_MACRO(VL_API_PROXY_ARP_ADD_DEL_REPLY);
2221 vl_api_proxy_arp_intfc_enable_disable_t_handler
2222 (vl_api_proxy_arp_intfc_enable_disable_t *mp)
2225 vnet_main_t * vnm = vnet_get_main();
2226 vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;
2227 vnet_sw_interface_t * si;
2230 VALIDATE_SW_IF_INDEX(mp);
2232 sw_if_index = ntohl(mp->sw_if_index);
2234 if (pool_is_free_index (vnm->interface_main.sw_interfaces,
2236 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
2240 si = vnet_get_sw_interface (vnm, sw_if_index);
2244 if (mp->enable_disable)
2245 si->flags |= VNET_SW_INTERFACE_FLAG_PROXY_ARP;
2247 si->flags &= ~VNET_SW_INTERFACE_FLAG_PROXY_ARP;
2249 BAD_SW_IF_INDEX_LABEL;
2252 REPLY_MACRO(VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
2256 vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t *mp, vlib_main_t * vm)
2258 vl_api_ip_neighbor_add_del_reply_t * rmp;
2259 vnet_main_t * vnm = vnet_get_main();
2262 stats_main_t * sm = &stats_main;
2264 VALIDATE_SW_IF_INDEX(mp);
2266 dslock (sm, 1 /* release hint */, 7 /* tag */);
2270 rv = vnet_set_ip6_ethernet_neighbor
2271 (vm, ntohl(mp->sw_if_index),
2272 (ip6_address_t *)(mp->dst_address),
2273 mp->mac_address, sizeof (mp->mac_address), mp->is_static);
2275 rv = vnet_unset_ip6_ethernet_neighbor
2276 (vm, ntohl(mp->sw_if_index),
2277 (ip6_address_t *)(mp->dst_address),
2278 mp->mac_address, sizeof(mp->mac_address));
2280 ip4_main_t * im = &ip4_main;
2281 ip_lookup_main_t * lm = &im->lookup_main;
2282 ethernet_arp_ip4_over_ethernet_address_t a;
2284 ip_adjacency_t *nh_adj;
2286 uword * p = hash_get (im->fib_index_by_table_id, ntohl(mp->vrf_id));
2288 rv = VNET_API_ERROR_NO_SUCH_FIB;
2294 * Unfortunately, folks have a penchant for
2295 * adding interface addresses to the ARP cache, and
2296 * wondering why the forwarder eventually ASSERTs...
2298 ai = ip4_fib_lookup_with_table
2299 (im, fib_index, (ip4_address_t *)(mp->dst_address),
2300 1 /* disable default route */);
2303 nh_adj = ip_get_adjacency (lm, ai);
2304 /* Never allow manipulation of a local adj! */
2305 if (nh_adj->lookup_next_index == IP_LOOKUP_NEXT_LOCAL) {
2306 clib_warning("%U matches local adj",
2308 (ip4_address_t *)(mp->dst_address));
2309 rv = VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
2314 clib_memcpy (&a.ethernet, mp->mac_address, 6);
2315 clib_memcpy (&a.ip4, mp->dst_address, 4);
2318 rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl(mp->sw_if_index),
2319 fib_index, &a, mp->is_static);
2321 rv = vnet_arp_unset_ip4_over_ethernet (vnm, ntohl(mp->sw_if_index),
2325 BAD_SW_IF_INDEX_LABEL;
2328 REPLY_MACRO(VL_API_IP_NEIGHBOR_ADD_DEL_REPLY);
2332 vl_api_is_address_reachable_t_handler (vl_api_is_address_reachable_t *mp)
2335 vpe_main_t *rm = &vpe_main;
2336 ip4_main_t *im4 = &ip4_main;
2337 ip6_main_t *im6 = &ip6_main;
2338 ip_lookup_main_t * lm;
2343 u32 adj_index, sw_if_index;
2344 vl_api_is_address_reachable_t *rmp;
2345 ip_adjacency_t * adj;
2346 unix_shared_memory_queue_t *q;
2348 q = vl_api_client_index_to_input_queue (mp->client_index);
2350 increment_missing_api_client_counter (rm->vlib_main);
2354 rmp = vl_msg_api_alloc (sizeof (*rmp));
2355 clib_memcpy (rmp, mp, sizeof (*rmp));
2357 sw_if_index = mp->next_hop_sw_if_index;
2358 clib_memcpy (&addr, mp->address, sizeof (addr));
2360 lm = &im6->lookup_main;
2362 ip6_fib_lookup (im6, sw_if_index, &addr.ip6);
2364 lm = &im4->lookup_main;
2366 ip4_fib_lookup (im4, sw_if_index, &addr.ip4);
2368 if (adj_index == ~0) {
2372 adj = ip_get_adjacency (lm, adj_index);
2374 if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE
2375 && adj->rewrite_header.sw_if_index == sw_if_index) {
2378 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP
2379 && adj->rewrite_header.sw_if_index == sw_if_index) {
2381 ip6_probe_neighbor (rm->vlib_main, &addr.ip6, sw_if_index);
2383 ip4_probe_neighbor (rm->vlib_main, &addr.ip4, sw_if_index);
2384 } else if (adj->lookup_next_index == IP_LOOKUP_NEXT_DROP) {
2392 vl_msg_api_send_shmem (q, (u8 *)&rmp);
2396 static void vl_api_sw_interface_details_t_handler (
2397 vl_api_sw_interface_details_t * mp)
2399 clib_warning ("BUG");
2402 static void vl_api_sw_interface_set_flags_t_handler (
2403 vl_api_sw_interface_set_flags_t * mp)
2405 vl_api_sw_interface_set_flags_reply_t *rmp;
2406 vnet_main_t * vnm = vnet_get_main();
2408 clib_error_t * error;
2411 VALIDATE_SW_IF_INDEX(mp);
2413 flags = mp->admin_up_down ? VNET_SW_INTERFACE_FLAG_ADMIN_UP : 0;
2415 error = vnet_sw_interface_set_flags (vnm,
2416 ntohl(mp->sw_if_index),
2420 clib_error_report (error);
2423 BAD_SW_IF_INDEX_LABEL;
2424 REPLY_MACRO(VL_API_SW_INTERFACE_SET_FLAGS_REPLY);
2427 static void vl_api_sw_interface_clear_stats_t_handler (
2428 vl_api_sw_interface_clear_stats_t * mp)
2430 vl_api_sw_interface_clear_stats_reply_t *rmp;
2432 vnet_main_t * vnm = vnet_get_main();
2433 vnet_interface_main_t * im = &vnm->interface_main;
2434 vlib_simple_counter_main_t * sm;
2435 vlib_combined_counter_main_t * cm;
2436 static vnet_main_t ** my_vnet_mains;
2437 int i, j, n_counters;
2441 vec_reset_length (my_vnet_mains);
2443 for (i = 0; i < vec_len (vnet_mains); i++)
2446 vec_add1 (my_vnet_mains, vnet_mains[i]);
2449 if (vec_len (vnet_mains) == 0)
2450 vec_add1 (my_vnet_mains, vnm);
2452 n_counters = vec_len (im->combined_sw_if_counters);
2454 for (j = 0; j < n_counters; j++)
2456 for (i = 0; i < vec_len(my_vnet_mains); i++)
2458 im = &my_vnet_mains[i]->interface_main;
2459 cm = im->combined_sw_if_counters + j;
2460 if (mp->sw_if_index == (u32)~0)
2461 vlib_clear_combined_counters (cm);
2463 vlib_zero_combined_counter (cm, ntohl(mp->sw_if_index));
2467 n_counters = vec_len (im->sw_if_counters);
2469 for (j = 0; j < n_counters; j++)
2471 for (i = 0; i < vec_len(my_vnet_mains); i++)
2473 im = &my_vnet_mains[i]->interface_main;
2474 sm = im->sw_if_counters + j;
2475 if (mp->sw_if_index == (u32)~0)
2476 vlib_clear_simple_counters (sm);
2478 vlib_zero_simple_counter (sm, ntohl(mp->sw_if_index));
2482 REPLY_MACRO(VL_API_SW_INTERFACE_CLEAR_STATS_REPLY);
2485 static void send_sw_interface_details (vpe_api_main_t * am,
2486 unix_shared_memory_queue_t *q,
2487 vnet_sw_interface_t * swif,
2488 u8 * interface_name,
2491 vl_api_sw_interface_details_t * mp;
2492 vnet_hw_interface_t * hi;
2494 hi = vnet_get_sup_hw_interface (am->vnet_main, swif->sw_if_index);
2496 mp = vl_msg_api_alloc (sizeof (*mp));
2497 memset (mp, 0, sizeof (*mp));
2498 mp->_vl_msg_id = ntohs(VL_API_SW_INTERFACE_DETAILS);
2499 mp->sw_if_index = ntohl(swif->sw_if_index);
2500 mp->sup_sw_if_index = ntohl(swif->sup_sw_if_index);
2501 mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
2503 mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ?
2505 mp->link_duplex = ((hi->flags & VNET_HW_INTERFACE_FLAG_DUPLEX_MASK) >>
2506 VNET_HW_INTERFACE_FLAG_DUPLEX_SHIFT);
2507 mp->link_speed = ((hi->flags & VNET_HW_INTERFACE_FLAG_SPEED_MASK) >>
2508 VNET_HW_INTERFACE_FLAG_SPEED_SHIFT);
2509 mp->link_mtu = ntohs(hi->max_packet_bytes);
2510 mp->context = context;
2512 strncpy ((char *) mp->interface_name,
2513 (char *) interface_name, ARRAY_LEN(mp->interface_name)-1);
2515 /* Send the L2 address for ethernet physical intfcs */
2516 if (swif->sup_sw_if_index == swif->sw_if_index
2517 && hi->hw_class_index == ethernet_hw_interface_class.index) {
2518 ethernet_main_t *em = ethernet_get_main (am->vlib_main);
2519 ethernet_interface_t *ei;
2521 ei = pool_elt_at_index (em->interfaces, hi->hw_instance);
2522 ASSERT (sizeof (mp->l2_address) >= sizeof (ei->address));
2523 clib_memcpy (mp->l2_address, ei->address, sizeof (ei->address));
2524 mp->l2_address_length = ntohl(sizeof (ei->address));
2525 } else if (swif->sup_sw_if_index != swif->sw_if_index) {
2526 vnet_sub_interface_t *sub = &swif->sub;
2527 mp->sub_id = ntohl(sub->id);
2528 mp->sub_dot1ad = sub->eth.flags.dot1ad;
2529 mp->sub_number_of_tags = sub->eth.flags.one_tag + sub->eth.flags.two_tags*2;
2530 mp->sub_outer_vlan_id = ntohs(sub->eth.outer_vlan_id);
2531 mp->sub_inner_vlan_id = ntohs(sub->eth.inner_vlan_id);
2532 mp->sub_exact_match = sub->eth.flags.exact_match;
2533 mp->sub_default = sub->eth.flags.default_sub;
2534 mp->sub_outer_vlan_id_any = sub->eth.flags.outer_vlan_id_any;
2535 mp->sub_inner_vlan_id_any = sub->eth.flags.inner_vlan_id_any;
2537 /* vlan tag rewrite data */
2538 u32 vtr_op = L2_VTR_DISABLED;
2539 u32 vtr_push_dot1q = 0, vtr_tag1 = 0, vtr_tag2 = 0;
2541 if (l2vtr_get(am->vlib_main, am->vnet_main, swif->sw_if_index,
2542 &vtr_op, &vtr_push_dot1q, &vtr_tag1, &vtr_tag2) != 0) {
2543 // error - default to disabled
2544 mp->vtr_op = ntohl(L2_VTR_DISABLED);
2545 clib_warning("cannot get vlan tag rewrite for sw_if_index %d",
2548 mp->vtr_op = ntohl(vtr_op);
2549 mp->vtr_push_dot1q = ntohl(vtr_push_dot1q);
2550 mp->vtr_tag1 = ntohl(vtr_tag1);
2551 mp->vtr_tag2 = ntohl(vtr_tag2);
2555 vl_msg_api_send_shmem (q, (u8 *)&mp);
2558 static void send_sw_interface_flags (vpe_api_main_t * am,
2559 unix_shared_memory_queue_t *q,
2560 vnet_sw_interface_t * swif)
2562 vl_api_sw_interface_set_flags_t *mp;
2563 vnet_main_t * vnm = am->vnet_main;
2565 vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm,
2567 mp = vl_msg_api_alloc (sizeof (*mp));
2568 memset (mp, 0, sizeof (*mp));
2569 mp->_vl_msg_id = ntohs(VL_API_SW_INTERFACE_SET_FLAGS);
2570 mp->sw_if_index = ntohl(swif->sw_if_index);
2572 mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
2574 mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ?
2576 vl_msg_api_send_shmem (q, (u8 *)&mp);
2579 static void send_sw_interface_flags_deleted (vpe_api_main_t * am,
2580 unix_shared_memory_queue_t *q,
2582 __attribute__((unused));
2584 static void send_sw_interface_flags_deleted (vpe_api_main_t * am,
2585 unix_shared_memory_queue_t *q,
2588 vl_api_sw_interface_set_flags_t *mp;
2590 mp = vl_msg_api_alloc (sizeof (*mp));
2591 memset (mp, 0, sizeof (*mp));
2592 mp->_vl_msg_id = ntohs(VL_API_SW_INTERFACE_SET_FLAGS);
2593 mp->sw_if_index = ntohl(sw_if_index);
2595 mp->admin_up_down = 0;
2596 mp->link_up_down = 0;
2598 vl_msg_api_send_shmem (q, (u8 *)&mp);
2601 static void vl_api_sw_interface_dump_t_handler (
2602 vl_api_sw_interface_dump_t *mp)
2604 vpe_api_main_t * am = &vpe_api_main;
2605 vnet_sw_interface_t * swif;
2606 vnet_interface_main_t * im = &am->vnet_main->interface_main;
2607 u8 * filter_string = 0, * name_string = 0;
2608 unix_shared_memory_queue_t * q;
2609 char * strcasestr (char *, char *); /* lnx hdr file botch */
2611 q = vl_api_client_index_to_input_queue (mp->client_index);
2616 if (mp->name_filter_valid) {
2617 mp->name_filter [ARRAY_LEN(mp->name_filter)-1] = 0;
2618 filter_string = format (0, "%s%c", mp->name_filter, 0);
2621 pool_foreach (swif, im->sw_interfaces,
2623 name_string = format (name_string, "%U%c",
2624 format_vnet_sw_interface_name,
2625 am->vnet_main, swif, 0);
2627 if (mp->name_filter_valid == 0 ||
2628 strcasestr((char *) name_string, (char *) filter_string)) {
2630 send_sw_interface_details (am, q, swif, name_string, mp->context);
2632 _vec_len (name_string) = 0;
2635 vec_free (name_string);
2636 vec_free (filter_string);
2639 void send_oam_event (oam_target_t * t)
2641 vpe_api_main_t * vam = &vpe_api_main;
2642 unix_shared_memory_queue_t * q;
2643 vpe_client_registration_t *reg;
2644 vl_api_oam_event_t * mp;
2646 pool_foreach(reg, vam->oam_events_registrations,
2648 q = vl_api_client_index_to_input_queue (reg->client_index);
2650 mp = vl_msg_api_alloc (sizeof (*mp));
2651 mp->_vl_msg_id = ntohs (VL_API_OAM_EVENT);
2652 clib_memcpy (mp->dst_address, &t->dst_address, sizeof (mp->dst_address));
2653 mp->state = t->state;
2654 vl_msg_api_send_shmem (q, (u8 *)&mp);
2660 vl_api_oam_add_del_t_handler (vl_api_oam_add_del_t *mp)
2662 vl_api_oam_add_del_reply_t * rmp;
2665 rv = vpe_oam_add_del_target ((ip4_address_t *)mp->src_address,
2666 (ip4_address_t *)mp->dst_address,
2670 REPLY_MACRO(VL_API_OAM_ADD_DEL_REPLY);
2674 vl_api_vnet_get_summary_stats_t_handler (
2675 vl_api_vnet_get_summary_stats_t *mp)
2677 stats_main_t * sm = &stats_main;
2678 vnet_interface_main_t * im = sm->interface_main;
2679 vl_api_vnet_summary_stats_reply_t *rmp;
2680 vlib_combined_counter_main_t * cm;
2683 u64 total_pkts[VLIB_N_RX_TX];
2684 u64 total_bytes[VLIB_N_RX_TX];
2686 unix_shared_memory_queue_t * q =
2687 vl_api_client_index_to_input_queue (mp->client_index);
2692 rmp = vl_msg_api_alloc (sizeof (*rmp));
2693 rmp->_vl_msg_id = ntohs(VL_API_VNET_SUMMARY_STATS_REPLY);
2694 rmp->context = mp->context;
2697 memset (total_pkts, 0, sizeof (total_pkts));
2698 memset (total_bytes, 0, sizeof (total_bytes));
2700 vnet_interface_counter_lock (im);
2702 vec_foreach (cm, im->combined_sw_if_counters) {
2703 which = cm - im->combined_sw_if_counters;
2705 for (i = 0; i < vec_len (cm->maxi); i++) {
2706 vlib_get_combined_counter (cm, i, &v);
2707 total_pkts[which] += v.packets;
2708 total_bytes[which] += v.bytes;
2711 vnet_interface_counter_unlock (im);
2713 /* Note: in HOST byte order! */
2714 rmp->total_pkts[VLIB_RX] = total_pkts[VLIB_RX];
2715 rmp->total_bytes[VLIB_RX] = total_bytes[VLIB_RX];
2716 rmp->total_pkts[VLIB_TX] = total_pkts[VLIB_TX];
2717 rmp->total_bytes[VLIB_TX] = total_bytes[VLIB_TX];
2718 rmp->vector_rate = vlib_last_vector_length_per_node (sm->vlib_main);
2720 vl_msg_api_send_shmem (q, (u8 *)&rmp);
2723 typedef CLIB_PACKED (struct {
2724 ip4_address_t address;
2726 u32 address_length : 6;
2731 static int ip4_reset_fib_t_handler (vl_api_reset_fib_t *mp)
2733 vnet_main_t * vnm = vnet_get_main();
2734 vnet_interface_main_t * im = &vnm->interface_main;
2735 ip4_main_t * im4 = &ip4_main;
2736 static ip4_route_t * routes;
2737 static u32 * sw_if_indices_to_shut;
2738 stats_main_t * sm = &stats_main;
2743 int rv = VNET_API_ERROR_NO_SUCH_FIB;
2744 u32 target_fib_id = ntohl(mp->vrf_id);
2746 dslock (sm, 1 /* release hint */, 8 /* tag */);
2748 vec_foreach (fib, im4->fibs) {
2749 vnet_sw_interface_t * si;
2751 if (fib->table_id != target_fib_id)
2754 /* remove any mpls/gre tunnels in this fib */
2755 vnet_mpls_gre_delete_fib_tunnels (fib->table_id);
2757 /* remove any mpls encap/decap labels */
2758 mpls_fib_reset_labels (fib->table_id);
2760 /* remove any proxy arps in this fib */
2761 vnet_proxy_arp_fib_reset (fib->table_id);
2763 /* Set the flow hash for this fib to the default */
2764 vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
2766 vec_reset_length (sw_if_indices_to_shut);
2768 /* Shut down interfaces in this FIB / clean out intfc routes */
2769 pool_foreach (si, im->sw_interfaces,
2771 u32 sw_if_index = si->sw_if_index;
2773 if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
2774 && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
2776 vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
2779 for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
2780 sw_if_index = sw_if_indices_to_shut[i];
2781 // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
2783 u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
2784 flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
2785 vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
2788 vec_reset_length (routes);
2790 for (i = 0; i < ARRAY_LEN (fib->adj_index_by_dst_address); i++) {
2791 uword * hash = fib->adj_index_by_dst_address[i];
2795 x.address_length = i;
2797 hash_foreach_pair (p, hash,
2799 x.address.data_u32 = p->key;
2800 vec_add1 (routes, x);
2804 vec_foreach (r, routes) {
2805 ip4_add_del_route_args_t a;
2807 memset (&a, 0, sizeof (a));
2808 a.flags = IP4_ROUTE_FLAG_FIB_INDEX | IP4_ROUTE_FLAG_DEL;
2809 a.table_index_or_table_id = fib - im4->fibs;
2810 a.dst_address = r->address;
2811 a.dst_address_length = r->address_length;
2814 ip4_add_del_route (im4, &a);
2815 ip4_maybe_remap_adjacencies (im4, fib - im4->fibs,
2816 IP4_ROUTE_FLAG_FIB_INDEX);
2820 } /* vec_foreach (fib) */
2827 ip6_address_t address;
2834 ip6_route_t ** routep;
2835 } add_routes_in_fib_arg_t;
2837 static void add_routes_in_fib (clib_bihash_kv_24_8_t * kvp, void *arg)
2839 add_routes_in_fib_arg_t * ap = arg;
2841 if (kvp->key[2]>>32 == ap->fib_index)
2843 ip6_address_t *addr;
2845 addr = (ip6_address_t *) kvp;
2846 vec_add2 (*ap->routep, r, 1);
2847 r->address = addr[0];
2848 r->address_length = kvp->key[2] & 0xFF;
2849 r->index = kvp->value;
2853 static int ip6_reset_fib_t_handler (vl_api_reset_fib_t *mp)
2855 vnet_main_t * vnm = vnet_get_main();
2856 vnet_interface_main_t * im = &vnm->interface_main;
2857 ip6_main_t * im6 = &ip6_main;
2858 stats_main_t * sm = &stats_main;
2859 static ip6_route_t * routes;
2860 static u32 * sw_if_indices_to_shut;
2865 int rv = VNET_API_ERROR_NO_SUCH_FIB;
2866 u32 target_fib_id = ntohl(mp->vrf_id);
2867 add_routes_in_fib_arg_t _a, *a=&_a;
2868 clib_bihash_24_8_t * h = &im6->ip6_lookup_table;
2870 dslock (sm, 1 /* release hint */, 9 /* tag */);
2872 vec_foreach (fib, im6->fibs) {
2873 vnet_sw_interface_t * si;
2875 if (fib->table_id != target_fib_id)
2878 vec_reset_length (sw_if_indices_to_shut);
2880 /* Shut down interfaces in this FIB / clean out intfc routes */
2881 pool_foreach (si, im->sw_interfaces,
2883 if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
2885 vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
2888 for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
2889 sw_if_index = sw_if_indices_to_shut[i];
2890 // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
2892 u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
2893 flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
2894 vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
2897 vec_reset_length (routes);
2899 a->fib_index = fib - im6->fibs;
2900 a->routep = &routes;
2902 clib_bihash_foreach_key_value_pair_24_8 (h, add_routes_in_fib, a);
2904 vec_foreach (r, routes) {
2905 ip6_add_del_route_args_t a;
2907 memset (&a, 0, sizeof (a));
2908 a.flags = IP6_ROUTE_FLAG_FIB_INDEX | IP6_ROUTE_FLAG_DEL;
2909 a.table_index_or_table_id = fib - im6->fibs;
2910 a.dst_address = r->address;
2911 a.dst_address_length = r->address_length;
2914 ip6_add_del_route (im6, &a);
2915 ip6_maybe_remap_adjacencies (im6, fib - im6->fibs,
2916 IP6_ROUTE_FLAG_FIB_INDEX);
2919 /* Reinstall the neighbor / router discovery routes */
2920 vnet_ip6_fib_init (im6, fib - im6->fibs);
2922 } /* vec_foreach (fib) */
2928 static void vl_api_reset_fib_t_handler (vl_api_reset_fib_t *mp)
2931 vl_api_reset_fib_reply_t * rmp;
2934 rv = ip6_reset_fib_t_handler (mp);
2936 rv = ip4_reset_fib_t_handler (mp);
2938 REPLY_MACRO(VL_API_RESET_FIB_REPLY);
2943 dhcpv4_proxy_config (vl_api_dhcp_proxy_config_t *mp)
2945 vl_api_dhcp_proxy_config_reply_t * rmp;
2948 rv = dhcp_proxy_set_server ((ip4_address_t *)(&mp->dhcp_server),
2949 (ip4_address_t *)(&mp->dhcp_src_address),
2950 (u32) ntohl(mp->vrf_id),
2951 (int) mp->insert_circuit_id,
2952 (int) (mp->is_add == 0));
2954 REPLY_MACRO(VL_API_DHCP_PROXY_CONFIG_REPLY);
2959 dhcpv6_proxy_config (vl_api_dhcp_proxy_config_t *mp)
2961 vl_api_dhcp_proxy_config_reply_t * rmp;
2964 rv = dhcpv6_proxy_set_server ((ip6_address_t *)(&mp->dhcp_server),
2965 (ip6_address_t *)(&mp->dhcp_src_address),
2966 (u32) ntohl(mp->vrf_id),
2967 (int) mp->insert_circuit_id,
2968 (int) (mp->is_add == 0));
2970 REPLY_MACRO(VL_API_DHCP_PROXY_CONFIG_REPLY);
2974 dhcpv4_proxy_config_2 (vl_api_dhcp_proxy_config_2_t *mp)
2976 vl_api_dhcp_proxy_config_reply_t * rmp;
2979 rv = dhcp_proxy_set_server_2 ((ip4_address_t *)(&mp->dhcp_server),
2980 (ip4_address_t *)(&mp->dhcp_src_address),
2981 (u32) ntohl(mp->rx_vrf_id),
2982 (u32) ntohl(mp->server_vrf_id),
2983 (int) mp->insert_circuit_id,
2984 (int) (mp->is_add == 0));
2986 REPLY_MACRO(VL_API_DHCP_PROXY_CONFIG_2_REPLY);
2991 dhcpv6_proxy_config_2 (vl_api_dhcp_proxy_config_2_t *mp)
2993 vl_api_dhcp_proxy_config_reply_t * rmp;
2997 rv = dhcpv6_proxy_set_server_2 ((ip6_address_t *)(&mp->dhcp_server),
2998 (ip6_address_t *)(&mp->dhcp_src_address),
2999 (u32) ntohl(mp->rx_vrf_id),
3000 (u32) ntohl(mp->server_vrf_id),
3001 (int) mp->insert_circuit_id,
3002 (int) (mp->is_add == 0));
3004 rv = VNET_API_ERROR_UNIMPLEMENTED;
3007 REPLY_MACRO(VL_API_DHCP_PROXY_CONFIG_2_REPLY);
3012 vl_api_dhcp_proxy_set_vss_t_handler (vl_api_dhcp_proxy_set_vss_t *mp)
3014 vl_api_dhcp_proxy_set_vss_reply_t *rmp;
3017 rv = dhcp_proxy_set_option82_vss(ntohl(mp->tbl_id),
3020 (int)mp->is_add == 0);
3022 rv = dhcpv6_proxy_set_vss( ntohl(mp->tbl_id),
3025 (int)mp->is_add == 0);
3027 REPLY_MACRO(VL_API_DHCP_PROXY_SET_VSS_REPLY);
3031 static void vl_api_dhcp_proxy_config_t_handler
3032 (vl_api_dhcp_proxy_config_t *mp)
3034 if (mp->is_ipv6 == 0)
3035 dhcpv4_proxy_config (mp);
3037 dhcpv6_proxy_config (mp);
3040 static void vl_api_dhcp_proxy_config_2_t_handler
3041 (vl_api_dhcp_proxy_config_2_t *mp)
3043 if (mp->is_ipv6 == 0)
3044 dhcpv4_proxy_config_2 (mp);
3046 dhcpv6_proxy_config_2 (mp);
3049 void dhcp_compl_event_callback (u32 client_index, u32 pid, u8 * hostname,
3050 u8 is_ipv6, u8 * host_address, u8 * router_address, u8 * host_mac)
3052 unix_shared_memory_queue_t * q;
3053 vl_api_dhcp_compl_event_t * mp;
3055 q = vl_api_client_index_to_input_queue (client_index);
3059 mp = vl_msg_api_alloc (sizeof (*mp));
3060 mp->client_index = client_index;
3062 mp->is_ipv6 = is_ipv6;
3063 clib_memcpy (&mp->hostname, hostname, vec_len(hostname));
3064 mp->hostname[vec_len(hostname) + 1] = '\n';
3065 clib_memcpy (&mp->host_address[0], host_address, 16);
3066 clib_memcpy (&mp->router_address[0], router_address, 16);
3067 clib_memcpy (&mp->host_mac[0], host_mac, 6);
3069 mp->_vl_msg_id = ntohs (VL_API_DHCP_COMPL_EVENT);
3071 vl_msg_api_send_shmem (q, (u8 *)&mp);
3074 static void vl_api_dhcp_client_config_t_handler
3075 (vl_api_dhcp_client_config_t *mp)
3077 vlib_main_t *vm = vlib_get_main();
3078 vl_api_dhcp_client_config_reply_t * rmp;
3081 VALIDATE_SW_IF_INDEX(mp);
3083 rv = dhcp_client_config(vm, ntohl(mp->sw_if_index),
3084 mp->hostname, mp->is_add, mp->client_index,
3085 mp->want_dhcp_event ? dhcp_compl_event_callback : NULL,
3088 BAD_SW_IF_INDEX_LABEL;
3090 REPLY_MACRO(VL_API_DHCP_CLIENT_CONFIG_REPLY);
3094 vl_api_sw_interface_ip6nd_ra_config_t_handler
3095 (vl_api_sw_interface_ip6nd_ra_config_t *mp, vlib_main_t *vm)
3097 vl_api_sw_interface_ip6nd_ra_config_reply_t * rmp;
3099 u8 is_no, surpress, managed, other, ll_option, send_unicast, cease, default_router;
3101 is_no = mp->is_no == 1;
3102 surpress = mp->surpress == 1;
3103 managed = mp->managed == 1;
3104 other = mp->other == 1;
3105 ll_option = mp->ll_option == 1;
3106 send_unicast = mp->send_unicast == 1;
3107 cease = mp->cease == 1;
3108 default_router = mp->default_router == 1;
3110 VALIDATE_SW_IF_INDEX(mp);
3112 rv = ip6_neighbor_ra_config(vm, ntohl(mp->sw_if_index),
3113 surpress, managed, other,
3114 ll_option, send_unicast, cease,
3115 default_router, ntohl (mp->lifetime),
3116 ntohl(mp->initial_count), ntohl(mp->initial_interval),
3117 ntohl(mp->max_interval), ntohl( mp->min_interval),
3120 BAD_SW_IF_INDEX_LABEL;
3122 REPLY_MACRO(VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
3126 vl_api_sw_interface_ip6nd_ra_prefix_t_handler
3127 (vl_api_sw_interface_ip6nd_ra_prefix_t *mp, vlib_main_t *vm)
3129 vl_api_sw_interface_ip6nd_ra_prefix_reply_t * rmp;
3131 u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
3133 VALIDATE_SW_IF_INDEX(mp);
3135 is_no = mp->is_no == 1;
3136 use_default = mp->use_default == 1;
3137 no_advertise = mp->no_advertise == 1;
3138 off_link = mp->off_link == 1;
3139 no_autoconfig = mp->no_autoconfig == 1;
3140 no_onlink = mp->no_onlink == 1;
3142 rv = ip6_neighbor_ra_prefix(vm, ntohl(mp->sw_if_index),
3143 (ip6_address_t *)mp->address, mp->address_length,
3144 use_default, ntohl(mp->val_lifetime), ntohl(mp->pref_lifetime),
3145 no_advertise, off_link, no_autoconfig, no_onlink,
3148 BAD_SW_IF_INDEX_LABEL;
3149 REPLY_MACRO(VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
3153 vl_api_sw_interface_ip6_enable_disable_t_handler
3154 (vl_api_sw_interface_ip6_enable_disable_t *mp, vlib_main_t *vm)
3156 vl_api_sw_interface_ip6_enable_disable_reply_t * rmp;
3157 vnet_main_t * vnm = vnet_get_main();
3159 clib_error_t * error;
3163 VALIDATE_SW_IF_INDEX(mp);
3165 error = ( mp->enable == 1) ? enable_ip6_interface(vm,ntohl(mp->sw_if_index)) :
3166 disable_ip6_interface(vm,ntohl(mp->sw_if_index));
3169 clib_error_report(error);
3170 rv = VNET_API_ERROR_UNSPECIFIED;
3172 rv = vnm->api_errno;
3175 BAD_SW_IF_INDEX_LABEL;
3177 REPLY_MACRO(VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
3181 vl_api_sw_interface_ip6_set_link_local_address_t_handler
3182 (vl_api_sw_interface_ip6_set_link_local_address_t *mp, vlib_main_t *vm)
3184 vl_api_sw_interface_ip6_set_link_local_address_reply_t * rmp;
3186 clib_error_t * error;
3187 vnet_main_t * vnm = vnet_get_main();
3191 VALIDATE_SW_IF_INDEX(mp);
3193 error = set_ip6_link_local_address(vm,
3194 ntohl(mp->sw_if_index),
3195 (ip6_address_t *)mp->address,
3196 mp->address_length);
3198 clib_error_report(error);
3199 rv = VNET_API_ERROR_UNSPECIFIED;
3201 rv = vnm->api_errno;
3204 BAD_SW_IF_INDEX_LABEL;
3206 REPLY_MACRO(VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY);
3209 static void set_ip6_flow_hash (vl_api_set_ip_flow_hash_t *mp)
3211 vl_api_set_ip_flow_hash_reply_t *rmp;
3212 int rv = VNET_API_ERROR_UNIMPLEMENTED;
3214 clib_warning ("unimplemented...");
3216 REPLY_MACRO(VL_API_SET_IP_FLOW_HASH_REPLY);
3219 static void set_ip4_flow_hash (vl_api_set_ip_flow_hash_t *mp)
3221 vl_api_set_ip_flow_hash_reply_t *rmp;
3224 u32 flow_hash_config = 0;
3226 table_id = ntohl(mp->vrf_id);
3228 #define _(a,b) if (mp->a) flow_hash_config |= b;
3229 foreach_flow_hash_bit;
3232 rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config);
3234 REPLY_MACRO(VL_API_SET_IP_FLOW_HASH_REPLY);
3238 static void vl_api_set_ip_flow_hash_t_handler
3239 (vl_api_set_ip_flow_hash_t *mp)
3241 if (mp->is_ipv6 == 0)
3242 set_ip4_flow_hash (mp);
3244 set_ip6_flow_hash (mp);
3247 static void vl_api_sw_interface_set_unnumbered_t_handler
3248 (vl_api_sw_interface_set_unnumbered_t *mp)
3250 vl_api_sw_interface_set_unnumbered_reply_t * rmp;
3252 vnet_sw_interface_t * si;
3253 vnet_main_t *vnm = vnet_get_main();
3254 u32 sw_if_index, unnumbered_sw_if_index;
3256 sw_if_index = ntohl(mp->sw_if_index);
3257 unnumbered_sw_if_index = ntohl(mp->unnumbered_sw_if_index);
3260 * The API message field names are backwards from
3261 * the underlying data structure names.
3262 * It's not worth changing them now.
3264 if (pool_is_free_index (vnm->interface_main.sw_interfaces,
3265 unnumbered_sw_if_index)) {
3266 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
3270 /* Only check the "use loop0" field when setting the binding */
3272 pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index)) {
3273 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
3277 si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index);
3280 si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED;
3281 si->unnumbered_sw_if_index = sw_if_index;
3283 si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED);
3284 si->unnumbered_sw_if_index = (u32)~0;
3288 REPLY_MACRO(VL_API_SW_INTERFACE_SET_UNNUMBERED_REPLY);
3291 static void vl_api_create_loopback_t_handler
3292 (vl_api_create_loopback_t *mp)
3294 vl_api_create_loopback_reply_t * rmp;
3298 rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address);
3300 REPLY_MACRO2(VL_API_CREATE_LOOPBACK_REPLY,
3302 rmp->sw_if_index = ntohl (sw_if_index);
3306 static void vl_api_delete_loopback_t_handler
3307 (vl_api_delete_loopback_t *mp)
3309 vl_api_delete_loopback_reply_t * rmp;
3313 sw_if_index = ntohl (mp->sw_if_index);
3314 rv = vnet_delete_loopback_interface (sw_if_index);
3316 REPLY_MACRO(VL_API_DELETE_LOOPBACK_REPLY);
3319 static void vl_api_control_ping_t_handler
3320 (vl_api_control_ping_t *mp)
3322 vl_api_control_ping_reply_t * rmp;
3325 REPLY_MACRO2(VL_API_CONTROL_PING_REPLY,
3327 rmp->vpe_pid = ntohl (getpid());
3331 static void shmem_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
3333 u8 **shmem_vecp = (u8 **)arg;
3336 api_main_t * am = &api_main;
3339 shmem_vec = *shmem_vecp;
3341 offset = vec_len (shmem_vec);
3343 pthread_mutex_lock (&am->vlib_rp->mutex);
3344 oldheap = svm_push_data_heap (am->vlib_rp);
3346 vec_validate (shmem_vec, offset + buffer_bytes - 1);
3348 clib_memcpy (shmem_vec + offset, buffer, buffer_bytes);
3350 svm_pop_heap (oldheap);
3351 pthread_mutex_unlock (&am->vlib_rp->mutex);
3353 *shmem_vecp = shmem_vec;
3357 static void vl_api_cli_request_t_handler
3358 (vl_api_cli_request_t *mp)
3360 vl_api_cli_reply_t *rp;
3361 unix_shared_memory_queue_t *q;
3362 vlib_main_t * vm = vlib_get_main();
3363 api_main_t * am = &api_main;
3364 unformat_input_t input;
3368 q = vl_api_client_index_to_input_queue (mp->client_index);
3372 rp = vl_msg_api_alloc (sizeof (*rp));
3373 rp->_vl_msg_id = ntohs(VL_API_CLI_REPLY);
3374 rp->context = mp->context;
3376 unformat_init_vector (&input, (u8 *)(uword)mp->cmd_in_shmem);
3378 vlib_cli_input (vm, &input, shmem_cli_output,
3381 pthread_mutex_lock (&am->vlib_rp->mutex);
3382 oldheap = svm_push_data_heap (am->vlib_rp);
3384 vec_add1(shmem_vec, 0);
3386 svm_pop_heap (oldheap);
3387 pthread_mutex_unlock (&am->vlib_rp->mutex);
3389 rp->reply_in_shmem = (uword)shmem_vec;
3391 vl_msg_api_send_shmem (q, (u8 *)&rp);
3394 static void vl_api_set_arp_neighbor_limit_t_handler (vl_api_set_arp_neighbor_limit_t *mp)
3397 vl_api_set_arp_neighbor_limit_reply_t * rmp;
3398 vnet_main_t *vnm = vnet_get_main();
3399 clib_error_t * error;
3404 error = ip6_set_neighbor_limit (ntohl(mp->arp_neighbor_limit));
3406 error = ip4_set_arp_limit (ntohl(mp->arp_neighbor_limit));
3409 clib_error_report(error);
3410 rv = VNET_API_ERROR_UNSPECIFIED;
3412 rv = vnm->api_errno;
3415 REPLY_MACRO(VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
3418 static void vl_api_sr_tunnel_add_del_t_handler
3419 (vl_api_sr_tunnel_add_del_t *mp)
3422 clib_warning ("unimplemented");
3424 ip6_sr_add_del_tunnel_args_t _a, *a=&_a;
3426 vl_api_sr_tunnel_add_del_reply_t * rmp;
3427 ip6_address_t * segments = 0, * seg;
3428 ip6_address_t * tags = 0, *tag;
3429 ip6_address_t * this_address;
3432 if (mp->n_segments == 0) {
3437 memset (a, 0, sizeof (*a));
3438 a->src_address = (ip6_address_t *)&mp->src_address;
3439 a->dst_address = (ip6_address_t *)&mp->dst_address;
3440 a->dst_mask_width = mp->dst_mask_width;
3441 a->flags_net_byte_order = mp->flags_net_byte_order;
3442 a->is_del = (mp->is_add == 0);
3443 a->rx_table_id = ntohl(mp->outer_vrf_id);
3444 a->tx_table_id = ntohl(mp->inner_vrf_id);
3446 a->name = format(0, "%s", mp->name);
3447 if (!(vec_len(a->name)))
3450 a->policy_name = format(0, "%s", mp->policy_name);
3451 if (!(vec_len(a->policy_name)))
3454 /* Yank segments and tags out of the API message */
3455 this_address = (ip6_address_t *)mp->segs_and_tags;
3456 for (i = 0; i < mp->n_segments; i++) {
3457 vec_add2 (segments, seg, 1);
3458 clib_memcpy (seg->as_u8, this_address->as_u8, sizeof (*this_address));
3461 for (i = 0; i < mp->n_tags; i++) {
3462 vec_add2 (tags, tag, 1);
3463 clib_memcpy (tag->as_u8, this_address->as_u8, sizeof (*this_address));
3467 a->segments = segments;
3470 rv = ip6_sr_add_del_tunnel (a);
3474 REPLY_MACRO(VL_API_SR_TUNNEL_ADD_DEL_REPLY);
3478 static void vl_api_sr_policy_add_del_t_handler
3479 (vl_api_sr_policy_add_del_t *mp)
3482 clib_warning ("unimplemented");
3484 ip6_sr_add_del_policy_args_t _a, *a=&_a;
3486 vl_api_sr_policy_add_del_reply_t * rmp;
3489 memset (a, 0, sizeof (*a));
3490 a->is_del = (mp->is_add == 0);
3492 a->name = format(0, "%s", mp->name);
3493 if (!(vec_len(a->name)))
3495 rv = VNET_API_ERROR_NO_SUCH_NODE2;
3499 if (!(mp->tunnel_names[0]))
3501 rv = VNET_API_ERROR_NO_SUCH_NODE2;
3505 // start deserializing tunnel_names
3506 int num_tunnels = mp->tunnel_names[0]; //number of tunnels
3507 u8 * deser_tun_names = mp->tunnel_names;
3508 deser_tun_names += 1; //moving along
3511 int tun_name_len = 0;
3513 for (i=0; i < num_tunnels; i++)
3515 tun_name_len= *deser_tun_names;
3516 deser_tun_names += 1;
3517 vec_resize (tun_name, tun_name_len);
3518 memcpy(tun_name, deser_tun_names, tun_name_len);
3519 vec_add1 (a->tunnel_names, tun_name);
3520 deser_tun_names += tun_name_len;
3524 rv = ip6_sr_add_del_policy (a);
3528 REPLY_MACRO(VL_API_SR_POLICY_ADD_DEL_REPLY);
3532 static void vl_api_sr_multicast_map_add_del_t_handler
3533 (vl_api_sr_multicast_map_add_del_t *mp)
3536 clib_warning ("unimplemented");
3538 ip6_sr_add_del_multicastmap_args_t _a, *a=&_a;
3540 vl_api_sr_multicast_map_add_del_reply_t * rmp;
3542 memset (a, 0, sizeof (*a));
3543 a->is_del = (mp->is_add == 0);
3545 a->multicast_address = (ip6_address_t *)&mp->multicast_address;
3546 a->policy_name = format(0, "%s", mp->policy_name);
3548 if (a->multicast_address == 0)
3554 if (!(a->policy_name))
3560 #if DPDK > 0 /* Cannot call replicate without DPDK */
3561 rv = ip6_sr_add_del_multicastmap (a);
3563 clib_warning ("multicast replication without DPDK not implemented");
3564 rv = VNET_API_ERROR_UNIMPLEMENTED;
3569 REPLY_MACRO(VL_API_SR_MULTICAST_MAP_ADD_DEL_REPLY);
3573 #define foreach_classify_add_del_table_field \
3578 _(match_n_vectors) \
3579 _(next_table_index) \
3582 static void vl_api_classify_add_del_table_t_handler
3583 (vl_api_classify_add_del_table_t * mp)
3585 vl_api_classify_add_del_table_reply_t * rmp;
3586 vnet_classify_main_t * cm = &vnet_classify_main;
3587 vnet_classify_table_t * t;
3591 foreach_classify_add_del_table_field;
3594 #define _(a) a = ntohl(mp->a);
3595 foreach_classify_add_del_table_field;
3598 /* The underlying API fails silently, on purpose, so check here */
3599 if (mp->is_add == 0)
3600 if (pool_is_free_index (cm->tables, table_index)) {
3601 rv = VNET_API_ERROR_NO_SUCH_TABLE;
3605 rv = vnet_classify_add_del_table
3606 (cm, mp->mask, nbuckets, memory_size,
3607 skip_n_vectors, match_n_vectors,
3608 next_table_index, miss_next_index,
3609 &table_index, mp->is_add);
3612 REPLY_MACRO2(VL_API_CLASSIFY_ADD_DEL_TABLE_REPLY,
3614 if (rv == 0 && mp->is_add) {
3615 t = pool_elt_at_index (cm->tables, table_index);
3616 rmp->skip_n_vectors = ntohl(t->skip_n_vectors);
3617 rmp->match_n_vectors = ntohl(t->match_n_vectors);
3618 rmp->new_table_index = ntohl(table_index);
3620 rmp->skip_n_vectors = ~0;
3621 rmp->match_n_vectors = ~0;
3622 rmp->new_table_index = ~0;
3627 static void vl_api_classify_add_del_session_t_handler
3628 (vl_api_classify_add_del_session_t * mp)
3630 vnet_classify_main_t * cm = &vnet_classify_main;
3631 vl_api_classify_add_del_session_reply_t * rmp;
3633 u32 table_index, hit_next_index, opaque_index;
3636 table_index = ntohl (mp->table_index);
3637 hit_next_index = ntohl (mp->hit_next_index);
3638 opaque_index = ntohl (mp->opaque_index);
3639 advance = ntohl (mp->advance);
3641 rv = vnet_classify_add_del_session
3642 (cm, table_index, mp->match, hit_next_index, opaque_index,
3643 advance, mp->is_add);
3645 REPLY_MACRO(VL_API_CLASSIFY_ADD_DEL_SESSION_REPLY);
3648 static void vl_api_classify_set_interface_ip_table_t_handler
3649 (vl_api_classify_set_interface_ip_table_t * mp)
3651 vlib_main_t * vm = vlib_get_main();
3652 vl_api_classify_set_interface_ip_table_reply_t * rmp;
3654 u32 table_index, sw_if_index;
3656 table_index = ntohl (mp->table_index);
3657 sw_if_index = ntohl (mp->sw_if_index);
3659 VALIDATE_SW_IF_INDEX(mp);
3662 rv = vnet_set_ip6_classify_intfc (vm, sw_if_index, table_index);
3664 rv = vnet_set_ip4_classify_intfc (vm, sw_if_index, table_index);
3666 BAD_SW_IF_INDEX_LABEL;
3668 REPLY_MACRO(VL_API_CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY);
3671 static void vl_api_classify_set_interface_l2_tables_t_handler
3672 (vl_api_classify_set_interface_l2_tables_t * mp)
3674 vl_api_classify_set_interface_l2_tables_reply_t * rmp;
3676 u32 sw_if_index, ip4_table_index, ip6_table_index, other_table_index;
3679 ip4_table_index = ntohl(mp->ip4_table_index);
3680 ip6_table_index = ntohl(mp->ip6_table_index);
3681 other_table_index = ntohl(mp->other_table_index);
3682 sw_if_index = ntohl(mp->sw_if_index);
3684 VALIDATE_SW_IF_INDEX(mp);
3686 rv = vnet_l2_classify_set_tables (sw_if_index, ip4_table_index,
3687 ip6_table_index, other_table_index);
3690 if (ip4_table_index != ~0 || ip6_table_index != ~0
3691 || other_table_index != ~0)
3696 vnet_l2_classify_enable_disable (sw_if_index, enable);
3699 BAD_SW_IF_INDEX_LABEL;
3701 REPLY_MACRO(VL_API_CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY);
3705 vl_api_l2_fib_clear_table_t_handler (vl_api_l2_fib_clear_table_t *mp)
3708 vl_api_l2_fib_clear_table_reply_t * rmp;
3710 /* DAW-FIXME: This API should only clear non-static l2fib entries, but
3711 * that is not currently implemented. When that TODO is fixed
3712 * this call should be changed to pass 1 instead of 0.
3714 l2fib_clear_table (0);
3716 REPLY_MACRO(VL_API_L2_FIB_CLEAR_TABLE_REPLY);
3719 extern void l2_efp_filter_configure(vnet_main_t * vnet_main,
3724 vl_api_l2_interface_efp_filter_t_handler (vl_api_l2_interface_efp_filter_t *mp)
3727 vl_api_l2_interface_efp_filter_reply_t * rmp;
3728 vnet_main_t *vnm = vnet_get_main();
3730 // enable/disable the feature
3731 l2_efp_filter_configure (vnm, mp->sw_if_index, mp->enable_disable);
3732 rv = vnm->api_errno;
3734 REPLY_MACRO(VL_API_L2_INTERFACE_EFP_FILTER_REPLY);
3738 vl_api_l2_interface_vlan_tag_rewrite_t_handler (vl_api_l2_interface_vlan_tag_rewrite_t *mp)
3741 vl_api_l2_interface_vlan_tag_rewrite_reply_t * rmp;
3742 vnet_main_t * vnm = vnet_get_main();
3743 vlib_main_t * vm = vlib_get_main();
3746 VALIDATE_SW_IF_INDEX(mp);
3748 vtr_op = ntohl(mp->vtr_op);
3750 /* The L2 code is unsuspicious */
3752 case L2_VTR_DISABLED:
3757 case L2_VTR_TRANSLATE_1_1:
3758 case L2_VTR_TRANSLATE_1_2:
3759 case L2_VTR_TRANSLATE_2_1:
3760 case L2_VTR_TRANSLATE_2_2:
3764 rv = VNET_API_ERROR_INVALID_VALUE;
3765 goto bad_sw_if_index;
3768 rv = l2vtr_configure (vm, vnm, ntohl(mp->sw_if_index), vtr_op,
3769 ntohl(mp->push_dot1q), ntohl(mp->tag1),
3772 BAD_SW_IF_INDEX_LABEL;
3774 REPLY_MACRO(VL_API_L2_INTERFACE_VLAN_TAG_REWRITE_REPLY);
3778 vl_api_create_vhost_user_if_t_handler (vl_api_create_vhost_user_if_t *mp)
3782 vl_api_create_vhost_user_if_reply_t * rmp;
3783 u32 sw_if_index = (u32)~0;
3785 vnet_main_t * vnm = vnet_get_main();
3786 vlib_main_t * vm = vlib_get_main();
3788 rv = dpdk_vhost_user_create_if(vnm, vm, (char *)mp->sock_filename,
3789 mp->is_server, &sw_if_index, (u64)~0,
3790 mp->renumber, ntohl(mp->custom_dev_instance),
3791 (mp->use_custom_mac)?mp->mac_address:NULL);
3793 REPLY_MACRO2(VL_API_CREATE_VHOST_USER_IF_REPLY,
3795 rmp->sw_if_index = ntohl (sw_if_index);
3801 vl_api_modify_vhost_user_if_t_handler (vl_api_modify_vhost_user_if_t *mp)
3805 vl_api_modify_vhost_user_if_reply_t * rmp;
3806 u32 sw_if_index = ntohl(mp->sw_if_index);
3808 vnet_main_t * vnm = vnet_get_main();
3809 vlib_main_t * vm = vlib_get_main();
3811 rv = dpdk_vhost_user_modify_if(vnm, vm, (char *)mp->sock_filename,
3812 mp->is_server, sw_if_index, (u64)~0,
3813 mp->renumber, ntohl(mp->custom_dev_instance));
3815 REPLY_MACRO(VL_API_MODIFY_VHOST_USER_IF_REPLY);
3820 vl_api_delete_vhost_user_if_t_handler (vl_api_delete_vhost_user_if_t *mp)
3824 vpe_api_main_t * vam = &vpe_api_main;
3825 vl_api_delete_vhost_user_if_reply_t * rmp;
3826 u32 sw_if_index = ntohl(mp->sw_if_index);
3828 vnet_main_t * vnm = vnet_get_main();
3829 vlib_main_t * vm = vlib_get_main();
3831 rv = dpdk_vhost_user_delete_if(vnm, vm, sw_if_index);
3833 REPLY_MACRO(VL_API_DELETE_VHOST_USER_IF_REPLY);
3835 unix_shared_memory_queue_t * q =
3836 vl_api_client_index_to_input_queue (mp->client_index);
3840 send_sw_interface_flags_deleted (vam, q, sw_if_index);
3845 static void vl_api_sw_interface_vhost_user_details_t_handler (
3846 vl_api_sw_interface_vhost_user_details_t * mp)
3848 clib_warning ("BUG");
3852 static void send_sw_interface_vhost_user_details (vpe_api_main_t * am,
3853 unix_shared_memory_queue_t *q,
3854 vhost_user_intf_details_t * vui,
3857 vl_api_sw_interface_vhost_user_details_t * mp;
3859 mp = vl_msg_api_alloc (sizeof (*mp));
3860 memset (mp, 0, sizeof (*mp));
3861 mp->_vl_msg_id = ntohs(VL_API_SW_INTERFACE_VHOST_USER_DETAILS);
3862 mp->sw_if_index = ntohl(vui->sw_if_index);
3863 mp->virtio_net_hdr_sz = ntohl (vui->virtio_net_hdr_sz);
3864 mp->features = clib_net_to_host_u64 (vui->features);
3865 mp->is_server = vui->is_server;
3866 mp->num_regions = ntohl(vui->num_regions);
3867 mp->sock_errno = ntohl(vui->sock_errno);
3868 mp->context = context;
3870 strncpy ((char *) mp->sock_filename,
3871 (char *) vui->sock_filename, ARRAY_LEN(mp->sock_filename)-1);
3872 strncpy ((char *) mp->interface_name,
3873 (char *) vui->if_name, ARRAY_LEN(mp->interface_name)-1);
3875 vl_msg_api_send_shmem (q, (u8 *)&mp);
3880 vl_api_sw_interface_vhost_user_dump_t_handler (
3881 vl_api_sw_interface_vhost_user_dump_t *mp)
3885 vpe_api_main_t * am = &vpe_api_main;
3886 vnet_main_t * vnm = vnet_get_main();
3887 vlib_main_t * vm = vlib_get_main();
3888 vhost_user_intf_details_t *ifaces = NULL;
3889 vhost_user_intf_details_t *vuid = NULL;
3890 unix_shared_memory_queue_t * q;
3892 q = vl_api_client_index_to_input_queue (mp->client_index);
3896 rv = dpdk_vhost_user_dump_ifs(vnm, vm, &ifaces);
3900 vec_foreach (vuid, ifaces) {
3901 send_sw_interface_vhost_user_details (am, q, vuid, mp->context);
3907 static void send_sw_if_l2tpv3_tunnel_details (vpe_api_main_t * am,
3908 unix_shared_memory_queue_t *q,
3913 vl_api_sw_if_l2tpv3_tunnel_details_t * mp;
3914 u8 * if_name = NULL;
3915 vnet_sw_interface_t * si = NULL;
3917 si = vnet_get_hw_sw_interface (lm->vnet_main, s->hw_if_index);
3919 if_name = format(if_name, "%U",
3920 format_vnet_sw_interface_name, lm->vnet_main, si);
3922 mp = vl_msg_api_alloc (sizeof (*mp));
3923 memset (mp, 0, sizeof (*mp));
3924 mp->_vl_msg_id = ntohs(VL_API_SW_IF_L2TPV3_TUNNEL_DETAILS);
3925 strncpy((char *)mp->interface_name,
3926 (char *)if_name, ARRAY_LEN(mp->interface_name)-1);
3927 mp->sw_if_index = ntohl(si->sw_if_index);
3928 mp->local_session_id = s->local_session_id;
3929 mp->remote_session_id = s->remote_session_id;
3930 mp->local_cookie[0] = s->local_cookie[0];
3931 mp->local_cookie[1] = s->local_cookie[1];
3932 mp->remote_cookie = s->remote_cookie;
3933 clib_memcpy(mp->client_address, &s->client_address, sizeof(s->client_address));
3934 clib_memcpy(mp->our_address, &s->our_address, sizeof(s->our_address));
3935 mp->l2_sublayer_present = s->l2_sublayer_present;
3936 mp->context = context;
3938 vl_msg_api_send_shmem (q, (u8 *)&mp);
3941 static void send_ip_address_details (vpe_api_main_t * am,
3942 unix_shared_memory_queue_t * q,
3948 vl_api_ip_address_details_t * mp;
3950 mp = vl_msg_api_alloc (sizeof (*mp));
3951 memset (mp, 0, sizeof (*mp));
3952 mp->_vl_msg_id = ntohs(VL_API_IP_ADDRESS_DETAILS);
3955 clib_memcpy(&mp->ip, ip, sizeof(mp->ip));
3957 u32 * tp = (u32 *)mp->ip;
3958 *tp = ntohl(*(u32*)ip);
3960 mp->prefix_length = prefix_length;
3961 mp->context = context;
3963 vl_msg_api_send_shmem (q, (u8 *)&mp);
3967 vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t *mp)
3969 vpe_api_main_t * am = &vpe_api_main;
3970 unix_shared_memory_queue_t * q;
3973 ip6_main_t * im6 = &ip6_main;
3974 ip4_main_t * im4 = &ip4_main;
3975 ip_lookup_main_t * lm6 = &im6->lookup_main;
3976 ip_lookup_main_t * lm4 = &im4->lookup_main;
3977 ip_interface_address_t * ia = 0;
3978 u32 sw_if_index = ~0;
3979 int rv __attribute__ ((unused)) = 0;
3981 VALIDATE_SW_IF_INDEX(mp);
3983 sw_if_index = ntohl(mp->sw_if_index);
3985 q = vl_api_client_index_to_input_queue (mp->client_index);
3991 foreach_ip_interface_address (lm6, ia, sw_if_index,
3992 1 /* honor unnumbered */,
3994 r6 = ip_interface_address_get_address (lm6, ia);
3995 u16 prefix_length = ia->address_length;
3996 send_ip_address_details(am, q, (u8*)r6, prefix_length, 1, mp->context);
3999 foreach_ip_interface_address (lm4, ia, sw_if_index,
4000 1 /* honor unnumbered */,
4002 r4 = ip_interface_address_get_address (lm4, ia);
4003 u16 prefix_length = ia->address_length;
4004 send_ip_address_details(am, q, (u8*)r4, prefix_length, 0, mp->context);
4007 BAD_SW_IF_INDEX_LABEL;
4010 static void send_ip_details (vpe_api_main_t * am,
4011 unix_shared_memory_queue_t *q,
4015 vl_api_ip_details_t * mp;
4017 mp = vl_msg_api_alloc (sizeof (*mp));
4018 memset (mp, 0, sizeof (*mp));
4019 mp->_vl_msg_id = ntohs(VL_API_IP_DETAILS);
4021 mp->sw_if_index = ntohl(sw_if_index);
4022 mp->context = context;
4024 vl_msg_api_send_shmem (q, (u8 *)&mp);
4028 vl_api_sw_if_l2tpv3_tunnel_dump_t_handler (
4029 vl_api_sw_if_l2tpv3_tunnel_dump_t *mp)
4031 vpe_api_main_t * am = &vpe_api_main;
4032 l2t_main_t * lm = &l2t_main;
4033 unix_shared_memory_queue_t * q;
4034 l2t_session_t *session;
4036 q = vl_api_client_index_to_input_queue (mp->client_index);
4040 pool_foreach (session, lm->sessions,
4042 send_sw_if_l2tpv3_tunnel_details (am, q, session, lm, mp->context);
4047 static void send_sw_interface_tap_details (vpe_api_main_t * am,
4048 unix_shared_memory_queue_t *q,
4049 tapcli_interface_details_t *tap_if,
4052 vl_api_sw_interface_tap_details_t * mp;
4053 mp = vl_msg_api_alloc (sizeof (*mp));
4054 memset (mp, 0, sizeof (*mp));
4055 mp->_vl_msg_id = ntohs(VL_API_SW_INTERFACE_TAP_DETAILS);
4056 mp->sw_if_index = ntohl(tap_if->sw_if_index);
4057 strncpy((char *)mp->dev_name,
4058 (char *)tap_if->dev_name, ARRAY_LEN(mp->dev_name)-1);
4059 mp->context = context;
4061 vl_msg_api_send_shmem (q, (u8 *)&mp);
4065 vl_api_sw_interface_tap_dump_t_handler (
4066 vl_api_sw_interface_tap_dump_t *mp)
4069 vpe_api_main_t * am = &vpe_api_main;
4070 unix_shared_memory_queue_t * q;
4071 tapcli_interface_details_t *tapifs = NULL;
4072 tapcli_interface_details_t *tap_if = NULL;
4074 q = vl_api_client_index_to_input_queue (mp->client_index);
4078 rv = vnet_tap_dump_ifs(&tapifs);
4082 vec_foreach(tap_if, tapifs) {
4083 send_sw_interface_tap_details(am, q, tap_if, mp->context);
4090 vl_api_ip_dump_t_handler (vl_api_ip_dump_t *mp)
4092 vpe_api_main_t * am = &vpe_api_main;
4093 vnet_main_t * vnm = vnet_get_main();
4094 vlib_main_t * vm = vlib_get_main();
4095 vnet_interface_main_t * im = &vnm->interface_main;
4096 unix_shared_memory_queue_t * q;
4097 vnet_sw_interface_t * si, * sorted_sis;
4098 u32 sw_if_index = ~0;
4100 q = vl_api_client_index_to_input_queue (mp->client_index);
4105 /* Gather interfaces. */
4106 sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
4107 _vec_len (sorted_sis) = 0;
4108 pool_foreach (si, im->sw_interfaces, ({ vec_add1 (sorted_sis, si[0]); }));
4110 vec_foreach (si, sorted_sis) {
4111 if (!(si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)) {
4112 if (mp->is_ipv6 && !ip6_interface_enabled(vm, si->sw_if_index)) {
4115 sw_if_index = si->sw_if_index;
4116 send_ip_details(am, q, sw_if_index, mp->context);
4121 static void vl_api_l2_fib_table_entry_t_handler (
4122 vl_api_l2_fib_table_entry_t * mp)
4124 clib_warning ("BUG");
4127 static void send_l2fib_table_entry (vpe_api_main_t * am,
4128 unix_shared_memory_queue_t *q,
4129 l2fib_entry_key_t * l2fe_key,
4130 l2fib_entry_result_t * l2fe_res,
4133 vl_api_l2_fib_table_entry_t * mp;
4135 mp = vl_msg_api_alloc (sizeof (*mp));
4136 memset (mp, 0, sizeof (*mp));
4137 mp->_vl_msg_id = ntohs(VL_API_L2_FIB_TABLE_ENTRY);
4139 mp->bd_id = ntohl(l2input_main.bd_configs[l2fe_key->fields.bd_index].bd_id);
4141 mp->mac = l2fib_make_key (l2fe_key->fields.mac, 0);
4142 mp->sw_if_index = ntohl(l2fe_res->fields.sw_if_index);
4143 mp->static_mac = l2fe_res->fields.static_mac;
4144 mp->filter_mac = l2fe_res->fields.filter;
4145 mp->bvi_mac = l2fe_res->fields.bvi;
4146 mp->context = context;
4148 vl_msg_api_send_shmem (q, (u8 *)&mp);
4152 vl_api_l2_fib_table_dump_t_handler (vl_api_l2_fib_table_dump_t *mp)
4154 vpe_api_main_t * am = &vpe_api_main;
4155 bd_main_t * bdm = &bd_main;
4156 l2fib_entry_key_t *l2fe_key = NULL;
4157 l2fib_entry_result_t *l2fe_res = NULL;
4158 u32 ni, bd_id = ntohl (mp->bd_id);
4160 unix_shared_memory_queue_t * q;
4163 q = vl_api_client_index_to_input_queue (mp->client_index);
4167 /* see l2fib_table_dump: ~0 means "any" */
4171 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
4178 l2fib_table_dump (bd_index, &l2fe_key, &l2fe_res);
4180 vec_foreach_index (ni, l2fe_key) {
4181 send_l2fib_table_entry (am, q, vec_elt_at_index(l2fe_key, ni),
4182 vec_elt_at_index(l2fe_res, ni), mp->context);
4189 vl_api_show_version_t_handler (vl_api_show_version_t *mp)
4191 vl_api_show_version_reply_t *rmp;
4193 char * vpe_api_get_build_directory(void);
4194 char * vpe_api_get_version(void);
4195 char * vpe_api_get_build_date(void);
4197 unix_shared_memory_queue_t * q =
4198 vl_api_client_index_to_input_queue (mp->client_index);
4203 REPLY_MACRO2(VL_API_SHOW_VERSION_REPLY,
4205 strncpy ((char *) rmp->program, "vpe", ARRAY_LEN(rmp->program)-1);
4206 strncpy ((char *) rmp->build_directory, vpe_api_get_build_directory(),
4207 ARRAY_LEN(rmp->build_directory)-1);
4208 strncpy ((char *) rmp->version, vpe_api_get_version(),
4209 ARRAY_LEN(rmp->version)-1);
4210 strncpy ((char *) rmp->build_date, vpe_api_get_build_date(),
4211 ARRAY_LEN(rmp->build_date)-1);
4215 static void vl_api_get_node_index_t_handler
4216 (vl_api_get_node_index_t * mp)
4218 vlib_main_t * vm = vlib_get_main();
4219 vl_api_get_node_index_reply_t * rmp;
4222 u32 node_index = ~0;
4224 n = vlib_get_node_by_name (vm, mp->node_name);
4227 rv = VNET_API_ERROR_NO_SUCH_NODE;
4229 node_index = n->index;
4231 REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
4233 rmp->node_index = ntohl(node_index);
4237 static void vl_api_add_node_next_t_handler
4238 (vl_api_add_node_next_t * mp)
4240 vlib_main_t * vm = vlib_get_main();
4241 vl_api_add_node_next_reply_t * rmp;
4242 vlib_node_t * n, * next;
4244 u32 next_index = ~0;
4246 n = vlib_get_node_by_name (vm, mp->node_name);
4249 rv = VNET_API_ERROR_NO_SUCH_NODE;
4253 next = vlib_get_node_by_name (vm, mp->next_name);
4256 rv = VNET_API_ERROR_NO_SUCH_NODE2;
4258 next_index = vlib_node_add_next (vm, n->index, next->index);
4261 REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
4263 rmp->next_index = ntohl(next_index);
4267 static void vl_api_l2tpv3_create_tunnel_t_handler
4268 (vl_api_l2tpv3_create_tunnel_t *mp)
4270 vl_api_l2tpv3_create_tunnel_reply_t * rmp;
4271 l2t_main_t *lm = &l2t_main;
4272 u32 sw_if_index = (u32)~0;
4275 if (mp->is_ipv6 != 1) {
4276 rv = VNET_API_ERROR_UNIMPLEMENTED;
4280 rv = create_l2tpv3_ipv6_tunnel (lm,
4281 (ip6_address_t *) mp->client_address,
4282 (ip6_address_t *) mp->our_address,
4283 ntohl(mp->local_session_id),
4284 ntohl(mp->remote_session_id),
4285 clib_net_to_host_u64(mp->local_cookie),
4286 clib_net_to_host_u64(mp->remote_cookie),
4287 mp->l2_sublayer_present,
4291 REPLY_MACRO2(VL_API_L2TPV3_CREATE_TUNNEL_REPLY,
4293 rmp->sw_if_index = ntohl (sw_if_index);
4297 static void vl_api_l2tpv3_set_tunnel_cookies_t_handler
4298 (vl_api_l2tpv3_set_tunnel_cookies_t *mp)
4300 vl_api_l2tpv3_set_tunnel_cookies_reply_t * rmp;
4301 l2t_main_t *lm = &l2t_main;
4304 VALIDATE_SW_IF_INDEX(mp);
4306 rv = l2tpv3_set_tunnel_cookies (lm, ntohl(mp->sw_if_index),
4307 clib_net_to_host_u64(mp->new_local_cookie),
4308 clib_net_to_host_u64(mp->new_remote_cookie));
4310 BAD_SW_IF_INDEX_LABEL;
4312 REPLY_MACRO (VL_API_L2TPV3_SET_TUNNEL_COOKIES_REPLY);
4315 static void vl_api_l2tpv3_interface_enable_disable_t_handler
4316 (vl_api_l2tpv3_interface_enable_disable_t * mp)
4319 vnet_main_t * vnm = vnet_get_main();
4320 vl_api_l2tpv3_interface_enable_disable_reply_t * rmp;
4322 VALIDATE_SW_IF_INDEX(mp);
4324 rv = l2tpv3_interface_enable_disable
4325 (vnm, ntohl(mp->sw_if_index), mp->enable_disable);
4327 BAD_SW_IF_INDEX_LABEL;
4329 REPLY_MACRO (VL_API_L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY);
4332 static void vl_api_l2tpv3_set_lookup_key_t_handler
4333 (vl_api_l2tpv3_set_lookup_key_t * mp)
4336 l2t_main_t *lm = &l2t_main;
4337 vl_api_l2tpv3_set_lookup_key_reply_t * rmp;
4339 if (mp->key > L2T_LOOKUP_SESSION_ID) {
4340 rv = VNET_API_ERROR_INVALID_VALUE;
4344 lm->lookup_type = mp->key;
4347 REPLY_MACRO (VL_API_L2TPV3_SET_LOOKUP_KEY_REPLY);
4350 static void vl_api_vxlan_add_del_tunnel_t_handler
4351 (vl_api_vxlan_add_del_tunnel_t * mp)
4353 vl_api_vxlan_add_del_tunnel_reply_t * rmp;
4355 vnet_vxlan_add_del_tunnel_args_t _a, *a = &_a;
4356 u32 encap_fib_index;
4358 ip4_main_t * im = &ip4_main;
4359 u32 sw_if_index = ~0;
4361 p = hash_get (im->fib_index_by_table_id, ntohl(mp->encap_vrf_id));
4363 rv = VNET_API_ERROR_NO_SUCH_FIB;
4366 encap_fib_index = p[0];
4368 /* Check src & dst are different */
4369 if ((mp->is_ipv6 && memcmp(mp->src_address, mp->dst_address, 16) == 0) ||
4370 (!mp->is_ipv6 && memcmp(mp->src_address, mp->dst_address, 4) == 0)) {
4371 rv = VNET_API_ERROR_SAME_SRC_DST;
4374 memset (a, 0, sizeof (*a));
4376 a->is_add = mp->is_add;
4377 a->is_ip6 = mp->is_ipv6;
4379 /* ip addresses sent in network byte order */
4381 memcpy(&(a->src.ip6), mp->src_address, 16);
4382 memcpy(&(a->dst.ip6), mp->dst_address, 16);
4384 memcpy(&(a->src.ip4), mp->src_address, 4);
4385 memcpy(&(a->dst.ip4), mp->dst_address, 4);
4388 a->encap_fib_index = encap_fib_index;
4389 a->decap_next_index = ntohl(mp->decap_next_index);
4390 a->vni = ntohl(mp->vni);
4391 rv = vnet_vxlan_add_del_tunnel (a, &sw_if_index);
4394 REPLY_MACRO2(VL_API_VXLAN_ADD_DEL_TUNNEL_REPLY,
4396 rmp->sw_if_index = ntohl (sw_if_index);
4400 static void send_vxlan_tunnel_details
4401 (vxlan_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
4403 vl_api_vxlan_tunnel_details_t * rmp;
4404 ip4_main_t * im4 = &ip4_main;
4405 ip6_main_t * im6 = &ip6_main;
4406 u8 is_ipv6 = !(t->flags & VXLAN_TUNNEL_IS_IPV4);
4408 rmp = vl_msg_api_alloc (sizeof (*rmp));
4409 memset (rmp, 0, sizeof (*rmp));
4410 rmp->_vl_msg_id = ntohs(VL_API_VXLAN_TUNNEL_DETAILS);
4412 memcpy(rmp->src_address, &(t->src.ip6), 16);
4413 memcpy(rmp->dst_address, &(t->dst.ip6), 16);
4414 rmp->encap_vrf_id = htonl(im6->fibs[t->encap_fib_index].table_id);
4416 memcpy(rmp->src_address, &(t->src.ip4), 4);
4417 memcpy(rmp->dst_address, &(t->dst.ip4), 4);
4418 rmp->encap_vrf_id = htonl(im4->fibs[t->encap_fib_index].table_id);
4420 rmp->vni = htonl(t->vni);
4421 rmp->decap_next_index = htonl(t->decap_next_index);
4422 rmp->sw_if_index = htonl(t->sw_if_index);
4423 rmp->is_ipv6 = is_ipv6;
4424 rmp->context = context;
4426 vl_msg_api_send_shmem (q, (u8 *)&rmp);
4429 static void vl_api_vxlan_tunnel_dump_t_handler
4430 (vl_api_vxlan_tunnel_dump_t * mp)
4432 unix_shared_memory_queue_t * q;
4433 vxlan_main_t * vxm = &vxlan_main;
4437 q = vl_api_client_index_to_input_queue (mp->client_index);
4442 sw_if_index = ntohl(mp->sw_if_index);
4444 if (~0 == sw_if_index) {
4445 pool_foreach (t, vxm->tunnels,
4447 send_vxlan_tunnel_details(t, q, mp->context);
4450 if ((sw_if_index >= vec_len(vxm->tunnel_index_by_sw_if_index)) ||
4451 (~0 == vxm->tunnel_index_by_sw_if_index[sw_if_index])) {
4454 t = &vxm->tunnels[vxm->tunnel_index_by_sw_if_index[sw_if_index]];
4455 send_vxlan_tunnel_details(t, q, mp->context);
4459 static void vl_api_gre_add_del_tunnel_t_handler
4460 (vl_api_gre_add_del_tunnel_t * mp)
4462 vl_api_gre_add_del_tunnel_reply_t * rmp;
4464 vnet_gre_add_del_tunnel_args_t _a, *a = &_a;
4467 ip4_main_t * im = &ip4_main;
4468 u32 sw_if_index = ~0;
4470 p = hash_get (im->fib_index_by_table_id, ntohl(mp->outer_table_id));
4472 rv = VNET_API_ERROR_NO_SUCH_FIB;
4475 outer_table_id = p[0];
4477 /* Check src & dst are different */
4478 if (memcmp(&mp->src_address, &mp->dst_address, 4) == 0) {
4479 rv = VNET_API_ERROR_SAME_SRC_DST;
4483 memset (a, 0, sizeof (*a));
4485 a->is_add = mp->is_add;
4487 /* ip addresses sent in network byte order */
4488 a->src.as_u32 = mp->src_address;
4489 a->dst.as_u32 = mp->dst_address;
4491 a->outer_table_id = outer_table_id;
4492 rv = vnet_gre_add_del_tunnel (a, &sw_if_index);
4495 REPLY_MACRO2(VL_API_GRE_ADD_DEL_TUNNEL_REPLY,
4497 rmp->sw_if_index = ntohl (sw_if_index);
4501 static void send_gre_tunnel_details
4502 (gre_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
4504 vl_api_gre_tunnel_details_t * rmp;
4505 ip4_main_t * im = &ip4_main;
4507 rmp = vl_msg_api_alloc (sizeof (*rmp));
4508 memset (rmp, 0, sizeof (*rmp));
4509 rmp->_vl_msg_id = ntohs(VL_API_GRE_TUNNEL_DETAILS);
4510 rmp->src_address = t->tunnel_src.data_u32;
4511 rmp->dst_address = t->tunnel_dst.data_u32;
4512 rmp->outer_table_id = htonl(im->fibs[t->outer_fib_index].table_id);
4513 rmp->sw_if_index = htonl(t->sw_if_index);
4514 rmp->context = context;
4516 vl_msg_api_send_shmem (q, (u8 *)&rmp);
4519 static void vl_api_gre_tunnel_dump_t_handler
4520 (vl_api_gre_tunnel_dump_t * mp)
4522 unix_shared_memory_queue_t * q;
4523 gre_main_t * gm = &gre_main;
4527 q = vl_api_client_index_to_input_queue (mp->client_index);
4532 sw_if_index = ntohl(mp->sw_if_index);
4534 if (~0 == sw_if_index) {
4535 pool_foreach (t, gm->tunnels,
4537 send_gre_tunnel_details(t, q, mp->context);
4540 if ((sw_if_index >= vec_len(gm->tunnel_index_by_sw_if_index)) ||
4541 (~0 == gm->tunnel_index_by_sw_if_index[sw_if_index])) {
4544 t = &gm->tunnels[gm->tunnel_index_by_sw_if_index[sw_if_index]];
4545 send_gre_tunnel_details(t, q, mp->context);
4550 vl_api_l2_patch_add_del_t_handler (vl_api_l2_patch_add_del_t *mp)
4552 extern int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
4554 vl_api_l2_patch_add_del_reply_t * rmp;
4555 int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
4559 VALIDATE_RX_SW_IF_INDEX(mp);
4560 VALIDATE_TX_SW_IF_INDEX(mp);
4562 rv = vnet_l2_patch_add_del (ntohl(mp->rx_sw_if_index),
4563 ntohl(mp->tx_sw_if_index),
4564 (int)(mp->is_add != 0));
4566 BAD_RX_SW_IF_INDEX_LABEL;
4567 BAD_TX_SW_IF_INDEX_LABEL;
4569 REPLY_MACRO(VL_API_L2_PATCH_ADD_DEL_REPLY);
4573 vl_api_vxlan_gpe_add_del_tunnel_t_handler
4574 (vl_api_vxlan_gpe_add_del_tunnel_t * mp)
4576 vl_api_vxlan_gpe_add_del_tunnel_reply_t * rmp;
4578 vnet_vxlan_gpe_add_del_tunnel_args_t _a, *a = &_a;
4579 u32 encap_fib_index, decap_fib_index;
4582 ip4_main_t * im = &ip4_main;
4583 u32 sw_if_index = ~0;
4586 p = hash_get (im->fib_index_by_table_id, ntohl(mp->encap_vrf_id));
4588 rv = VNET_API_ERROR_NO_SUCH_FIB;
4591 encap_fib_index = p[0];
4593 protocol = mp->protocol;
4595 /* Interpret decap_vrf_id as an opaque if sending to other-than-ip4-input */
4596 if (protocol == VXLAN_GPE_INPUT_NEXT_IP4_INPUT) {
4597 p = hash_get (im->fib_index_by_table_id, ntohl(mp->decap_vrf_id));
4599 rv = VNET_API_ERROR_NO_SUCH_INNER_FIB;
4602 decap_fib_index = p[0];
4604 decap_fib_index = ntohl(mp->decap_vrf_id);
4607 /* Check src & dst are different */
4608 if ((mp->is_ipv6 && memcmp(mp->local, mp->remote, 16) == 0) ||
4609 (!mp->is_ipv6 && memcmp(mp->local, mp->remote, 4) == 0)) {
4610 rv = VNET_API_ERROR_SAME_SRC_DST;
4613 memset (a, 0, sizeof (*a));
4615 a->is_add = mp->is_add;
4616 a->is_ip6 = mp->is_ipv6;
4617 /* ip addresses sent in network byte order */
4619 clib_memcpy(&(a->local.ip6), mp->local, 16);
4620 clib_memcpy(&(a->remote.ip6), mp->remote, 16);
4622 clib_memcpy(&(a->local.ip4), mp->local, 4);
4623 clib_memcpy(&(a->remote.ip4), mp->remote, 4);
4625 a->encap_fib_index = encap_fib_index;
4626 a->decap_fib_index = decap_fib_index;
4627 a->protocol = protocol;
4628 a->vni = ntohl(mp->vni);
4629 rv = vnet_vxlan_gpe_add_del_tunnel (a, &sw_if_index);
4632 REPLY_MACRO2(VL_API_VXLAN_GPE_ADD_DEL_TUNNEL_REPLY,
4634 rmp->sw_if_index = ntohl (sw_if_index);
4638 static void send_vxlan_gpe_tunnel_details
4639 (vxlan_gpe_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
4641 vl_api_vxlan_gpe_tunnel_details_t * rmp;
4642 ip4_main_t * im4 = &ip4_main;
4643 ip6_main_t * im6 = &ip6_main;
4644 u8 is_ipv6 = !(t->flags & VXLAN_GPE_TUNNEL_IS_IPV4);
4646 rmp = vl_msg_api_alloc (sizeof (*rmp));
4647 memset (rmp, 0, sizeof (*rmp));
4648 rmp->_vl_msg_id = ntohs(VL_API_VXLAN_GPE_TUNNEL_DETAILS);
4650 memcpy(rmp->local, &(t->local.ip6), 16);
4651 memcpy(rmp->remote, &(t->remote.ip6), 16);
4652 rmp->encap_vrf_id = htonl(im6->fibs[t->encap_fib_index].table_id);
4653 rmp->decap_vrf_id = htonl(im6->fibs[t->decap_fib_index].table_id);
4655 memcpy(rmp->local, &(t->local.ip4), 4);
4656 memcpy(rmp->remote, &(t->remote.ip4), 4);
4657 rmp->encap_vrf_id = htonl(im4->fibs[t->encap_fib_index].table_id);
4658 rmp->decap_vrf_id = htonl(im4->fibs[t->decap_fib_index].table_id);
4660 rmp->vni = htonl(t->vni);
4661 rmp->protocol = t->protocol;
4662 rmp->sw_if_index = htonl(t->sw_if_index);
4663 rmp->is_ipv6 = is_ipv6;
4664 rmp->context = context;
4666 vl_msg_api_send_shmem (q, (u8 *)&rmp);
4669 static void vl_api_vxlan_gpe_tunnel_dump_t_handler
4670 (vl_api_vxlan_gpe_tunnel_dump_t * mp)
4672 unix_shared_memory_queue_t * q;
4673 vxlan_gpe_main_t * vgm = &vxlan_gpe_main;
4674 vxlan_gpe_tunnel_t * t;
4677 q = vl_api_client_index_to_input_queue (mp->client_index);
4682 sw_if_index = ntohl(mp->sw_if_index);
4684 if (~0 == sw_if_index) {
4685 pool_foreach (t, vgm->tunnels,
4687 send_vxlan_gpe_tunnel_details(t, q, mp->context);
4690 if ((sw_if_index >= vec_len(vgm->tunnel_index_by_sw_if_index)) ||
4691 (~0 == vgm->tunnel_index_by_sw_if_index[sw_if_index])) {
4694 t = &vgm->tunnels[vgm->tunnel_index_by_sw_if_index[sw_if_index]];
4695 send_vxlan_gpe_tunnel_details(t, q, mp->context);
4700 vl_api_lisp_add_del_locator_set_t_handler(vl_api_lisp_add_del_locator_set_t *mp)
4702 vl_api_lisp_add_del_locator_set_reply_t *rmp;
4704 vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
4706 u8 *locator_name = NULL;
4708 memset(a, 0, sizeof(a[0]));
4710 locator_name = format(0, "%s", mp->locator_set_name);
4712 a->name = locator_name;
4714 a->is_add = mp->is_add;
4717 rv = vnet_lisp_add_del_locator_set(a, &ls_index);
4719 vec_free(locator_name);
4721 REPLY_MACRO(VL_API_LISP_ADD_DEL_LOCATOR_SET_REPLY);
4725 vl_api_lisp_add_del_locator_t_handler(
4726 vl_api_lisp_add_del_locator_t *mp)
4728 vl_api_lisp_add_del_locator_reply_t *rmp;
4730 locator_t locator, *locators = NULL;
4731 vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
4733 u8 *locator_name = NULL;
4735 memset(&locator, 0, sizeof(locator));
4736 memset(a, 0, sizeof(a[0]));
4738 locator.sw_if_index = ntohl(mp->sw_if_index);
4739 locator.priority = mp->priority;
4740 locator.weight = mp->weight;
4742 vec_add1(locators, locator);
4744 locator_name = format(0, "%s", mp->locator_set_name);
4746 a->name = locator_name;
4747 a->locators = locators;
4748 a->is_add = mp->is_add;
4751 rv = vnet_lisp_add_del_locator(a, NULL, &ls_index);
4754 vec_free(locator_name);
4756 REPLY_MACRO(VL_API_LISP_ADD_DEL_LOCATOR_REPLY);
4760 vl_api_lisp_add_del_local_eid_t_handler(
4761 vl_api_lisp_add_del_local_eid_t *mp)
4763 vl_api_lisp_add_del_local_eid_reply_t *rmp;
4764 lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
4766 ip_prefix_t *prefp = NULL;
4767 ip_address_t *ip_eid = NULL;
4770 u32 locator_set_index = ~0, map_index = ~0;
4771 vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
4774 prefp = &gid_address_ippref(&eid);
4775 ip_eid = &ip_prefix_addr(prefp);
4776 gid_address_type (&eid) = GID_ADDR_IP_PREFIX;
4779 clib_memcpy(&ip_addr_v6(ip_eid), mp->ip_address,
4780 sizeof(ip_addr_v6(ip_eid)));
4781 ip_addr_version(ip_eid) = IP6;
4783 clib_memcpy(&ip_addr_v4(ip_eid), mp->ip_address,
4784 sizeof(ip_addr_v4(ip_eid)));
4785 ip_addr_version(ip_eid) = IP4;
4787 ip_prefix_len(prefp) = mp->prefix_len;
4789 name = format(0, "%s", mp->locator_set_name);
4790 p = hash_get_mem(lcm->locator_set_index_by_name, name);
4792 rv = VNET_API_ERROR_INVALID_VALUE;
4795 locator_set_index = p[0];
4797 /* XXX treat batch configuration */
4798 a->is_add = mp->is_add;
4800 a->locator_set_index = locator_set_index;
4803 rv = vnet_lisp_add_del_local_mapping(a, &map_index);
4808 REPLY_MACRO(VL_API_LISP_ADD_DEL_LOCAL_EID_REPLY);
4812 lisp_gpe_add_del_fwd_entry_set_address(
4813 vl_api_lisp_gpe_add_del_fwd_entry_t *mp,
4814 ip_address_t *slocator,
4815 ip_address_t *dlocator,
4818 ip_address_t *ip_eid = NULL;
4819 ip_prefix_t *prefp = NULL;
4821 prefp = &gid_address_ippref(eid);
4822 ip_eid = &ip_prefix_addr(prefp);
4824 if (mp->eid_is_ipv6) {
4825 clib_memcpy(&ip_addr_v6(ip_eid), mp->eid_ip_address,
4826 sizeof(ip_addr_v6(ip_eid)));
4827 ip_addr_version(ip_eid) = IP6;
4829 clib_memcpy(&ip_addr_v4(ip_eid), mp->eid_ip_address,
4830 sizeof(ip_addr_v4(ip_eid)));
4831 ip_addr_version(ip_eid) = IP4;
4833 ip_prefix_len(prefp) = mp->eid_prefix_len;
4835 if (mp->address_is_ipv6) {
4836 clib_memcpy(&ip_addr_v6(slocator), mp->source_ip_address,
4837 sizeof(ip_addr_v6(slocator)));
4838 ip_addr_version(slocator) = IP6;
4839 clib_memcpy(&ip_addr_v6(dlocator), mp->destination_ip_address,
4840 sizeof(ip_addr_v6(dlocator)));
4841 ip_addr_version(dlocator) = IP6;
4843 clib_memcpy(&ip_addr_v4(slocator), mp->source_ip_address,
4844 sizeof(ip_addr_v4(slocator)));
4845 ip_addr_version(slocator) = IP4;
4846 clib_memcpy(&ip_addr_v4(dlocator), mp->destination_ip_address,
4847 sizeof(ip_addr_v4(dlocator)));
4848 ip_addr_version(dlocator) = IP4;
4853 vl_api_lisp_gpe_add_del_fwd_entry_t_handler(
4854 vl_api_lisp_gpe_add_del_fwd_entry_t *mp)
4856 vl_api_lisp_gpe_add_del_fwd_entry_reply_t *rmp;
4858 ip_address_t slocator, dlocator;
4860 vnet_lisp_gpe_add_del_fwd_entry_args_t a;
4862 lisp_gpe_add_del_fwd_entry_set_address(mp, &slocator, &dlocator, &eid);
4864 memset (&a, 0, sizeof(a));
4866 a.is_add = mp->is_add;
4868 a.slocator = slocator;
4869 a.dlocator = dlocator;
4870 rv = vnet_lisp_gpe_add_del_fwd_entry (&a, 0);
4872 REPLY_MACRO(VL_API_LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY);
4876 vl_api_lisp_add_del_map_resolver_t_handler(
4877 vl_api_lisp_add_del_map_resolver_t *mp)
4879 vl_api_lisp_add_del_map_resolver_reply_t *rmp;
4881 ip_address_t *ip_addr = NULL;
4882 vnet_lisp_add_del_map_resolver_args_t _a, * a = &_a;
4884 a->is_add = mp->is_add;
4885 ip_addr = &a->address;
4888 clib_memcpy(&ip_addr_v6(ip_addr), mp->ip_address,
4889 sizeof(ip_addr_v6(ip_addr)));
4890 ip_addr_version(ip_addr) = IP6;
4892 clib_memcpy(&ip_addr_v4(ip_addr), mp->ip_address,
4893 sizeof(ip_addr_v4(ip_addr)));
4894 ip_addr_version(ip_addr) = IP4;
4897 rv = vnet_lisp_add_del_map_resolver (a);
4899 REPLY_MACRO(VL_API_LISP_ADD_DEL_MAP_RESOLVER_REPLY);
4903 vl_api_lisp_gpe_enable_disable_t_handler(
4904 vl_api_lisp_gpe_enable_disable_t *mp)
4906 vl_api_lisp_gpe_enable_disable_reply_t *rmp;
4908 vnet_lisp_gpe_enable_disable_args_t _a, * a = &_a;
4910 a->is_en = mp->is_en;
4911 vnet_lisp_gpe_enable_disable (a);
4913 REPLY_MACRO(VL_API_LISP_GPE_ENABLE_DISABLE_REPLY);
4917 vl_api_lisp_enable_disable_t_handler(
4918 vl_api_lisp_enable_disable_t *mp)
4920 vl_api_lisp_enable_disable_reply_t *rmp;
4923 vnet_lisp_enable_disable (mp->is_en);
4924 REPLY_MACRO(VL_API_LISP_ENABLE_DISABLE_REPLY);
4928 vl_api_lisp_gpe_add_del_iface_t_handler(
4929 vl_api_lisp_gpe_add_del_iface_t *mp)
4931 vl_api_lisp_gpe_add_del_iface_reply_t *rmp;
4933 vnet_lisp_gpe_add_del_iface_args_t _a, * a = &_a;
4935 a->is_add = mp->is_add;
4936 a->table_id = mp->table_id;
4938 rv = vnet_lisp_gpe_add_del_iface (a, 0);
4940 REPLY_MACRO(VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
4944 vl_api_lisp_pitr_set_locator_set_t_handler(
4945 vl_api_lisp_pitr_set_locator_set_t *mp)
4947 vl_api_lisp_pitr_set_locator_set_reply_t *rmp;
4951 ls_name = format (0, "%s", mp->ls_name);
4952 rv = vnet_lisp_pitr_set_locator_set (ls_name, mp->is_add);
4955 REPLY_MACRO(VL_API_LISP_PITR_SET_LOCATOR_SET_REPLY);
4959 vl_api_lisp_add_del_map_request_itr_rlocs_t_handler
4960 (vl_api_lisp_add_del_map_request_itr_rlocs_t *mp)
4962 vl_api_lisp_add_del_map_request_itr_rlocs_reply_t *rmp;
4964 u8 * locator_set_name = NULL;
4965 vnet_lisp_add_del_mreq_itr_rloc_args_t _a, * a = &_a;
4967 locator_set_name = format (0, "%s", mp->locator_set_name);
4969 a->is_add = mp->is_add;
4970 a->locator_set_name = locator_set_name;
4972 rv = vnet_lisp_add_del_mreq_itr_rlocs(a);
4974 vec_free(locator_set_name);
4976 REPLY_MACRO(VL_API_LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY);
4979 /** Used for transferring locators via VPP API */
4980 typedef CLIB_PACKED(struct
4982 u8 is_ip4; /**< is locator an IPv4 address */
4983 u8 addr[16]; /**< IPv4/IPv6 address */
4987 send_lisp_locator_set_details_set_address
4988 (vl_api_lisp_locator_set_details_t *rmp,
4989 gid_address_t *gid_address)
4991 ip_prefix_t *ip_addr;
4993 if (gid_address_type(gid_address) != GID_ADDR_IP_PREFIX) {
4997 ip_addr = &gid_address_ippref(gid_address);
4998 rmp->prefix_len = ip_prefix_len(ip_addr);
4999 rmp->is_ipv6 = ip_prefix_version(ip_addr);
5000 ip_address_copy_addr(rmp->ip_address, &ip_prefix_addr(ip_addr));
5004 vl_api_lisp_add_del_remote_mapping_t_handler (
5005 vl_api_lisp_add_del_remote_mapping_t *mp)
5008 ip_address_t rloc, * rlocs = 0;
5009 vl_api_lisp_add_del_remote_mapping_reply_t * rmp;
5011 gid_address_t _seid, * seid = &_seid;
5012 gid_address_t _deid, * deid = &_deid;
5013 ip_prefix_t * seid_pref = &gid_address_ippref(seid);
5014 ip_prefix_t * deid_pref = &gid_address_ippref(deid);
5016 gid_address_type(seid) = GID_ADDR_IP_PREFIX;
5017 gid_address_type(deid) = GID_ADDR_IP_PREFIX;
5018 ip_address_t * seid_addr = &ip_prefix_addr(seid_pref);
5019 ip_address_t * deid_addr = &ip_prefix_addr(deid_pref);
5020 ip_prefix_len(seid_pref) = mp->seid_len;
5021 ip_prefix_len(deid_pref) = mp->deid_len;
5022 gid_address_set_vni (seid, ntohl (mp->vni));
5023 gid_address_set_vni (deid, ntohl (mp->vni));
5025 if (mp->eid_is_ip4) {
5026 ip_prefix_version(seid_pref) = IP4;
5027 ip_prefix_version(deid_pref) = IP4;
5028 clib_memcpy (&ip_addr_v4(seid_addr),
5029 mp->seid, sizeof (ip_addr_v4(seid_addr)));
5030 clib_memcpy (&ip_addr_v4(deid_addr),
5031 mp->deid, sizeof (ip_addr_v4(deid_addr)));
5033 ip_prefix_version(seid_pref) = IP6;
5034 ip_prefix_version(deid_pref) = IP6;
5035 clib_memcpy (&ip_addr_v6(seid_addr),
5036 mp->seid, sizeof (ip_addr_v6(seid_addr)));
5037 clib_memcpy (&ip_addr_v6(deid_addr),
5038 mp->deid, sizeof (ip_addr_v6(deid_addr)));
5041 for (i = 0; i < mp->rloc_num; i++) {
5042 rloc_t * r = &((rloc_t *) mp->rlocs)[i];
5044 clib_memcpy (&ip_addr_v4(&rloc), &r->addr, sizeof (rloc_t));
5045 ip_addr_version (&rloc) = IP4;
5047 clib_memcpy (&ip_addr_v6(&rloc), &r->addr, sizeof (rloc_t));
5048 ip_addr_version (&rloc) = IP6;
5050 vec_add1 (rlocs, rloc);
5053 rv = vnet_lisp_add_del_remote_mapping (deid, seid, rlocs, mp->action,
5054 mp->is_add, mp->del_all);
5056 REPLY_MACRO(VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
5060 send_lisp_locator_set_details (lisp_cp_main_t *lcm,
5061 locator_set_t *lsit,
5062 unix_shared_memory_queue_t *q,
5066 vl_api_lisp_locator_set_details_t *rmp;
5067 locator_t *loc = NULL;
5071 vec_foreach (locit, lsit->locator_indices) {
5072 loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
5073 rmp = vl_msg_api_alloc (sizeof (*rmp));
5074 memset (rmp, 0, sizeof (*rmp));
5075 rmp->_vl_msg_id = ntohs(VL_API_LISP_LOCATOR_SET_DETAILS);
5076 rmp->local = lsit->local;
5078 ASSERT(lsit->name != NULL);
5079 strncpy((char *) rmp->locator_set_name,
5080 (char *) lsit->name, ARRAY_LEN(rmp->locator_set_name) - 1);
5081 rmp->sw_if_index = htonl(loc->sw_if_index);
5083 str = format(0, "remote-%d", index);
5084 strncpy((char *) rmp->locator_set_name, (char *) str,
5085 ARRAY_LEN(rmp->locator_set_name) - 1);
5086 send_lisp_locator_set_details_set_address(rmp, &loc->address);
5090 rmp->priority = loc->priority;
5091 rmp->weight = loc->weight;
5092 rmp->context = context;
5094 vl_msg_api_send_shmem (q, (u8 *)&rmp);
5099 vl_api_lisp_locator_set_dump_t_handler (vl_api_lisp_locator_set_dump_t *mp)
5101 unix_shared_memory_queue_t * q = NULL;
5102 lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
5103 locator_set_t * lsit = NULL;
5106 q = vl_api_client_index_to_input_queue (mp->client_index);
5112 pool_foreach (lsit, lcm->locator_set_pool,
5114 send_lisp_locator_set_details(lcm, lsit, q, mp->context, index++);
5119 send_lisp_local_eid_table_details (mapping_t *mapit,
5120 unix_shared_memory_queue_t *q,
5123 vl_api_lisp_local_eid_table_details_t *rmp = NULL;
5124 lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
5125 locator_set_t *ls = NULL;
5126 gid_address_t *gid = NULL;
5127 ip_prefix_t *ip_prefix = NULL;
5131 ls = pool_elt_at_index (lcm->locator_set_pool,
5132 mapit->locator_set_index);
5135 type = gid_address_type(gid);
5137 if (type != GID_ADDR_IP_PREFIX) {
5141 ip_prefix = &gid_address_ippref(gid);
5143 rmp = vl_msg_api_alloc (sizeof (*rmp));
5144 memset (rmp, 0, sizeof (*rmp));
5145 rmp->_vl_msg_id = ntohs(VL_API_LISP_LOCAL_EID_TABLE_DETAILS);
5147 ASSERT(ls->name != NULL);
5148 strncpy((char *) rmp->locator_set_name,
5149 (char *) ls->name, ARRAY_LEN(rmp->locator_set_name) - 1);
5151 str = format(0, "remote-%d", mapit->locator_set_index);
5152 strncpy((char *) rmp->locator_set_name, (char *) str,
5153 ARRAY_LEN(rmp->locator_set_name) - 1);
5157 switch (ip_prefix_version(ip_prefix)) {
5159 rmp->eid_is_ipv6 = 0;
5160 clib_memcpy(rmp->eid_ip_address, &ip_prefix_v4(ip_prefix),
5161 sizeof(ip_prefix_v4(ip_prefix)));
5165 rmp->eid_is_ipv6 = 1;
5166 clib_memcpy(rmp->eid_ip_address, &ip_prefix_v6(ip_prefix),
5167 sizeof(ip_prefix_v6(ip_prefix)));
5173 rmp->eid_prefix_len = ip_prefix_len(ip_prefix);
5174 rmp->context = context;
5176 vl_msg_api_send_shmem (q, (u8 *)&rmp);
5180 vl_api_lisp_local_eid_table_dump_t_handler (
5181 vl_api_lisp_local_eid_table_dump_t *mp)
5183 unix_shared_memory_queue_t * q = NULL;
5184 lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
5185 mapping_t * mapit = NULL;
5187 q = vl_api_client_index_to_input_queue (mp->client_index);
5192 pool_foreach (mapit, lcm->mapping_pool,
5194 send_lisp_local_eid_table_details(mapit, q, mp->context);
5199 send_lisp_gpe_tunnel_details (lisp_gpe_tunnel_t *tunnel,
5200 unix_shared_memory_queue_t *q,
5203 vl_api_lisp_gpe_tunnel_details_t *rmp;
5204 lisp_gpe_main_t * lgm = &lisp_gpe_main;
5206 rmp = vl_msg_api_alloc (sizeof (*rmp));
5207 memset (rmp, 0, sizeof (*rmp));
5208 rmp->_vl_msg_id = ntohs(VL_API_LISP_GPE_TUNNEL_DETAILS);
5210 rmp->tunnels = tunnel - lgm->tunnels;
5212 rmp->is_ipv6 = ip_addr_version(&tunnel->src) == IP6 ? 1 : 0;
5213 ip_address_copy_addr(rmp->source_ip, &tunnel->src);
5214 ip_address_copy_addr(rmp->destination_ip, &tunnel->dst);
5216 rmp->encap_fib_id = htonl(tunnel->encap_fib_index);
5217 rmp->decap_fib_id = htonl(tunnel->decap_fib_index);
5218 rmp->dcap_next = htonl(tunnel->decap_next_index);
5219 rmp->lisp_ver = tunnel->ver_res;
5220 rmp->next_protocol = tunnel->next_protocol;
5221 rmp->flags = tunnel->flags;
5222 rmp->ver_res = tunnel->ver_res;
5223 rmp->res = tunnel->res;
5224 rmp->iid = htonl(tunnel->vni);
5225 rmp->context = context;
5227 vl_msg_api_send_shmem (q, (u8 *)&rmp);
5231 vl_api_lisp_gpe_tunnel_dump_t_handler (
5232 vl_api_lisp_local_eid_table_dump_t *mp)
5234 unix_shared_memory_queue_t * q = NULL;
5235 lisp_gpe_main_t * lgm = &lisp_gpe_main;
5236 lisp_gpe_tunnel_t * tunnel = NULL;
5238 if (pool_elts(lgm->tunnels) == 0) {
5242 q = vl_api_client_index_to_input_queue (mp->client_index);
5247 pool_foreach(tunnel, lgm->tunnels,
5249 send_lisp_gpe_tunnel_details(tunnel, q, mp->context);
5254 send_lisp_map_resolver_details (ip_address_t *ip,
5255 unix_shared_memory_queue_t *q,
5258 vl_api_lisp_map_resolver_details_t *rmp = NULL;
5260 rmp = vl_msg_api_alloc (sizeof (*rmp));
5261 memset (rmp, 0, sizeof (*rmp));
5262 rmp->_vl_msg_id = ntohs(VL_API_LISP_MAP_RESOLVER_DETAILS);
5264 switch (ip_addr_version(ip)) {
5267 clib_memcpy(rmp->ip_address, &ip_addr_v4(ip), sizeof(ip_addr_v4(ip)));
5272 clib_memcpy(rmp->ip_address, &ip_addr_v6(ip), sizeof(ip_addr_v6(ip)));
5278 rmp->context = context;
5280 vl_msg_api_send_shmem (q, (u8 *)&rmp);
5284 vl_api_lisp_map_resolver_dump_t_handler (
5285 vl_api_lisp_map_resolver_dump_t *mp)
5287 unix_shared_memory_queue_t * q = NULL;
5288 lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
5289 ip_address_t *ip = NULL;
5291 q = vl_api_client_index_to_input_queue (mp->client_index);
5296 vec_foreach(ip, lcm->map_resolvers) {
5297 send_lisp_map_resolver_details(ip, q, mp->context);
5303 send_lisp_enable_disable_details (unix_shared_memory_queue_t *q,
5306 vl_api_lisp_enable_disable_status_details_t *rmp = NULL;
5308 rmp = vl_msg_api_alloc (sizeof (*rmp));
5309 memset (rmp, 0, sizeof (*rmp));
5310 rmp->_vl_msg_id = ntohs(VL_API_LISP_ENABLE_DISABLE_STATUS_DETAILS);
5312 rmp->gpe_status = vnet_lisp_gpe_enable_disable_status ();
5313 rmp->feature_status = vnet_lisp_enable_disable_status ();
5314 rmp->context = context;
5316 vl_msg_api_send_shmem (q, (u8 *)&rmp);
5320 vl_api_lisp_enable_disable_status_dump_t_handler
5321 (vl_api_lisp_enable_disable_status_dump_t *mp)
5323 unix_shared_memory_queue_t * q = NULL;
5325 q = vl_api_client_index_to_input_queue (mp->client_index);
5330 send_lisp_enable_disable_details(q, mp->context);
5334 vl_api_lisp_get_map_request_itr_rlocs_t_handler (
5335 vl_api_lisp_get_map_request_itr_rlocs_t *mp)
5337 unix_shared_memory_queue_t * q = NULL;
5338 vl_api_lisp_get_map_request_itr_rlocs_reply_t *rmp = NULL;
5339 lisp_cp_main_t * lcm = vnet_lisp_cp_get_main();
5340 locator_set_t * loc_set = 0;
5344 q = vl_api_client_index_to_input_queue (mp->client_index);
5349 if (~0 == lcm->mreq_itr_rlocs) {
5350 tmp_str = format(0, " ");
5352 loc_set = pool_elt_at_index (lcm->locator_set_pool, lcm->mreq_itr_rlocs);
5353 tmp_str = format(0, "%s", loc_set->name);
5356 REPLY_MACRO2(VL_API_LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,
5358 strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
5359 ARRAY_LEN(rmp->locator_set_name) - 1);
5366 vl_api_interface_name_renumber_t_handler (vl_api_interface_name_renumber_t *mp)
5368 vl_api_interface_name_renumber_reply_t * rmp;
5371 VALIDATE_SW_IF_INDEX(mp);
5373 rv = vnet_interface_name_renumber
5374 (ntohl(mp->sw_if_index), ntohl(mp->new_show_dev_instance));
5376 BAD_SW_IF_INDEX_LABEL;
5378 REPLY_MACRO(VL_API_INTERFACE_NAME_RENUMBER_REPLY);
5381 static int arp_change_data_callback (u32 pool_index, u8 * new_mac,
5382 u32 sw_if_index, u32 address)
5384 vpe_api_main_t * am = &vpe_api_main;
5385 vlib_main_t * vm = am->vlib_main;
5386 vl_api_ip4_arp_event_t * event;
5387 static f64 arp_event_last_time;
5388 f64 now = vlib_time_now (vm);
5390 if (pool_is_free_index (am->arp_events, pool_index))
5393 event = pool_elt_at_index (am->arp_events, pool_index);
5394 if (memcmp (&event->new_mac, new_mac, sizeof (event->new_mac))) {
5395 clib_memcpy (event->new_mac, new_mac, sizeof(event->new_mac));
5396 } else { /* same mac */
5397 if ((sw_if_index == event->sw_if_index) &&
5399 /* for BD case, also check IP address with 10 sec timeout */
5400 ((address == event->address) &&
5401 ((now - arp_event_last_time) < 10.0))))
5405 arp_event_last_time = now;
5406 event->sw_if_index = sw_if_index;
5407 if (address) event->address = address;
5411 static int arp_change_delete_callback (u32 pool_index, u8 * notused)
5413 vpe_api_main_t * am = &vpe_api_main;
5415 if (pool_is_free_index (am->arp_events, pool_index))
5418 pool_put_index (am->arp_events, pool_index);
5423 vl_api_want_ip4_arp_events_t_handler
5424 (vl_api_want_ip4_arp_events_t * mp)
5426 vpe_api_main_t * am = &vpe_api_main;
5427 vnet_main_t * vnm = vnet_get_main();
5428 vl_api_want_ip4_arp_events_reply_t *rmp;
5429 vl_api_ip4_arp_event_t * event;
5432 if (mp->enable_disable) {
5433 pool_get (am->arp_events, event);
5434 memset (event, 0, sizeof (*event));
5436 event->_vl_msg_id = ntohs(VL_API_IP4_ARP_EVENT);
5437 event->client_index = mp->client_index;
5438 event->context = mp->context;
5439 event->address = mp->address;
5440 event->pid = mp->pid;
5442 rv = vnet_add_del_ip4_arp_change_event
5443 (vnm, arp_change_data_callback,
5445 &mp->address /* addr, in net byte order */,
5446 vpe_resolver_process_node.index,
5447 IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */);
5449 rv = vnet_add_del_ip4_arp_change_event
5450 (vnm, arp_change_delete_callback,
5452 &mp->address /* addr, in net byte order */,
5453 vpe_resolver_process_node.index,
5454 IP4_ARP_EVENT, ~0 /* pool index */, 0 /* is_add */);
5456 REPLY_MACRO(VL_API_WANT_IP4_ARP_EVENTS_REPLY);
5459 static void vl_api_input_acl_set_interface_t_handler
5460 (vl_api_input_acl_set_interface_t * mp)
5462 vlib_main_t *vm = vlib_get_main();
5463 vl_api_input_acl_set_interface_reply_t * rmp;
5465 u32 sw_if_index, ip4_table_index, ip6_table_index, l2_table_index;
5467 ip4_table_index = ntohl(mp->ip4_table_index);
5468 ip6_table_index = ntohl(mp->ip6_table_index);
5469 l2_table_index = ntohl(mp->l2_table_index);
5470 sw_if_index = ntohl(mp->sw_if_index);
5472 VALIDATE_SW_IF_INDEX(mp);
5474 rv = vnet_set_input_acl_intfc (vm, sw_if_index, ip4_table_index,
5475 ip6_table_index, l2_table_index,
5478 BAD_SW_IF_INDEX_LABEL;
5480 REPLY_MACRO(VL_API_INPUT_ACL_SET_INTERFACE_REPLY);
5483 static void vl_api_ipsec_spd_add_del_t_handler
5484 (vl_api_ipsec_spd_add_del_t * mp)
5487 clib_warning ("unimplemented");
5490 vlib_main_t *vm __attribute__((unused)) = vlib_get_main();
5491 vl_api_ipsec_spd_add_del_reply_t * rmp;
5495 rv = ipsec_add_del_spd (vm, ntohl(mp->spd_id), mp->is_add);
5497 rv = VNET_API_ERROR_UNIMPLEMENTED;
5500 REPLY_MACRO(VL_API_IPSEC_SPD_ADD_DEL_REPLY);
5504 static void vl_api_ipsec_interface_add_del_spd_t_handler
5505 (vl_api_ipsec_interface_add_del_spd_t * mp)
5507 vlib_main_t *vm __attribute__((unused)) = vlib_get_main();
5508 vl_api_ipsec_interface_add_del_spd_reply_t * rmp;
5510 u32 sw_if_index __attribute__((unused));
5511 u32 spd_id __attribute__((unused));
5513 sw_if_index = ntohl(mp->sw_if_index);
5514 spd_id = ntohl(mp->spd_id);
5516 VALIDATE_SW_IF_INDEX(mp);
5519 rv = ipsec_set_interface_spd(vm, sw_if_index, spd_id, mp->is_add);
5521 rv = VNET_API_ERROR_UNIMPLEMENTED;
5524 BAD_SW_IF_INDEX_LABEL;
5526 REPLY_MACRO(VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY);
5529 static void vl_api_ipsec_spd_add_del_entry_t_handler
5530 (vl_api_ipsec_spd_add_del_entry_t * mp)
5532 vlib_main_t *vm __attribute__((unused)) = vlib_get_main();
5533 vl_api_ipsec_spd_add_del_entry_reply_t * rmp;
5539 memset(&p, 0, sizeof(p));
5541 p.id = ntohl(mp->spd_id);
5542 p.priority = ntohl(mp->priority);
5543 p.is_outbound = mp->is_outbound;
5544 p.is_ipv6 = mp->is_ipv6;
5546 clib_memcpy(&p.raddr.start, mp->remote_address_start, 16);
5547 clib_memcpy(&p.raddr.stop, mp->remote_address_stop, 16);
5548 clib_memcpy(&p.laddr.start, mp->local_address_start, 16);
5549 clib_memcpy(&p.laddr.stop, mp->local_address_stop, 16);
5551 p.protocol = mp->protocol;
5552 p.rport.start = ntohs(mp->remote_port_start);
5553 p.rport.stop = ntohs(mp->remote_port_stop);
5554 p.lport.start = ntohs(mp->local_port_start);
5555 p.lport.stop = ntohs(mp->local_port_stop);
5556 /* policy action resolve unsupported */
5557 if (mp->policy == IPSEC_POLICY_ACTION_RESOLVE) {
5558 clib_warning("unsupported action: 'resolve'");
5559 rv = VNET_API_ERROR_UNIMPLEMENTED;
5562 p.policy = mp->policy;
5563 p.sa_id = ntohl(mp->sa_id);
5565 rv = ipsec_add_del_policy(vm, &p, mp->is_add);
5569 if (mp->is_ip_any) {
5571 rv = ipsec_add_del_policy(vm, &p, mp->is_add);
5574 rv = VNET_API_ERROR_UNIMPLEMENTED;
5579 REPLY_MACRO(VL_API_IPSEC_SPD_ADD_DEL_ENTRY_REPLY);
5582 static void vl_api_ipsec_sad_add_del_entry_t_handler
5583 (vl_api_ipsec_sad_add_del_entry_t * mp)
5585 vlib_main_t *vm __attribute__((unused)) = vlib_get_main();
5586 vl_api_ipsec_sad_add_del_entry_reply_t * rmp;
5591 memset(&sa, 0, sizeof(sa));
5593 sa.id = ntohl(mp->sad_id);
5594 sa.spi = ntohl(mp->spi);
5595 /* security protocol AH unsupported */
5596 if (mp->protocol == IPSEC_PROTOCOL_AH) {
5597 clib_warning("unsupported security protocol 'AH'");
5598 rv = VNET_API_ERROR_UNIMPLEMENTED;
5601 sa.protocol = mp->protocol;
5602 /* check for unsupported crypto-alg */
5603 if (mp->crypto_algorithm < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
5604 mp->crypto_algorithm > IPSEC_CRYPTO_ALG_AES_CBC_256) {
5605 clib_warning("unsupported crypto-alg: '%U'", format_ipsec_crypto_alg,
5606 mp->crypto_algorithm);
5607 rv = VNET_API_ERROR_UNIMPLEMENTED;
5610 sa.crypto_alg = mp->crypto_algorithm;
5611 sa.crypto_key_len = mp->crypto_key_length;
5612 clib_memcpy(&sa.crypto_key, mp->crypto_key, sizeof(sa.crypto_key));
5613 /* check for unsupported integ-alg */
5614 if (mp->integrity_algorithm < IPSEC_INTEG_ALG_SHA1_96 ||
5615 mp->integrity_algorithm > IPSEC_INTEG_ALG_SHA_512_256) {
5616 clib_warning("unsupported integ-alg: '%U'", format_ipsec_integ_alg,
5617 mp->integrity_algorithm);
5618 rv = VNET_API_ERROR_UNIMPLEMENTED;
5621 sa.integ_alg = mp->integrity_algorithm;
5622 sa.integ_key_len = mp->integrity_key_length;
5623 clib_memcpy(&sa.integ_key, mp->integrity_key, sizeof(sa.integ_key));
5624 sa.use_esn = mp->use_extended_sequence_number;
5625 sa.is_tunnel = mp->is_tunnel;
5626 sa.is_tunnel_ip6 = mp->is_tunnel_ipv6;
5627 clib_memcpy(&sa.tunnel_src_addr, mp->tunnel_src_address, 16);
5628 clib_memcpy(&sa.tunnel_dst_addr, mp->tunnel_dst_address, 16);
5630 rv = ipsec_add_del_sa(vm, &sa, mp->is_add);
5632 rv = VNET_API_ERROR_UNIMPLEMENTED;
5637 REPLY_MACRO(VL_API_IPSEC_SAD_ADD_DEL_ENTRY_REPLY);
5641 vl_api_ikev2_profile_add_del_t_handler
5642 (vl_api_ikev2_profile_add_del_t * mp)
5644 vl_api_ikev2_profile_add_del_reply_t * rmp;
5648 vlib_main_t * vm = vlib_get_main();
5649 clib_error_t * error;
5650 u8 * tmp = format(0, "%s", mp->name);
5651 error = ikev2_add_del_profile(vm, tmp, mp->is_add);
5654 rv = VNET_API_ERROR_UNSPECIFIED;
5656 rv = VNET_API_ERROR_UNIMPLEMENTED;
5659 REPLY_MACRO(VL_API_IKEV2_PROFILE_ADD_DEL_REPLY);
5663 vl_api_ikev2_profile_set_auth_t_handler
5664 (vl_api_ikev2_profile_set_auth_t * mp)
5666 vl_api_ikev2_profile_set_auth_reply_t * rmp;
5670 vlib_main_t * vm = vlib_get_main();
5671 clib_error_t * error;
5672 u8 * tmp = format(0, "%s", mp->name);
5673 u8 * data = vec_new (u8, mp->data_len);
5674 clib_memcpy(data, mp->data, mp->data_len);
5675 error = ikev2_set_profile_auth(vm, tmp, mp->auth_method, data, mp->is_hex);
5679 rv = VNET_API_ERROR_UNSPECIFIED;
5681 rv = VNET_API_ERROR_UNIMPLEMENTED;
5684 REPLY_MACRO(VL_API_IKEV2_PROFILE_SET_AUTH_REPLY);
5688 vl_api_ikev2_profile_set_id_t_handler
5689 (vl_api_ikev2_profile_set_id_t * mp)
5691 vl_api_ikev2_profile_add_del_reply_t * rmp;
5695 vlib_main_t * vm = vlib_get_main();
5696 clib_error_t * error;
5697 u8 * tmp = format(0, "%s", mp->name);
5698 u8 * data = vec_new (u8, mp->data_len);
5699 clib_memcpy(data, mp->data, mp->data_len);
5700 error = ikev2_set_profile_id(vm, tmp, mp->id_type, data, mp->is_local);
5704 rv = VNET_API_ERROR_UNSPECIFIED;
5706 rv = VNET_API_ERROR_UNIMPLEMENTED;
5709 REPLY_MACRO(VL_API_IKEV2_PROFILE_SET_ID_REPLY);
5713 vl_api_ikev2_profile_set_ts_t_handler
5714 (vl_api_ikev2_profile_set_ts_t * mp)
5716 vl_api_ikev2_profile_set_ts_reply_t * rmp;
5720 vlib_main_t * vm = vlib_get_main();
5721 clib_error_t * error;
5722 u8 * tmp = format(0, "%s", mp->name);
5723 error = ikev2_set_profile_ts(vm, tmp, mp->proto, mp->start_port,
5724 mp->end_port, (ip4_address_t) mp->start_addr,
5725 (ip4_address_t) mp->end_addr, mp->is_local);
5728 rv = VNET_API_ERROR_UNSPECIFIED;
5730 rv = VNET_API_ERROR_UNIMPLEMENTED;
5733 REPLY_MACRO(VL_API_IKEV2_PROFILE_SET_TS_REPLY);
5737 vl_api_ikev2_set_local_key_t_handler
5738 (vl_api_ikev2_set_local_key_t * mp)
5740 vl_api_ikev2_profile_set_ts_reply_t * rmp;
5744 vlib_main_t * vm = vlib_get_main();
5745 clib_error_t * error;
5747 error = ikev2_set_local_key(vm, mp->key_file);
5749 rv = VNET_API_ERROR_UNSPECIFIED;
5751 rv = VNET_API_ERROR_UNIMPLEMENTED;
5754 REPLY_MACRO(VL_API_IKEV2_SET_LOCAL_KEY_REPLY);
5758 vl_api_map_add_domain_t_handler
5759 (vl_api_map_add_domain_t * mp)
5761 vl_api_map_add_domain_reply_t * rmp;
5764 u8 flags = mp->is_translation ? MAP_DOMAIN_TRANSLATION : 0;
5765 rv = map_create_domain((ip4_address_t *)&mp->ip4_prefix, mp->ip4_prefix_len,
5766 (ip6_address_t *)&mp->ip6_prefix, mp->ip6_prefix_len,
5767 (ip6_address_t *)&mp->ip6_src, mp->ip6_src_prefix_len,
5768 mp->ea_bits_len, mp->psid_offset, mp->psid_length, &index, ntohs(mp->mtu), flags);
5770 REPLY_MACRO2(VL_API_MAP_ADD_DOMAIN_REPLY,
5772 rmp->index = ntohl(index);
5777 vl_api_map_del_domain_t_handler
5778 (vl_api_map_del_domain_t * mp)
5780 vl_api_map_del_domain_reply_t * rmp;
5783 rv = map_delete_domain(ntohl(mp->index));
5785 REPLY_MACRO(VL_API_MAP_DEL_DOMAIN_REPLY);
5789 vl_api_map_add_del_rule_t_handler
5790 (vl_api_map_add_del_rule_t * mp)
5792 vl_api_map_del_domain_reply_t * rmp;
5795 rv = map_add_del_psid(ntohl(mp->index), ntohs(mp->psid), (ip6_address_t *)mp->ip6_dst, mp->is_add);
5797 REPLY_MACRO(VL_API_MAP_ADD_DEL_RULE_REPLY);
5801 vl_api_map_domain_dump_t_handler
5802 (vl_api_map_domain_dump_t * mp)
5804 vl_api_map_domain_details_t * rmp;
5805 map_main_t *mm = &map_main;
5807 unix_shared_memory_queue_t * q;
5809 if (pool_elts (mm->domains) == 0)
5812 q = vl_api_client_index_to_input_queue (mp->client_index);
5817 pool_foreach(d, mm->domains, ({
5818 /* Make sure every field is initiated (or don't skip the memset()) */
5819 rmp = vl_msg_api_alloc (sizeof (*rmp));
5820 rmp->_vl_msg_id = ntohs(VL_API_MAP_DOMAIN_DETAILS);
5821 rmp->domain_index = htonl(d - mm->domains);
5822 rmp->ea_bits_len = d->ea_bits_len;
5823 rmp->psid_offset = d->psid_offset;
5824 rmp->psid_length = d->psid_length;
5825 clib_memcpy(rmp->ip4_prefix, &d->ip4_prefix, sizeof(rmp->ip4_prefix));
5826 rmp->ip4_prefix_len = d->ip4_prefix_len;
5827 clib_memcpy(rmp->ip6_prefix, &d->ip6_prefix, sizeof(rmp->ip6_prefix));
5828 rmp->ip6_prefix_len = d->ip6_prefix_len;
5829 clib_memcpy(rmp->ip6_src, &d->ip6_src, sizeof(rmp->ip6_src));
5830 rmp->ip6_src_len = d->ip6_src_len;
5831 rmp->mtu = htons(d->mtu);
5832 rmp->is_translation = (d->flags & MAP_DOMAIN_TRANSLATION);
5833 rmp->context = mp->context;
5835 vl_msg_api_send_shmem (q, (u8 *)&rmp);
5840 vl_api_map_rule_dump_t_handler
5841 (vl_api_map_rule_dump_t * mp)
5843 unix_shared_memory_queue_t * q;
5846 vl_api_map_rule_details_t * rmp;
5847 map_main_t *mm = &map_main;
5848 u32 domain_index = ntohl(mp->domain_index);
5851 if (pool_elts (mm->domains) == 0)
5854 d = pool_elt_at_index(mm->domains, domain_index);
5855 if (!d || !d->rules) {
5859 q = vl_api_client_index_to_input_queue (mp->client_index);
5864 for (i = 0; i < (0x1 << d->psid_length); i++) {
5866 if (dst.as_u64[0] == 0 && dst.as_u64[1] == 0) {
5869 rmp = vl_msg_api_alloc(sizeof(*rmp));
5870 memset(rmp, 0, sizeof(*rmp));
5871 rmp->_vl_msg_id = ntohs(VL_API_MAP_RULE_DETAILS);
5872 rmp->psid = htons(i);
5873 clib_memcpy(rmp->ip6_dst, &dst, sizeof(rmp->ip6_dst));
5874 rmp->context = mp->context;
5875 vl_msg_api_send_shmem(q, (u8 *)&rmp);
5880 vl_api_map_summary_stats_t_handler (
5881 vl_api_map_summary_stats_t *mp)
5883 vl_api_map_summary_stats_reply_t *rmp;
5884 vlib_combined_counter_main_t *cm;
5887 u64 total_pkts[VLIB_N_RX_TX];
5888 u64 total_bytes[VLIB_N_RX_TX];
5889 map_main_t *mm = &map_main;
5890 unix_shared_memory_queue_t *q =
5891 vl_api_client_index_to_input_queue(mp->client_index);
5896 rmp = vl_msg_api_alloc (sizeof (*rmp));
5897 rmp->_vl_msg_id = ntohs(VL_API_MAP_SUMMARY_STATS_REPLY);
5898 rmp->context = mp->context;
5901 memset (total_pkts, 0, sizeof (total_pkts));
5902 memset (total_bytes, 0, sizeof (total_bytes));
5904 map_domain_counter_lock (mm);
5905 vec_foreach(cm, mm->domain_counters) {
5906 which = cm - mm->domain_counters;
5908 for (i = 0; i < vec_len(cm->maxi); i++) {
5909 vlib_get_combined_counter (cm, i, &v);
5910 total_pkts[which] += v.packets;
5911 total_bytes[which] += v.bytes;
5915 map_domain_counter_unlock (mm);
5917 /* Note: in network byte order! */
5918 rmp->total_pkts[MAP_DOMAIN_COUNTER_RX] = clib_host_to_net_u64(total_pkts[MAP_DOMAIN_COUNTER_RX]);
5919 rmp->total_bytes[MAP_DOMAIN_COUNTER_RX] = clib_host_to_net_u64(total_bytes[MAP_DOMAIN_COUNTER_RX]);
5920 rmp->total_pkts[MAP_DOMAIN_COUNTER_TX] = clib_host_to_net_u64(total_pkts[MAP_DOMAIN_COUNTER_TX]);
5921 rmp->total_bytes[MAP_DOMAIN_COUNTER_TX] = clib_host_to_net_u64(total_bytes[MAP_DOMAIN_COUNTER_TX]);
5922 rmp->total_bindings = clib_host_to_net_u64(pool_elts(mm->domains));
5923 rmp->total_ip4_fragments = 0; // Not yet implemented. Should be a simple counter.
5924 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));
5925 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));
5927 vl_msg_api_send_shmem(q, (u8 *)&rmp);
5930 static void vl_api_ipsec_sa_set_key_t_handler
5931 (vl_api_ipsec_sa_set_key_t * mp)
5933 vlib_main_t *vm __attribute__((unused)) = vlib_get_main();
5934 vl_api_ipsec_sa_set_key_reply_t *rmp;
5938 sa.id = ntohl(mp->sa_id);
5939 sa.crypto_key_len = mp->crypto_key_length;
5940 clib_memcpy(&sa.crypto_key, mp->crypto_key, sizeof(sa.crypto_key));
5941 sa.integ_key_len = mp->integrity_key_length;
5942 clib_memcpy(&sa.integ_key, mp->integrity_key, sizeof(sa.integ_key));
5944 rv = ipsec_set_sa_key(vm, &sa);
5946 rv = VNET_API_ERROR_UNIMPLEMENTED;
5949 REPLY_MACRO(VL_API_IPSEC_SA_SET_KEY_REPLY);
5952 static void vl_api_cop_interface_enable_disable_t_handler
5953 (vl_api_cop_interface_enable_disable_t * mp)
5955 vl_api_cop_interface_enable_disable_reply_t * rmp;
5957 u32 sw_if_index = ntohl(mp->sw_if_index);
5960 VALIDATE_SW_IF_INDEX(mp);
5962 enable_disable = (int) mp->enable_disable;
5964 rv = cop_interface_enable_disable (sw_if_index, enable_disable);
5966 BAD_SW_IF_INDEX_LABEL;
5968 REPLY_MACRO(VL_API_COP_INTERFACE_ENABLE_DISABLE_REPLY);
5971 static void vl_api_cop_whitelist_enable_disable_t_handler
5972 (vl_api_cop_whitelist_enable_disable_t * mp)
5974 vl_api_cop_whitelist_enable_disable_reply_t * rmp;
5975 cop_whitelist_enable_disable_args_t _a, *a=&_a;
5976 u32 sw_if_index = ntohl(mp->sw_if_index);
5979 VALIDATE_SW_IF_INDEX(mp);
5981 a->sw_if_index = sw_if_index;
5984 a->default_cop = mp->default_cop;
5985 a->fib_id = ntohl(mp->fib_id);
5987 rv = cop_whitelist_enable_disable (a);
5989 BAD_SW_IF_INDEX_LABEL;
5991 REPLY_MACRO(VL_API_COP_WHITELIST_ENABLE_DISABLE_REPLY);
5994 static void vl_api_get_node_graph_t_handler
5995 (vl_api_get_node_graph_t * mp)
5999 api_main_t * am = &api_main;
6000 vlib_main_t * vm = vlib_get_main();
6002 vl_api_get_node_graph_reply_t * rmp;
6004 pthread_mutex_lock (&am->vlib_rp->mutex);
6005 oldheap = svm_push_data_heap (am->vlib_rp);
6008 * Keep the number of memcpy ops to a minimum (e.g. 1).
6010 vec_validate (vector, 16384);
6011 vec_reset_length (vector);
6014 vector = vlib_node_serialize (&vm->node_main, vector,
6015 (u32)~0 /* all threads */,
6016 1 /* include nexts */,
6017 1 /* include stats */);
6019 svm_pop_heap (oldheap);
6020 pthread_mutex_unlock (&am->vlib_rp->mutex);
6022 REPLY_MACRO2(VL_API_GET_NODE_GRAPH_REPLY,
6023 rmp->reply_in_shmem = (uword) vector);
6026 static void vl_api_trace_profile_add_t_handler
6027 (vl_api_trace_profile_add_t *mp)
6030 vl_api_trace_profile_add_reply_t * rmp;
6031 clib_error_t *error;
6033 /* Ignoring the profile id as currently a single profile
6035 error = ip6_ioam_trace_profile_set(mp->trace_num_elt, mp->trace_type,
6036 ntohl(mp->node_id), ntohl(mp->trace_app_data),
6037 mp->pow_enable, mp->trace_tsp,
6040 clib_error_report(error);
6041 rv = clib_error_get_code(error);
6044 REPLY_MACRO(VL_API_TRACE_PROFILE_ADD_REPLY);
6047 static void vl_api_trace_profile_apply_t_handler
6048 (vl_api_trace_profile_apply_t *mp)
6051 vl_api_trace_profile_apply_reply_t * rmp;
6053 if (mp->enable != 0) {
6054 rv = ip6_ioam_set_destination ((ip6_address_t *)(&mp->dest_ipv6),
6055 ntohl(mp->prefix_length),
6057 mp->trace_op == IOAM_HBYH_ADD,
6058 mp->trace_op == IOAM_HBYH_POP,
6059 mp->trace_op == IOAM_HBYH_MOD);
6061 //ip6_ioam_clear_destination(&ip6, mp->prefix_length, mp->vrf_id);
6063 REPLY_MACRO(VL_API_TRACE_PROFILE_APPLY_REPLY);
6066 static void vl_api_trace_profile_del_t_handler
6067 (vl_api_trace_profile_del_t *mp)
6070 vl_api_trace_profile_del_reply_t * rmp;
6071 clib_error_t *error;
6073 error = clear_ioam_rewrite_fn();
6075 clib_error_report(error);
6076 rv = clib_error_get_code(error);
6079 REPLY_MACRO(VL_API_TRACE_PROFILE_DEL_REPLY);
6083 vl_api_af_packet_create_t_handler
6084 (vl_api_af_packet_create_t *mp)
6086 vlib_main_t *vm = vlib_get_main();
6087 vl_api_af_packet_create_reply_t *rmp;
6089 u8 *host_if_name = NULL;
6092 host_if_name = format(0, "%s", mp->host_if_name);
6093 vec_add1 (host_if_name, 0);
6095 rv = af_packet_create_if(vm, host_if_name,
6096 mp->use_random_hw_addr ? 0 : mp->hw_addr, &sw_if_index);
6098 vec_free(host_if_name);
6100 REPLY_MACRO2(VL_API_AF_PACKET_CREATE_REPLY,
6101 rmp->sw_if_index = clib_host_to_net_u32(sw_if_index));
6105 vl_api_af_packet_delete_t_handler
6106 (vl_api_af_packet_delete_t *mp)
6108 vlib_main_t * vm = vlib_get_main();
6109 vl_api_af_packet_delete_reply_t *rmp;
6111 u8 *host_if_name = NULL;
6113 host_if_name = format(0, "%s", mp->host_if_name);
6114 vec_add1 (host_if_name, 0);
6116 rv = af_packet_delete_if(vm, host_if_name);
6118 vec_free(host_if_name);
6120 REPLY_MACRO(VL_API_AF_PACKET_DELETE_REPLY);
6124 vl_api_policer_add_del_t_handler
6125 (vl_api_policer_add_del_t *mp)
6127 vlib_main_t * vm = vlib_get_main();
6128 vl_api_policer_add_del_reply_t *rmp;
6131 sse2_qos_pol_cfg_params_st cfg;
6132 clib_error_t * error;
6134 name = format(0, "%s", mp->name);
6136 memset (&cfg, 0, sizeof (cfg));
6138 cfg.rnd_type = mp->round_type;
6139 cfg.rate_type = mp->rate_type;
6140 cfg.rb.kbps.cir_kbps = mp->cir;
6141 cfg.rb.kbps.eir_kbps = mp->eir;
6142 cfg.rb.kbps.cb_bytes = mp->cb;
6143 cfg.rb.kbps.eb_bytes = mp->eb;
6145 error = policer_add_del(vm, name, &cfg, mp->is_add);
6148 rv = VNET_API_ERROR_UNSPECIFIED;
6150 REPLY_MACRO(VL_API_POLICER_ADD_DEL_REPLY);
6154 send_policer_details (u8 *name,
6155 sse2_qos_pol_cfg_params_st *config,
6156 policer_read_response_type_st *templ,
6157 unix_shared_memory_queue_t *q,
6160 vl_api_policer_details_t * mp;
6162 mp = vl_msg_api_alloc (sizeof (*mp));
6163 memset (mp, 0, sizeof (*mp));
6164 mp->_vl_msg_id = ntohs (VL_API_POLICER_DETAILS);
6165 mp->context = context;
6166 mp->cir = htonl(config->rb.kbps.cir_kbps);
6167 mp->eir = htonl(config->rb.kbps.eir_kbps);
6168 mp->cb = htonl(config->rb.kbps.cb_bytes);
6169 mp->eb = htonl(config->rb.kbps.eb_bytes);
6170 mp->rate_type = config->rate_type;
6171 mp->round_type = config->rnd_type;
6172 mp->type = config->rfc;
6173 mp->single_rate = templ->single_rate ? 1 : 0;
6174 mp->color_aware = templ->color_aware ? 1 : 0;
6175 mp->scale = htonl(templ->scale);
6176 mp->cir_tokens_per_period = htonl(templ->cir_tokens_per_period);
6177 mp->pir_tokens_per_period = htonl(templ->pir_tokens_per_period);
6178 mp->current_limit = htonl(templ->current_limit);
6179 mp->current_bucket = htonl(templ->current_bucket);
6180 mp->extended_limit = htonl(templ->extended_limit);
6181 mp->extended_bucket = htonl(templ->extended_bucket);
6182 mp->last_update_time = clib_host_to_net_u64(templ->last_update_time);
6184 strncpy ((char *) mp->name, (char *) name, ARRAY_LEN(mp->name) - 1);
6186 vl_msg_api_send_shmem (q, (u8 *)&mp);
6190 vl_api_policer_dump_t_handler
6191 (vl_api_policer_dump_t *mp)
6193 unix_shared_memory_queue_t * q;
6194 vnet_policer_main_t * pm = &vnet_policer_main;
6198 u8 * match_name = 0;
6200 sse2_qos_pol_cfg_params_st *config;
6201 policer_read_response_type_st *templ;
6203 q = vl_api_client_index_to_input_queue (mp->client_index);
6207 if (mp->match_name_valid) {
6208 match_name = format(0, "%s%c", mp->match_name, 0);
6211 if (mp->match_name_valid) {
6212 p = hash_get_mem (pm->policer_config_by_name, match_name);
6215 config = pool_elt_at_index (pm->configs, pool_index);
6216 templ = pool_elt_at_index (pm->policer_templates, pool_index);
6217 send_policer_details(match_name, config, templ, q, mp->context);
6220 hash_foreach_pair (hp, pm->policer_config_by_name,
6222 name = (u8 *) hp->key;
6223 pool_index = hp->value[0];
6224 config = pool_elt_at_index (pm->configs, pool_index);
6225 templ = pool_elt_at_index (pm->policer_templates, pool_index);
6226 send_policer_details(name, config, templ, q, mp->context);
6232 vl_api_netmap_create_t_handler
6233 (vl_api_netmap_create_t *mp)
6235 vlib_main_t *vm = vlib_get_main();
6236 vl_api_netmap_create_reply_t *rmp;
6240 if_name = format(0, "%s", mp->netmap_if_name);
6241 vec_add1 (if_name, 0);
6243 rv = netmap_create_if(vm, if_name, mp->use_random_hw_addr ? 0 : mp->hw_addr,
6244 mp->is_pipe, mp->is_master, 0);
6248 REPLY_MACRO(VL_API_NETMAP_CREATE_REPLY);
6252 vl_api_netmap_delete_t_handler
6253 (vl_api_netmap_delete_t *mp)
6255 vlib_main_t * vm = vlib_get_main();
6256 vl_api_netmap_delete_reply_t *rmp;
6260 if_name = format(0, "%s", mp->netmap_if_name);
6261 vec_add1 (if_name, 0);
6263 rv = netmap_delete_if(vm, if_name);
6267 REPLY_MACRO(VL_API_NETMAP_DELETE_REPLY);
6270 #define BOUNCE_HANDLER(nn) \
6271 static void vl_api_##nn##_t_handler ( \
6272 vl_api_##nn##_t *mp) \
6274 vpe_client_registration_t *reg; \
6275 vpe_api_main_t * vam = &vpe_api_main; \
6276 unix_shared_memory_queue_t * q; \
6278 /* One registration only... */ \
6279 pool_foreach(reg, vam->nn##_registrations, \
6281 q = vl_api_client_index_to_input_queue (reg->client_index); \
6284 * If the queue is stuffed, turf the msg and complain \
6285 * It's unlikely that the intended recipient is \
6286 * alive; avoid deadlock at all costs. \
6288 if (q->cursize == q->maxsize) { \
6289 clib_warning ("ERROR: receiver queue full, drop msg"); \
6290 vl_msg_api_free (mp); \
6293 vl_msg_api_send_shmem (q, (u8 *)&mp); \
6297 vl_msg_api_free (mp); \
6302 * Add vpe's API message handlers to the table.
6303 * vlib has alread mapped shared memory and
6304 * added the client registration handlers.
6305 * See .../open-repo/vlib/memclnt_vlib.c:memclnt_process()
6308 static clib_error_t *
6309 vpe_api_hookup (vlib_main_t *vm)
6311 api_main_t * am = &api_main;
6314 vl_msg_api_set_handlers(VL_API_##N, #n, \
6315 vl_api_##n##_t_handler, \
6317 vl_api_##n##_t_endian, \
6318 vl_api_##n##_t_print, \
6319 sizeof(vl_api_##n##_t), 1);
6320 foreach_vpe_api_msg;
6324 * Manually register the sr tunnel add del msg, so we trace
6325 * enough bytes to capture a typical segment list
6327 vl_msg_api_set_handlers (VL_API_SR_TUNNEL_ADD_DEL,
6328 "sr_tunnel_add_del",
6329 vl_api_sr_tunnel_add_del_t_handler,
6331 vl_api_sr_tunnel_add_del_t_endian,
6332 vl_api_sr_tunnel_add_del_t_print,
6337 * Manually register the sr policy add del msg, so we trace
6338 * enough bytes to capture a typical tunnel name list
6340 vl_msg_api_set_handlers (VL_API_SR_POLICY_ADD_DEL,
6341 "sr_policy_add_del",
6342 vl_api_sr_policy_add_del_t_handler,
6344 vl_api_sr_policy_add_del_t_endian,
6345 vl_api_sr_policy_add_del_t_print,
6349 * Trace space for 8 MPLS encap labels, classifier mask+match
6351 am->api_trace_cfg [VL_API_MPLS_ADD_DEL_ENCAP].size += 8 * sizeof(u32);
6352 am->api_trace_cfg [VL_API_CLASSIFY_ADD_DEL_TABLE].size
6353 += 5 * sizeof (u32x4);
6354 am->api_trace_cfg [VL_API_CLASSIFY_ADD_DEL_SESSION].size
6355 += 5 * sizeof (u32x4);
6356 am->api_trace_cfg [VL_API_VXLAN_ADD_DEL_TUNNEL].size
6357 += 16 * sizeof (u32);
6360 * Thread-safe API messages
6362 am->is_mp_safe [VL_API_IP_ADD_DEL_ROUTE] = 1;
6363 am->is_mp_safe [VL_API_GET_NODE_GRAPH] = 1;
6368 VLIB_API_INIT_FUNCTION(vpe_api_hookup);
6370 static clib_error_t *
6371 vpe_api_init (vlib_main_t *vm)
6373 vpe_api_main_t *am = &vpe_api_main;
6376 am->vnet_main = vnet_get_main();
6377 am->interface_events_registration_hash = hash_create (0, sizeof (uword));
6378 am->to_netconf_server_registration_hash = hash_create (0, sizeof (uword));
6379 am->from_netconf_server_registration_hash = hash_create (0, sizeof (uword));
6380 am->to_netconf_client_registration_hash = hash_create (0, sizeof (uword));
6381 am->from_netconf_client_registration_hash = hash_create (0, sizeof (uword));
6382 am->oam_events_registration_hash = hash_create (0, sizeof (uword));
6385 vl_set_memory_region_name ("/vpe-api");
6386 vl_enable_disable_memory_api (vm, 1 /* enable it */);
6391 VLIB_INIT_FUNCTION(vpe_api_init);
6394 static clib_error_t *
6395 api_segment_config (vlib_main_t * vm, unformat_input_t * input)
6400 struct passwd _pw, *pw;
6401 struct group _grp, *grp;
6404 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6406 if (unformat (input, "prefix %s", &chroot_path))
6408 vec_add1 (chroot_path, 0);
6409 vl_set_memory_root_path ((char *)chroot_path);
6411 else if (unformat (input, "uid %d", &uid))
6412 vl_set_memory_uid (uid);
6413 else if (unformat (input, "gid %d", &gid))
6414 vl_set_memory_gid (gid);
6415 else if (unformat (input, "uid %s", &s))
6417 /* lookup the username */
6419 rv = getpwnam_r(s, &_pw, buf, sizeof(buf), &pw);
6422 e = clib_error_return_code(0, rv,
6423 CLIB_ERROR_ERRNO_VALID | CLIB_ERROR_FATAL,
6424 "cannot fetch username %s", s);
6430 e = clib_error_return_fatal(0, "username %s does not exist", s);
6435 vl_set_memory_uid (pw->pw_uid);
6437 else if (unformat (input, "gid %s", &s))
6439 /* lookup the group name */
6441 rv = getgrnam_r(s, &_grp, buf, sizeof(buf), &grp);
6444 e = clib_error_return_code(0, rv,
6445 CLIB_ERROR_ERRNO_VALID | CLIB_ERROR_FATAL,
6446 "cannot fetch group %s", s);
6452 e = clib_error_return_fatal(0, "group %s does not exist", s);
6457 vl_set_memory_gid (grp->gr_gid);
6460 return clib_error_return (0, "unknown input `%U'",
6461 format_unformat_error, input);
6465 VLIB_EARLY_CONFIG_FUNCTION (api_segment_config, "api-segment");
6467 void * get_unformat_vnet_sw_interface (void)
6469 return (void *) &unformat_vnet_sw_interface;
6472 #undef vl_api_version
6473 #define vl_api_version(n,v) static u32 vpe_api_version = v;
6474 #include <api/vpe.api.h>
6475 #undef vl_api_version
6477 int vl_msg_api_version_check (vl_api_memclnt_create_t * mp)
6479 if (clib_host_to_net_u32(mp->api_versions[0]) != vpe_api_version) {
6480 clib_warning ("vpe API mismatch: 0x%08x instead of 0x%08x",
6481 clib_host_to_net_u32 (mp->api_versions[0]),
6488 static u8 * format_arp_event (u8 * s, va_list * args)
6490 vl_api_ip4_arp_event_t * event = va_arg (*args, vl_api_ip4_arp_event_t *);
6492 s = format (s, "pid %d: %U", event->pid,
6493 format_ip4_address, &event->address);
6497 static clib_error_t *
6498 show_ip4_arp_events_fn (vlib_main_t * vm,
6499 unformat_input_t * input,
6500 vlib_cli_command_t * cmd)
6502 vpe_api_main_t * am = &vpe_api_main;
6503 vl_api_ip4_arp_event_t * event;
6505 if (pool_elts (am->arp_events) == 0) {
6506 vlib_cli_output (vm, "No active arp event registrations");
6510 pool_foreach (event, am->arp_events,
6512 vlib_cli_output (vm, "%U", format_arp_event, event);
6518 VLIB_CLI_COMMAND (show_ip4_arp_events, static) = {
6519 .path = "show arp event registrations",
6520 .function = show_ip4_arp_events_fn,
6521 .short_help = "Show arp event registrations",