2 *------------------------------------------------------------------
3 * api.c - message handler registration
5 * Copyright (c) 2010 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
23 #include <sys/types.h>
26 #include <netinet/in.h>
36 #include <vppinfra/clib.h>
37 #include <vppinfra/vec.h>
38 #include <vppinfra/hash.h>
39 #include <vppinfra/bitmap.h>
40 #include <vppinfra/fifo.h>
41 #include <vppinfra/time.h>
42 #include <vppinfra/mheap.h>
43 #include <vppinfra/heap.h>
44 #include <vppinfra/pool.h>
45 #include <vppinfra/format.h>
46 #include <vppinfra/error.h>
48 #include <vnet/api_errno.h>
49 #include <vnet/vnet.h>
50 #include <vnet/l2/l2_input.h>
51 #include <vnet/l2/l2_bd.h>
52 #include <vnet/l2tp/l2tp.h>
53 #include <vnet/ip/ip.h>
54 #include <vnet/ip/ip6.h>
55 #include <vnet/unix/tuntap.h>
56 #include <vnet/unix/tapcli.h>
57 #include <vnet/mpls-gre/mpls.h>
58 #include <vnet/dhcp/proxy.h>
59 #include <vnet/dhcp/client.h>
61 #include <vnet/sr/sr.h>
63 #include <vnet/dhcpv6/proxy.h>
64 #include <vlib/vlib.h>
65 #include <vlib/unix/unix.h>
66 #include <vlibapi/api.h>
67 #include <vlibmemory/api.h>
68 #include <vnet/classify/vnet_classify.h>
69 #include <vnet/classify/input_acl.h>
70 #include <vnet/classify/policer_classify.h>
71 #include <vnet/l2/l2_classify.h>
72 #include <vnet/vxlan/vxlan.h>
73 #include <vnet/gre/gre.h>
74 #include <vnet/l2/l2_vtr.h>
75 #include <vnet/vxlan-gpe/vxlan_gpe.h>
76 #include <vnet/lisp-gpe/lisp_gpe.h>
77 #include <vnet/lisp-cp/control.h>
78 #include <vnet/map/map.h>
79 #include <vnet/cop/cop.h>
80 #include <vnet/ip/ip6_hop_by_hop.h>
81 #include <vnet/ip/ip_source_and_port_range_check.h>
82 #include <vnet/devices/af_packet/af_packet.h>
83 #include <vnet/policer/policer.h>
84 #include <vnet/devices/netmap/netmap.h>
85 #include <vnet/flow/flow_report.h>
86 #include <vnet/ipsec-gre/ipsec_gre.h>
89 #undef __included_bihash_template_h__
90 #include <vnet/l2/l2_fib.h>
93 #include <vnet/ipsec/ipsec.h>
94 #include <vnet/ipsec/ikev2.h>
96 #include <vnet/devices/virtio/vhost-user.h>
98 #include <stats/stats.h>
101 #include <vnet/ethernet/ethernet.h>
102 #include <vnet/ethernet/arp_packet.h>
103 #include <vnet/interface.h>
105 #include <vnet/l2/l2_fib.h>
106 #include <vnet/l2/l2_bd.h>
107 #include <vpp-api/vpe_msg_enum.h>
109 #define f64_endian(a)
110 #define f64_print(a,b)
112 #define vl_typedefs /* define message structures */
113 #include <vpp-api/vpe_all_api_h.h>
116 #define vl_endianfun /* define message structures */
117 #include <vpp-api/vpe_all_api_h.h>
120 /* instantiate all the print functions we know about */
121 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
123 #include <vpp-api/vpe_all_api_h.h>
126 #define REPLY_MACRO(t) \
128 unix_shared_memory_queue_t * q; \
129 rv = vl_msg_api_pd_handler (mp, rv); \
130 q = vl_api_client_index_to_input_queue (mp->client_index); \
134 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
135 rmp->_vl_msg_id = ntohs((t)); \
136 rmp->context = mp->context; \
137 rmp->retval = ntohl(rv); \
139 vl_msg_api_send_shmem (q, (u8 *)&rmp); \
142 #define REPLY_MACRO2(t, body) \
144 unix_shared_memory_queue_t * q; \
145 rv = vl_msg_api_pd_handler (mp, rv); \
146 q = vl_api_client_index_to_input_queue (mp->client_index); \
150 rmp = vl_msg_api_alloc (sizeof (*rmp)); \
151 rmp->_vl_msg_id = ntohs((t)); \
152 rmp->context = mp->context; \
153 rmp->retval = ntohl(rv); \
154 do {body;} while (0); \
155 vl_msg_api_send_shmem (q, (u8 *)&rmp); \
158 #define REPLY_MACRO3(t, n, body) \
160 unix_shared_memory_queue_t * q; \
161 rv = vl_msg_api_pd_handler (mp, rv); \
162 q = vl_api_client_index_to_input_queue (mp->client_index); \
166 rmp = vl_msg_api_alloc (sizeof (*rmp) + n); \
167 rmp->_vl_msg_id = ntohs((t)); \
168 rmp->context = mp->context; \
169 rmp->retval = ntohl(rv); \
170 do {body;} while (0); \
171 vl_msg_api_send_shmem (q, (u8 *)&rmp); \
174 #if (1 || CLIB_DEBUG > 0) /* "trust, but verify" */
176 #define VALIDATE_SW_IF_INDEX(mp) \
177 do { u32 __sw_if_index = ntohl(mp->sw_if_index); \
178 vnet_main_t *__vnm = vnet_get_main(); \
179 if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
181 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
182 goto bad_sw_if_index; \
186 #define BAD_SW_IF_INDEX_LABEL \
192 #define VALIDATE_RX_SW_IF_INDEX(mp) \
193 do { u32 __rx_sw_if_index = ntohl(mp->rx_sw_if_index); \
194 vnet_main_t *__vnm = vnet_get_main(); \
195 if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
196 __rx_sw_if_index)) { \
197 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
198 goto bad_rx_sw_if_index; \
202 #define BAD_RX_SW_IF_INDEX_LABEL \
204 bad_rx_sw_if_index: \
208 #define VALIDATE_TX_SW_IF_INDEX(mp) \
209 do { u32 __tx_sw_if_index = ntohl(mp->tx_sw_if_index); \
210 vnet_main_t *__vnm = vnet_get_main(); \
211 if (pool_is_free_index(__vnm->interface_main.sw_interfaces, \
212 __tx_sw_if_index)) { \
213 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; \
214 goto bad_tx_sw_if_index; \
218 #define BAD_TX_SW_IF_INDEX_LABEL \
220 bad_tx_sw_if_index: \
226 #define VALIDATE_SW_IF_INDEX(mp)
227 #define BAD_SW_IF_INDEX_LABEL
228 #define VALIDATE_RX_SW_IF_INDEX(mp)
229 #define BAD_RX_SW_IF_INDEX_LABEL
230 #define VALIDATE_TX_SW_IF_INDEX(mp)
231 #define BAD_TX_SW_IF_INDEX_LABEL
233 #endif /* CLIB_DEBUG > 0 */
235 #define foreach_vpe_api_msg \
236 _(WANT_INTERFACE_EVENTS, want_interface_events) \
237 _(WANT_OAM_EVENTS, want_oam_events) \
238 _(OAM_ADD_DEL, oam_add_del) \
239 _(SW_INTERFACE_DUMP, sw_interface_dump) \
240 _(SW_INTERFACE_DETAILS, sw_interface_details) \
241 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
242 _(IP_ADD_DEL_ROUTE, ip_add_del_route) \
243 _(IS_ADDRESS_REACHABLE, is_address_reachable) \
244 _(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address) \
245 _(SW_INTERFACE_SET_TABLE, sw_interface_set_table) \
246 _(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath) \
247 _(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect) \
248 _(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge) \
249 _(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del) \
250 _(BRIDGE_DOMAIN_DUMP, bridge_domain_dump) \
251 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
252 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
253 _(L2FIB_ADD_DEL, l2fib_add_del) \
254 _(L2_FLAGS, l2_flags) \
255 _(BRIDGE_FLAGS, bridge_flags) \
256 _(TAP_CONNECT, tap_connect) \
257 _(TAP_MODIFY, tap_modify) \
258 _(TAP_DELETE, tap_delete) \
259 _(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump) \
260 _(CREATE_VLAN_SUBIF, create_vlan_subif) \
261 _(CREATE_SUBIF, create_subif) \
262 _(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel) \
263 _(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel) \
264 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2) \
265 _(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap) \
266 _(MPLS_ADD_DEL_DECAP, mpls_add_del_decap) \
267 _(PROXY_ARP_ADD_DEL, proxy_arp_add_del) \
268 _(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable) \
269 _(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del) \
270 _(VNET_GET_SUMMARY_STATS, vnet_get_summary_stats) \
271 _(RESET_FIB, reset_fib) \
272 _(DHCP_PROXY_CONFIG,dhcp_proxy_config) \
273 _(DHCP_PROXY_CONFIG_2,dhcp_proxy_config_2) \
274 _(DHCP_PROXY_SET_VSS,dhcp_proxy_set_vss) \
275 _(DHCP_CLIENT_CONFIG, dhcp_client_config) \
276 _(SET_IP_FLOW_HASH,set_ip_flow_hash) \
277 _(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config) \
278 _(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix) \
279 _(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable ) \
280 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
281 sw_interface_ip6_set_link_local_address) \
282 _(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered) \
283 _(CREATE_LOOPBACK, create_loopback) \
284 _(CONTROL_PING, control_ping) \
285 _(NOPRINT_CONTROL_PING, noprint_control_ping) \
286 _(CLI_REQUEST, cli_request) \
287 _(CLI_INBAND, cli_inband) \
288 _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \
289 _(L2_PATCH_ADD_DEL, l2_patch_add_del) \
290 _(CLASSIFY_ADD_DEL_TABLE, classify_add_del_table) \
291 _(CLASSIFY_ADD_DEL_SESSION, classify_add_del_session) \
292 _(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table) \
293 _(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables) \
294 _(GET_NODE_INDEX, get_node_index) \
295 _(ADD_NODE_NEXT, add_node_next) \
296 _(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel) \
297 _(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies) \
298 _(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable) \
299 _(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key) \
300 _(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump) \
301 _(VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel) \
302 _(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump) \
303 _(GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel) \
304 _(GRE_TUNNEL_DUMP, gre_tunnel_dump) \
305 _(L2_FIB_CLEAR_TABLE, l2_fib_clear_table) \
306 _(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter) \
307 _(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite) \
308 _(CREATE_VHOST_USER_IF, create_vhost_user_if) \
309 _(MODIFY_VHOST_USER_IF, modify_vhost_user_if) \
310 _(DELETE_VHOST_USER_IF, delete_vhost_user_if) \
311 _(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump) \
312 _(IP_ADDRESS_DUMP, ip_address_dump) \
313 _(IP_DUMP, ip_dump) \
314 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
315 _(SHOW_VERSION, show_version) \
316 _(L2_FIB_TABLE_DUMP, l2_fib_table_dump) \
317 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
318 _(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel) \
319 _(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump) \
320 _(INTERFACE_NAME_RENUMBER, interface_name_renumber) \
321 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events) \
322 _(WANT_IP6_ND_EVENTS, want_ip6_nd_events) \
323 _(INPUT_ACL_SET_INTERFACE, input_acl_set_interface) \
324 _(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
325 _(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
326 _(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry) \
327 _(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry) \
328 _(IPSEC_SA_SET_KEY, ipsec_sa_set_key) \
329 _(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del) \
330 _(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth) \
331 _(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id) \
332 _(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts) \
333 _(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key) \
334 _(DELETE_LOOPBACK, delete_loopback) \
335 _(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del) \
336 _(MAP_ADD_DOMAIN, map_add_domain) \
337 _(MAP_DEL_DOMAIN, map_del_domain) \
338 _(MAP_ADD_DEL_RULE, map_add_del_rule) \
339 _(MAP_DOMAIN_DUMP, map_domain_dump) \
340 _(MAP_RULE_DUMP, map_rule_dump) \
341 _(MAP_SUMMARY_STATS, map_summary_stats) \
342 _(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable) \
343 _(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable) \
344 _(GET_NODE_GRAPH, get_node_graph) \
345 _(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats) \
346 _(IOAM_ENABLE, ioam_enable) \
347 _(IOAM_DISABLE, ioam_disable) \
348 _(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set) \
349 _(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator) \
350 _(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid) \
351 _(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry) \
352 _(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver) \
353 _(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable) \
354 _(LISP_ENABLE_DISABLE, lisp_enable_disable) \
355 _(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface) \
356 _(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping) \
357 _(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency) \
358 _(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set) \
359 _(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map) \
360 _(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump) \
361 _(LISP_LOCATOR_DUMP, lisp_locator_dump) \
362 _(LISP_EID_TABLE_DUMP, lisp_eid_table_dump) \
363 _(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump) \
364 _(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump) \
365 _(LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump) \
366 _(LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump) \
367 _(SHOW_LISP_STATUS, show_lisp_status) \
368 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, \
369 lisp_add_del_map_request_itr_rlocs) \
370 _(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs) \
371 _(SHOW_LISP_PITR, show_lisp_pitr) \
372 _(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del) \
373 _(AF_PACKET_CREATE, af_packet_create) \
374 _(AF_PACKET_DELETE, af_packet_delete) \
375 _(POLICER_ADD_DEL, policer_add_del) \
376 _(POLICER_DUMP, policer_dump) \
377 _(POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface) \
378 _(POLICER_CLASSIFY_DUMP, policer_classify_dump) \
379 _(NETMAP_CREATE, netmap_create) \
380 _(NETMAP_DELETE, netmap_delete) \
381 _(MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump) \
382 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details) \
383 _(MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump) \
384 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details) \
385 _(MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump) \
386 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details) \
387 _(MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump) \
388 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details) \
389 _(CLASSIFY_TABLE_IDS,classify_table_ids) \
390 _(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface) \
391 _(CLASSIFY_TABLE_INFO,classify_table_info) \
392 _(CLASSIFY_SESSION_DUMP,classify_session_dump) \
393 _(CLASSIFY_SESSION_DETAILS,classify_session_details) \
394 _(IPFIX_ENABLE,ipfix_enable) \
395 _(IPFIX_DUMP,ipfix_dump) \
396 _(GET_NEXT_INDEX, get_next_index) \
397 _(PG_CREATE_INTERFACE, pg_create_interface) \
398 _(PG_CAPTURE, pg_capture) \
399 _(PG_ENABLE_DISABLE, pg_enable_disable) \
400 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \
401 ip_source_and_port_range_check_add_del) \
402 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \
403 ip_source_and_port_range_check_interface_add_del) \
404 _(IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel) \
405 _(IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump) \
406 _(DELETE_SUBIF, delete_subif)
409 #define QUOTE(x) QUOTE_(x)
411 #define foreach_registration_hash \
412 _(interface_events) \
413 _(to_netconf_server) \
414 _(from_netconf_server) \
415 _(to_netconf_client) \
416 _(from_netconf_client) \
421 RESOLVE_IP4_ADD_DEL_ROUTE = 1,
422 RESOLVE_IP6_ADD_DEL_ROUTE,
423 RESOLVE_MPLS_ETHERNET_ADD_DEL,
431 vl_api_ip_add_del_route_t r;
432 vl_api_mpls_ethernet_add_del_tunnel_2_t t;
439 #define _(a) uword *a##_registration_hash; \
440 vpe_client_registration_t * a##_registrations;
441 foreach_registration_hash
443 /* notifications happen really early in the game */
444 u8 link_state_process_up;
446 /* ip4 and ip6 pending route adds */
447 pending_route_t *pending_routes;
449 /* ip4 arp event registration pool */
450 vl_api_ip4_arp_event_t *arp_events;
452 /* ip6 nd event registration pool */
453 vl_api_ip6_nd_event_t *nd_events;
456 vlib_main_t *vlib_main;
457 vnet_main_t *vnet_main;
460 static vlib_node_registration_t vpe_resolver_process_node;
461 static vpe_api_main_t vpe_api_main;
463 static void send_sw_interface_flags (vpe_api_main_t * am,
464 unix_shared_memory_queue_t * q,
465 vnet_sw_interface_t * swif);
466 static void send_sw_interface_flags_deleted (vpe_api_main_t * am,
467 unix_shared_memory_queue_t * q,
470 static int arp_change_delete_callback (u32 pool_index, u8 * notused);
471 static int nd_change_delete_callback (u32 pool_index, u8 * notused);
474 /* Clean up all registrations belonging to the indicated client */
476 vl_api_memclnt_delete_callback (u32 client_index)
478 vpe_api_main_t *vam = &vpe_api_main;
479 vpe_client_registration_t *rp;
481 int stats_memclnt_delete_callback (u32 client_index);
483 stats_memclnt_delete_callback (client_index);
486 p = hash_get (vam->a##_registration_hash, client_index); \
488 rp = pool_elt_at_index (vam->a##_registrations, p[0]); \
489 pool_put (vam->a##_registrations, rp); \
490 hash_unset (vam->a##_registration_hash, client_index); \
492 foreach_registration_hash;
497 #define API_LINK_STATE_EVENT 1
498 #define API_ADMIN_UP_DOWN_EVENT 2
501 event_data_cmp (void *a1, void *a2)
506 return (word) e1[0] - (word) e2[0];
510 link_state_process (vlib_main_t * vm,
511 vlib_node_runtime_t * rt, vlib_frame_t * f)
513 vpe_api_main_t *vam = &vpe_api_main;
514 vnet_main_t *vnm = vam->vnet_main;
515 vnet_sw_interface_t *swif;
516 uword *event_data = 0;
517 vpe_client_registration_t *reg;
519 u32 prev_sw_if_index;
520 unix_shared_memory_queue_t *q;
522 vam->link_state_process_up = 1;
526 vlib_process_wait_for_event (vm);
528 /* Unified list of changed link or admin state sw_if_indices */
529 vlib_process_get_events_with_type
530 (vm, &event_data, API_LINK_STATE_EVENT);
531 vlib_process_get_events_with_type
532 (vm, &event_data, API_ADMIN_UP_DOWN_EVENT);
534 /* Sort, so we can eliminate duplicates */
535 vec_sort_with_function (event_data, event_data_cmp);
537 prev_sw_if_index = ~0;
539 for (i = 0; i < vec_len (event_data); i++)
541 /* Only one message per swif */
542 if (prev_sw_if_index == event_data[i])
544 prev_sw_if_index = event_data[i];
547 pool_foreach(reg, vam->interface_events_registrations,
549 q = vl_api_client_index_to_input_queue (reg->client_index);
552 /* sw_interface may be deleted already */
553 if (!pool_is_free_index (vnm->interface_main.sw_interfaces,
556 swif = vnet_get_sw_interface (vnm, event_data[i]);
557 send_sw_interface_flags (vam, q, swif);
563 vec_reset_length (event_data);
569 static clib_error_t *link_up_down_function (vnet_main_t * vm, u32 hw_if_index,
571 static clib_error_t *admin_up_down_function (vnet_main_t * vm,
572 u32 hw_if_index, u32 flags);
575 VLIB_REGISTER_NODE (link_state_process_node,static) = {
576 .function = link_state_process,
577 .type = VLIB_NODE_TYPE_PROCESS,
578 .name = "vpe-link-state-process",
582 VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (admin_up_down_function);
583 VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION (link_up_down_function);
585 static clib_error_t *
586 link_up_down_function (vnet_main_t * vm, u32 hw_if_index, u32 flags)
588 vpe_api_main_t *vam = &vpe_api_main;
589 vnet_hw_interface_t *hi = vnet_get_hw_interface (vm, hw_if_index);
591 if (vam->link_state_process_up)
592 vlib_process_signal_event (vam->vlib_main,
593 link_state_process_node.index,
594 API_LINK_STATE_EVENT, hi->sw_if_index);
598 static clib_error_t *
599 admin_up_down_function (vnet_main_t * vm, u32 sw_if_index, u32 flags)
601 vpe_api_main_t *vam = &vpe_api_main;
604 * Note: it's perfectly fair to set a subif admin up / admin down.
605 * Note the subtle distinction between this routine and the previous
608 if (vam->link_state_process_up)
609 vlib_process_signal_event (vam->vlib_main,
610 link_state_process_node.index,
611 API_ADMIN_UP_DOWN_EVENT, sw_if_index);
615 #define pub_sub_handler(lca,UCA) \
616 static void vl_api_want_##lca##_t_handler ( \
617 vl_api_want_##lca##_t *mp) \
619 vpe_api_main_t *vam = &vpe_api_main; \
620 vpe_client_registration_t *rp; \
621 vl_api_want_##lca##_reply_t *rmp; \
625 p = hash_get (vam->lca##_registration_hash, mp->client_index); \
627 if (mp->enable_disable) { \
628 clib_warning ("pid %d: already enabled...", mp->pid); \
629 rv = VNET_API_ERROR_INVALID_REGISTRATION; \
632 rp = pool_elt_at_index (vam->lca##_registrations, p[0]); \
633 pool_put (vam->lca##_registrations, rp); \
634 hash_unset (vam->lca##_registration_hash, \
639 if (mp->enable_disable == 0) { \
640 clib_warning ("pid %d: already disabled...", mp->pid); \
641 rv = VNET_API_ERROR_INVALID_REGISTRATION; \
644 pool_get (vam->lca##_registrations, rp); \
645 rp->client_index = mp->client_index; \
646 rp->client_pid = mp->pid; \
647 hash_set (vam->lca##_registration_hash, rp->client_index, \
648 rp - vam->lca##_registrations); \
651 REPLY_MACRO (VL_API_WANT_##UCA##_REPLY); \
655 pub_sub_handler (interface_events, INTERFACE_EVENTS)
656 pub_sub_handler (oam_events, OAM_EVENTS)
659 #define RESOLUTION_EVENT 1
660 #define RESOLUTION_PENDING_EVENT 2
661 #define IP4_ARP_EVENT 3
662 #define IP6_ND_EVENT 4
664 static int ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
666 static int ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
668 static int mpls_ethernet_add_del_tunnel_2_t_handler
669 (vl_api_mpls_ethernet_add_del_tunnel_2_t * mp);
672 handle_ip4_arp_event (u32 pool_index)
674 vpe_api_main_t *vam = &vpe_api_main;
675 vnet_main_t *vnm = vam->vnet_main;
676 vlib_main_t *vm = vam->vlib_main;
677 vl_api_ip4_arp_event_t *event;
678 vl_api_ip4_arp_event_t *mp;
679 unix_shared_memory_queue_t *q;
681 /* Client can cancel, die, etc. */
682 if (pool_is_free_index (vam->arp_events, pool_index))
685 event = pool_elt_at_index (vam->arp_events, pool_index);
687 q = vl_api_client_index_to_input_queue (event->client_index);
690 (void) vnet_add_del_ip4_arp_change_event
691 (vnm, arp_change_delete_callback,
692 event->pid, &event->address,
693 vpe_resolver_process_node.index, IP4_ARP_EVENT,
694 ~0 /* pool index, notused */ , 0 /* is_add */ );
698 if (q->cursize < q->maxsize)
700 mp = vl_msg_api_alloc (sizeof (*mp));
701 clib_memcpy (mp, event, sizeof (*mp));
702 vl_msg_api_send_shmem (q, (u8 *) & mp);
706 static f64 last_time;
708 * Throttle syslog msgs.
709 * It's pretty tempting to just revoke the registration...
711 if (vlib_time_now (vm) > last_time + 10.0)
713 clib_warning ("arp event for %U to pid %d: queue stuffed!",
714 format_ip4_address, &event->address, event->pid);
715 last_time = vlib_time_now (vm);
721 handle_ip6_nd_event (u32 pool_index)
723 vpe_api_main_t *vam = &vpe_api_main;
724 vnet_main_t *vnm = vam->vnet_main;
725 vlib_main_t *vm = vam->vlib_main;
726 vl_api_ip6_nd_event_t *event;
727 vl_api_ip6_nd_event_t *mp;
728 unix_shared_memory_queue_t *q;
730 /* Client can cancel, die, etc. */
731 if (pool_is_free_index (vam->nd_events, pool_index))
734 event = pool_elt_at_index (vam->nd_events, pool_index);
736 q = vl_api_client_index_to_input_queue (event->client_index);
739 (void) vnet_add_del_ip6_nd_change_event
740 (vnm, nd_change_delete_callback,
741 event->pid, &event->address,
742 vpe_resolver_process_node.index, IP6_ND_EVENT,
743 ~0 /* pool index, notused */ , 0 /* is_add */ );
747 if (q->cursize < q->maxsize)
749 mp = vl_msg_api_alloc (sizeof (*mp));
750 clib_memcpy (mp, event, sizeof (*mp));
751 vl_msg_api_send_shmem (q, (u8 *) & mp);
755 static f64 last_time;
757 * Throttle syslog msgs.
758 * It's pretty tempting to just revoke the registration...
760 if (vlib_time_now (vm) > last_time + 10.0)
762 clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
763 format_ip6_address, &event->address, event->pid);
764 last_time = vlib_time_now (vm);
770 resolver_process (vlib_main_t * vm,
771 vlib_node_runtime_t * rt, vlib_frame_t * f)
774 uword *event_data = 0;
776 vpe_api_main_t *vam = &vpe_api_main;
778 vl_api_ip_add_del_route_t *adr;
779 vl_api_mpls_ethernet_add_del_tunnel_2_t *pme;
780 u32 *resolution_failures = 0;
786 vlib_process_wait_for_event_or_clock (vm, timeout);
788 event_type = vlib_process_get_events (vm, &event_data);
792 case RESOLUTION_PENDING_EVENT:
796 case RESOLUTION_EVENT:
797 for (i = 0; i < vec_len (event_data); i++)
800 * Resolution events can occur long after the
801 * original request has timed out. $$$ add a cancel
804 if (pool_is_free_index (vam->pending_routes, event_data[i]))
807 pr = pool_elt_at_index (vam->pending_routes, event_data[i]);
811 switch (pr->resolve_type)
813 case RESOLVE_IP4_ADD_DEL_ROUTE:
814 rv = ip4_add_del_route_t_handler (adr);
815 clib_warning ("resolver: add %U/%d via %U %s",
817 (ip4_address_t *) & (adr->dst_address),
818 adr->dst_address_length,
820 (ip4_address_t *) & (adr->next_hop_address),
821 (rv >= 0) ? "succeeded" : "failed");
824 case RESOLVE_IP6_ADD_DEL_ROUTE:
825 rv = ip6_add_del_route_t_handler (adr);
826 clib_warning ("resolver: add %U/%d via %U %s",
828 (ip6_address_t *) & (adr->dst_address),
829 adr->dst_address_length,
831 (ip6_address_t *) & (adr->next_hop_address),
832 (rv >= 0) ? "succeeded" : "failed");
835 case RESOLVE_MPLS_ETHERNET_ADD_DEL:
836 rv = mpls_ethernet_add_del_tunnel_2_t_handler (pme);
837 clib_warning ("resolver: add mpls-o-e via %U %s",
840 (pme->next_hop_ip4_address_in_outer_vrf),
841 (rv >= 0) ? "succeeded" : "failed");
845 clib_warning ("resolver: BOGUS TYPE %d", pr->resolve_type);
847 pool_put (vam->pending_routes, pr);
852 for (i = 0; i < vec_len (event_data); i++)
853 handle_ip4_arp_event (event_data[i]);
857 for (i = 0; i < vec_len (event_data); i++)
858 handle_ip6_nd_event (event_data[i]);
861 case ~0: /* timeout, retry pending resolutions */
863 pool_foreach (pr, vam->pending_routes,
869 /* May fail, e.g. due to interface down */
870 switch (pr->resolve_type)
872 case RESOLVE_IP4_ADD_DEL_ROUTE:
873 e = ip4_probe_neighbor
874 (vm, (ip4_address_t *)&(adr->next_hop_address),
875 ntohl(adr->next_hop_sw_if_index));
878 case RESOLVE_IP6_ADD_DEL_ROUTE:
879 e = ip6_probe_neighbor
880 (vm, (ip6_address_t *)&(adr->next_hop_address),
881 ntohl(adr->next_hop_sw_if_index));
884 case RESOLVE_MPLS_ETHERNET_ADD_DEL:
886 e = ip4_probe_neighbor
888 (ip4_address_t *)&(pme->next_hop_ip4_address_in_outer_vrf),
889 pme->resolve_opaque);
893 e = clib_error_return (0, "resolver: BOGUS TYPE %d",
898 clib_error_report (e);
900 adr->resolve_attempts = 1;
902 pme->resolve_attempts = 1;
906 adr->resolve_attempts -= 1;
907 if (adr->resolve_attempts == 0)
908 vec_add1 (resolution_failures,
909 pr - vam->pending_routes);
913 pme->resolve_attempts -= 1;
914 if (pme->resolve_attempts == 0)
915 vec_add1 (resolution_failures,
916 pr - vam->pending_routes);
920 for (i = 0; i < vec_len (resolution_failures); i++)
922 pr = pool_elt_at_index (vam->pending_routes,
923 resolution_failures[i]);
927 switch (pr->resolve_type)
929 case RESOLVE_IP4_ADD_DEL_ROUTE:
930 clib_warning ("resolver: add %U/%d via %U retry failure",
932 (ip4_address_t *) & (adr->dst_address),
933 adr->dst_address_length,
935 (ip4_address_t *) & (adr->next_hop_address));
938 case RESOLVE_IP6_ADD_DEL_ROUTE:
939 clib_warning ("resolver: add %U/%d via %U retry failure",
941 (ip6_address_t *) & (adr->dst_address),
942 adr->dst_address_length,
944 (ip6_address_t *) & (adr->next_hop_address));
947 case RESOLVE_MPLS_ETHERNET_ADD_DEL:
948 clib_warning ("resolver: add mpls-o-e via %U retry failure",
951 (pme->next_hop_ip4_address_in_outer_vrf));
955 clib_warning ("BUG");
957 pool_put (vam->pending_routes, pr);
959 vec_reset_length (resolution_failures);
962 if (pool_elts (vam->pending_routes) == 0)
964 vec_reset_length (event_data);
966 return 0; /* or not */
970 VLIB_REGISTER_NODE (vpe_resolver_process_node,static) = {
971 .function = resolver_process,
972 .type = VLIB_NODE_TYPE_PROCESS,
973 .name = "vpe-route-resolver-process",
978 ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
980 ip4_main_t *im = &ip4_main;
981 ip_lookup_main_t *lm = &im->lookup_main;
982 vnet_classify_main_t *cm = &vnet_classify_main;
983 stats_main_t *sm = &stats_main;
984 ip4_add_del_route_args_t a;
985 ip4_address_t next_hop_address;
987 vpe_api_main_t *vam = &vpe_api_main;
988 vnet_main_t *vnm = vam->vnet_main;
989 vlib_main_t *vm = vlib_get_main ();
991 vl_api_ip_add_del_route_t *adr;
997 p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
1000 if (mp->create_vrf_if_needed)
1003 f = find_ip4_fib_by_table_index_or_id (im, ntohl (mp->vrf_id),
1005 fib_index = f->index;
1009 /* No such VRF, and we weren't asked to create one */
1010 return VNET_API_ERROR_NO_SUCH_FIB;
1018 if (~0 != mp->next_hop_sw_if_index &&
1019 pool_is_free_index (vnm->interface_main.sw_interfaces,
1020 ntohl (mp->next_hop_sw_if_index)))
1021 return VNET_API_ERROR_NO_MATCHING_INTERFACE;
1023 clib_memcpy (next_hop_address.data, mp->next_hop_address,
1024 sizeof (next_hop_address.data));
1026 /* Arp for the next_hop if necessary */
1027 if (mp->is_add && mp->resolve_if_needed && ~0 != mp->next_hop_sw_if_index)
1030 ip_adjacency_t *adj;
1032 lookup_result = ip4_fib_lookup_with_table
1033 (im, fib_index, &next_hop_address, 1 /* disable default route */ );
1035 adj = ip_get_adjacency (lm, lookup_result);
1037 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
1039 pool_get (vam->pending_routes, pr);
1040 pr->resolve_type = RESOLVE_IP4_ADD_DEL_ROUTE;
1042 clib_memcpy (adr, mp, sizeof (*adr));
1043 /* recursion block, "just in case" */
1044 adr->resolve_if_needed = 0;
1045 adr->resolve_attempts = ntohl (mp->resolve_attempts);
1046 vnet_register_ip4_arp_resolution_event
1047 (vnm, &next_hop_address, vpe_resolver_process_node.index,
1048 RESOLUTION_EVENT, pr - vam->pending_routes);
1050 vlib_process_signal_event
1051 (vm, vpe_resolver_process_node.index,
1052 RESOLUTION_PENDING_EVENT, 0 /* data */ );
1054 /* The interface may be down, etc. */
1055 e = ip4_probe_neighbor
1056 (vm, (ip4_address_t *) & (mp->next_hop_address),
1057 ntohl (mp->next_hop_sw_if_index));
1060 clib_error_report (e);
1062 return VNET_API_ERROR_IN_PROGRESS;
1066 if (mp->is_multipath)
1070 dslock (sm, 1 /* release hint */ , 10 /* tag */ );
1073 flags = IP4_ROUTE_FLAG_ADD;
1075 flags = IP4_ROUTE_FLAG_DEL;
1078 flags |= IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP;
1080 ip4_add_del_route_next_hop (im, flags,
1081 (ip4_address_t *) mp->dst_address,
1082 (u32) mp->dst_address_length,
1083 (ip4_address_t *) mp->next_hop_address,
1084 ntohl (mp->next_hop_sw_if_index),
1085 (u32) mp->next_hop_weight,
1086 ~0 /* adj_index */ ,
1092 memset (&a, 0, sizeof (a));
1093 clib_memcpy (a.dst_address.data, mp->dst_address,
1094 sizeof (a.dst_address.data));
1096 a.dst_address_length = mp->dst_address_length;
1098 a.flags = (mp->is_add ? IP4_ROUTE_FLAG_ADD : IP4_ROUTE_FLAG_DEL);
1099 a.flags |= IP4_ROUTE_FLAG_FIB_INDEX;
1100 a.table_index_or_table_id = fib_index;
1105 a.flags |= IP4_ROUTE_FLAG_NOT_LAST_IN_GROUP;
1107 dslock (sm, 1 /* release hint */ , 2 /* tag */ );
1112 ai = lm->drop_adj_index;
1113 else if (mp->is_local)
1114 ai = lm->local_adj_index;
1115 else if (mp->is_classify)
1117 if (pool_is_free_index
1118 (cm->tables, ntohl (mp->classify_table_index)))
1121 return VNET_API_ERROR_NO_SUCH_TABLE;
1123 adj = ip_add_adjacency (lm,
1128 adj->lookup_next_index = IP_LOOKUP_NEXT_CLASSIFY;
1129 adj->classify.table_index = ntohl (mp->classify_table_index);
1131 else if (mp->lookup_in_vrf)
1133 p = hash_get (im->fib_index_by_table_id, ntohl (mp->lookup_in_vrf));
1136 adj = ip_add_adjacency (lm,
1140 adj->explicit_fib_index = p[0];
1145 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
1149 ai = ip4_route_get_next_hop_adj (im,
1152 ntohl (mp->next_hop_sw_if_index),
1155 if (ai == lm->miss_adj_index)
1158 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
1163 ip_adjacency_t *adj;
1164 int disable_default_route = 1;
1166 /* Trying to delete the default route? */
1167 if (a.dst_address.as_u32 == 0 && a.dst_address_length == 0)
1168 disable_default_route = 0;
1170 ai = ip4_fib_lookup_with_table
1171 (im, fib_index, &a.dst_address, disable_default_route);
1172 if (ai == lm->miss_adj_index)
1175 return VNET_API_ERROR_UNKNOWN_DESTINATION;
1178 adj = ip_get_adjacency (lm, ai);
1179 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
1182 return VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
1187 ip4_add_del_route (im, &a);
1194 ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
1196 ip6_main_t *im = &ip6_main;
1197 ip_lookup_main_t *lm = &im->lookup_main;
1198 vnet_main_t *vnm = vnet_get_main ();
1199 vlib_main_t *vm = vlib_get_main ();
1200 vpe_api_main_t *vam = &vpe_api_main;
1201 stats_main_t *sm = &stats_main;
1202 ip6_add_del_route_args_t a;
1203 ip6_address_t next_hop_address;
1204 pending_route_t *pr;
1205 vl_api_ip_add_del_route_t *adr;
1210 ip_adjacency_t *adj = 0;
1213 p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
1217 if (mp->create_vrf_if_needed)
1220 f = find_ip6_fib_by_table_index_or_id (im, ntohl (mp->vrf_id),
1222 fib_index = f->index;
1226 /* No such VRF, and we weren't asked to create one */
1227 return VNET_API_ERROR_NO_SUCH_FIB;
1235 if (~0 != mp->next_hop_sw_if_index &&
1236 pool_is_free_index (vnm->interface_main.sw_interfaces,
1237 ntohl (mp->next_hop_sw_if_index)))
1238 return VNET_API_ERROR_NO_MATCHING_INTERFACE;
1240 clib_memcpy (next_hop_address.as_u8, mp->next_hop_address,
1241 sizeof (next_hop_address.as_u8));
1243 /* Arp for the next_hop if necessary */
1244 if (mp->is_add && mp->resolve_if_needed && ~0 != mp->next_hop_sw_if_index)
1247 ip_adjacency_t *adj;
1249 lookup_result = ip6_fib_lookup_with_table
1250 (im, fib_index, &next_hop_address);
1252 adj = ip_get_adjacency (lm, lookup_result);
1254 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
1256 pool_get (vam->pending_routes, pr);
1258 pr->resolve_type = RESOLVE_IP6_ADD_DEL_ROUTE;
1259 clib_memcpy (adr, mp, sizeof (*adr));
1260 /* recursion block, "just in case" */
1261 adr->resolve_if_needed = 0;
1262 adr->resolve_attempts = ntohl (mp->resolve_attempts);
1263 vnet_register_ip6_neighbor_resolution_event
1264 (vnm, &next_hop_address, vpe_resolver_process_node.index,
1265 RESOLUTION_EVENT, pr - vam->pending_routes);
1267 vlib_process_signal_event
1268 (vm, vpe_resolver_process_node.index,
1269 RESOLUTION_PENDING_EVENT, 0 /* data */ );
1271 /* The interface may be down, etc. */
1272 e = ip6_probe_neighbor
1273 (vm, (ip6_address_t *) & (mp->next_hop_address),
1274 ntohl (mp->next_hop_sw_if_index));
1277 clib_error_report (e);
1279 return VNET_API_ERROR_IN_PROGRESS;
1283 if (mp->is_multipath)
1287 dslock (sm, 1 /* release hint */ , 11 /* tag */ );
1290 flags = IP6_ROUTE_FLAG_ADD;
1292 flags = IP6_ROUTE_FLAG_DEL;
1295 flags |= IP6_ROUTE_FLAG_NOT_LAST_IN_GROUP;
1297 ip6_add_del_route_next_hop (im, flags,
1298 (ip6_address_t *) mp->dst_address,
1299 (u32) mp->dst_address_length,
1300 (ip6_address_t *) mp->next_hop_address,
1301 ntohl (mp->next_hop_sw_if_index),
1302 (u32) mp->next_hop_weight,
1303 ~0 /* adj_index */ ,
1309 memset (&a, 0, sizeof (a));
1310 clib_memcpy (a.dst_address.as_u8, mp->dst_address,
1311 sizeof (a.dst_address.as_u8));
1313 a.dst_address_length = mp->dst_address_length;
1315 a.flags = (mp->is_add ? IP6_ROUTE_FLAG_ADD : IP6_ROUTE_FLAG_DEL);
1316 a.flags |= IP6_ROUTE_FLAG_FIB_INDEX;
1317 a.table_index_or_table_id = fib_index;
1322 a.flags |= IP6_ROUTE_FLAG_NOT_LAST_IN_GROUP;
1324 dslock (sm, 1 /* release hint */ , 3 /* tag */ );
1329 ai = lm->drop_adj_index;
1330 else if (mp->is_local)
1331 ai = lm->local_adj_index;
1332 else if (mp->lookup_in_vrf)
1334 p = hash_get (im->fib_index_by_table_id, ntohl (mp->lookup_in_vrf));
1337 adj = ip_add_adjacency (lm,
1341 adj->explicit_fib_index = p[0];
1346 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
1350 ai = ip6_route_get_next_hop_adj (im,
1353 ntohl (mp->next_hop_sw_if_index),
1355 if (ai == lm->miss_adj_index)
1358 return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
1363 ip_adjacency_t *adj;
1365 ai = ip6_fib_lookup_with_table (im, fib_index, &a.dst_address);
1366 if (ai == lm->miss_adj_index)
1369 return VNET_API_ERROR_UNKNOWN_DESTINATION;
1371 adj = ip_get_adjacency (lm, ai);
1372 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
1375 return VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
1380 ip6_add_del_route (im, &a);
1387 vl_api_ip_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
1389 vl_api_ip_add_del_route_reply_t *rmp;
1391 vnet_main_t *vnm = vnet_get_main ();
1396 rv = ip6_add_del_route_t_handler (mp);
1398 rv = ip4_add_del_route_t_handler (mp);
1400 rv = (rv == 0) ? vnm->api_errno : rv;
1402 REPLY_MACRO (VL_API_IP_ADD_DEL_ROUTE_REPLY);
1406 api_config_default_ip_route (u8 is_ipv6, u8 is_add, u32 vrf_id,
1407 u32 sw_if_index, u8 * next_hop_addr)
1409 vl_api_ip_add_del_route_t mp;
1412 memset (&mp, 0, sizeof (vl_api_ip_add_del_route_t));
1415 * Configure default IP route:
1416 * - ip route add 0.0.0.0/1 via <GW IP>
1417 * - ip route add 128.0.0.0/1 via <GW IP>
1419 mp.next_hop_sw_if_index = ntohl (sw_if_index);
1421 mp.resolve_attempts = ~0;
1422 mp.resolve_if_needed = 1;
1424 mp.is_ipv6 = is_ipv6;
1425 mp.next_hop_weight = 1;
1427 clib_memcpy (&mp.next_hop_address[0], next_hop_addr, 16);
1430 rv = ip6_add_del_route_t_handler (&mp);
1433 mp.dst_address_length = 1;
1435 mp.dst_address[0] = 0;
1436 rv = ip4_add_del_route_t_handler (&mp);
1438 mp.dst_address[0] = 128;
1439 rv |= ip4_add_del_route_t_handler (&mp);
1443 clib_error_return (0, "failed to config default IP route");
1448 vl_api_sw_interface_add_del_address_t_handler
1449 (vl_api_sw_interface_add_del_address_t * mp)
1451 vlib_main_t *vm = vlib_get_main ();
1452 vl_api_sw_interface_add_del_address_reply_t *rmp;
1456 VALIDATE_SW_IF_INDEX (mp);
1458 is_del = mp->is_add == 0;
1461 ip_del_all_interface_addresses (vm, ntohl (mp->sw_if_index));
1462 else if (mp->is_ipv6)
1463 ip6_add_del_interface_address (vm, ntohl (mp->sw_if_index),
1464 (void *) mp->address,
1465 mp->address_length, is_del);
1467 ip4_add_del_interface_address (vm, ntohl (mp->sw_if_index),
1468 (void *) mp->address,
1469 mp->address_length, is_del);
1471 BAD_SW_IF_INDEX_LABEL;
1473 REPLY_MACRO (VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY);
1477 vl_api_sw_interface_set_table_t_handler (vl_api_sw_interface_set_table_t * mp)
1480 u32 table_id = ntohl (mp->vrf_id);
1481 u32 sw_if_index = ntohl (mp->sw_if_index);
1482 vl_api_sw_interface_set_table_reply_t *rmp;
1483 stats_main_t *sm = &stats_main;
1485 VALIDATE_SW_IF_INDEX (mp);
1487 dslock (sm, 1 /* release hint */ , 4 /* tag */ );
1491 ip6_main_t *im = &ip6_main;
1492 ip6_fib_t *fib = find_ip6_fib_by_table_index_or_id (im, table_id,
1493 IP6_ROUTE_FLAG_TABLE_ID);
1496 vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
1497 im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
1501 rv = VNET_API_ERROR_NO_SUCH_FIB;
1506 ip4_main_t *im = &ip4_main;
1507 ip4_fib_t *fib = find_ip4_fib_by_table_index_or_id
1508 (im, table_id, IP4_ROUTE_FLAG_TABLE_ID);
1510 /* Truthfully this can't fail */
1513 vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
1514 im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
1518 rv = VNET_API_ERROR_NO_SUCH_FIB;
1523 BAD_SW_IF_INDEX_LABEL;
1525 REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY);
1529 vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t * mp)
1531 vlib_main_t *vm = vlib_get_main ();
1532 ip4_main_t *im4 = &ip4_main;
1533 ip6_main_t *im6 = &ip6_main;
1534 vl_api_sw_interface_set_vpath_reply_t *rmp;
1537 u32 sw_if_index = ntohl (mp->sw_if_index);
1538 ip4_main_t *ip4m = &ip4_main;
1539 ip6_main_t *ip6m = &ip6_main;
1540 ip_lookup_main_t *ip4lm = &ip4m->lookup_main;
1541 ip_lookup_main_t *ip6lm = &ip6m->lookup_main;
1542 ip_config_main_t *rx_cm4u =
1543 &ip4lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT];
1544 ip_config_main_t *rx_cm4m =
1545 &ip4lm->feature_config_mains[VNET_IP_RX_MULTICAST_FEAT];
1546 ip_config_main_t *rx_cm6u =
1547 &ip6lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT];
1548 ip_config_main_t *rx_cm6m =
1549 &ip6lm->feature_config_mains[VNET_IP_RX_MULTICAST_FEAT];
1551 VALIDATE_SW_IF_INDEX (mp);
1553 l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_VPATH, mp->enable);
1556 ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast
1557 ci = vnet_config_add_feature (vm, &rx_cm4u->config_main,
1559 im4->ip4_unicast_rx_feature_vpath, 0, 0);
1560 rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci;
1561 ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast
1562 ci = vnet_config_add_feature (vm, &rx_cm4m->config_main,
1564 im4->ip4_multicast_rx_feature_vpath,
1566 rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci;
1567 ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast
1568 ci = vnet_config_add_feature (vm, &rx_cm6u->config_main,
1570 im6->ip6_unicast_rx_feature_vpath, 0, 0);
1571 rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci;
1572 ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast
1573 ci = vnet_config_add_feature (vm, &rx_cm6m->config_main,
1575 im6->ip6_multicast_rx_feature_vpath,
1577 rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci;
1581 ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast
1582 ci = vnet_config_del_feature (vm, &rx_cm4u->config_main,
1584 im4->ip4_unicast_rx_feature_vpath, 0, 0);
1585 rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci;
1586 ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast
1587 ci = vnet_config_del_feature (vm, &rx_cm4m->config_main,
1589 im4->ip4_multicast_rx_feature_vpath,
1591 rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci;
1592 ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast
1593 ci = vnet_config_del_feature (vm, &rx_cm6u->config_main,
1595 im6->ip6_unicast_rx_feature_vpath, 0, 0);
1596 rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci;
1597 ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast
1598 ci = vnet_config_del_feature (vm, &rx_cm6m->config_main,
1600 im6->ip6_multicast_rx_feature_vpath,
1602 rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci;
1605 BAD_SW_IF_INDEX_LABEL;
1607 REPLY_MACRO (VL_API_SW_INTERFACE_SET_VPATH_REPLY);
1611 vl_api_sw_interface_set_l2_xconnect_t_handler
1612 (vl_api_sw_interface_set_l2_xconnect_t * mp)
1614 vl_api_sw_interface_set_l2_xconnect_reply_t *rmp;
1616 u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
1617 u32 tx_sw_if_index = ntohl (mp->tx_sw_if_index);
1618 vlib_main_t *vm = vlib_get_main ();
1619 vnet_main_t *vnm = vnet_get_main ();
1621 VALIDATE_RX_SW_IF_INDEX (mp);
1625 VALIDATE_TX_SW_IF_INDEX (mp);
1626 rv = set_int_l2_mode (vm, vnm, MODE_L2_XC,
1627 rx_sw_if_index, 0, 0, 0, tx_sw_if_index);
1631 rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
1634 BAD_RX_SW_IF_INDEX_LABEL;
1635 BAD_TX_SW_IF_INDEX_LABEL;
1637 REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_XCONNECT_REPLY);
1641 vl_api_sw_interface_set_l2_bridge_t_handler
1642 (vl_api_sw_interface_set_l2_bridge_t * mp)
1644 bd_main_t *bdm = &bd_main;
1645 vl_api_sw_interface_set_l2_bridge_reply_t *rmp;
1647 u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
1648 u32 bd_id = ntohl (mp->bd_id);
1652 vlib_main_t *vm = vlib_get_main ();
1653 vnet_main_t *vnm = vnet_get_main ();
1655 VALIDATE_RX_SW_IF_INDEX (mp);
1657 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
1661 //VALIDATE_TX_SW_IF_INDEX(mp);
1662 rv = set_int_l2_mode (vm, vnm, MODE_L2_BRIDGE,
1663 rx_sw_if_index, bd_index, bvi, shg, 0);
1667 rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
1670 BAD_RX_SW_IF_INDEX_LABEL;
1672 REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_BRIDGE_REPLY);
1676 vl_api_bridge_domain_add_del_t_handler (vl_api_bridge_domain_add_del_t * mp)
1678 vlib_main_t *vm = vlib_get_main ();
1679 bd_main_t *bdm = &bd_main;
1680 vl_api_bridge_domain_add_del_reply_t *rmp;
1682 u32 enable_flags = 0, disable_flags = 0;
1683 u32 bd_id = ntohl (mp->bd_id);
1688 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
1691 enable_flags |= L2_FLOOD;
1693 disable_flags |= L2_FLOOD;
1696 enable_flags |= L2_UU_FLOOD;
1698 disable_flags |= L2_UU_FLOOD;
1701 enable_flags |= L2_FWD;
1703 disable_flags |= L2_FWD;
1706 enable_flags |= L2_ARP_TERM;
1708 disable_flags |= L2_ARP_TERM;
1711 enable_flags |= L2_LEARN;
1713 disable_flags |= L2_LEARN;
1716 bd_set_flags (vm, bd_index, enable_flags, 1 /* enable */ );
1719 bd_set_flags (vm, bd_index, disable_flags, 0 /* disable */ );
1723 rv = bd_delete_bd_index (bdm, bd_id);
1725 REPLY_MACRO (VL_API_BRIDGE_DOMAIN_ADD_DEL_REPLY);
1729 vl_api_bridge_domain_details_t_handler (vl_api_bridge_domain_details_t * mp)
1731 clib_warning ("BUG");
1735 vl_api_bridge_domain_sw_if_details_t_handler
1736 (vl_api_bridge_domain_sw_if_details_t * mp)
1738 clib_warning ("BUG");
1742 send_bridge_domain_details (unix_shared_memory_queue_t * q,
1743 l2_bridge_domain_t * bd_config,
1744 u32 n_sw_ifs, u32 context)
1746 vl_api_bridge_domain_details_t *mp;
1748 mp = vl_msg_api_alloc (sizeof (*mp));
1749 memset (mp, 0, sizeof (*mp));
1750 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_DETAILS);
1751 mp->bd_id = ntohl (bd_config->bd_id);
1752 mp->flood = bd_feature_flood (bd_config);
1753 mp->uu_flood = bd_feature_uu_flood (bd_config);
1754 mp->forward = bd_feature_forward (bd_config);
1755 mp->learn = bd_feature_learn (bd_config);
1756 mp->arp_term = bd_feature_arp_term (bd_config);
1757 mp->bvi_sw_if_index = ntohl (bd_config->bvi_sw_if_index);
1758 mp->n_sw_ifs = ntohl (n_sw_ifs);
1759 mp->context = context;
1761 vl_msg_api_send_shmem (q, (u8 *) & mp);
1765 send_bd_sw_if_details (l2input_main_t * l2im,
1766 unix_shared_memory_queue_t * q,
1767 l2_flood_member_t * member, u32 bd_id, u32 context)
1769 vl_api_bridge_domain_sw_if_details_t *mp;
1770 l2_input_config_t *input_cfg;
1772 mp = vl_msg_api_alloc (sizeof (*mp));
1773 memset (mp, 0, sizeof (*mp));
1774 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_SW_IF_DETAILS);
1775 mp->bd_id = ntohl (bd_id);
1776 mp->sw_if_index = ntohl (member->sw_if_index);
1777 input_cfg = vec_elt_at_index (l2im->configs, member->sw_if_index);
1778 mp->shg = input_cfg->shg;
1779 mp->context = context;
1781 vl_msg_api_send_shmem (q, (u8 *) & mp);
1785 vl_api_bridge_domain_dump_t_handler (vl_api_bridge_domain_dump_t * mp)
1787 bd_main_t *bdm = &bd_main;
1788 l2input_main_t *l2im = &l2input_main;
1789 unix_shared_memory_queue_t *q;
1790 l2_bridge_domain_t *bd_config;
1791 u32 bd_id, bd_index;
1794 q = vl_api_client_index_to_input_queue (mp->client_index);
1799 bd_id = ntohl (mp->bd_id);
1801 bd_index = (bd_id == ~0) ? 0 : bd_find_or_add_bd_index (bdm, bd_id);
1802 end = (bd_id == ~0) ? vec_len (l2im->bd_configs) : bd_index + 1;
1803 for (; bd_index < end; bd_index++)
1805 bd_config = l2input_bd_config_from_index (l2im, bd_index);
1806 /* skip dummy bd_id 0 */
1807 if (bd_config && (bd_config->bd_id > 0))
1810 l2_flood_member_t *m;
1812 n_sw_ifs = vec_len (bd_config->members);
1813 send_bridge_domain_details (q, bd_config, n_sw_ifs, mp->context);
1815 vec_foreach (m, bd_config->members)
1817 send_bd_sw_if_details (l2im, q, m, bd_config->bd_id, mp->context);
1824 vl_api_l2fib_add_del_t_handler (vl_api_l2fib_add_del_t * mp)
1826 bd_main_t *bdm = &bd_main;
1827 l2input_main_t *l2im = &l2input_main;
1828 vl_api_l2fib_add_del_reply_t *rmp;
1831 u32 sw_if_index = ntohl (mp->sw_if_index);
1832 u32 bd_id = ntohl (mp->bd_id);
1841 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1844 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1845 goto bad_sw_if_index;
1851 VALIDATE_SW_IF_INDEX (mp);
1852 if (vec_len (l2im->configs) <= sw_if_index)
1854 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1855 goto bad_sw_if_index;
1859 l2_input_config_t *config;
1860 config = vec_elt_at_index (l2im->configs, sw_if_index);
1861 if (config->bridge == 0)
1863 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1864 goto bad_sw_if_index;
1867 static_mac = mp->static_mac ? 1 : 0;
1868 filter_mac = mp->filter_mac ? 1 : 0;
1869 bvi_mac = mp->bvi_mac ? 1 : 0;
1870 l2fib_add_entry (mac, bd_index, sw_if_index, static_mac, filter_mac,
1875 l2fib_del_entry (mac, bd_index);
1878 BAD_SW_IF_INDEX_LABEL;
1880 REPLY_MACRO (VL_API_L2FIB_ADD_DEL_REPLY);
1884 vl_api_l2_flags_t_handler (vl_api_l2_flags_t * mp)
1886 vl_api_l2_flags_reply_t *rmp;
1888 u32 sw_if_index = ntohl (mp->sw_if_index);
1889 u32 flags = ntohl (mp->feature_bitmap);
1892 VALIDATE_SW_IF_INDEX (mp);
1895 if (flags & L2INPUT_FEAT_ ## a) \
1896 rbm = l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_ ## a, mp->is_set);
1897 foreach_l2input_feat;
1900 BAD_SW_IF_INDEX_LABEL;
1903 REPLY_MACRO2(VL_API_L2_FLAGS_REPLY,
1905 rmp->resulting_feature_bitmap = ntohl(rbm);
1911 vl_api_bridge_flags_t_handler (vl_api_bridge_flags_t * mp)
1913 vlib_main_t *vm = vlib_get_main ();
1914 bd_main_t *bdm = &bd_main;
1915 vl_api_bridge_flags_reply_t *rmp;
1917 u32 bd_id = ntohl (mp->bd_id);
1919 u32 flags = ntohl (mp->feature_bitmap);
1922 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1925 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1931 bd_set_flags (vm, bd_index, flags, mp->is_set);
1935 REPLY_MACRO2(VL_API_BRIDGE_FLAGS_REPLY,
1937 rmp->resulting_feature_bitmap = ntohl(flags);
1943 vl_api_bd_ip_mac_add_del_t_handler (vl_api_bd_ip_mac_add_del_t * mp)
1945 bd_main_t *bdm = &bd_main;
1946 vl_api_bd_ip_mac_add_del_reply_t *rmp;
1948 u32 bd_id = ntohl (mp->bd_id);
1952 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1955 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1960 if (bd_add_del_ip_mac (bd_index, mp->ip_address,
1961 mp->mac_address, mp->is_ipv6, mp->is_add))
1962 rv = VNET_API_ERROR_UNSPECIFIED;
1965 REPLY_MACRO (VL_API_BD_IP_MAC_ADD_DEL_REPLY);
1969 vl_api_tap_connect_t_handler (vl_api_tap_connect_t * mp, vlib_main_t * vm)
1972 vl_api_tap_connect_reply_t *rmp;
1973 unix_shared_memory_queue_t *q;
1974 u32 sw_if_index = (u32) ~ 0;
1976 rv = vnet_tap_connect_renumber (vm, mp->tap_name,
1977 mp->use_random_mac ? 0 : mp->mac_address,
1978 &sw_if_index, mp->renumber,
1979 ntohl (mp->custom_dev_instance));
1981 q = vl_api_client_index_to_input_queue (mp->client_index);
1985 rmp = vl_msg_api_alloc (sizeof (*rmp));
1986 rmp->_vl_msg_id = ntohs (VL_API_TAP_CONNECT_REPLY);
1987 rmp->context = mp->context;
1988 rmp->retval = ntohl (rv);
1989 rmp->sw_if_index = ntohl (sw_if_index);
1991 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1995 vl_api_tap_modify_t_handler (vl_api_tap_modify_t * mp, vlib_main_t * vm)
1998 vl_api_tap_modify_reply_t *rmp;
1999 unix_shared_memory_queue_t *q;
2000 u32 sw_if_index = (u32) ~ 0;
2002 rv = vnet_tap_modify (vm, ntohl (mp->sw_if_index), mp->tap_name,
2003 mp->use_random_mac ? 0 : mp->mac_address,
2004 &sw_if_index, mp->renumber,
2005 ntohl (mp->custom_dev_instance));
2007 q = vl_api_client_index_to_input_queue (mp->client_index);
2011 rmp = vl_msg_api_alloc (sizeof (*rmp));
2012 rmp->_vl_msg_id = ntohs (VL_API_TAP_MODIFY_REPLY);
2013 rmp->context = mp->context;
2014 rmp->retval = ntohl (rv);
2015 rmp->sw_if_index = ntohl (sw_if_index);
2017 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2021 vl_api_tap_delete_t_handler (vl_api_tap_delete_t * mp, vlib_main_t * vm)
2024 vpe_api_main_t *vam = &vpe_api_main;
2025 vl_api_tap_delete_reply_t *rmp;
2026 unix_shared_memory_queue_t *q;
2027 u32 sw_if_index = ntohl (mp->sw_if_index);
2029 rv = vnet_tap_delete (vm, sw_if_index);
2031 q = vl_api_client_index_to_input_queue (mp->client_index);
2035 rmp = vl_msg_api_alloc (sizeof (*rmp));
2036 rmp->_vl_msg_id = ntohs (VL_API_TAP_DELETE_REPLY);
2037 rmp->context = mp->context;
2038 rmp->retval = ntohl (rv);
2040 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2043 send_sw_interface_flags_deleted (vam, q, sw_if_index);
2047 vl_api_create_vlan_subif_t_handler (vl_api_create_vlan_subif_t * mp)
2049 vl_api_create_vlan_subif_reply_t *rmp;
2050 vnet_main_t *vnm = vnet_get_main ();
2051 u32 hw_if_index, sw_if_index = (u32) ~ 0;
2052 vnet_hw_interface_t *hi;
2055 vnet_sw_interface_t template;
2057 vnet_interface_main_t *im = &vnm->interface_main;
2058 u64 sup_and_sub_key;
2060 unix_shared_memory_queue_t *q;
2061 clib_error_t *error;
2063 VALIDATE_SW_IF_INDEX (mp);
2065 hw_if_index = ntohl (mp->sw_if_index);
2066 hi = vnet_get_hw_interface (vnm, hw_if_index);
2068 id = ntohl (mp->vlan_id);
2069 if (id == 0 || id > 4095)
2071 rv = VNET_API_ERROR_INVALID_VLAN;
2075 sup_and_sub_key = ((u64) (hi->sw_if_index) << 32) | (u64) id;
2077 p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
2080 rv = VNET_API_ERROR_VLAN_ALREADY_EXISTS;
2084 kp = clib_mem_alloc (sizeof (*kp));
2085 *kp = sup_and_sub_key;
2087 memset (&template, 0, sizeof (template));
2088 template.type = VNET_SW_INTERFACE_TYPE_SUB;
2089 template.sup_sw_if_index = hi->sw_if_index;
2090 template.sub.id = id;
2091 template.sub.eth.raw_flags = 0;
2092 template.sub.eth.flags.one_tag = 1;
2093 template.sub.eth.outer_vlan_id = id;
2094 template.sub.eth.flags.exact_match = 1;
2096 error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
2099 clib_error_report (error);
2100 rv = VNET_API_ERROR_INVALID_REGISTRATION;
2103 hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
2104 hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
2106 BAD_SW_IF_INDEX_LABEL;
2109 q = vl_api_client_index_to_input_queue (mp->client_index);
2113 rmp = vl_msg_api_alloc (sizeof (*rmp));
2114 rmp->_vl_msg_id = ntohs (VL_API_CREATE_VLAN_SUBIF_REPLY);
2115 rmp->context = mp->context;
2116 rmp->retval = ntohl (rv);
2117 rmp->sw_if_index = ntohl (sw_if_index);
2118 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2122 vl_api_create_subif_t_handler (vl_api_create_subif_t * mp)
2124 vl_api_create_subif_reply_t *rmp;
2125 vnet_main_t *vnm = vnet_get_main ();
2126 u32 sw_if_index = ~0;
2129 vnet_sw_interface_t *si;
2130 vnet_hw_interface_t *hi;
2131 vnet_sw_interface_t template;
2133 vnet_interface_main_t *im = &vnm->interface_main;
2134 u64 sup_and_sub_key;
2136 clib_error_t *error;
2138 VALIDATE_SW_IF_INDEX (mp);
2140 si = vnet_get_sup_sw_interface (vnm, ntohl (mp->sw_if_index));
2141 hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
2143 if (hi->bond_info == VNET_HW_INTERFACE_BOND_INFO_SLAVE)
2145 rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
2149 sw_if_index = si->sw_if_index;
2150 sub_id = ntohl (mp->sub_id);
2152 sup_and_sub_key = ((u64) (sw_if_index) << 32) | (u64) sub_id;
2154 p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
2158 clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
2159 sw_if_index, sub_id);
2160 rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
2164 kp = clib_mem_alloc (sizeof (*kp));
2165 *kp = sup_and_sub_key;
2167 memset (&template, 0, sizeof (template));
2168 template.type = VNET_SW_INTERFACE_TYPE_SUB;
2169 template.sup_sw_if_index = sw_if_index;
2170 template.sub.id = sub_id;
2171 template.sub.eth.flags.no_tags = mp->no_tags;
2172 template.sub.eth.flags.one_tag = mp->one_tag;
2173 template.sub.eth.flags.two_tags = mp->two_tags;
2174 template.sub.eth.flags.dot1ad = mp->dot1ad;
2175 template.sub.eth.flags.exact_match = mp->exact_match;
2176 template.sub.eth.flags.default_sub = mp->default_sub;
2177 template.sub.eth.flags.outer_vlan_id_any = mp->outer_vlan_id_any;
2178 template.sub.eth.flags.inner_vlan_id_any = mp->inner_vlan_id_any;
2179 template.sub.eth.outer_vlan_id = ntohs (mp->outer_vlan_id);
2180 template.sub.eth.inner_vlan_id = ntohs (mp->inner_vlan_id);
2182 error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
2185 clib_error_report (error);
2186 rv = VNET_API_ERROR_SUBIF_CREATE_FAILED;
2190 hash_set (hi->sub_interface_sw_if_index_by_id, sub_id, sw_if_index);
2191 hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
2193 BAD_SW_IF_INDEX_LABEL;
2198 REPLY_MACRO2(VL_API_CREATE_SUBIF_REPLY,
2200 rmp->sw_if_index = ntohl(sw_if_index);
2206 vl_api_mpls_gre_add_del_tunnel_t_handler (vl_api_mpls_gre_add_del_tunnel_t *
2209 vl_api_mpls_gre_add_del_tunnel_reply_t *rmp;
2211 stats_main_t *sm = &stats_main;
2212 u32 tunnel_sw_if_index = ~0;
2214 dslock (sm, 1 /* release hint */ , 5 /* tag */ );
2216 rv = vnet_mpls_gre_add_del_tunnel ((ip4_address_t *) (mp->src_address),
2217 (ip4_address_t *) (mp->dst_address),
2218 (ip4_address_t *) (mp->intfc_address),
2219 (u32) (mp->intfc_address_length),
2220 ntohl (mp->inner_vrf_id),
2221 ntohl (mp->outer_vrf_id),
2222 &tunnel_sw_if_index,
2223 mp->l2_only, mp->is_add);
2227 REPLY_MACRO2(VL_API_MPLS_GRE_ADD_DEL_TUNNEL_REPLY,
2229 rmp->tunnel_sw_if_index = ntohl(tunnel_sw_if_index);
2235 vl_api_mpls_ethernet_add_del_tunnel_t_handler
2236 (vl_api_mpls_ethernet_add_del_tunnel_t * mp)
2238 vl_api_mpls_ethernet_add_del_tunnel_reply_t *rmp;
2240 stats_main_t *sm = &stats_main;
2241 u32 tunnel_sw_if_index;
2243 dslock (sm, 1 /* release hint */ , 5 /* tag */ );
2245 rv = vnet_mpls_ethernet_add_del_tunnel
2246 (mp->dst_mac_address, (ip4_address_t *) (mp->adj_address),
2247 (u32) (mp->adj_address_length), ntohl (mp->vrf_id),
2248 ntohl (mp->tx_sw_if_index),
2249 &tunnel_sw_if_index, mp->l2_only, mp->is_add);
2254 REPLY_MACRO2(VL_API_MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,
2256 rmp->tunnel_sw_if_index = ntohl(tunnel_sw_if_index);
2262 * This piece of misery brought to you because the control-plane
2263 * can't figure out the tx interface + dst-mac address all by itself
2265 static int mpls_ethernet_add_del_tunnel_2_t_handler
2266 (vl_api_mpls_ethernet_add_del_tunnel_2_t * mp)
2268 pending_route_t *pr;
2269 vl_api_mpls_ethernet_add_del_tunnel_2_t *pme;
2270 vnet_main_t *vnm = vnet_get_main ();
2271 vlib_main_t *vm = vlib_get_main ();
2272 stats_main_t *sm = &stats_main;
2273 vpe_api_main_t *vam = &vpe_api_main;
2274 u32 inner_fib_index, outer_fib_index;
2275 ip4_main_t *im = &ip4_main;
2276 ip_lookup_main_t *lm = &im->lookup_main;
2277 ip_adjacency_t *adj = 0;
2280 u8 *dst_mac_address;
2284 u32 tunnel_sw_if_index;
2286 p = hash_get (im->fib_index_by_table_id, ntohl (mp->outer_vrf_id));
2288 return VNET_API_ERROR_NO_SUCH_FIB;
2290 outer_fib_index = p[0];
2293 p = hash_get (im->fib_index_by_table_id, ntohl (mp->inner_vrf_id));
2295 return VNET_API_ERROR_NO_SUCH_INNER_FIB;
2297 inner_fib_index = p[0];
2299 if (inner_fib_index == outer_fib_index)
2300 return VNET_API_ERROR_INVALID_VALUE;
2302 lookup_result = ip4_fib_lookup_with_table
2303 (im, outer_fib_index,
2304 (ip4_address_t *) mp->next_hop_ip4_address_in_outer_vrf,
2305 1 /* disable default route */ );
2307 adj = ip_get_adjacency (lm, lookup_result);
2308 tx_sw_if_index = adj->rewrite_header.sw_if_index;
2310 if (mp->is_add && mp->resolve_if_needed)
2312 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
2314 pool_get (vam->pending_routes, pr);
2315 pr->resolve_type = RESOLVE_MPLS_ETHERNET_ADD_DEL;
2317 clib_memcpy (pme, mp, sizeof (*pme));
2318 /* recursion block, "just in case" */
2319 pme->resolve_if_needed = 0;
2320 pme->resolve_attempts = ntohl (mp->resolve_attempts);
2321 pme->resolve_opaque = tx_sw_if_index;
2322 vnet_register_ip4_arp_resolution_event
2324 (ip4_address_t *) & (pme->next_hop_ip4_address_in_outer_vrf),
2325 vpe_resolver_process_node.index,
2326 RESOLUTION_EVENT, pr - vam->pending_routes);
2328 vlib_process_signal_event
2329 (vm, vpe_resolver_process_node.index,
2330 RESOLUTION_PENDING_EVENT, 0 /* data */ );
2332 /* The interface may be down, etc. */
2333 e = ip4_probe_neighbor
2334 (vm, (ip4_address_t *) & (mp->next_hop_ip4_address_in_outer_vrf),
2338 clib_error_report (e);
2340 return VNET_API_ERROR_IN_PROGRESS;
2344 if (adj->lookup_next_index != IP_LOOKUP_NEXT_REWRITE)
2345 return VNET_API_ERROR_NEXT_HOP_NOT_IN_FIB;
2348 vnet_rewrite_get_data_internal
2349 (&adj->rewrite_header, sizeof (adj->rewrite_data));
2351 dslock (sm, 1 /* release hint */ , 10 /* tag */ );
2353 rv = vnet_mpls_ethernet_add_del_tunnel
2354 (dst_mac_address, (ip4_address_t *) (mp->adj_address),
2355 (u32) (mp->adj_address_length), ntohl (mp->inner_vrf_id),
2356 tx_sw_if_index, &tunnel_sw_if_index, mp->l2_only, mp->is_add);
2364 vl_api_mpls_ethernet_add_del_tunnel_2_t_handler
2365 (vl_api_mpls_ethernet_add_del_tunnel_2_t * mp)
2367 vl_api_mpls_ethernet_add_del_tunnel_reply_t *rmp;
2370 rv = mpls_ethernet_add_del_tunnel_2_t_handler (mp);
2372 REPLY_MACRO (VL_API_MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY);
2377 vl_api_mpls_add_del_encap_t_handler (vl_api_mpls_add_del_encap_t * mp)
2379 vl_api_mpls_add_del_encap_reply_t *rmp;
2384 vec_reset_length (labels);
2386 for (i = 0; i < mp->nlabels; i++)
2387 vec_add1 (labels, ntohl (mp->labels[i]));
2390 rv = vnet_mpls_add_del_encap ((ip4_address_t *) mp->dst_address,
2391 ntohl (mp->vrf_id), labels,
2392 ~0 /* policy_tunnel_index */ ,
2393 0 /* no_dst_hash */ ,
2397 REPLY_MACRO (VL_API_MPLS_ADD_DEL_ENCAP_REPLY);
2401 vl_api_mpls_add_del_decap_t_handler (vl_api_mpls_add_del_decap_t * mp)
2403 vl_api_mpls_add_del_decap_reply_t *rmp;
2406 rv = vnet_mpls_add_del_decap (ntohl (mp->rx_vrf_id), ntohl (mp->tx_vrf_id),
2407 ntohl (mp->label), ntohl (mp->next_index),
2408 mp->s_bit, mp->is_add);
2410 REPLY_MACRO (VL_API_MPLS_ADD_DEL_DECAP_REPLY);
2414 vl_api_proxy_arp_add_del_t_handler (vl_api_proxy_arp_add_del_t * mp)
2416 vl_api_proxy_arp_add_del_reply_t *rmp;
2419 ip4_main_t *im = &ip4_main;
2420 stats_main_t *sm = &stats_main;
2421 int vnet_proxy_arp_add_del (ip4_address_t * lo_addr,
2422 ip4_address_t * hi_addr,
2423 u32 fib_index, int is_del);
2426 dslock (sm, 1 /* release hint */ , 6 /* tag */ );
2428 p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
2432 rv = VNET_API_ERROR_NO_SUCH_FIB;
2438 rv = vnet_proxy_arp_add_del ((ip4_address_t *) mp->low_address,
2439 (ip4_address_t *) mp->hi_address,
2440 fib_index, mp->is_add == 0);
2444 REPLY_MACRO (VL_API_PROXY_ARP_ADD_DEL_REPLY);
2448 vl_api_proxy_arp_intfc_enable_disable_t_handler
2449 (vl_api_proxy_arp_intfc_enable_disable_t * mp)
2452 vnet_main_t *vnm = vnet_get_main ();
2453 vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;
2454 vnet_sw_interface_t *si;
2457 VALIDATE_SW_IF_INDEX (mp);
2459 sw_if_index = ntohl (mp->sw_if_index);
2461 if (pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index))
2463 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
2467 si = vnet_get_sw_interface (vnm, sw_if_index);
2471 if (mp->enable_disable)
2472 si->flags |= VNET_SW_INTERFACE_FLAG_PROXY_ARP;
2474 si->flags &= ~VNET_SW_INTERFACE_FLAG_PROXY_ARP;
2476 BAD_SW_IF_INDEX_LABEL;
2479 REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
2483 vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
2486 vl_api_ip_neighbor_add_del_reply_t *rmp;
2487 vnet_main_t *vnm = vnet_get_main ();
2490 stats_main_t *sm = &stats_main;
2492 VALIDATE_SW_IF_INDEX (mp);
2494 dslock (sm, 1 /* release hint */ , 7 /* tag */ );
2499 rv = vnet_set_ip6_ethernet_neighbor
2500 (vm, ntohl (mp->sw_if_index),
2501 (ip6_address_t *) (mp->dst_address),
2502 mp->mac_address, sizeof (mp->mac_address), mp->is_static);
2504 rv = vnet_unset_ip6_ethernet_neighbor
2505 (vm, ntohl (mp->sw_if_index),
2506 (ip6_address_t *) (mp->dst_address),
2507 mp->mac_address, sizeof (mp->mac_address));
2511 ip4_main_t *im = &ip4_main;
2512 ip_lookup_main_t *lm = &im->lookup_main;
2513 ethernet_arp_ip4_over_ethernet_address_t a;
2515 ip_adjacency_t *nh_adj;
2517 uword *p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
2520 rv = VNET_API_ERROR_NO_SUCH_FIB;
2526 * Unfortunately, folks have a penchant for
2527 * adding interface addresses to the ARP cache, and
2528 * wondering why the forwarder eventually ASSERTs...
2530 ai = ip4_fib_lookup_with_table
2531 (im, fib_index, (ip4_address_t *) (mp->dst_address),
2532 1 /* disable default route */ );
2536 nh_adj = ip_get_adjacency (lm, ai);
2537 /* Never allow manipulation of a local adj! */
2538 if (nh_adj->lookup_next_index == IP_LOOKUP_NEXT_LOCAL)
2540 clib_warning ("%U matches local adj",
2542 (ip4_address_t *) (mp->dst_address));
2543 rv = VNET_API_ERROR_ADDRESS_MATCHES_INTERFACE_ADDRESS;
2548 clib_memcpy (&a.ethernet, mp->mac_address, 6);
2549 clib_memcpy (&a.ip4, mp->dst_address, 4);
2552 rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
2553 fib_index, &a, mp->is_static);
2555 rv = vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
2559 BAD_SW_IF_INDEX_LABEL;
2562 REPLY_MACRO (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY);
2566 vl_api_is_address_reachable_t_handler (vl_api_is_address_reachable_t * mp)
2569 vpe_main_t *rm = &vpe_main;
2570 ip4_main_t *im4 = &ip4_main;
2571 ip6_main_t *im6 = &ip6_main;
2572 ip_lookup_main_t *lm;
2578 u32 adj_index, sw_if_index;
2579 vl_api_is_address_reachable_t *rmp;
2580 ip_adjacency_t *adj;
2581 unix_shared_memory_queue_t *q;
2583 q = vl_api_client_index_to_input_queue (mp->client_index);
2586 increment_missing_api_client_counter (rm->vlib_main);
2590 rmp = vl_msg_api_alloc (sizeof (*rmp));
2591 clib_memcpy (rmp, mp, sizeof (*rmp));
2593 sw_if_index = mp->next_hop_sw_if_index;
2594 clib_memcpy (&addr, mp->address, sizeof (addr));
2597 lm = &im6->lookup_main;
2598 adj_index = ip6_fib_lookup (im6, sw_if_index, &addr.ip6);
2602 lm = &im4->lookup_main;
2603 adj_index = ip4_fib_lookup (im4, sw_if_index, &addr.ip4);
2605 if (adj_index == ~0)
2610 adj = ip_get_adjacency (lm, adj_index);
2612 if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE
2613 && adj->rewrite_header.sw_if_index == sw_if_index)
2619 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP
2620 && adj->rewrite_header.sw_if_index == sw_if_index)
2623 ip6_probe_neighbor (rm->vlib_main, &addr.ip6, sw_if_index);
2625 ip4_probe_neighbor (rm->vlib_main, &addr.ip4, sw_if_index);
2627 else if (adj->lookup_next_index == IP_LOOKUP_NEXT_DROP)
2636 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2641 vl_api_sw_interface_details_t_handler (vl_api_sw_interface_details_t * mp)
2643 clib_warning ("BUG");
2647 vl_api_sw_interface_set_flags_t_handler (vl_api_sw_interface_set_flags_t * mp)
2649 vl_api_sw_interface_set_flags_reply_t *rmp;
2650 vnet_main_t *vnm = vnet_get_main ();
2652 clib_error_t *error;
2655 VALIDATE_SW_IF_INDEX (mp);
2657 flags = mp->admin_up_down ? VNET_SW_INTERFACE_FLAG_ADMIN_UP : 0;
2659 error = vnet_sw_interface_set_flags (vnm, ntohl (mp->sw_if_index), flags);
2663 clib_error_report (error);
2666 BAD_SW_IF_INDEX_LABEL;
2667 REPLY_MACRO (VL_API_SW_INTERFACE_SET_FLAGS_REPLY);
2671 vl_api_sw_interface_clear_stats_t_handler (vl_api_sw_interface_clear_stats_t *
2674 vl_api_sw_interface_clear_stats_reply_t *rmp;
2676 vnet_main_t *vnm = vnet_get_main ();
2677 vnet_interface_main_t *im = &vnm->interface_main;
2678 vlib_simple_counter_main_t *sm;
2679 vlib_combined_counter_main_t *cm;
2680 static vnet_main_t **my_vnet_mains;
2681 int i, j, n_counters;
2684 if (mp->sw_if_index != ~0)
2685 VALIDATE_SW_IF_INDEX (mp);
2687 vec_reset_length (my_vnet_mains);
2689 for (i = 0; i < vec_len (vnet_mains); i++)
2692 vec_add1 (my_vnet_mains, vnet_mains[i]);
2695 if (vec_len (vnet_mains) == 0)
2696 vec_add1 (my_vnet_mains, vnm);
2698 n_counters = vec_len (im->combined_sw_if_counters);
2700 for (j = 0; j < n_counters; j++)
2702 for (i = 0; i < vec_len (my_vnet_mains); i++)
2704 im = &my_vnet_mains[i]->interface_main;
2705 cm = im->combined_sw_if_counters + j;
2706 if (mp->sw_if_index == (u32) ~ 0)
2707 vlib_clear_combined_counters (cm);
2709 vlib_zero_combined_counter (cm, ntohl (mp->sw_if_index));
2713 n_counters = vec_len (im->sw_if_counters);
2715 for (j = 0; j < n_counters; j++)
2717 for (i = 0; i < vec_len (my_vnet_mains); i++)
2719 im = &my_vnet_mains[i]->interface_main;
2720 sm = im->sw_if_counters + j;
2721 if (mp->sw_if_index == (u32) ~ 0)
2722 vlib_clear_simple_counters (sm);
2724 vlib_zero_simple_counter (sm, ntohl (mp->sw_if_index));
2728 BAD_SW_IF_INDEX_LABEL;
2730 REPLY_MACRO (VL_API_SW_INTERFACE_CLEAR_STATS_REPLY);
2734 send_sw_interface_details (vpe_api_main_t * am,
2735 unix_shared_memory_queue_t * q,
2736 vnet_sw_interface_t * swif,
2737 u8 * interface_name, u32 context)
2739 vl_api_sw_interface_details_t *mp;
2740 vnet_hw_interface_t *hi;
2742 hi = vnet_get_sup_hw_interface (am->vnet_main, swif->sw_if_index);
2744 mp = vl_msg_api_alloc (sizeof (*mp));
2745 memset (mp, 0, sizeof (*mp));
2746 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_DETAILS);
2747 mp->sw_if_index = ntohl (swif->sw_if_index);
2748 mp->sup_sw_if_index = ntohl (swif->sup_sw_if_index);
2749 mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0;
2750 mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0;
2751 mp->link_duplex = ((hi->flags & VNET_HW_INTERFACE_FLAG_DUPLEX_MASK) >>
2752 VNET_HW_INTERFACE_FLAG_DUPLEX_SHIFT);
2753 mp->link_speed = ((hi->flags & VNET_HW_INTERFACE_FLAG_SPEED_MASK) >>
2754 VNET_HW_INTERFACE_FLAG_SPEED_SHIFT);
2755 mp->link_mtu = ntohs (hi->max_packet_bytes);
2756 mp->context = context;
2758 strncpy ((char *) mp->interface_name,
2759 (char *) interface_name, ARRAY_LEN (mp->interface_name) - 1);
2761 /* Send the L2 address for ethernet physical intfcs */
2762 if (swif->sup_sw_if_index == swif->sw_if_index
2763 && hi->hw_class_index == ethernet_hw_interface_class.index)
2765 ethernet_main_t *em = ethernet_get_main (am->vlib_main);
2766 ethernet_interface_t *ei;
2768 ei = pool_elt_at_index (em->interfaces, hi->hw_instance);
2769 ASSERT (sizeof (mp->l2_address) >= sizeof (ei->address));
2770 clib_memcpy (mp->l2_address, ei->address, sizeof (ei->address));
2771 mp->l2_address_length = ntohl (sizeof (ei->address));
2773 else if (swif->sup_sw_if_index != swif->sw_if_index)
2775 vnet_sub_interface_t *sub = &swif->sub;
2776 mp->sub_id = ntohl (sub->id);
2777 mp->sub_dot1ad = sub->eth.flags.dot1ad;
2778 mp->sub_number_of_tags =
2779 sub->eth.flags.one_tag + sub->eth.flags.two_tags * 2;
2780 mp->sub_outer_vlan_id = ntohs (sub->eth.outer_vlan_id);
2781 mp->sub_inner_vlan_id = ntohs (sub->eth.inner_vlan_id);
2782 mp->sub_exact_match = sub->eth.flags.exact_match;
2783 mp->sub_default = sub->eth.flags.default_sub;
2784 mp->sub_outer_vlan_id_any = sub->eth.flags.outer_vlan_id_any;
2785 mp->sub_inner_vlan_id_any = sub->eth.flags.inner_vlan_id_any;
2787 /* vlan tag rewrite data */
2788 u32 vtr_op = L2_VTR_DISABLED;
2789 u32 vtr_push_dot1q = 0, vtr_tag1 = 0, vtr_tag2 = 0;
2791 if (l2vtr_get (am->vlib_main, am->vnet_main, swif->sw_if_index,
2792 &vtr_op, &vtr_push_dot1q, &vtr_tag1, &vtr_tag2) != 0)
2794 // error - default to disabled
2795 mp->vtr_op = ntohl (L2_VTR_DISABLED);
2796 clib_warning ("cannot get vlan tag rewrite for sw_if_index %d",
2801 mp->vtr_op = ntohl (vtr_op);
2802 mp->vtr_push_dot1q = ntohl (vtr_push_dot1q);
2803 mp->vtr_tag1 = ntohl (vtr_tag1);
2804 mp->vtr_tag2 = ntohl (vtr_tag2);
2808 vl_msg_api_send_shmem (q, (u8 *) & mp);
2812 send_sw_interface_flags (vpe_api_main_t * am,
2813 unix_shared_memory_queue_t * q,
2814 vnet_sw_interface_t * swif)
2816 vl_api_sw_interface_set_flags_t *mp;
2817 vnet_main_t *vnm = am->vnet_main;
2819 vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm,
2821 mp = vl_msg_api_alloc (sizeof (*mp));
2822 memset (mp, 0, sizeof (*mp));
2823 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SET_FLAGS);
2824 mp->sw_if_index = ntohl (swif->sw_if_index);
2826 mp->admin_up_down = (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? 1 : 0;
2827 mp->link_up_down = (hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ? 1 : 0;
2828 vl_msg_api_send_shmem (q, (u8 *) & mp);
2831 static void send_sw_interface_flags_deleted (vpe_api_main_t * am,
2832 unix_shared_memory_queue_t * q,
2834 __attribute__ ((unused));
2837 send_sw_interface_flags_deleted (vpe_api_main_t * am,
2838 unix_shared_memory_queue_t * q,
2841 vl_api_sw_interface_set_flags_t *mp;
2843 mp = vl_msg_api_alloc (sizeof (*mp));
2844 memset (mp, 0, sizeof (*mp));
2845 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SET_FLAGS);
2846 mp->sw_if_index = ntohl (sw_if_index);
2848 mp->admin_up_down = 0;
2849 mp->link_up_down = 0;
2851 vl_msg_api_send_shmem (q, (u8 *) & mp);
2855 vl_api_sw_interface_dump_t_handler (vl_api_sw_interface_dump_t * mp)
2857 vpe_api_main_t *am = &vpe_api_main;
2858 vnet_sw_interface_t *swif;
2859 vnet_interface_main_t *im = &am->vnet_main->interface_main;
2860 u8 *filter_string = 0, *name_string = 0;
2861 unix_shared_memory_queue_t *q;
2862 char *strcasestr (char *, char *); /* lnx hdr file botch */
2864 q = vl_api_client_index_to_input_queue (mp->client_index);
2869 if (mp->name_filter_valid)
2871 mp->name_filter[ARRAY_LEN (mp->name_filter) - 1] = 0;
2872 filter_string = format (0, "%s%c", mp->name_filter, 0);
2876 pool_foreach (swif, im->sw_interfaces,
2878 name_string = format (name_string, "%U%c",
2879 format_vnet_sw_interface_name,
2880 am->vnet_main, swif, 0);
2882 if (mp->name_filter_valid == 0 ||
2883 strcasestr((char *) name_string, (char *) filter_string)) {
2885 send_sw_interface_details (am, q, swif, name_string, mp->context);
2887 _vec_len (name_string) = 0;
2891 vec_free (name_string);
2892 vec_free (filter_string);
2896 send_oam_event (oam_target_t * t)
2898 vpe_api_main_t *vam = &vpe_api_main;
2899 unix_shared_memory_queue_t *q;
2900 vpe_client_registration_t *reg;
2901 vl_api_oam_event_t *mp;
2904 pool_foreach(reg, vam->oam_events_registrations,
2906 q = vl_api_client_index_to_input_queue (reg->client_index);
2909 mp = vl_msg_api_alloc (sizeof (*mp));
2910 mp->_vl_msg_id = ntohs (VL_API_OAM_EVENT);
2911 clib_memcpy (mp->dst_address, &t->dst_address,
2912 sizeof (mp->dst_address));
2913 mp->state = t->state;
2914 vl_msg_api_send_shmem (q, (u8 *)&mp);
2921 vl_api_oam_add_del_t_handler (vl_api_oam_add_del_t * mp)
2923 vl_api_oam_add_del_reply_t *rmp;
2926 rv = vpe_oam_add_del_target ((ip4_address_t *) mp->src_address,
2927 (ip4_address_t *) mp->dst_address,
2928 ntohl (mp->vrf_id), (int) (mp->is_add));
2930 REPLY_MACRO (VL_API_OAM_ADD_DEL_REPLY);
2934 vl_api_vnet_get_summary_stats_t_handler (vl_api_vnet_get_summary_stats_t * mp)
2936 stats_main_t *sm = &stats_main;
2937 vnet_interface_main_t *im = sm->interface_main;
2938 vl_api_vnet_summary_stats_reply_t *rmp;
2939 vlib_combined_counter_main_t *cm;
2942 u64 total_pkts[VLIB_N_RX_TX];
2943 u64 total_bytes[VLIB_N_RX_TX];
2945 unix_shared_memory_queue_t *q =
2946 vl_api_client_index_to_input_queue (mp->client_index);
2951 rmp = vl_msg_api_alloc (sizeof (*rmp));
2952 rmp->_vl_msg_id = ntohs (VL_API_VNET_SUMMARY_STATS_REPLY);
2953 rmp->context = mp->context;
2956 memset (total_pkts, 0, sizeof (total_pkts));
2957 memset (total_bytes, 0, sizeof (total_bytes));
2959 vnet_interface_counter_lock (im);
2961 vec_foreach (cm, im->combined_sw_if_counters)
2963 which = cm - im->combined_sw_if_counters;
2965 for (i = 0; i < vec_len (cm->maxi); i++)
2967 vlib_get_combined_counter (cm, i, &v);
2968 total_pkts[which] += v.packets;
2969 total_bytes[which] += v.bytes;
2972 vnet_interface_counter_unlock (im);
2974 rmp->total_pkts[VLIB_RX] = clib_host_to_net_u64 (total_pkts[VLIB_RX]);
2975 rmp->total_bytes[VLIB_RX] = clib_host_to_net_u64 (total_bytes[VLIB_RX]);
2976 rmp->total_pkts[VLIB_TX] = clib_host_to_net_u64 (total_pkts[VLIB_TX]);
2977 rmp->total_bytes[VLIB_TX] = clib_host_to_net_u64 (total_bytes[VLIB_TX]);
2979 clib_host_to_net_u64 (vlib_last_vector_length_per_node (sm->vlib_main));
2981 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2985 typedef CLIB_PACKED (struct {
2986 ip4_address_t address;
2987 u32 address_length: 6;
2993 ip4_reset_fib_t_handler (vl_api_reset_fib_t * mp)
2995 vnet_main_t *vnm = vnet_get_main ();
2996 vnet_interface_main_t *im = &vnm->interface_main;
2997 ip4_main_t *im4 = &ip4_main;
2998 static ip4_route_t *routes;
2999 static u32 *sw_if_indices_to_shut;
3000 stats_main_t *sm = &stats_main;
3005 int rv = VNET_API_ERROR_NO_SUCH_FIB;
3006 u32 target_fib_id = ntohl (mp->vrf_id);
3008 dslock (sm, 1 /* release hint */ , 8 /* tag */ );
3010 vec_foreach (fib, im4->fibs)
3012 vnet_sw_interface_t *si;
3014 if (fib->table_id != target_fib_id)
3017 /* remove any mpls/gre tunnels in this fib */
3018 vnet_mpls_gre_delete_fib_tunnels (fib->table_id);
3020 /* remove any mpls encap/decap labels */
3021 mpls_fib_reset_labels (fib->table_id);
3023 /* remove any proxy arps in this fib */
3024 vnet_proxy_arp_fib_reset (fib->table_id);
3026 /* Set the flow hash for this fib to the default */
3027 vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
3029 vec_reset_length (sw_if_indices_to_shut);
3031 /* Shut down interfaces in this FIB / clean out intfc routes */
3033 pool_foreach (si, im->sw_interfaces,
3035 u32 sw_if_index = si->sw_if_index;
3037 if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
3038 && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
3040 vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
3044 for (i = 0; i < vec_len (sw_if_indices_to_shut); i++)
3046 sw_if_index = sw_if_indices_to_shut[i];
3047 // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
3049 u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
3050 flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
3051 vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
3054 vec_reset_length (routes);
3056 for (i = 0; i < ARRAY_LEN (fib->adj_index_by_dst_address); i++)
3058 uword *hash = fib->adj_index_by_dst_address[i];
3062 x.address_length = i;
3065 hash_foreach_pair (p, hash,
3067 x.address.data_u32 = p->key;
3068 vec_add1 (routes, x);
3073 vec_foreach (r, routes)
3075 ip4_add_del_route_args_t a;
3077 memset (&a, 0, sizeof (a));
3078 a.flags = IP4_ROUTE_FLAG_FIB_INDEX | IP4_ROUTE_FLAG_DEL;
3079 a.table_index_or_table_id = fib - im4->fibs;
3080 a.dst_address = r->address;
3081 a.dst_address_length = r->address_length;
3084 ip4_add_del_route (im4, &a);
3085 ip4_maybe_remap_adjacencies (im4, fib - im4->fibs,
3086 IP4_ROUTE_FLAG_FIB_INDEX);
3090 } /* vec_foreach (fib) */
3098 ip6_address_t address;
3106 ip6_route_t **routep;
3107 } add_routes_in_fib_arg_t;
3110 add_routes_in_fib (clib_bihash_kv_24_8_t * kvp, void *arg)
3112 add_routes_in_fib_arg_t *ap = arg;
3114 if (kvp->key[2] >> 32 == ap->fib_index)
3116 ip6_address_t *addr;
3118 addr = (ip6_address_t *) kvp;
3119 vec_add2 (*ap->routep, r, 1);
3120 r->address = addr[0];
3121 r->address_length = kvp->key[2] & 0xFF;
3122 r->index = kvp->value;
3127 ip6_reset_fib_t_handler (vl_api_reset_fib_t * mp)
3129 vnet_main_t *vnm = vnet_get_main ();
3130 vnet_interface_main_t *im = &vnm->interface_main;
3131 ip6_main_t *im6 = &ip6_main;
3132 stats_main_t *sm = &stats_main;
3133 static ip6_route_t *routes;
3134 static u32 *sw_if_indices_to_shut;
3139 int rv = VNET_API_ERROR_NO_SUCH_FIB;
3140 u32 target_fib_id = ntohl (mp->vrf_id);
3141 add_routes_in_fib_arg_t _a, *a = &_a;
3142 clib_bihash_24_8_t *h = &im6->ip6_lookup_table;
3144 dslock (sm, 1 /* release hint */ , 9 /* tag */ );
3146 vec_foreach (fib, im6->fibs)
3148 vnet_sw_interface_t *si;
3150 if (fib->table_id != target_fib_id)
3153 vec_reset_length (sw_if_indices_to_shut);
3155 /* Shut down interfaces in this FIB / clean out intfc routes */
3157 pool_foreach (si, im->sw_interfaces,
3159 if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
3161 vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
3165 for (i = 0; i < vec_len (sw_if_indices_to_shut); i++)
3167 sw_if_index = sw_if_indices_to_shut[i];
3168 // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
3170 u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
3171 flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
3172 vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
3175 vec_reset_length (routes);
3177 a->fib_index = fib - im6->fibs;
3178 a->routep = &routes;
3180 clib_bihash_foreach_key_value_pair_24_8 (h, add_routes_in_fib, a);
3182 vec_foreach (r, routes)
3184 ip6_add_del_route_args_t a;
3186 memset (&a, 0, sizeof (a));
3187 a.flags = IP6_ROUTE_FLAG_FIB_INDEX | IP6_ROUTE_FLAG_DEL;
3188 a.table_index_or_table_id = fib - im6->fibs;
3189 a.dst_address = r->address;
3190 a.dst_address_length = r->address_length;
3193 ip6_add_del_route (im6, &a);
3194 ip6_maybe_remap_adjacencies (im6, fib - im6->fibs,
3195 IP6_ROUTE_FLAG_FIB_INDEX);
3198 /* Reinstall the neighbor / router discovery routes */
3199 vnet_ip6_fib_init (im6, fib - im6->fibs);
3201 } /* vec_foreach (fib) */
3208 vl_api_reset_fib_t_handler (vl_api_reset_fib_t * mp)
3211 vl_api_reset_fib_reply_t *rmp;
3214 rv = ip6_reset_fib_t_handler (mp);
3216 rv = ip4_reset_fib_t_handler (mp);
3218 REPLY_MACRO (VL_API_RESET_FIB_REPLY);
3223 dhcpv4_proxy_config (vl_api_dhcp_proxy_config_t * mp)
3225 vl_api_dhcp_proxy_config_reply_t *rmp;
3228 rv = dhcp_proxy_set_server ((ip4_address_t *) (&mp->dhcp_server),
3229 (ip4_address_t *) (&mp->dhcp_src_address),
3230 (u32) ntohl (mp->vrf_id),
3231 (int) mp->insert_circuit_id,
3232 (int) (mp->is_add == 0));
3234 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_REPLY);
3239 dhcpv6_proxy_config (vl_api_dhcp_proxy_config_t * mp)
3241 vl_api_dhcp_proxy_config_reply_t *rmp;
3244 rv = dhcpv6_proxy_set_server ((ip6_address_t *) (&mp->dhcp_server),
3245 (ip6_address_t *) (&mp->dhcp_src_address),
3246 (u32) ntohl (mp->vrf_id),
3247 (int) mp->insert_circuit_id,
3248 (int) (mp->is_add == 0));
3250 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_REPLY);
3254 dhcpv4_proxy_config_2 (vl_api_dhcp_proxy_config_2_t * mp)
3256 vl_api_dhcp_proxy_config_reply_t *rmp;
3259 rv = dhcp_proxy_set_server_2 ((ip4_address_t *) (&mp->dhcp_server),
3260 (ip4_address_t *) (&mp->dhcp_src_address),
3261 (u32) ntohl (mp->rx_vrf_id),
3262 (u32) ntohl (mp->server_vrf_id),
3263 (int) mp->insert_circuit_id,
3264 (int) (mp->is_add == 0));
3266 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_2_REPLY);
3271 dhcpv6_proxy_config_2 (vl_api_dhcp_proxy_config_2_t * mp)
3273 vl_api_dhcp_proxy_config_reply_t *rmp;
3277 rv = dhcpv6_proxy_set_server_2 ((ip6_address_t *) (&mp->dhcp_server),
3278 (ip6_address_t *) (&mp->dhcp_src_address),
3279 (u32) ntohl (mp->rx_vrf_id),
3280 (u32) ntohl (mp->server_vrf_id),
3281 (int) mp->insert_circuit_id,
3282 (int) (mp->is_add == 0));
3284 rv = VNET_API_ERROR_UNIMPLEMENTED;
3287 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_2_REPLY);
3292 vl_api_dhcp_proxy_set_vss_t_handler (vl_api_dhcp_proxy_set_vss_t * mp)
3294 vl_api_dhcp_proxy_set_vss_reply_t *rmp;
3297 rv = dhcp_proxy_set_option82_vss (ntohl (mp->tbl_id),
3300 (int) mp->is_add == 0);
3302 rv = dhcpv6_proxy_set_vss (ntohl (mp->tbl_id),
3304 ntohl (mp->fib_id), (int) mp->is_add == 0);
3306 REPLY_MACRO (VL_API_DHCP_PROXY_SET_VSS_REPLY);
3310 static void vl_api_dhcp_proxy_config_t_handler
3311 (vl_api_dhcp_proxy_config_t * mp)
3313 if (mp->is_ipv6 == 0)
3314 dhcpv4_proxy_config (mp);
3316 dhcpv6_proxy_config (mp);
3319 static void vl_api_dhcp_proxy_config_2_t_handler
3320 (vl_api_dhcp_proxy_config_2_t * mp)
3322 if (mp->is_ipv6 == 0)
3323 dhcpv4_proxy_config_2 (mp);
3325 dhcpv6_proxy_config_2 (mp);
3329 dhcp_compl_event_callback (u32 client_index, u32 pid, u8 * hostname,
3330 u8 is_ipv6, u8 * host_address, u8 * router_address,
3333 unix_shared_memory_queue_t *q;
3334 vl_api_dhcp_compl_event_t *mp;
3336 q = vl_api_client_index_to_input_queue (client_index);
3340 mp = vl_msg_api_alloc (sizeof (*mp));
3341 mp->client_index = client_index;
3343 mp->is_ipv6 = is_ipv6;
3344 clib_memcpy (&mp->hostname, hostname, vec_len (hostname));
3345 mp->hostname[vec_len (hostname) + 1] = '\n';
3346 clib_memcpy (&mp->host_address[0], host_address, 16);
3347 clib_memcpy (&mp->router_address[0], router_address, 16);
3348 clib_memcpy (&mp->host_mac[0], host_mac, 6);
3350 mp->_vl_msg_id = ntohs (VL_API_DHCP_COMPL_EVENT);
3352 vl_msg_api_send_shmem (q, (u8 *) & mp);
3355 static void vl_api_dhcp_client_config_t_handler
3356 (vl_api_dhcp_client_config_t * mp)
3358 vlib_main_t *vm = vlib_get_main ();
3359 vl_api_dhcp_client_config_reply_t *rmp;
3362 VALIDATE_SW_IF_INDEX (mp);
3364 rv = dhcp_client_config (vm, ntohl (mp->sw_if_index),
3365 mp->hostname, mp->is_add, mp->client_index,
3366 mp->want_dhcp_event ? dhcp_compl_event_callback :
3369 BAD_SW_IF_INDEX_LABEL;
3371 REPLY_MACRO (VL_API_DHCP_CLIENT_CONFIG_REPLY);
3375 vl_api_sw_interface_ip6nd_ra_config_t_handler
3376 (vl_api_sw_interface_ip6nd_ra_config_t * mp, vlib_main_t * vm)
3378 vl_api_sw_interface_ip6nd_ra_config_reply_t *rmp;
3380 u8 is_no, suppress, managed, other, ll_option, send_unicast, cease,
3383 is_no = mp->is_no == 1;
3384 suppress = mp->suppress == 1;
3385 managed = mp->managed == 1;
3386 other = mp->other == 1;
3387 ll_option = mp->ll_option == 1;
3388 send_unicast = mp->send_unicast == 1;
3389 cease = mp->cease == 1;
3390 default_router = mp->default_router == 1;
3392 VALIDATE_SW_IF_INDEX (mp);
3394 rv = ip6_neighbor_ra_config (vm, ntohl (mp->sw_if_index),
3395 suppress, managed, other,
3396 ll_option, send_unicast, cease,
3397 default_router, ntohl (mp->lifetime),
3398 ntohl (mp->initial_count),
3399 ntohl (mp->initial_interval),
3400 ntohl (mp->max_interval),
3401 ntohl (mp->min_interval), is_no);
3403 BAD_SW_IF_INDEX_LABEL;
3405 REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
3409 vl_api_sw_interface_ip6nd_ra_prefix_t_handler
3410 (vl_api_sw_interface_ip6nd_ra_prefix_t * mp, vlib_main_t * vm)
3412 vl_api_sw_interface_ip6nd_ra_prefix_reply_t *rmp;
3414 u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
3416 VALIDATE_SW_IF_INDEX (mp);
3418 is_no = mp->is_no == 1;
3419 use_default = mp->use_default == 1;
3420 no_advertise = mp->no_advertise == 1;
3421 off_link = mp->off_link == 1;
3422 no_autoconfig = mp->no_autoconfig == 1;
3423 no_onlink = mp->no_onlink == 1;
3425 rv = ip6_neighbor_ra_prefix (vm, ntohl (mp->sw_if_index),
3426 (ip6_address_t *) mp->address,
3427 mp->address_length, use_default,
3428 ntohl (mp->val_lifetime),
3429 ntohl (mp->pref_lifetime), no_advertise,
3430 off_link, no_autoconfig, no_onlink, is_no);
3432 BAD_SW_IF_INDEX_LABEL;
3433 REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
3437 vl_api_sw_interface_ip6_enable_disable_t_handler
3438 (vl_api_sw_interface_ip6_enable_disable_t * mp, vlib_main_t * vm)
3440 vl_api_sw_interface_ip6_enable_disable_reply_t *rmp;
3441 vnet_main_t *vnm = vnet_get_main ();
3443 clib_error_t *error;
3447 VALIDATE_SW_IF_INDEX (mp);
3450 (mp->enable == 1) ? enable_ip6_interface (vm,
3451 ntohl (mp->sw_if_index)) :
3452 disable_ip6_interface (vm, ntohl (mp->sw_if_index));
3456 clib_error_report (error);
3457 rv = VNET_API_ERROR_UNSPECIFIED;
3461 rv = vnm->api_errno;
3464 BAD_SW_IF_INDEX_LABEL;
3466 REPLY_MACRO (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
3470 vl_api_sw_interface_ip6_set_link_local_address_t_handler
3471 (vl_api_sw_interface_ip6_set_link_local_address_t * mp, vlib_main_t * vm)
3473 vl_api_sw_interface_ip6_set_link_local_address_reply_t *rmp;
3475 clib_error_t *error;
3476 vnet_main_t *vnm = vnet_get_main ();
3480 VALIDATE_SW_IF_INDEX (mp);
3482 error = set_ip6_link_local_address (vm,
3483 ntohl (mp->sw_if_index),
3484 (ip6_address_t *) mp->address,
3485 mp->address_length);
3488 clib_error_report (error);
3489 rv = VNET_API_ERROR_UNSPECIFIED;
3493 rv = vnm->api_errno;
3496 BAD_SW_IF_INDEX_LABEL;
3498 REPLY_MACRO (VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY);
3502 set_ip6_flow_hash (vl_api_set_ip_flow_hash_t * mp)
3504 vl_api_set_ip_flow_hash_reply_t *rmp;
3505 int rv = VNET_API_ERROR_UNIMPLEMENTED;
3507 clib_warning ("unimplemented...");
3509 REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
3513 set_ip4_flow_hash (vl_api_set_ip_flow_hash_t * mp)
3515 vl_api_set_ip_flow_hash_reply_t *rmp;
3518 u32 flow_hash_config = 0;
3520 table_id = ntohl (mp->vrf_id);
3522 #define _(a,b) if (mp->a) flow_hash_config |= b;
3523 foreach_flow_hash_bit;
3526 rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config);
3528 REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
3533 vl_api_set_ip_flow_hash_t_handler (vl_api_set_ip_flow_hash_t * mp)
3535 if (mp->is_ipv6 == 0)
3536 set_ip4_flow_hash (mp);
3538 set_ip6_flow_hash (mp);
3541 static void vl_api_sw_interface_set_unnumbered_t_handler
3542 (vl_api_sw_interface_set_unnumbered_t * mp)
3544 vl_api_sw_interface_set_unnumbered_reply_t *rmp;
3546 vnet_sw_interface_t *si;
3547 vnet_main_t *vnm = vnet_get_main ();
3548 u32 sw_if_index, unnumbered_sw_if_index;
3550 sw_if_index = ntohl (mp->sw_if_index);
3551 unnumbered_sw_if_index = ntohl (mp->unnumbered_sw_if_index);
3554 * The API message field names are backwards from
3555 * the underlying data structure names.
3556 * It's not worth changing them now.
3558 if (pool_is_free_index (vnm->interface_main.sw_interfaces,
3559 unnumbered_sw_if_index))
3561 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
3565 /* Only check the "use loop0" field when setting the binding */
3567 pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index))
3569 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
3573 si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index);
3577 si->flags |= VNET_SW_INTERFACE_FLAG_UNNUMBERED;
3578 si->unnumbered_sw_if_index = sw_if_index;
3582 si->flags &= ~(VNET_SW_INTERFACE_FLAG_UNNUMBERED);
3583 si->unnumbered_sw_if_index = (u32) ~ 0;
3587 REPLY_MACRO (VL_API_SW_INTERFACE_SET_UNNUMBERED_REPLY);
3591 vl_api_create_loopback_t_handler (vl_api_create_loopback_t * mp)
3593 vl_api_create_loopback_reply_t *rmp;
3597 rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address);
3600 REPLY_MACRO2(VL_API_CREATE_LOOPBACK_REPLY,
3602 rmp->sw_if_index = ntohl (sw_if_index);
3608 vl_api_delete_loopback_t_handler (vl_api_delete_loopback_t * mp)
3610 vl_api_delete_loopback_reply_t *rmp;
3614 sw_if_index = ntohl (mp->sw_if_index);
3615 rv = vnet_delete_loopback_interface (sw_if_index);
3617 REPLY_MACRO (VL_API_DELETE_LOOPBACK_REPLY);
3621 vl_api_control_ping_t_handler (vl_api_control_ping_t * mp)
3623 vl_api_control_ping_reply_t *rmp;
3627 REPLY_MACRO2(VL_API_CONTROL_PING_REPLY,
3629 rmp->vpe_pid = ntohl (getpid());
3634 static void vl_api_noprint_control_ping_t_handler
3635 (vl_api_noprint_control_ping_t * mp)
3637 vl_api_noprint_control_ping_reply_t *rmp;
3641 REPLY_MACRO2(VL_API_NOPRINT_CONTROL_PING_REPLY,
3643 rmp->vpe_pid = ntohl (getpid());
3649 shmem_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
3651 u8 **shmem_vecp = (u8 **) arg;
3654 api_main_t *am = &api_main;
3657 shmem_vec = *shmem_vecp;
3659 offset = vec_len (shmem_vec);
3661 pthread_mutex_lock (&am->vlib_rp->mutex);
3662 oldheap = svm_push_data_heap (am->vlib_rp);
3664 vec_validate (shmem_vec, offset + buffer_bytes - 1);
3666 clib_memcpy (shmem_vec + offset, buffer, buffer_bytes);
3668 svm_pop_heap (oldheap);
3669 pthread_mutex_unlock (&am->vlib_rp->mutex);
3671 *shmem_vecp = shmem_vec;
3676 vl_api_cli_request_t_handler (vl_api_cli_request_t * mp)
3678 vl_api_cli_reply_t *rp;
3679 unix_shared_memory_queue_t *q;
3680 vlib_main_t *vm = vlib_get_main ();
3681 api_main_t *am = &api_main;
3682 unformat_input_t input;
3686 q = vl_api_client_index_to_input_queue (mp->client_index);
3690 rp = vl_msg_api_alloc (sizeof (*rp));
3691 rp->_vl_msg_id = ntohs (VL_API_CLI_REPLY);
3692 rp->context = mp->context;
3694 unformat_init_vector (&input, (u8 *) (uword) mp->cmd_in_shmem);
3696 vlib_cli_input (vm, &input, shmem_cli_output, (uword) & shmem_vec);
3698 pthread_mutex_lock (&am->vlib_rp->mutex);
3699 oldheap = svm_push_data_heap (am->vlib_rp);
3701 vec_add1 (shmem_vec, 0);
3703 svm_pop_heap (oldheap);
3704 pthread_mutex_unlock (&am->vlib_rp->mutex);
3706 rp->reply_in_shmem = (uword) shmem_vec;
3708 vl_msg_api_send_shmem (q, (u8 *) & rp);
3712 inband_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
3714 u8 **mem_vecp = (u8 **) arg;
3715 u8 *mem_vec = *mem_vecp;
3716 u32 offset = vec_len (mem_vec);
3718 vec_validate (mem_vec, offset + buffer_bytes - 1);
3719 clib_memcpy (mem_vec + offset, buffer, buffer_bytes);
3720 *mem_vecp = mem_vec;
3724 vl_api_cli_inband_t_handler (vl_api_cli_inband_t * mp)
3726 vl_api_cli_inband_reply_t *rmp;
3728 unix_shared_memory_queue_t *q;
3729 vlib_main_t *vm = vlib_get_main ();
3730 unformat_input_t input;
3733 q = vl_api_client_index_to_input_queue (mp->client_index);
3737 unformat_init_string (&input, (char *) mp->cmd, ntohl (mp->length));
3738 vlib_cli_input (vm, &input, inband_cli_output, (uword) & out_vec);
3740 u32 len = vec_len (out_vec);
3742 REPLY_MACRO3(VL_API_CLI_INBAND_REPLY, len,
3744 rmp->length = htonl (len);
3745 clib_memcpy (rmp->reply, out_vec, len);
3752 vl_api_set_arp_neighbor_limit_t_handler (vl_api_set_arp_neighbor_limit_t * mp)
3755 vl_api_set_arp_neighbor_limit_reply_t *rmp;
3756 vnet_main_t *vnm = vnet_get_main ();
3757 clib_error_t *error;
3762 error = ip6_set_neighbor_limit (ntohl (mp->arp_neighbor_limit));
3764 error = ip4_set_arp_limit (ntohl (mp->arp_neighbor_limit));
3768 clib_error_report (error);
3769 rv = VNET_API_ERROR_UNSPECIFIED;
3773 rv = vnm->api_errno;
3776 REPLY_MACRO (VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
3779 static void vl_api_sr_tunnel_add_del_t_handler
3780 (vl_api_sr_tunnel_add_del_t * mp)
3783 clib_warning ("unimplemented");
3785 ip6_sr_add_del_tunnel_args_t _a, *a = &_a;
3787 vl_api_sr_tunnel_add_del_reply_t *rmp;
3788 ip6_address_t *segments = 0, *seg;
3789 ip6_address_t *tags = 0, *tag;
3790 ip6_address_t *this_address;
3793 if (mp->n_segments == 0)
3799 memset (a, 0, sizeof (*a));
3800 a->src_address = (ip6_address_t *) & mp->src_address;
3801 a->dst_address = (ip6_address_t *) & mp->dst_address;
3802 a->dst_mask_width = mp->dst_mask_width;
3803 a->flags_net_byte_order = mp->flags_net_byte_order;
3804 a->is_del = (mp->is_add == 0);
3805 a->rx_table_id = ntohl (mp->outer_vrf_id);
3806 a->tx_table_id = ntohl (mp->inner_vrf_id);
3808 a->name = format (0, "%s", mp->name);
3809 if (!(vec_len (a->name)))
3812 a->policy_name = format (0, "%s", mp->policy_name);
3813 if (!(vec_len (a->policy_name)))
3816 /* Yank segments and tags out of the API message */
3817 this_address = (ip6_address_t *) mp->segs_and_tags;
3818 for (i = 0; i < mp->n_segments; i++)
3820 vec_add2 (segments, seg, 1);
3821 clib_memcpy (seg->as_u8, this_address->as_u8, sizeof (*this_address));
3824 for (i = 0; i < mp->n_tags; i++)
3826 vec_add2 (tags, tag, 1);
3827 clib_memcpy (tag->as_u8, this_address->as_u8, sizeof (*this_address));
3831 a->segments = segments;
3834 rv = ip6_sr_add_del_tunnel (a);
3838 REPLY_MACRO (VL_API_SR_TUNNEL_ADD_DEL_REPLY);
3842 static void vl_api_sr_policy_add_del_t_handler
3843 (vl_api_sr_policy_add_del_t * mp)
3846 clib_warning ("unimplemented");
3848 ip6_sr_add_del_policy_args_t _a, *a = &_a;
3850 vl_api_sr_policy_add_del_reply_t *rmp;
3853 memset (a, 0, sizeof (*a));
3854 a->is_del = (mp->is_add == 0);
3856 a->name = format (0, "%s", mp->name);
3857 if (!(vec_len (a->name)))
3859 rv = VNET_API_ERROR_NO_SUCH_NODE2;
3863 if (!(mp->tunnel_names[0]))
3865 rv = VNET_API_ERROR_NO_SUCH_NODE2;
3869 // start deserializing tunnel_names
3870 int num_tunnels = mp->tunnel_names[0]; //number of tunnels
3871 u8 *deser_tun_names = mp->tunnel_names;
3872 deser_tun_names += 1; //moving along
3875 int tun_name_len = 0;
3877 for (i = 0; i < num_tunnels; i++)
3879 tun_name_len = *deser_tun_names;
3880 deser_tun_names += 1;
3881 vec_resize (tun_name, tun_name_len);
3882 memcpy (tun_name, deser_tun_names, tun_name_len);
3883 vec_add1 (a->tunnel_names, tun_name);
3884 deser_tun_names += tun_name_len;
3888 rv = ip6_sr_add_del_policy (a);
3892 REPLY_MACRO (VL_API_SR_POLICY_ADD_DEL_REPLY);
3896 static void vl_api_sr_multicast_map_add_del_t_handler
3897 (vl_api_sr_multicast_map_add_del_t * mp)
3900 clib_warning ("unimplemented");
3902 ip6_sr_add_del_multicastmap_args_t _a, *a = &_a;
3904 vl_api_sr_multicast_map_add_del_reply_t *rmp;
3906 memset (a, 0, sizeof (*a));
3907 a->is_del = (mp->is_add == 0);
3909 a->multicast_address = (ip6_address_t *) & mp->multicast_address;
3910 a->policy_name = format (0, "%s", mp->policy_name);
3912 if (a->multicast_address == 0)
3918 if (!(a->policy_name))
3924 #if DPDK > 0 /* Cannot call replicate without DPDK */
3925 rv = ip6_sr_add_del_multicastmap (a);
3927 clib_warning ("multicast replication without DPDK not implemented");
3928 rv = VNET_API_ERROR_UNIMPLEMENTED;
3933 REPLY_MACRO (VL_API_SR_MULTICAST_MAP_ADD_DEL_REPLY);
3937 #define foreach_classify_add_del_table_field \
3942 _(match_n_vectors) \
3943 _(next_table_index) \
3946 static void vl_api_classify_add_del_table_t_handler
3947 (vl_api_classify_add_del_table_t * mp)
3949 vl_api_classify_add_del_table_reply_t *rmp;
3950 vnet_classify_main_t *cm = &vnet_classify_main;
3951 vnet_classify_table_t *t;
3955 foreach_classify_add_del_table_field;
3958 #define _(a) a = ntohl(mp->a);
3959 foreach_classify_add_del_table_field;
3962 /* The underlying API fails silently, on purpose, so check here */
3963 if (mp->is_add == 0)
3964 if (pool_is_free_index (cm->tables, table_index))
3966 rv = VNET_API_ERROR_NO_SUCH_TABLE;
3970 rv = vnet_classify_add_del_table
3971 (cm, mp->mask, nbuckets, memory_size,
3972 skip_n_vectors, match_n_vectors,
3973 next_table_index, miss_next_index, &table_index, mp->is_add);
3977 REPLY_MACRO2(VL_API_CLASSIFY_ADD_DEL_TABLE_REPLY,
3979 if (rv == 0 && mp->is_add)
3981 t = pool_elt_at_index (cm->tables, table_index);
3982 rmp->skip_n_vectors = ntohl(t->skip_n_vectors);
3983 rmp->match_n_vectors = ntohl(t->match_n_vectors);
3984 rmp->new_table_index = ntohl(table_index);
3988 rmp->skip_n_vectors = ~0;
3989 rmp->match_n_vectors = ~0;
3990 rmp->new_table_index = ~0;
3996 static void vl_api_classify_add_del_session_t_handler
3997 (vl_api_classify_add_del_session_t * mp)
3999 vnet_classify_main_t *cm = &vnet_classify_main;
4000 vl_api_classify_add_del_session_reply_t *rmp;
4002 u32 table_index, hit_next_index, opaque_index;
4005 table_index = ntohl (mp->table_index);
4006 hit_next_index = ntohl (mp->hit_next_index);
4007 opaque_index = ntohl (mp->opaque_index);
4008 advance = ntohl (mp->advance);
4010 rv = vnet_classify_add_del_session
4011 (cm, table_index, mp->match, hit_next_index, opaque_index,
4012 advance, mp->is_add);
4014 REPLY_MACRO (VL_API_CLASSIFY_ADD_DEL_SESSION_REPLY);
4017 static void vl_api_classify_set_interface_ip_table_t_handler
4018 (vl_api_classify_set_interface_ip_table_t * mp)
4020 vlib_main_t *vm = vlib_get_main ();
4021 vl_api_classify_set_interface_ip_table_reply_t *rmp;
4023 u32 table_index, sw_if_index;
4025 table_index = ntohl (mp->table_index);
4026 sw_if_index = ntohl (mp->sw_if_index);
4028 VALIDATE_SW_IF_INDEX (mp);
4031 rv = vnet_set_ip6_classify_intfc (vm, sw_if_index, table_index);
4033 rv = vnet_set_ip4_classify_intfc (vm, sw_if_index, table_index);
4035 BAD_SW_IF_INDEX_LABEL;
4037 REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY);
4040 static void vl_api_classify_set_interface_l2_tables_t_handler
4041 (vl_api_classify_set_interface_l2_tables_t * mp)
4043 vl_api_classify_set_interface_l2_tables_reply_t *rmp;
4045 u32 sw_if_index, ip4_table_index, ip6_table_index, other_table_index;
4048 ip4_table_index = ntohl (mp->ip4_table_index);
4049 ip6_table_index = ntohl (mp->ip6_table_index);
4050 other_table_index = ntohl (mp->other_table_index);
4051 sw_if_index = ntohl (mp->sw_if_index);
4053 VALIDATE_SW_IF_INDEX (mp);
4056 rv = vnet_l2_input_classify_set_tables (sw_if_index, ip4_table_index,
4060 rv = vnet_l2_output_classify_set_tables (sw_if_index, ip4_table_index,
4066 if (ip4_table_index != ~0 || ip6_table_index != ~0
4067 || other_table_index != ~0)
4073 vnet_l2_input_classify_enable_disable (sw_if_index, enable);
4075 vnet_l2_output_classify_enable_disable (sw_if_index, enable);
4078 BAD_SW_IF_INDEX_LABEL;
4080 REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY);
4084 vl_api_l2_fib_clear_table_t_handler (vl_api_l2_fib_clear_table_t * mp)
4087 vl_api_l2_fib_clear_table_reply_t *rmp;
4089 /* DAW-FIXME: This API should only clear non-static l2fib entries, but
4090 * that is not currently implemented. When that TODO is fixed
4091 * this call should be changed to pass 1 instead of 0.
4093 l2fib_clear_table (0);
4095 REPLY_MACRO (VL_API_L2_FIB_CLEAR_TABLE_REPLY);
4098 extern void l2_efp_filter_configure (vnet_main_t * vnet_main,
4099 u32 sw_if_index, u32 enable);
4102 vl_api_l2_interface_efp_filter_t_handler (vl_api_l2_interface_efp_filter_t *
4106 vl_api_l2_interface_efp_filter_reply_t *rmp;
4107 vnet_main_t *vnm = vnet_get_main ();
4109 // enable/disable the feature
4110 l2_efp_filter_configure (vnm, mp->sw_if_index, mp->enable_disable);
4111 rv = vnm->api_errno;
4113 REPLY_MACRO (VL_API_L2_INTERFACE_EFP_FILTER_REPLY);
4117 vl_api_l2_interface_vlan_tag_rewrite_t_handler
4118 (vl_api_l2_interface_vlan_tag_rewrite_t * mp)
4121 vl_api_l2_interface_vlan_tag_rewrite_reply_t *rmp;
4122 vnet_main_t *vnm = vnet_get_main ();
4123 vlib_main_t *vm = vlib_get_main ();
4126 VALIDATE_SW_IF_INDEX (mp);
4128 vtr_op = ntohl (mp->vtr_op);
4130 /* The L2 code is unsuspicious */
4133 case L2_VTR_DISABLED:
4138 case L2_VTR_TRANSLATE_1_1:
4139 case L2_VTR_TRANSLATE_1_2:
4140 case L2_VTR_TRANSLATE_2_1:
4141 case L2_VTR_TRANSLATE_2_2:
4145 rv = VNET_API_ERROR_INVALID_VALUE;
4146 goto bad_sw_if_index;
4149 rv = l2vtr_configure (vm, vnm, ntohl (mp->sw_if_index), vtr_op,
4150 ntohl (mp->push_dot1q), ntohl (mp->tag1),
4153 BAD_SW_IF_INDEX_LABEL;
4155 REPLY_MACRO (VL_API_L2_INTERFACE_VLAN_TAG_REWRITE_REPLY);
4159 vl_api_create_vhost_user_if_t_handler (vl_api_create_vhost_user_if_t * mp)
4162 vl_api_create_vhost_user_if_reply_t *rmp;
4163 u32 sw_if_index = (u32) ~ 0;
4165 vnet_main_t *vnm = vnet_get_main ();
4166 vlib_main_t *vm = vlib_get_main ();
4168 #if DPDK > 0 && DPDK_VHOST_USER
4169 rv = dpdk_vhost_user_create_if (
4171 rv = vhost_user_create_if (
4173 vnm, vm, (char *) mp->sock_filename,
4174 mp->is_server, &sw_if_index, (u64) ~ 0,
4175 mp->renumber, ntohl (mp->custom_dev_instance),
4176 (mp->use_custom_mac) ? mp->mac_address : NULL);
4179 REPLY_MACRO2(VL_API_CREATE_VHOST_USER_IF_REPLY,
4181 rmp->sw_if_index = ntohl (sw_if_index);
4187 vl_api_modify_vhost_user_if_t_handler (vl_api_modify_vhost_user_if_t * mp)
4190 vl_api_modify_vhost_user_if_reply_t *rmp;
4191 u32 sw_if_index = ntohl (mp->sw_if_index);
4193 vnet_main_t *vnm = vnet_get_main ();
4194 vlib_main_t *vm = vlib_get_main ();
4196 #if DPDK > 0 && DPDK_VHOST_USER
4197 rv = dpdk_vhost_user_modify_if (
4199 rv = vhost_user_modify_if (
4201 vnm, vm, (char *) mp->sock_filename,
4202 mp->is_server, sw_if_index, (u64) ~ 0,
4203 mp->renumber, ntohl (mp->custom_dev_instance));
4204 REPLY_MACRO (VL_API_MODIFY_VHOST_USER_IF_REPLY);
4208 vl_api_delete_vhost_user_if_t_handler (vl_api_delete_vhost_user_if_t * mp)
4211 vl_api_delete_vhost_user_if_reply_t *rmp;
4212 vpe_api_main_t *vam = &vpe_api_main;
4213 u32 sw_if_index = ntohl (mp->sw_if_index);
4215 vnet_main_t *vnm = vnet_get_main ();
4216 vlib_main_t *vm = vlib_get_main ();
4218 #if DPDK > 0 && DPDK_VHOST_USER
4219 rv = dpdk_vhost_user_delete_if (vnm, vm, sw_if_index);
4221 rv = vhost_user_delete_if (vnm, vm, sw_if_index);
4224 REPLY_MACRO (VL_API_DELETE_VHOST_USER_IF_REPLY);
4227 unix_shared_memory_queue_t *q =
4228 vl_api_client_index_to_input_queue (mp->client_index);
4232 send_sw_interface_flags_deleted (vam, q, sw_if_index);
4237 vl_api_sw_interface_vhost_user_details_t_handler
4238 (vl_api_sw_interface_vhost_user_details_t * mp)
4240 clib_warning ("BUG");
4244 send_sw_interface_vhost_user_details (vpe_api_main_t * am,
4245 unix_shared_memory_queue_t * q,
4246 vhost_user_intf_details_t * vui,
4249 vl_api_sw_interface_vhost_user_details_t *mp;
4251 mp = vl_msg_api_alloc (sizeof (*mp));
4252 memset (mp, 0, sizeof (*mp));
4253 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_VHOST_USER_DETAILS);
4254 mp->sw_if_index = ntohl (vui->sw_if_index);
4255 mp->virtio_net_hdr_sz = ntohl (vui->virtio_net_hdr_sz);
4256 mp->features = clib_net_to_host_u64 (vui->features);
4257 mp->is_server = vui->is_server;
4258 mp->num_regions = ntohl (vui->num_regions);
4259 mp->sock_errno = ntohl (vui->sock_errno);
4260 mp->context = context;
4262 strncpy ((char *) mp->sock_filename,
4263 (char *) vui->sock_filename, ARRAY_LEN (mp->sock_filename) - 1);
4264 strncpy ((char *) mp->interface_name,
4265 (char *) vui->if_name, ARRAY_LEN (mp->interface_name) - 1);
4267 vl_msg_api_send_shmem (q, (u8 *) & mp);
4271 vl_api_sw_interface_vhost_user_dump_t_handler
4272 (vl_api_sw_interface_vhost_user_dump_t * mp)
4275 vpe_api_main_t *am = &vpe_api_main;
4276 vnet_main_t *vnm = vnet_get_main ();
4277 vlib_main_t *vm = vlib_get_main ();
4278 vhost_user_intf_details_t *ifaces = NULL;
4279 vhost_user_intf_details_t *vuid = NULL;
4280 unix_shared_memory_queue_t *q;
4282 q = vl_api_client_index_to_input_queue (mp->client_index);
4286 #if DPDK > 0 && DPDK_VHOST_USER
4287 rv = dpdk_vhost_user_dump_ifs (vnm, vm, &ifaces);
4289 rv = vhost_user_dump_ifs (vnm, vm, &ifaces);
4294 vec_foreach (vuid, ifaces)
4296 send_sw_interface_vhost_user_details (am, q, vuid, mp->context);
4302 send_sw_if_l2tpv3_tunnel_details (vpe_api_main_t * am,
4303 unix_shared_memory_queue_t * q,
4305 l2t_main_t * lm, u32 context)
4307 vl_api_sw_if_l2tpv3_tunnel_details_t *mp;
4309 vnet_sw_interface_t *si = NULL;
4311 si = vnet_get_hw_sw_interface (lm->vnet_main, s->hw_if_index);
4313 if_name = format (if_name, "%U",
4314 format_vnet_sw_interface_name, lm->vnet_main, si);
4316 mp = vl_msg_api_alloc (sizeof (*mp));
4317 memset (mp, 0, sizeof (*mp));
4318 mp->_vl_msg_id = ntohs (VL_API_SW_IF_L2TPV3_TUNNEL_DETAILS);
4319 strncpy ((char *) mp->interface_name,
4320 (char *) if_name, ARRAY_LEN (mp->interface_name) - 1);
4321 mp->sw_if_index = ntohl (si->sw_if_index);
4322 mp->local_session_id = s->local_session_id;
4323 mp->remote_session_id = s->remote_session_id;
4324 mp->local_cookie[0] = s->local_cookie[0];
4325 mp->local_cookie[1] = s->local_cookie[1];
4326 mp->remote_cookie = s->remote_cookie;
4327 clib_memcpy (mp->client_address, &s->client_address,
4328 sizeof (s->client_address));
4329 clib_memcpy (mp->our_address, &s->our_address, sizeof (s->our_address));
4330 mp->l2_sublayer_present = s->l2_sublayer_present;
4331 mp->context = context;
4333 vl_msg_api_send_shmem (q, (u8 *) & mp);
4337 send_ip_address_details (vpe_api_main_t * am,
4338 unix_shared_memory_queue_t * q,
4339 u8 * ip, u16 prefix_length, u8 is_ipv6, u32 context)
4341 vl_api_ip_address_details_t *mp;
4343 mp = vl_msg_api_alloc (sizeof (*mp));
4344 memset (mp, 0, sizeof (*mp));
4345 mp->_vl_msg_id = ntohs (VL_API_IP_ADDRESS_DETAILS);
4349 clib_memcpy (&mp->ip, ip, sizeof (mp->ip));
4353 u32 *tp = (u32 *) mp->ip;
4354 *tp = ntohl (*(u32 *) ip);
4356 mp->prefix_length = prefix_length;
4357 mp->context = context;
4359 vl_msg_api_send_shmem (q, (u8 *) & mp);
4363 vl_api_ip_address_dump_t_handler (vl_api_ip_address_dump_t * mp)
4365 vpe_api_main_t *am = &vpe_api_main;
4366 unix_shared_memory_queue_t *q;
4369 ip6_main_t *im6 = &ip6_main;
4370 ip4_main_t *im4 = &ip4_main;
4371 ip_lookup_main_t *lm6 = &im6->lookup_main;
4372 ip_lookup_main_t *lm4 = &im4->lookup_main;
4373 ip_interface_address_t *ia = 0;
4374 u32 sw_if_index = ~0;
4375 int rv __attribute__ ((unused)) = 0;
4377 VALIDATE_SW_IF_INDEX (mp);
4379 sw_if_index = ntohl (mp->sw_if_index);
4381 q = vl_api_client_index_to_input_queue (mp->client_index);
4390 foreach_ip_interface_address (lm6, ia, sw_if_index,
4391 1 /* honor unnumbered */,
4393 r6 = ip_interface_address_get_address (lm6, ia);
4394 u16 prefix_length = ia->address_length;
4395 send_ip_address_details(am, q, (u8*)r6, prefix_length, 1, mp->context);
4402 foreach_ip_interface_address (lm4, ia, sw_if_index,
4403 1 /* honor unnumbered */,
4405 r4 = ip_interface_address_get_address (lm4, ia);
4406 u16 prefix_length = ia->address_length;
4407 send_ip_address_details(am, q, (u8*)r4, prefix_length, 0, mp->context);
4411 BAD_SW_IF_INDEX_LABEL;
4415 send_ip_details (vpe_api_main_t * am,
4416 unix_shared_memory_queue_t * q, u32 sw_if_index, u32 context)
4418 vl_api_ip_details_t *mp;
4420 mp = vl_msg_api_alloc (sizeof (*mp));
4421 memset (mp, 0, sizeof (*mp));
4422 mp->_vl_msg_id = ntohs (VL_API_IP_DETAILS);
4424 mp->sw_if_index = ntohl (sw_if_index);
4425 mp->context = context;
4427 vl_msg_api_send_shmem (q, (u8 *) & mp);
4431 vl_api_sw_if_l2tpv3_tunnel_dump_t_handler (vl_api_sw_if_l2tpv3_tunnel_dump_t *
4434 vpe_api_main_t *am = &vpe_api_main;
4435 l2t_main_t *lm = &l2t_main;
4436 unix_shared_memory_queue_t *q;
4437 l2t_session_t *session;
4439 q = vl_api_client_index_to_input_queue (mp->client_index);
4444 pool_foreach (session, lm->sessions,
4446 send_sw_if_l2tpv3_tunnel_details (am, q, session, lm, mp->context);
4453 send_sw_interface_tap_details (vpe_api_main_t * am,
4454 unix_shared_memory_queue_t * q,
4455 tapcli_interface_details_t * tap_if,
4458 vl_api_sw_interface_tap_details_t *mp;
4459 mp = vl_msg_api_alloc (sizeof (*mp));
4460 memset (mp, 0, sizeof (*mp));
4461 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_TAP_DETAILS);
4462 mp->sw_if_index = ntohl (tap_if->sw_if_index);
4463 strncpy ((char *) mp->dev_name,
4464 (char *) tap_if->dev_name, ARRAY_LEN (mp->dev_name) - 1);
4465 mp->context = context;
4467 vl_msg_api_send_shmem (q, (u8 *) & mp);
4471 vl_api_sw_interface_tap_dump_t_handler (vl_api_sw_interface_tap_dump_t * mp)
4474 vpe_api_main_t *am = &vpe_api_main;
4475 unix_shared_memory_queue_t *q;
4476 tapcli_interface_details_t *tapifs = NULL;
4477 tapcli_interface_details_t *tap_if = NULL;
4479 q = vl_api_client_index_to_input_queue (mp->client_index);
4483 rv = vnet_tap_dump_ifs (&tapifs);
4487 vec_foreach (tap_if, tapifs)
4489 send_sw_interface_tap_details (am, q, tap_if, mp->context);
4496 vl_api_ip_dump_t_handler (vl_api_ip_dump_t * mp)
4498 vpe_api_main_t *am = &vpe_api_main;
4499 vnet_main_t *vnm = vnet_get_main ();
4500 vlib_main_t *vm = vlib_get_main ();
4501 vnet_interface_main_t *im = &vnm->interface_main;
4502 unix_shared_memory_queue_t *q;
4503 vnet_sw_interface_t *si, *sorted_sis;
4504 u32 sw_if_index = ~0;
4506 q = vl_api_client_index_to_input_queue (mp->client_index);
4512 /* Gather interfaces. */
4513 sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
4514 _vec_len (sorted_sis) = 0;
4516 pool_foreach (si, im->sw_interfaces,
4518 vec_add1 (sorted_sis, si[0]);
4522 vec_foreach (si, sorted_sis)
4524 if (!(si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
4526 if (mp->is_ipv6 && !ip6_interface_enabled (vm, si->sw_if_index))
4530 sw_if_index = si->sw_if_index;
4531 send_ip_details (am, q, sw_if_index, mp->context);
4537 vl_api_l2_fib_table_entry_t_handler (vl_api_l2_fib_table_entry_t * mp)
4539 clib_warning ("BUG");
4543 send_l2fib_table_entry (vpe_api_main_t * am,
4544 unix_shared_memory_queue_t * q,
4545 l2fib_entry_key_t * l2fe_key,
4546 l2fib_entry_result_t * l2fe_res, u32 context)
4548 vl_api_l2_fib_table_entry_t *mp;
4550 mp = vl_msg_api_alloc (sizeof (*mp));
4551 memset (mp, 0, sizeof (*mp));
4552 mp->_vl_msg_id = ntohs (VL_API_L2_FIB_TABLE_ENTRY);
4555 ntohl (l2input_main.bd_configs[l2fe_key->fields.bd_index].bd_id);
4557 mp->mac = l2fib_make_key (l2fe_key->fields.mac, 0);
4558 mp->sw_if_index = ntohl (l2fe_res->fields.sw_if_index);
4559 mp->static_mac = l2fe_res->fields.static_mac;
4560 mp->filter_mac = l2fe_res->fields.filter;
4561 mp->bvi_mac = l2fe_res->fields.bvi;
4562 mp->context = context;
4564 vl_msg_api_send_shmem (q, (u8 *) & mp);
4568 vl_api_l2_fib_table_dump_t_handler (vl_api_l2_fib_table_dump_t * mp)
4570 vpe_api_main_t *am = &vpe_api_main;
4571 bd_main_t *bdm = &bd_main;
4572 l2fib_entry_key_t *l2fe_key = NULL;
4573 l2fib_entry_result_t *l2fe_res = NULL;
4574 u32 ni, bd_id = ntohl (mp->bd_id);
4576 unix_shared_memory_queue_t *q;
4579 q = vl_api_client_index_to_input_queue (mp->client_index);
4583 /* see l2fib_table_dump: ~0 means "any" */
4588 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
4595 l2fib_table_dump (bd_index, &l2fe_key, &l2fe_res);
4597 vec_foreach_index (ni, l2fe_key)
4599 send_l2fib_table_entry (am, q, vec_elt_at_index (l2fe_key, ni),
4600 vec_elt_at_index (l2fe_res, ni), mp->context);
4602 vec_free (l2fe_key);
4603 vec_free (l2fe_res);
4607 vl_api_show_version_t_handler (vl_api_show_version_t * mp)
4609 vl_api_show_version_reply_t *rmp;
4611 char *vpe_api_get_build_directory (void);
4612 char *vpe_api_get_version (void);
4613 char *vpe_api_get_build_date (void);
4615 unix_shared_memory_queue_t *q =
4616 vl_api_client_index_to_input_queue (mp->client_index);
4622 REPLY_MACRO2(VL_API_SHOW_VERSION_REPLY,
4624 strncpy ((char *) rmp->program, "vpe", ARRAY_LEN(rmp->program)-1);
4625 strncpy ((char *) rmp->build_directory, vpe_api_get_build_directory(),
4626 ARRAY_LEN(rmp->build_directory)-1);
4627 strncpy ((char *) rmp->version, vpe_api_get_version(),
4628 ARRAY_LEN(rmp->version)-1);
4629 strncpy ((char *) rmp->build_date, vpe_api_get_build_date(),
4630 ARRAY_LEN(rmp->build_date)-1);
4636 vl_api_get_node_index_t_handler (vl_api_get_node_index_t * mp)
4638 vlib_main_t *vm = vlib_get_main ();
4639 vl_api_get_node_index_reply_t *rmp;
4642 u32 node_index = ~0;
4644 n = vlib_get_node_by_name (vm, mp->node_name);
4647 rv = VNET_API_ERROR_NO_SUCH_NODE;
4649 node_index = n->index;
4652 REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
4654 rmp->node_index = ntohl(node_index);
4660 vl_api_get_next_index_t_handler (vl_api_get_next_index_t * mp)
4662 vlib_main_t *vm = vlib_get_main ();
4663 vl_api_get_next_index_reply_t *rmp;
4664 vlib_node_t *node, *next_node;
4666 u32 next_node_index = ~0, next_index = ~0;
4669 node = vlib_get_node_by_name (vm, mp->node_name);
4673 rv = VNET_API_ERROR_NO_SUCH_NODE;
4677 next_node = vlib_get_node_by_name (vm, mp->next_name);
4681 rv = VNET_API_ERROR_NO_SUCH_NODE2;
4685 next_node_index = next_node->index;
4687 p = hash_get (node->next_slot_by_node, next_node_index);
4691 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
4699 REPLY_MACRO2(VL_API_GET_NEXT_INDEX_REPLY,
4701 rmp->next_index = ntohl(next_index);
4707 vl_api_add_node_next_t_handler (vl_api_add_node_next_t * mp)
4709 vlib_main_t *vm = vlib_get_main ();
4710 vl_api_add_node_next_reply_t *rmp;
4711 vlib_node_t *n, *next;
4713 u32 next_index = ~0;
4715 n = vlib_get_node_by_name (vm, mp->node_name);
4719 rv = VNET_API_ERROR_NO_SUCH_NODE;
4723 next = vlib_get_node_by_name (vm, mp->next_name);
4726 rv = VNET_API_ERROR_NO_SUCH_NODE2;
4728 next_index = vlib_node_add_next (vm, n->index, next->index);
4732 REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
4734 rmp->next_index = ntohl(next_index);
4739 static void vl_api_l2tpv3_create_tunnel_t_handler
4740 (vl_api_l2tpv3_create_tunnel_t * mp)
4742 vl_api_l2tpv3_create_tunnel_reply_t *rmp;
4743 l2t_main_t *lm = &l2t_main;
4744 u32 sw_if_index = (u32) ~ 0;
4747 if (mp->is_ipv6 != 1)
4749 rv = VNET_API_ERROR_UNIMPLEMENTED;
4753 u32 encap_fib_index;
4755 if (mp->encap_vrf_id != ~0)
4758 ip6_main_t *im = &ip6_main;
4761 hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id))))
4763 rv = VNET_API_ERROR_NO_SUCH_FIB;
4766 encap_fib_index = p[0];
4770 encap_fib_index = ~0;
4773 rv = create_l2tpv3_ipv6_tunnel (lm,
4774 (ip6_address_t *) mp->client_address,
4775 (ip6_address_t *) mp->our_address,
4776 ntohl (mp->local_session_id),
4777 ntohl (mp->remote_session_id),
4778 clib_net_to_host_u64 (mp->local_cookie),
4779 clib_net_to_host_u64 (mp->remote_cookie),
4780 mp->l2_sublayer_present,
4781 encap_fib_index, &sw_if_index);
4785 REPLY_MACRO2(VL_API_L2TPV3_CREATE_TUNNEL_REPLY,
4787 rmp->sw_if_index = ntohl (sw_if_index);
4792 static void vl_api_l2tpv3_set_tunnel_cookies_t_handler
4793 (vl_api_l2tpv3_set_tunnel_cookies_t * mp)
4795 vl_api_l2tpv3_set_tunnel_cookies_reply_t *rmp;
4796 l2t_main_t *lm = &l2t_main;
4799 VALIDATE_SW_IF_INDEX (mp);
4801 rv = l2tpv3_set_tunnel_cookies (lm, ntohl (mp->sw_if_index),
4802 clib_net_to_host_u64 (mp->new_local_cookie),
4803 clib_net_to_host_u64
4804 (mp->new_remote_cookie));
4806 BAD_SW_IF_INDEX_LABEL;
4808 REPLY_MACRO (VL_API_L2TPV3_SET_TUNNEL_COOKIES_REPLY);
4811 static void vl_api_l2tpv3_interface_enable_disable_t_handler
4812 (vl_api_l2tpv3_interface_enable_disable_t * mp)
4815 vnet_main_t *vnm = vnet_get_main ();
4816 vl_api_l2tpv3_interface_enable_disable_reply_t *rmp;
4818 VALIDATE_SW_IF_INDEX (mp);
4820 rv = l2tpv3_interface_enable_disable
4821 (vnm, ntohl (mp->sw_if_index), mp->enable_disable);
4823 BAD_SW_IF_INDEX_LABEL;
4825 REPLY_MACRO (VL_API_L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY);
4828 static void vl_api_l2tpv3_set_lookup_key_t_handler
4829 (vl_api_l2tpv3_set_lookup_key_t * mp)
4832 l2t_main_t *lm = &l2t_main;
4833 vl_api_l2tpv3_set_lookup_key_reply_t *rmp;
4835 if (mp->key > L2T_LOOKUP_SESSION_ID)
4837 rv = VNET_API_ERROR_INVALID_VALUE;
4841 lm->lookup_type = mp->key;
4844 REPLY_MACRO (VL_API_L2TPV3_SET_LOOKUP_KEY_REPLY);
4847 static void vl_api_vxlan_add_del_tunnel_t_handler
4848 (vl_api_vxlan_add_del_tunnel_t * mp)
4850 vl_api_vxlan_add_del_tunnel_reply_t *rmp;
4852 vnet_vxlan_add_del_tunnel_args_t _a, *a = &_a;
4853 u32 encap_fib_index;
4855 ip4_main_t *im = &ip4_main;
4856 u32 sw_if_index = ~0;
4858 p = hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id));
4861 rv = VNET_API_ERROR_NO_SUCH_FIB;
4864 encap_fib_index = p[0];
4866 /* Check src & dst are different */
4867 if ((mp->is_ipv6 && memcmp (mp->src_address, mp->dst_address, 16) == 0) ||
4868 (!mp->is_ipv6 && memcmp (mp->src_address, mp->dst_address, 4) == 0))
4870 rv = VNET_API_ERROR_SAME_SRC_DST;
4873 memset (a, 0, sizeof (*a));
4875 a->is_add = mp->is_add;
4876 a->is_ip6 = mp->is_ipv6;
4878 /* ip addresses sent in network byte order */
4881 memcpy (&(a->src.ip6), mp->src_address, 16);
4882 memcpy (&(a->dst.ip6), mp->dst_address, 16);
4886 memcpy (&(a->src.ip4), mp->src_address, 4);
4887 memcpy (&(a->dst.ip4), mp->dst_address, 4);
4890 a->encap_fib_index = encap_fib_index;
4891 a->decap_next_index = ntohl (mp->decap_next_index);
4892 a->vni = ntohl (mp->vni);
4893 rv = vnet_vxlan_add_del_tunnel (a, &sw_if_index);
4897 REPLY_MACRO2(VL_API_VXLAN_ADD_DEL_TUNNEL_REPLY,
4899 rmp->sw_if_index = ntohl (sw_if_index);
4904 static void send_vxlan_tunnel_details
4905 (vxlan_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
4907 vl_api_vxlan_tunnel_details_t *rmp;
4908 ip4_main_t *im4 = &ip4_main;
4909 ip6_main_t *im6 = &ip6_main;
4910 u8 is_ipv6 = !(t->flags & VXLAN_TUNNEL_IS_IPV4);
4912 rmp = vl_msg_api_alloc (sizeof (*rmp));
4913 memset (rmp, 0, sizeof (*rmp));
4914 rmp->_vl_msg_id = ntohs (VL_API_VXLAN_TUNNEL_DETAILS);
4917 memcpy (rmp->src_address, &(t->src.ip6), 16);
4918 memcpy (rmp->dst_address, &(t->dst.ip6), 16);
4919 rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].table_id);
4923 memcpy (rmp->src_address, &(t->src.ip4), 4);
4924 memcpy (rmp->dst_address, &(t->dst.ip4), 4);
4925 rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].table_id);
4927 rmp->vni = htonl (t->vni);
4928 rmp->decap_next_index = htonl (t->decap_next_index);
4929 rmp->sw_if_index = htonl (t->sw_if_index);
4930 rmp->is_ipv6 = is_ipv6;
4931 rmp->context = context;
4933 vl_msg_api_send_shmem (q, (u8 *) & rmp);
4936 static void vl_api_vxlan_tunnel_dump_t_handler
4937 (vl_api_vxlan_tunnel_dump_t * mp)
4939 unix_shared_memory_queue_t *q;
4940 vxlan_main_t *vxm = &vxlan_main;
4944 q = vl_api_client_index_to_input_queue (mp->client_index);
4950 sw_if_index = ntohl (mp->sw_if_index);
4952 if (~0 == sw_if_index)
4955 pool_foreach (t, vxm->tunnels,
4957 send_vxlan_tunnel_details(t, q, mp->context);
4963 if ((sw_if_index >= vec_len (vxm->tunnel_index_by_sw_if_index)) ||
4964 (~0 == vxm->tunnel_index_by_sw_if_index[sw_if_index]))
4968 t = &vxm->tunnels[vxm->tunnel_index_by_sw_if_index[sw_if_index]];
4969 send_vxlan_tunnel_details (t, q, mp->context);
4973 static void vl_api_gre_add_del_tunnel_t_handler
4974 (vl_api_gre_add_del_tunnel_t * mp)
4976 vl_api_gre_add_del_tunnel_reply_t *rmp;
4978 vnet_gre_add_del_tunnel_args_t _a, *a = &_a;
4981 ip4_main_t *im = &ip4_main;
4982 u32 sw_if_index = ~0;
4984 p = hash_get (im->fib_index_by_table_id, ntohl (mp->outer_fib_id));
4987 rv = VNET_API_ERROR_NO_SUCH_FIB;
4990 outer_fib_id = p[0];
4992 /* Check src & dst are different */
4993 if ((mp->is_ipv6 && memcmp (mp->src_address, mp->dst_address, 16) == 0) ||
4994 (!mp->is_ipv6 && memcmp (mp->src_address, mp->dst_address, 4) == 0))
4996 rv = VNET_API_ERROR_SAME_SRC_DST;
4999 memset (a, 0, sizeof (*a));
5001 a->is_add = mp->is_add;
5003 /* ip addresses sent in network byte order */
5004 clib_memcpy (&(a->src), mp->src_address, 4);
5005 clib_memcpy (&(a->dst), mp->dst_address, 4);
5007 a->outer_fib_id = outer_fib_id;
5008 rv = vnet_gre_add_del_tunnel (a, &sw_if_index);
5012 REPLY_MACRO2(VL_API_GRE_ADD_DEL_TUNNEL_REPLY,
5014 rmp->sw_if_index = ntohl (sw_if_index);
5019 static void send_gre_tunnel_details
5020 (gre_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
5022 vl_api_gre_tunnel_details_t *rmp;
5023 ip4_main_t *im = &ip4_main;
5025 rmp = vl_msg_api_alloc (sizeof (*rmp));
5026 memset (rmp, 0, sizeof (*rmp));
5027 rmp->_vl_msg_id = ntohs (VL_API_GRE_TUNNEL_DETAILS);
5028 clib_memcpy (rmp->src_address, &(t->tunnel_src), 4);
5029 clib_memcpy (rmp->dst_address, &(t->tunnel_dst), 4);
5030 rmp->outer_fib_id = htonl (im->fibs[t->outer_fib_index].table_id);
5031 rmp->sw_if_index = htonl (t->sw_if_index);
5032 rmp->context = context;
5034 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5038 vl_api_gre_tunnel_dump_t_handler (vl_api_gre_tunnel_dump_t * mp)
5040 unix_shared_memory_queue_t *q;
5041 gre_main_t *gm = &gre_main;
5045 q = vl_api_client_index_to_input_queue (mp->client_index);
5051 sw_if_index = ntohl (mp->sw_if_index);
5053 if (~0 == sw_if_index)
5056 pool_foreach (t, gm->tunnels,
5058 send_gre_tunnel_details(t, q, mp->context);
5064 if ((sw_if_index >= vec_len (gm->tunnel_index_by_sw_if_index)) ||
5065 (~0 == gm->tunnel_index_by_sw_if_index[sw_if_index]))
5069 t = &gm->tunnels[gm->tunnel_index_by_sw_if_index[sw_if_index]];
5070 send_gre_tunnel_details (t, q, mp->context);
5075 vl_api_l2_patch_add_del_t_handler (vl_api_l2_patch_add_del_t * mp)
5077 extern int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
5079 vl_api_l2_patch_add_del_reply_t *rmp;
5080 int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
5084 VALIDATE_RX_SW_IF_INDEX (mp);
5085 VALIDATE_TX_SW_IF_INDEX (mp);
5087 rv = vnet_l2_patch_add_del (ntohl (mp->rx_sw_if_index),
5088 ntohl (mp->tx_sw_if_index),
5089 (int) (mp->is_add != 0));
5091 BAD_RX_SW_IF_INDEX_LABEL;
5092 BAD_TX_SW_IF_INDEX_LABEL;
5094 REPLY_MACRO (VL_API_L2_PATCH_ADD_DEL_REPLY);
5098 vl_api_vxlan_gpe_add_del_tunnel_t_handler
5099 (vl_api_vxlan_gpe_add_del_tunnel_t * mp)
5101 vl_api_vxlan_gpe_add_del_tunnel_reply_t *rmp;
5103 vnet_vxlan_gpe_add_del_tunnel_args_t _a, *a = &_a;
5104 u32 encap_fib_index, decap_fib_index;
5107 ip4_main_t *im = &ip4_main;
5108 u32 sw_if_index = ~0;
5111 p = hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id));
5114 rv = VNET_API_ERROR_NO_SUCH_FIB;
5117 encap_fib_index = p[0];
5119 protocol = mp->protocol;
5121 /* Interpret decap_vrf_id as an opaque if sending to other-than-ip4-input */
5122 if (protocol == VXLAN_GPE_INPUT_NEXT_IP4_INPUT)
5124 p = hash_get (im->fib_index_by_table_id, ntohl (mp->decap_vrf_id));
5127 rv = VNET_API_ERROR_NO_SUCH_INNER_FIB;
5130 decap_fib_index = p[0];
5134 decap_fib_index = ntohl (mp->decap_vrf_id);
5137 /* Check src & dst are different */
5138 if ((mp->is_ipv6 && memcmp (mp->local, mp->remote, 16) == 0) ||
5139 (!mp->is_ipv6 && memcmp (mp->local, mp->remote, 4) == 0))
5141 rv = VNET_API_ERROR_SAME_SRC_DST;
5144 memset (a, 0, sizeof (*a));
5146 a->is_add = mp->is_add;
5147 a->is_ip6 = mp->is_ipv6;
5148 /* ip addresses sent in network byte order */
5151 clib_memcpy (&(a->local.ip6), mp->local, 16);
5152 clib_memcpy (&(a->remote.ip6), mp->remote, 16);
5156 clib_memcpy (&(a->local.ip4), mp->local, 4);
5157 clib_memcpy (&(a->remote.ip4), mp->remote, 4);
5159 a->encap_fib_index = encap_fib_index;
5160 a->decap_fib_index = decap_fib_index;
5161 a->protocol = protocol;
5162 a->vni = ntohl (mp->vni);
5163 rv = vnet_vxlan_gpe_add_del_tunnel (a, &sw_if_index);
5167 REPLY_MACRO2(VL_API_VXLAN_GPE_ADD_DEL_TUNNEL_REPLY,
5169 rmp->sw_if_index = ntohl (sw_if_index);
5174 static void send_vxlan_gpe_tunnel_details
5175 (vxlan_gpe_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
5177 vl_api_vxlan_gpe_tunnel_details_t *rmp;
5178 ip4_main_t *im4 = &ip4_main;
5179 ip6_main_t *im6 = &ip6_main;
5180 u8 is_ipv6 = !(t->flags & VXLAN_GPE_TUNNEL_IS_IPV4);
5182 rmp = vl_msg_api_alloc (sizeof (*rmp));
5183 memset (rmp, 0, sizeof (*rmp));
5184 rmp->_vl_msg_id = ntohs (VL_API_VXLAN_GPE_TUNNEL_DETAILS);
5187 memcpy (rmp->local, &(t->local.ip6), 16);
5188 memcpy (rmp->remote, &(t->remote.ip6), 16);
5189 rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].table_id);
5190 rmp->decap_vrf_id = htonl (im6->fibs[t->decap_fib_index].table_id);
5194 memcpy (rmp->local, &(t->local.ip4), 4);
5195 memcpy (rmp->remote, &(t->remote.ip4), 4);
5196 rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].table_id);
5197 rmp->decap_vrf_id = htonl (im4->fibs[t->decap_fib_index].table_id);
5199 rmp->vni = htonl (t->vni);
5200 rmp->protocol = t->protocol;
5201 rmp->sw_if_index = htonl (t->sw_if_index);
5202 rmp->is_ipv6 = is_ipv6;
5203 rmp->context = context;
5205 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5208 static void vl_api_vxlan_gpe_tunnel_dump_t_handler
5209 (vl_api_vxlan_gpe_tunnel_dump_t * mp)
5211 unix_shared_memory_queue_t *q;
5212 vxlan_gpe_main_t *vgm = &vxlan_gpe_main;
5213 vxlan_gpe_tunnel_t *t;
5216 q = vl_api_client_index_to_input_queue (mp->client_index);
5222 sw_if_index = ntohl (mp->sw_if_index);
5224 if (~0 == sw_if_index)
5227 pool_foreach (t, vgm->tunnels,
5229 send_vxlan_gpe_tunnel_details(t, q, mp->context);
5235 if ((sw_if_index >= vec_len (vgm->tunnel_index_by_sw_if_index)) ||
5236 (~0 == vgm->tunnel_index_by_sw_if_index[sw_if_index]))
5240 t = &vgm->tunnels[vgm->tunnel_index_by_sw_if_index[sw_if_index]];
5241 send_vxlan_gpe_tunnel_details (t, q, mp->context);
5245 /** Used for transferring locators via VPP API */
5247 typedef CLIB_PACKED (struct {
5248 u32 sw_if_index; /**< locator sw_if_index */
5249 u8 priority; /**< locator priority */
5250 u8 weight; /**< locator weight */
5255 vl_api_lisp_add_del_locator_set_t_handler (vl_api_lisp_add_del_locator_set_t *
5258 vl_api_lisp_add_del_locator_set_reply_t *rmp;
5260 vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
5262 ls_locator_t *ls_loc;
5263 u32 ls_index = ~0, locator_num;
5264 u8 *locator_name = NULL;
5267 memset (a, 0, sizeof (a[0]));
5269 locator_name = format (0, "%s", mp->locator_set_name);
5271 a->name = locator_name;
5272 a->is_add = mp->is_add;
5274 locator_num = clib_net_to_host_u32 (mp->locator_num);
5276 memset (&locator, 0, sizeof (locator));
5277 for (i = 0; i < locator_num; i++)
5279 ls_loc = &((ls_locator_t *) mp->locators)[i];
5280 VALIDATE_SW_IF_INDEX (ls_loc);
5282 locator.sw_if_index = htonl (ls_loc->sw_if_index);
5283 locator.priority = ls_loc->priority;
5284 locator.weight = ls_loc->weight;
5286 vec_add1 (a->locators, locator);
5289 rv = vnet_lisp_add_del_locator_set (a, &ls_index);
5291 BAD_SW_IF_INDEX_LABEL;
5293 vec_free (locator_name);
5294 vec_free (a->locators);
5297 REPLY_MACRO2 (VL_API_LISP_ADD_DEL_LOCATOR_SET_REPLY,
5299 rmp->ls_index = clib_host_to_net_u32 (ls_index);
5305 vl_api_lisp_add_del_locator_t_handler (vl_api_lisp_add_del_locator_t * mp)
5307 vl_api_lisp_add_del_locator_reply_t *rmp;
5309 locator_t locator, *locators = NULL;
5310 vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
5312 u8 *locator_name = NULL;
5314 memset (&locator, 0, sizeof (locator));
5315 memset (a, 0, sizeof (a[0]));
5317 locator.sw_if_index = ntohl (mp->sw_if_index);
5318 locator.priority = mp->priority;
5319 locator.weight = mp->weight;
5321 vec_add1 (locators, locator);
5323 locator_name = format (0, "%s", mp->locator_set_name);
5325 a->name = locator_name;
5326 a->locators = locators;
5327 a->is_add = mp->is_add;
5330 rv = vnet_lisp_add_del_locator (a, NULL, &ls_index);
5332 vec_free (locators);
5333 vec_free (locator_name);
5335 REPLY_MACRO (VL_API_LISP_ADD_DEL_LOCATOR_REPLY);
5339 unformat_lisp_eid_api (gid_address_t * dst, u32 vni, u8 type, void *src,
5345 gid_address_type (dst) = GID_ADDR_IP_PREFIX;
5346 gid_address_ip_set (dst, src, IP4);
5347 gid_address_ippref_len (dst) = len;
5348 ip_prefix_normalize (&gid_address_ippref (dst));
5351 gid_address_type (dst) = GID_ADDR_IP_PREFIX;
5352 gid_address_ip_set (dst, src, IP6);
5353 gid_address_ippref_len (dst) = len;
5354 ip_prefix_normalize (&gid_address_ippref (dst));
5356 case 2: /* l2 mac */
5357 gid_address_type (dst) = GID_ADDR_MAC;
5358 clib_memcpy (&gid_address_mac (dst), src, 6);
5362 return VNET_API_ERROR_INVALID_VALUE;
5365 gid_address_vni (dst) = vni;
5371 vl_api_lisp_add_del_local_eid_t_handler (vl_api_lisp_add_del_local_eid_t * mp)
5373 vl_api_lisp_add_del_local_eid_reply_t *rmp;
5374 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
5376 gid_address_t _eid, *eid = &_eid;
5378 u32 locator_set_index = ~0, map_index = ~0;
5379 vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
5381 memset (a, 0, sizeof (a[0]));
5382 memset (eid, 0, sizeof (eid[0]));
5384 rv = unformat_lisp_eid_api (eid, clib_net_to_host_u32 (mp->vni),
5385 mp->eid_type, mp->eid, mp->prefix_len);
5389 name = format (0, "%s", mp->locator_set_name);
5390 p = hash_get_mem (lcm->locator_set_index_by_name, name);
5393 rv = VNET_API_ERROR_INVALID_VALUE;
5396 locator_set_index = p[0];
5398 /* XXX treat batch configuration */
5399 a->is_add = mp->is_add;
5400 gid_address_copy (&a->eid, eid);
5401 a->locator_set_index = locator_set_index;
5403 rv = vnet_lisp_add_del_local_mapping (a, &map_index);
5407 gid_address_free (&a->eid);
5409 REPLY_MACRO (VL_API_LISP_ADD_DEL_LOCAL_EID_REPLY);
5413 vl_api_lisp_eid_table_add_del_map_t_handler
5414 (vl_api_lisp_eid_table_add_del_map_t * mp)
5416 vl_api_lisp_eid_table_add_del_map_reply_t *rmp;
5418 rv = vnet_lisp_eid_table_map (clib_net_to_host_u32 (mp->vni),
5419 clib_net_to_host_u32 (mp->dp_table),
5420 mp->is_l2, mp->is_add);
5421 REPLY_MACRO (VL_API_LISP_EID_TABLE_ADD_DEL_MAP_REPLY)}
5423 /** Used for transferring locators via VPP API */
5425 typedef CLIB_PACKED (struct {
5426 u8 is_ip4; /**< is locator an IPv4 address */
5427 u8 priority; /**< locator priority */
5428 u8 weight; /**< locator weight */
5429 u8 addr[16]; /**< IPv4/IPv6 address */
5433 static locator_pair_t *
5434 unformat_lisp_loc_pairs (void *lcl_locs, void *rmt_locs, u32 rloc_num)
5437 locator_pair_t *pairs = 0, pair;
5440 for (i = 0; i < rloc_num; i++)
5443 r = &((rloc_t *) lcl_locs)[i];
5444 memset (&pair.lcl_loc, 0, sizeof (pair.lcl_loc));
5445 ip_address_set (&pair.lcl_loc, &r->addr, r->is_ip4 ? IP4 : IP6);
5447 /* remote locators */
5448 r = &((rloc_t *) rmt_locs)[i];
5449 memset (&pair.rmt_loc, 0, sizeof (pair.rmt_loc));
5450 ip_address_set (&pair.rmt_loc, &r->addr, r->is_ip4 ? IP4 : IP6);
5452 pair.priority = r->priority;
5453 pair.weight = r->weight;
5455 vec_add1 (pairs, pair);
5461 unformat_lisp_locs (void *rmt_locs, u32 rloc_num)
5464 locator_t *locs = 0, loc;
5467 for (i = 0; i < rloc_num; i++)
5469 /* remote locators */
5470 r = &((rloc_t *) rmt_locs)[i];
5471 memset (&loc, 0, sizeof (loc));
5472 gid_address_ip_set (&loc.address, &r->addr, r->is_ip4 ? IP4 : IP6);
5474 loc.priority = r->priority;
5475 loc.weight = r->weight;
5477 vec_add1 (locs, loc);
5483 vl_api_lisp_gpe_add_del_fwd_entry_t_handler
5484 (vl_api_lisp_gpe_add_del_fwd_entry_t * mp)
5486 vl_api_lisp_gpe_add_del_fwd_entry_reply_t *rmp;
5487 vnet_lisp_gpe_add_del_fwd_entry_args_t _a, *a = &_a;
5488 locator_pair_t *pairs = 0;
5491 memset (a, 0, sizeof (a[0]));
5493 rv = unformat_lisp_eid_api (&a->rmt_eid, mp->vni, mp->eid_type,
5494 mp->rmt_eid, mp->rmt_len);
5495 rv |= unformat_lisp_eid_api (&a->lcl_eid, mp->vni, mp->eid_type,
5496 mp->lcl_eid, mp->lcl_len);
5498 pairs = unformat_lisp_loc_pairs (mp->lcl_locs, mp->rmt_locs, mp->loc_num);
5500 if (rv || 0 == pairs)
5503 a->is_add = mp->is_add;
5504 a->locator_pairs = pairs;
5505 a->dp_table = mp->dp_table;
5507 a->action = mp->action;
5509 rv = vnet_lisp_gpe_add_del_fwd_entry (a, 0);
5512 REPLY_MACRO (VL_API_LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY);
5516 vl_api_lisp_add_del_map_resolver_t_handler (vl_api_lisp_add_del_map_resolver_t
5519 vl_api_lisp_add_del_map_resolver_reply_t *rmp;
5521 vnet_lisp_add_del_map_resolver_args_t _a, *a = &_a;
5523 memset (a, 0, sizeof (a[0]));
5525 a->is_add = mp->is_add;
5526 ip_address_set (&a->address, mp->ip_address, mp->is_ipv6 ? IP6 : IP4);
5528 rv = vnet_lisp_add_del_map_resolver (a);
5530 REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_RESOLVER_REPLY);
5534 vl_api_lisp_gpe_enable_disable_t_handler (vl_api_lisp_gpe_enable_disable_t *
5537 vl_api_lisp_gpe_enable_disable_reply_t *rmp;
5539 vnet_lisp_gpe_enable_disable_args_t _a, *a = &_a;
5541 a->is_en = mp->is_en;
5542 vnet_lisp_gpe_enable_disable (a);
5544 REPLY_MACRO (VL_API_LISP_GPE_ENABLE_DISABLE_REPLY);
5548 vl_api_lisp_enable_disable_t_handler (vl_api_lisp_enable_disable_t * mp)
5550 vl_api_lisp_enable_disable_reply_t *rmp;
5553 vnet_lisp_enable_disable (mp->is_en);
5554 REPLY_MACRO (VL_API_LISP_ENABLE_DISABLE_REPLY);
5558 vl_api_lisp_gpe_add_del_iface_t_handler (vl_api_lisp_gpe_add_del_iface_t * mp)
5560 vl_api_lisp_gpe_add_del_iface_reply_t *rmp;
5562 vnet_lisp_gpe_add_del_iface_args_t _a, *a = &_a;
5564 a->is_add = mp->is_add;
5565 a->dp_table = mp->dp_table;
5567 a->is_l2 = mp->is_l2;
5568 rv = vnet_lisp_gpe_add_del_iface (a, 0);
5570 REPLY_MACRO (VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
5574 vl_api_lisp_pitr_set_locator_set_t_handler (vl_api_lisp_pitr_set_locator_set_t
5577 vl_api_lisp_pitr_set_locator_set_reply_t *rmp;
5581 ls_name = format (0, "%s", mp->ls_name);
5582 rv = vnet_lisp_pitr_set_locator_set (ls_name, mp->is_add);
5585 REPLY_MACRO (VL_API_LISP_PITR_SET_LOCATOR_SET_REPLY);
5589 vl_api_lisp_add_del_map_request_itr_rlocs_t_handler
5590 (vl_api_lisp_add_del_map_request_itr_rlocs_t * mp)
5592 vl_api_lisp_add_del_map_request_itr_rlocs_reply_t *rmp;
5594 u8 *locator_set_name = NULL;
5595 vnet_lisp_add_del_mreq_itr_rloc_args_t _a, *a = &_a;
5597 locator_set_name = format (0, "%s", mp->locator_set_name);
5599 a->is_add = mp->is_add;
5600 a->locator_set_name = locator_set_name;
5602 rv = vnet_lisp_add_del_mreq_itr_rlocs (a);
5604 vec_free (locator_set_name);
5606 REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY);
5610 vl_api_lisp_add_del_remote_mapping_t_handler
5611 (vl_api_lisp_add_del_remote_mapping_t * mp)
5613 locator_t *rlocs = 0;
5614 vl_api_lisp_add_del_remote_mapping_reply_t *rmp;
5616 gid_address_t _eid, *eid = &_eid;
5617 u32 rloc_num = clib_net_to_host_u32 (mp->rloc_num);
5619 memset (eid, 0, sizeof (eid[0]));
5621 rv = unformat_lisp_eid_api (eid, clib_net_to_host_u32 (mp->vni),
5622 mp->eid_type, mp->eid, mp->eid_len);
5626 rlocs = unformat_lisp_locs (mp->rlocs, rloc_num);
5630 vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
5631 gid_address_copy (&a->deid, eid);
5633 rv = vnet_lisp_add_del_adjacency (a);
5640 /* NOTE: for now this works as a static remote mapping, i.e.,
5641 * not authoritative and ttl infinite. */
5642 rv = vnet_lisp_add_del_mapping (eid, rlocs, mp->action, 0, ~0,
5643 mp->is_add, 1 /* is_static */ , 0);
5646 vnet_lisp_clear_all_remote_adjacencies ();
5651 REPLY_MACRO (VL_API_LISP_ADD_DEL_REMOTE_MAPPING_REPLY);
5655 vl_api_lisp_add_del_adjacency_t_handler (vl_api_lisp_add_del_adjacency_t * mp)
5657 vl_api_lisp_add_del_adjacency_reply_t *rmp;
5658 vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
5661 memset (a, 0, sizeof (a[0]));
5663 rv = unformat_lisp_eid_api (&a->seid, clib_net_to_host_u32 (mp->vni),
5664 mp->eid_type, mp->seid, mp->seid_len);
5665 rv |= unformat_lisp_eid_api (&a->deid, clib_net_to_host_u32 (mp->vni),
5666 mp->eid_type, mp->deid, mp->deid_len);
5671 a->is_add = mp->is_add;
5672 rv = vnet_lisp_add_del_adjacency (a);
5675 REPLY_MACRO (VL_API_LISP_ADD_DEL_ADJACENCY_REPLY);
5679 send_lisp_locator_details (lisp_cp_main_t * lcm,
5681 unix_shared_memory_queue_t * q, u32 context)
5683 vl_api_lisp_locator_details_t *rmp;
5685 rmp = vl_msg_api_alloc (sizeof (*rmp));
5686 memset (rmp, 0, sizeof (*rmp));
5687 rmp->_vl_msg_id = ntohs (VL_API_LISP_LOCATOR_DETAILS);
5688 rmp->context = context;
5690 rmp->local = loc->local;
5693 rmp->sw_if_index = ntohl (loc->sw_if_index);
5697 rmp->is_ipv6 = gid_address_ip_version (&loc->address);
5698 ip_address_copy_addr (rmp->ip_address, &gid_address_ip (&loc->address));
5700 rmp->priority = loc->priority;
5701 rmp->weight = loc->weight;
5703 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5707 vl_api_lisp_locator_dump_t_handler (vl_api_lisp_locator_dump_t * mp)
5709 unix_shared_memory_queue_t *q = 0;
5710 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
5711 locator_set_t *lsit = 0;
5713 u32 ls_index = ~0, *locit = 0;
5716 q = vl_api_client_index_to_input_queue (mp->client_index);
5722 ls_index = htonl (mp->locator_set_index);
5724 lsit = pool_elt_at_index (lcm->locator_set_pool, ls_index);
5726 filter = mp->filter;
5727 if (filter && !((1 == filter && lsit->local) ||
5728 (2 == filter && !lsit->local)))
5733 vec_foreach (locit, lsit->locator_indices)
5735 loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
5736 send_lisp_locator_details (lcm, loc, q, mp->context);
5741 send_lisp_locator_set_details (lisp_cp_main_t * lcm,
5742 locator_set_t * lsit,
5743 unix_shared_memory_queue_t * q,
5744 u32 context, u32 ls_index)
5746 vl_api_lisp_locator_set_details_t *rmp;
5749 rmp = vl_msg_api_alloc (sizeof (*rmp));
5750 memset (rmp, 0, sizeof (*rmp));
5751 rmp->_vl_msg_id = ntohs (VL_API_LISP_LOCATOR_SET_DETAILS);
5752 rmp->context = context;
5754 rmp->local = lsit->local;
5755 rmp->locator_set_index = htonl (ls_index);
5758 ASSERT (lsit->name != NULL);
5759 strncpy ((char *) rmp->locator_set_name,
5760 (char *) lsit->name, ARRAY_LEN (rmp->locator_set_name) - 1);
5764 str = format (0, "remote-%d", ls_index);
5765 strncpy ((char *) rmp->locator_set_name, (char *) str,
5766 ARRAY_LEN (rmp->locator_set_name) - 1);
5770 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5774 vl_api_lisp_locator_set_dump_t_handler (vl_api_lisp_locator_set_dump_t * mp)
5776 unix_shared_memory_queue_t *q = NULL;
5777 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
5778 locator_set_t *lsit = NULL;
5782 q = vl_api_client_index_to_input_queue (mp->client_index);
5788 filter = mp->filter;
5791 pool_foreach (lsit, lcm->locator_set_pool,
5793 if (filter && !((1 == filter && lsit->local) ||
5794 (2 == filter && !lsit->local))) {
5798 send_lisp_locator_set_details(lcm, lsit, q, mp->context, index++);
5804 send_lisp_eid_table_details (mapping_t * mapit,
5805 unix_shared_memory_queue_t * q,
5806 u32 context, u8 filter)
5808 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
5809 locator_set_t *ls = 0;
5810 vl_api_lisp_eid_table_details_t *rmp = NULL;
5811 gid_address_t *gid = NULL;
5813 ip_prefix_t *ip_prefix = NULL;
5817 case 0: /* all mappings */
5820 case 1: /* local only */
5824 case 2: /* remote only */
5829 clib_warning ("Filter error, unknown filter: %d", filter);
5834 ip_prefix = &gid_address_ippref (gid);
5835 mac = gid_address_mac (gid);
5837 rmp = vl_msg_api_alloc (sizeof (*rmp));
5838 memset (rmp, 0, sizeof (*rmp));
5839 rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_DETAILS);
5841 ls = pool_elt_at_index (lcm->locator_set_pool, mapit->locator_set_index);
5842 if (vec_len (ls->locator_indices) == 0)
5843 rmp->locator_set_index = ~0;
5845 rmp->locator_set_index = clib_host_to_net_u32 (mapit->locator_set_index);
5847 rmp->is_local = mapit->local;
5848 rmp->ttl = clib_host_to_net_u32 (mapit->ttl);
5849 rmp->action = mapit->action;
5850 rmp->authoritative = mapit->authoritative;
5852 switch (gid_address_type (gid))
5854 case GID_ADDR_IP_PREFIX:
5855 rmp->eid_prefix_len = ip_prefix_len (ip_prefix);
5856 if (ip_prefix_version (ip_prefix) == IP4)
5858 rmp->eid_type = 0; /* ipv4 type */
5859 clib_memcpy (rmp->eid, &ip_prefix_v4 (ip_prefix),
5860 sizeof (ip_prefix_v4 (ip_prefix)));
5864 rmp->eid_type = 1; /* ipv6 type */
5865 clib_memcpy (rmp->eid, &ip_prefix_v6 (ip_prefix),
5866 sizeof (ip_prefix_v6 (ip_prefix)));
5870 rmp->eid_type = 2; /* l2 mac type */
5871 clib_memcpy (rmp->eid, mac, 6);
5876 rmp->context = context;
5877 rmp->vni = clib_host_to_net_u32 (gid_address_vni (gid));
5878 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5882 vl_api_lisp_eid_table_dump_t_handler (vl_api_lisp_eid_table_dump_t * mp)
5885 unix_shared_memory_queue_t *q = NULL;
5886 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
5887 mapping_t *mapit = NULL;
5888 gid_address_t _eid, *eid = &_eid;
5890 q = vl_api_client_index_to_input_queue (mp->client_index);
5898 memset (eid, 0, sizeof (*eid));
5900 unformat_lisp_eid_api (eid, clib_net_to_host_u32 (mp->vni),
5901 mp->eid_type, mp->eid, mp->prefix_length);
5903 mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, eid);
5904 if ((u32) ~ 0 == mi)
5907 mapit = pool_elt_at_index (lcm->mapping_pool, mi);
5908 send_lisp_eid_table_details (mapit, q, mp->context,
5909 0 /* ignore filter */ );
5914 pool_foreach (mapit, lcm->mapping_pool,
5916 send_lisp_eid_table_details(mapit, q, mp->context,
5924 send_lisp_gpe_tunnel_details (lisp_gpe_tunnel_t * tunnel,
5925 unix_shared_memory_queue_t * q, u32 context)
5927 vl_api_lisp_gpe_tunnel_details_t *rmp;
5928 lisp_gpe_main_t *lgm = &lisp_gpe_main;
5930 rmp = vl_msg_api_alloc (sizeof (*rmp));
5931 memset (rmp, 0, sizeof (*rmp));
5932 rmp->_vl_msg_id = ntohs (VL_API_LISP_GPE_TUNNEL_DETAILS);
5934 rmp->tunnels = tunnel - lgm->tunnels;
5936 rmp->is_ipv6 = ip_addr_version (&tunnel->src) == IP6 ? 1 : 0;
5937 ip_address_copy_addr (rmp->source_ip, &tunnel->src);
5938 ip_address_copy_addr (rmp->destination_ip, &tunnel->dst);
5940 rmp->encap_fib_id = htonl (tunnel->encap_fib_index);
5941 rmp->decap_fib_id = htonl (tunnel->decap_fib_index);
5942 rmp->dcap_next = htonl (tunnel->decap_next_index);
5943 rmp->lisp_ver = tunnel->ver_res;
5944 rmp->next_protocol = tunnel->next_protocol;
5945 rmp->flags = tunnel->flags;
5946 rmp->ver_res = tunnel->ver_res;
5947 rmp->res = tunnel->res;
5948 rmp->iid = htonl (tunnel->vni);
5949 rmp->context = context;
5951 vl_msg_api_send_shmem (q, (u8 *) & rmp);
5955 vl_api_lisp_gpe_tunnel_dump_t_handler (vl_api_lisp_gpe_tunnel_dump_t * mp)
5957 unix_shared_memory_queue_t *q = NULL;
5958 lisp_gpe_main_t *lgm = &lisp_gpe_main;
5959 lisp_gpe_tunnel_t *tunnel = NULL;
5961 if (pool_elts (lgm->tunnels) == 0)
5966 q = vl_api_client_index_to_input_queue (mp->client_index);
5973 pool_foreach(tunnel, lgm->tunnels,
5975 send_lisp_gpe_tunnel_details(tunnel, q, mp->context);
5981 send_lisp_map_resolver_details (ip_address_t * ip,
5982 unix_shared_memory_queue_t * q, u32 context)
5984 vl_api_lisp_map_resolver_details_t *rmp = NULL;
5986 rmp = vl_msg_api_alloc (sizeof (*rmp));
5987 memset (rmp, 0, sizeof (*rmp));
5988 rmp->_vl_msg_id = ntohs (VL_API_LISP_MAP_RESOLVER_DETAILS);
5990 switch (ip_addr_version (ip))
5994 clib_memcpy (rmp->ip_address, &ip_addr_v4 (ip),
5995 sizeof (ip_addr_v4 (ip)));
6000 clib_memcpy (rmp->ip_address, &ip_addr_v6 (ip),
6001 sizeof (ip_addr_v6 (ip)));
6007 rmp->context = context;
6009 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6013 vl_api_lisp_map_resolver_dump_t_handler (vl_api_lisp_map_resolver_dump_t * mp)
6015 unix_shared_memory_queue_t *q = NULL;
6016 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
6019 q = vl_api_client_index_to_input_queue (mp->client_index);
6025 vec_foreach (mr, lcm->map_resolvers)
6027 send_lisp_map_resolver_details (&mr->address, q, mp->context);
6032 send_eid_table_map_pair (hash_pair_t * p,
6033 unix_shared_memory_queue_t * q, u32 context)
6035 vl_api_lisp_eid_table_map_details_t *rmp = NULL;
6037 rmp = vl_msg_api_alloc (sizeof (*rmp));
6038 memset (rmp, 0, sizeof (*rmp));
6039 rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_MAP_DETAILS);
6041 rmp->vni = clib_host_to_net_u32 (p->key);
6042 rmp->dp_table = clib_host_to_net_u32 (p->value[0]);
6043 rmp->context = context;
6044 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6048 vl_api_lisp_eid_table_map_dump_t_handler (vl_api_lisp_eid_table_map_dump_t *
6051 unix_shared_memory_queue_t *q = NULL;
6052 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
6054 uword *vni_table = 0;
6056 q = vl_api_client_index_to_input_queue (mp->client_index);
6064 vni_table = lcm->bd_id_by_vni;
6068 vni_table = lcm->table_id_by_vni;
6072 hash_foreach_pair (p, vni_table,
6074 send_eid_table_map_pair (p, q, mp->context);
6080 send_eid_table_vni (u32 vni, unix_shared_memory_queue_t * q, u32 context)
6082 vl_api_lisp_eid_table_vni_details_t *rmp = 0;
6084 rmp = vl_msg_api_alloc (sizeof (*rmp));
6085 memset (rmp, 0, sizeof (*rmp));
6086 rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_VNI_DETAILS);
6087 rmp->context = context;
6088 rmp->vni = clib_host_to_net_u32 (vni);
6089 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6093 vl_api_lisp_eid_table_vni_dump_t_handler (vl_api_lisp_eid_table_vni_dump_t *
6098 unix_shared_memory_queue_t *q = 0;
6099 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
6101 q = vl_api_client_index_to_input_queue (mp->client_index);
6108 hash_foreach_pair (p, lcm->table_id_by_vni,
6110 hash_set (vnis, p->key, 0);
6113 hash_foreach_pair (p, lcm->bd_id_by_vni,
6115 hash_set (vnis, p->key, 0);
6118 hash_foreach_pair (p, vnis,
6120 send_eid_table_vni (p->key, q, mp->context);
6128 vl_api_show_lisp_status_t_handler (vl_api_show_lisp_status_t * mp)
6130 unix_shared_memory_queue_t *q = NULL;
6131 vl_api_show_lisp_status_reply_t *rmp = NULL;
6134 q = vl_api_client_index_to_input_queue (mp->client_index);
6141 REPLY_MACRO2(VL_API_SHOW_LISP_STATUS_REPLY,
6143 rmp->gpe_status = vnet_lisp_gpe_enable_disable_status ();
6144 rmp->feature_status = vnet_lisp_enable_disable_status ();
6150 vl_api_lisp_get_map_request_itr_rlocs_t_handler
6151 (vl_api_lisp_get_map_request_itr_rlocs_t * mp)
6153 unix_shared_memory_queue_t *q = NULL;
6154 vl_api_lisp_get_map_request_itr_rlocs_reply_t *rmp = NULL;
6155 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
6156 locator_set_t *loc_set = 0;
6160 q = vl_api_client_index_to_input_queue (mp->client_index);
6166 if (~0 == lcm->mreq_itr_rlocs)
6168 tmp_str = format (0, " ");
6173 pool_elt_at_index (lcm->locator_set_pool, lcm->mreq_itr_rlocs);
6174 tmp_str = format (0, "%s", loc_set->name);
6178 REPLY_MACRO2(VL_API_LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,
6180 strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
6181 ARRAY_LEN(rmp->locator_set_name) - 1);
6189 vl_api_show_lisp_pitr_t_handler (vl_api_show_lisp_pitr_t * mp)
6191 unix_shared_memory_queue_t *q = NULL;
6192 vl_api_show_lisp_pitr_reply_t *rmp = NULL;
6193 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
6195 locator_set_t *ls = 0;
6199 q = vl_api_client_index_to_input_queue (mp->client_index);
6205 if (!lcm->lisp_pitr)
6207 tmp_str = format (0, "N/A");
6211 m = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
6212 if (~0 != m->locator_set_index)
6215 pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
6216 tmp_str = format (0, "%s", ls->name);
6220 tmp_str = format (0, "N/A");
6223 vec_add1 (tmp_str, 0);
6226 REPLY_MACRO2(VL_API_SHOW_LISP_PITR_REPLY,
6228 rmp->status = lcm->lisp_pitr;
6229 strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
6230 ARRAY_LEN(rmp->locator_set_name) - 1);
6236 vl_api_interface_name_renumber_t_handler (vl_api_interface_name_renumber_t *
6239 vl_api_interface_name_renumber_reply_t *rmp;
6242 VALIDATE_SW_IF_INDEX (mp);
6244 rv = vnet_interface_name_renumber
6245 (ntohl (mp->sw_if_index), ntohl (mp->new_show_dev_instance));
6247 BAD_SW_IF_INDEX_LABEL;
6249 REPLY_MACRO (VL_API_INTERFACE_NAME_RENUMBER_REPLY);
6253 arp_change_data_callback (u32 pool_index, u8 * new_mac,
6254 u32 sw_if_index, u32 address)
6256 vpe_api_main_t *am = &vpe_api_main;
6257 vlib_main_t *vm = am->vlib_main;
6258 vl_api_ip4_arp_event_t *event;
6259 static f64 arp_event_last_time;
6260 f64 now = vlib_time_now (vm);
6262 if (pool_is_free_index (am->arp_events, pool_index))
6265 event = pool_elt_at_index (am->arp_events, pool_index);
6267 if (memcmp (&event->new_mac, new_mac, sizeof (event->new_mac)))
6269 clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
6273 if (sw_if_index == event->sw_if_index &&
6275 /* for BD case, also check IP address with 10 sec timeout */
6276 (address == event->address &&
6277 (now - arp_event_last_time) < 10.0)))
6282 arp_event_last_time = now;
6283 event->sw_if_index = sw_if_index;
6285 event->address = address;
6290 nd_change_data_callback (u32 pool_index, u8 * new_mac,
6291 u32 sw_if_index, ip6_address_t * address)
6293 vpe_api_main_t *am = &vpe_api_main;
6294 vlib_main_t *vm = am->vlib_main;
6295 vl_api_ip6_nd_event_t *event;
6296 static f64 nd_event_last_time;
6297 f64 now = vlib_time_now (vm);
6299 if (pool_is_free_index (am->nd_events, pool_index))
6302 event = pool_elt_at_index (am->nd_events, pool_index);
6305 if (memcmp (&event->new_mac, new_mac, sizeof (event->new_mac)))
6307 clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
6311 if (sw_if_index == event->sw_if_index &&
6313 /* for BD case, also check IP address with 10 sec timeout */
6314 (ip6_address_is_equal (address,
6315 (ip6_address_t *) event->address) &&
6316 (now - nd_event_last_time) < 10.0)))
6321 nd_event_last_time = now;
6322 event->sw_if_index = sw_if_index;
6324 clib_memcpy (event->address, address, sizeof (event->address));
6329 arp_change_delete_callback (u32 pool_index, u8 * notused)
6331 vpe_api_main_t *am = &vpe_api_main;
6333 if (pool_is_free_index (am->arp_events, pool_index))
6336 pool_put_index (am->arp_events, pool_index);
6341 nd_change_delete_callback (u32 pool_index, u8 * notused)
6343 vpe_api_main_t *am = &vpe_api_main;
6345 if (pool_is_free_index (am->nd_events, pool_index))
6348 pool_put_index (am->nd_events, pool_index);
6353 vl_api_want_ip4_arp_events_t_handler (vl_api_want_ip4_arp_events_t * mp)
6355 vpe_api_main_t *am = &vpe_api_main;
6356 vnet_main_t *vnm = vnet_get_main ();
6357 vl_api_want_ip4_arp_events_reply_t *rmp;
6358 vl_api_ip4_arp_event_t *event;
6361 if (mp->enable_disable)
6363 pool_get (am->arp_events, event);
6364 memset (event, 0, sizeof (*event));
6366 event->_vl_msg_id = ntohs (VL_API_IP4_ARP_EVENT);
6367 event->client_index = mp->client_index;
6368 event->context = mp->context;
6369 event->address = mp->address;
6370 event->pid = mp->pid;
6371 if (mp->address == 0)
6374 rv = vnet_add_del_ip4_arp_change_event
6375 (vnm, arp_change_data_callback,
6376 mp->pid, &mp->address /* addr, in net byte order */ ,
6377 vpe_resolver_process_node.index,
6378 IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */ );
6382 rv = vnet_add_del_ip4_arp_change_event
6383 (vnm, arp_change_delete_callback,
6384 mp->pid, &mp->address /* addr, in net byte order */ ,
6385 vpe_resolver_process_node.index,
6386 IP4_ARP_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
6388 REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY);
6392 vl_api_want_ip6_nd_events_t_handler (vl_api_want_ip6_nd_events_t * mp)
6394 vpe_api_main_t *am = &vpe_api_main;
6395 vnet_main_t *vnm = vnet_get_main ();
6396 vl_api_want_ip6_nd_events_reply_t *rmp;
6397 vl_api_ip6_nd_event_t *event;
6400 if (mp->enable_disable)
6402 pool_get (am->nd_events, event);
6403 memset (event, 0, sizeof (*event));
6405 event->_vl_msg_id = ntohs (VL_API_IP6_ND_EVENT);
6406 event->client_index = mp->client_index;
6407 event->context = mp->context;
6408 clib_memcpy (event->address, mp->address, 16);
6409 event->pid = mp->pid;
6410 if (ip6_address_is_zero ((ip6_address_t *) mp->address))
6413 rv = vnet_add_del_ip6_nd_change_event
6414 (vnm, nd_change_data_callback,
6415 mp->pid, mp->address /* addr, in net byte order */ ,
6416 vpe_resolver_process_node.index,
6417 IP6_ND_EVENT, event - am->nd_events, 1 /* is_add */ );
6421 rv = vnet_add_del_ip6_nd_change_event
6422 (vnm, nd_change_delete_callback,
6423 mp->pid, mp->address /* addr, in net byte order */ ,
6424 vpe_resolver_process_node.index,
6425 IP6_ND_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
6427 REPLY_MACRO (VL_API_WANT_IP6_ND_EVENTS_REPLY);
6430 static void vl_api_input_acl_set_interface_t_handler
6431 (vl_api_input_acl_set_interface_t * mp)
6433 vlib_main_t *vm = vlib_get_main ();
6434 vl_api_input_acl_set_interface_reply_t *rmp;
6436 u32 sw_if_index, ip4_table_index, ip6_table_index, l2_table_index;
6438 ip4_table_index = ntohl (mp->ip4_table_index);
6439 ip6_table_index = ntohl (mp->ip6_table_index);
6440 l2_table_index = ntohl (mp->l2_table_index);
6441 sw_if_index = ntohl (mp->sw_if_index);
6443 VALIDATE_SW_IF_INDEX (mp);
6445 rv = vnet_set_input_acl_intfc (vm, sw_if_index, ip4_table_index,
6446 ip6_table_index, l2_table_index, mp->is_add);
6448 BAD_SW_IF_INDEX_LABEL;
6450 REPLY_MACRO (VL_API_INPUT_ACL_SET_INTERFACE_REPLY);
6453 static void vl_api_ipsec_spd_add_del_t_handler
6454 (vl_api_ipsec_spd_add_del_t * mp)
6457 clib_warning ("unimplemented");
6460 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
6461 vl_api_ipsec_spd_add_del_reply_t *rmp;
6465 rv = ipsec_add_del_spd (vm, ntohl (mp->spd_id), mp->is_add);
6467 rv = VNET_API_ERROR_UNIMPLEMENTED;
6470 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_REPLY);
6474 static void vl_api_ipsec_interface_add_del_spd_t_handler
6475 (vl_api_ipsec_interface_add_del_spd_t * mp)
6477 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
6478 vl_api_ipsec_interface_add_del_spd_reply_t *rmp;
6480 u32 sw_if_index __attribute__ ((unused));
6481 u32 spd_id __attribute__ ((unused));
6483 sw_if_index = ntohl (mp->sw_if_index);
6484 spd_id = ntohl (mp->spd_id);
6486 VALIDATE_SW_IF_INDEX (mp);
6489 rv = ipsec_set_interface_spd (vm, sw_if_index, spd_id, mp->is_add);
6491 rv = VNET_API_ERROR_UNIMPLEMENTED;
6494 BAD_SW_IF_INDEX_LABEL;
6496 REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY);
6499 static void vl_api_ipsec_spd_add_del_entry_t_handler
6500 (vl_api_ipsec_spd_add_del_entry_t * mp)
6502 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
6503 vl_api_ipsec_spd_add_del_entry_reply_t *rmp;
6509 memset (&p, 0, sizeof (p));
6511 p.id = ntohl (mp->spd_id);
6512 p.priority = ntohl (mp->priority);
6513 p.is_outbound = mp->is_outbound;
6514 p.is_ipv6 = mp->is_ipv6;
6516 if (mp->is_ipv6 || mp->is_ip_any)
6518 clib_memcpy (&p.raddr.start, mp->remote_address_start, 16);
6519 clib_memcpy (&p.raddr.stop, mp->remote_address_stop, 16);
6520 clib_memcpy (&p.laddr.start, mp->local_address_start, 16);
6521 clib_memcpy (&p.laddr.stop, mp->local_address_stop, 16);
6525 clib_memcpy (&p.raddr.start.ip4.data, mp->remote_address_start, 4);
6526 clib_memcpy (&p.raddr.stop.ip4.data, mp->remote_address_stop, 4);
6527 clib_memcpy (&p.laddr.start.ip4.data, mp->local_address_start, 4);
6528 clib_memcpy (&p.laddr.stop.ip4.data, mp->local_address_stop, 4);
6530 p.protocol = mp->protocol;
6531 p.rport.start = ntohs (mp->remote_port_start);
6532 p.rport.stop = ntohs (mp->remote_port_stop);
6533 p.lport.start = ntohs (mp->local_port_start);
6534 p.lport.stop = ntohs (mp->local_port_stop);
6535 /* policy action resolve unsupported */
6536 if (mp->policy == IPSEC_POLICY_ACTION_RESOLVE)
6538 clib_warning ("unsupported action: 'resolve'");
6539 rv = VNET_API_ERROR_UNIMPLEMENTED;
6542 p.policy = mp->policy;
6543 p.sa_id = ntohl (mp->sa_id);
6545 rv = ipsec_add_del_policy (vm, &p, mp->is_add);
6552 rv = ipsec_add_del_policy (vm, &p, mp->is_add);
6555 rv = VNET_API_ERROR_UNIMPLEMENTED;
6560 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_ENTRY_REPLY);
6563 static void vl_api_ipsec_sad_add_del_entry_t_handler
6564 (vl_api_ipsec_sad_add_del_entry_t * mp)
6566 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
6567 vl_api_ipsec_sad_add_del_entry_reply_t *rmp;
6572 memset (&sa, 0, sizeof (sa));
6574 sa.id = ntohl (mp->sad_id);
6575 sa.spi = ntohl (mp->spi);
6576 /* security protocol AH unsupported */
6577 if (mp->protocol == IPSEC_PROTOCOL_AH)
6579 clib_warning ("unsupported security protocol 'AH'");
6580 rv = VNET_API_ERROR_UNIMPLEMENTED;
6583 sa.protocol = mp->protocol;
6584 /* check for unsupported crypto-alg */
6585 if (mp->crypto_algorithm < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
6586 mp->crypto_algorithm > IPSEC_CRYPTO_ALG_AES_CBC_256)
6588 clib_warning ("unsupported crypto-alg: '%U'", format_ipsec_crypto_alg,
6589 mp->crypto_algorithm);
6590 rv = VNET_API_ERROR_UNIMPLEMENTED;
6593 sa.crypto_alg = mp->crypto_algorithm;
6594 sa.crypto_key_len = mp->crypto_key_length;
6595 clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key));
6596 /* check for unsupported integ-alg */
6597 if (mp->integrity_algorithm < IPSEC_INTEG_ALG_SHA1_96 ||
6598 mp->integrity_algorithm > IPSEC_INTEG_ALG_SHA_512_256)
6600 clib_warning ("unsupported integ-alg: '%U'", format_ipsec_integ_alg,
6601 mp->integrity_algorithm);
6602 rv = VNET_API_ERROR_UNIMPLEMENTED;
6605 sa.integ_alg = mp->integrity_algorithm;
6606 sa.integ_key_len = mp->integrity_key_length;
6607 clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key));
6608 sa.use_esn = mp->use_extended_sequence_number;
6609 sa.is_tunnel = mp->is_tunnel;
6610 sa.is_tunnel_ip6 = mp->is_tunnel_ipv6;
6611 if (sa.is_tunnel_ip6)
6613 clib_memcpy (&sa.tunnel_src_addr, mp->tunnel_src_address, 16);
6614 clib_memcpy (&sa.tunnel_dst_addr, mp->tunnel_dst_address, 16);
6618 clib_memcpy (&sa.tunnel_src_addr.ip4.data, mp->tunnel_src_address, 4);
6619 clib_memcpy (&sa.tunnel_dst_addr.ip4.data, mp->tunnel_dst_address, 4);
6622 rv = ipsec_add_del_sa (vm, &sa, mp->is_add);
6624 rv = VNET_API_ERROR_UNIMPLEMENTED;
6629 REPLY_MACRO (VL_API_IPSEC_SAD_ADD_DEL_ENTRY_REPLY);
6633 vl_api_ikev2_profile_add_del_t_handler (vl_api_ikev2_profile_add_del_t * mp)
6635 vl_api_ikev2_profile_add_del_reply_t *rmp;
6639 vlib_main_t *vm = vlib_get_main ();
6640 clib_error_t *error;
6641 u8 *tmp = format (0, "%s", mp->name);
6642 error = ikev2_add_del_profile (vm, tmp, mp->is_add);
6645 rv = VNET_API_ERROR_UNSPECIFIED;
6647 rv = VNET_API_ERROR_UNIMPLEMENTED;
6650 REPLY_MACRO (VL_API_IKEV2_PROFILE_ADD_DEL_REPLY);
6654 vl_api_ikev2_profile_set_auth_t_handler
6655 (vl_api_ikev2_profile_set_auth_t * mp)
6657 vl_api_ikev2_profile_set_auth_reply_t *rmp;
6661 vlib_main_t *vm = vlib_get_main ();
6662 clib_error_t *error;
6663 u8 *tmp = format (0, "%s", mp->name);
6664 u8 *data = vec_new (u8, mp->data_len);
6665 clib_memcpy (data, mp->data, mp->data_len);
6666 error = ikev2_set_profile_auth (vm, tmp, mp->auth_method, data, mp->is_hex);
6670 rv = VNET_API_ERROR_UNSPECIFIED;
6672 rv = VNET_API_ERROR_UNIMPLEMENTED;
6675 REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_AUTH_REPLY);
6679 vl_api_ikev2_profile_set_id_t_handler (vl_api_ikev2_profile_set_id_t * mp)
6681 vl_api_ikev2_profile_add_del_reply_t *rmp;
6685 vlib_main_t *vm = vlib_get_main ();
6686 clib_error_t *error;
6687 u8 *tmp = format (0, "%s", mp->name);
6688 u8 *data = vec_new (u8, mp->data_len);
6689 clib_memcpy (data, mp->data, mp->data_len);
6690 error = ikev2_set_profile_id (vm, tmp, mp->id_type, data, mp->is_local);
6694 rv = VNET_API_ERROR_UNSPECIFIED;
6696 rv = VNET_API_ERROR_UNIMPLEMENTED;
6699 REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_ID_REPLY);
6703 vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp)
6705 vl_api_ikev2_profile_set_ts_reply_t *rmp;
6709 vlib_main_t *vm = vlib_get_main ();
6710 clib_error_t *error;
6711 u8 *tmp = format (0, "%s", mp->name);
6712 error = ikev2_set_profile_ts (vm, tmp, mp->proto, mp->start_port,
6713 mp->end_port, (ip4_address_t) mp->start_addr,
6714 (ip4_address_t) mp->end_addr, mp->is_local);
6717 rv = VNET_API_ERROR_UNSPECIFIED;
6719 rv = VNET_API_ERROR_UNIMPLEMENTED;
6722 REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_TS_REPLY);
6726 vl_api_ikev2_set_local_key_t_handler (vl_api_ikev2_set_local_key_t * mp)
6728 vl_api_ikev2_profile_set_ts_reply_t *rmp;
6732 vlib_main_t *vm = vlib_get_main ();
6733 clib_error_t *error;
6735 error = ikev2_set_local_key (vm, mp->key_file);
6737 rv = VNET_API_ERROR_UNSPECIFIED;
6739 rv = VNET_API_ERROR_UNIMPLEMENTED;
6742 REPLY_MACRO (VL_API_IKEV2_SET_LOCAL_KEY_REPLY);
6746 vl_api_map_add_domain_t_handler (vl_api_map_add_domain_t * mp)
6748 vl_api_map_add_domain_reply_t *rmp;
6751 u8 flags = mp->is_translation ? MAP_DOMAIN_TRANSLATION : 0;
6753 map_create_domain ((ip4_address_t *) & mp->ip4_prefix, mp->ip4_prefix_len,
6754 (ip6_address_t *) & mp->ip6_prefix, mp->ip6_prefix_len,
6755 (ip6_address_t *) & mp->ip6_src,
6756 mp->ip6_src_prefix_len, mp->ea_bits_len,
6757 mp->psid_offset, mp->psid_length, &index,
6758 ntohs (mp->mtu), flags);
6761 REPLY_MACRO2(VL_API_MAP_ADD_DOMAIN_REPLY,
6763 rmp->index = ntohl(index);
6769 vl_api_map_del_domain_t_handler (vl_api_map_del_domain_t * mp)
6771 vl_api_map_del_domain_reply_t *rmp;
6774 rv = map_delete_domain (ntohl (mp->index));
6776 REPLY_MACRO (VL_API_MAP_DEL_DOMAIN_REPLY);
6780 vl_api_map_add_del_rule_t_handler (vl_api_map_add_del_rule_t * mp)
6782 vl_api_map_del_domain_reply_t *rmp;
6786 map_add_del_psid (ntohl (mp->index), ntohs (mp->psid),
6787 (ip6_address_t *) mp->ip6_dst, mp->is_add);
6789 REPLY_MACRO (VL_API_MAP_ADD_DEL_RULE_REPLY);
6793 vl_api_map_domain_dump_t_handler (vl_api_map_domain_dump_t * mp)
6795 vl_api_map_domain_details_t *rmp;
6796 map_main_t *mm = &map_main;
6798 unix_shared_memory_queue_t *q;
6800 if (pool_elts (mm->domains) == 0)
6803 q = vl_api_client_index_to_input_queue (mp->client_index);
6810 pool_foreach(d, mm->domains,
6812 /* Make sure every field is initiated (or don't skip the memset()) */
6813 rmp = vl_msg_api_alloc (sizeof (*rmp));
6814 rmp->_vl_msg_id = ntohs(VL_API_MAP_DOMAIN_DETAILS);
6815 rmp->domain_index = htonl(d - mm->domains);
6816 rmp->ea_bits_len = d->ea_bits_len;
6817 rmp->psid_offset = d->psid_offset;
6818 rmp->psid_length = d->psid_length;
6819 clib_memcpy(rmp->ip4_prefix, &d->ip4_prefix, sizeof(rmp->ip4_prefix));
6820 rmp->ip4_prefix_len = d->ip4_prefix_len;
6821 clib_memcpy(rmp->ip6_prefix, &d->ip6_prefix, sizeof(rmp->ip6_prefix));
6822 rmp->ip6_prefix_len = d->ip6_prefix_len;
6823 clib_memcpy(rmp->ip6_src, &d->ip6_src, sizeof(rmp->ip6_src));
6824 rmp->ip6_src_len = d->ip6_src_len;
6825 rmp->mtu = htons(d->mtu);
6826 rmp->is_translation = (d->flags & MAP_DOMAIN_TRANSLATION);
6827 rmp->context = mp->context;
6829 vl_msg_api_send_shmem (q, (u8 *)&rmp);
6835 vl_api_map_rule_dump_t_handler (vl_api_map_rule_dump_t * mp)
6837 unix_shared_memory_queue_t *q;
6840 vl_api_map_rule_details_t *rmp;
6841 map_main_t *mm = &map_main;
6842 u32 domain_index = ntohl (mp->domain_index);
6845 if (pool_elts (mm->domains) == 0)
6848 d = pool_elt_at_index (mm->domains, domain_index);
6849 if (!d || !d->rules)
6854 q = vl_api_client_index_to_input_queue (mp->client_index);
6860 for (i = 0; i < (0x1 << d->psid_length); i++)
6863 if (dst.as_u64[0] == 0 && dst.as_u64[1] == 0)
6867 rmp = vl_msg_api_alloc (sizeof (*rmp));
6868 memset (rmp, 0, sizeof (*rmp));
6869 rmp->_vl_msg_id = ntohs (VL_API_MAP_RULE_DETAILS);
6870 rmp->psid = htons (i);
6871 clib_memcpy (rmp->ip6_dst, &dst, sizeof (rmp->ip6_dst));
6872 rmp->context = mp->context;
6873 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6878 vl_api_map_summary_stats_t_handler (vl_api_map_summary_stats_t * mp)
6880 vl_api_map_summary_stats_reply_t *rmp;
6881 vlib_combined_counter_main_t *cm;
6884 u64 total_pkts[VLIB_N_RX_TX];
6885 u64 total_bytes[VLIB_N_RX_TX];
6886 map_main_t *mm = &map_main;
6887 unix_shared_memory_queue_t *q =
6888 vl_api_client_index_to_input_queue (mp->client_index);
6893 rmp = vl_msg_api_alloc (sizeof (*rmp));
6894 rmp->_vl_msg_id = ntohs (VL_API_MAP_SUMMARY_STATS_REPLY);
6895 rmp->context = mp->context;
6898 memset (total_pkts, 0, sizeof (total_pkts));
6899 memset (total_bytes, 0, sizeof (total_bytes));
6901 map_domain_counter_lock (mm);
6902 vec_foreach (cm, mm->domain_counters)
6904 which = cm - mm->domain_counters;
6906 for (i = 0; i < vec_len (cm->maxi); i++)
6908 vlib_get_combined_counter (cm, i, &v);
6909 total_pkts[which] += v.packets;
6910 total_bytes[which] += v.bytes;
6914 map_domain_counter_unlock (mm);
6916 /* Note: in network byte order! */
6917 rmp->total_pkts[MAP_DOMAIN_COUNTER_RX] =
6918 clib_host_to_net_u64 (total_pkts[MAP_DOMAIN_COUNTER_RX]);
6919 rmp->total_bytes[MAP_DOMAIN_COUNTER_RX] =
6920 clib_host_to_net_u64 (total_bytes[MAP_DOMAIN_COUNTER_RX]);
6921 rmp->total_pkts[MAP_DOMAIN_COUNTER_TX] =
6922 clib_host_to_net_u64 (total_pkts[MAP_DOMAIN_COUNTER_TX]);
6923 rmp->total_bytes[MAP_DOMAIN_COUNTER_TX] =
6924 clib_host_to_net_u64 (total_bytes[MAP_DOMAIN_COUNTER_TX]);
6925 rmp->total_bindings = clib_host_to_net_u64 (pool_elts (mm->domains));
6926 rmp->total_ip4_fragments = 0; // Not yet implemented. Should be a simple counter.
6927 rmp->total_security_check[MAP_DOMAIN_COUNTER_TX] =
6928 clib_host_to_net_u64 (map_error_counter_get
6929 (ip4_map_node.index, MAP_ERROR_ENCAP_SEC_CHECK));
6930 rmp->total_security_check[MAP_DOMAIN_COUNTER_RX] =
6931 clib_host_to_net_u64 (map_error_counter_get
6932 (ip4_map_node.index, MAP_ERROR_DECAP_SEC_CHECK));
6934 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6938 vl_api_ipsec_sa_set_key_t_handler (vl_api_ipsec_sa_set_key_t * mp)
6940 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
6941 vl_api_ipsec_sa_set_key_reply_t *rmp;
6945 sa.id = ntohl (mp->sa_id);
6946 sa.crypto_key_len = mp->crypto_key_length;
6947 clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key));
6948 sa.integ_key_len = mp->integrity_key_length;
6949 clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key));
6951 rv = ipsec_set_sa_key (vm, &sa);
6953 rv = VNET_API_ERROR_UNIMPLEMENTED;
6956 REPLY_MACRO (VL_API_IPSEC_SA_SET_KEY_REPLY);
6959 static void vl_api_cop_interface_enable_disable_t_handler
6960 (vl_api_cop_interface_enable_disable_t * mp)
6962 vl_api_cop_interface_enable_disable_reply_t *rmp;
6964 u32 sw_if_index = ntohl (mp->sw_if_index);
6967 VALIDATE_SW_IF_INDEX (mp);
6969 enable_disable = (int) mp->enable_disable;
6971 rv = cop_interface_enable_disable (sw_if_index, enable_disable);
6973 BAD_SW_IF_INDEX_LABEL;
6975 REPLY_MACRO (VL_API_COP_INTERFACE_ENABLE_DISABLE_REPLY);
6978 static void vl_api_cop_whitelist_enable_disable_t_handler
6979 (vl_api_cop_whitelist_enable_disable_t * mp)
6981 vl_api_cop_whitelist_enable_disable_reply_t *rmp;
6982 cop_whitelist_enable_disable_args_t _a, *a = &_a;
6983 u32 sw_if_index = ntohl (mp->sw_if_index);
6986 VALIDATE_SW_IF_INDEX (mp);
6988 a->sw_if_index = sw_if_index;
6991 a->default_cop = mp->default_cop;
6992 a->fib_id = ntohl (mp->fib_id);
6994 rv = cop_whitelist_enable_disable (a);
6996 BAD_SW_IF_INDEX_LABEL;
6998 REPLY_MACRO (VL_API_COP_WHITELIST_ENABLE_DISABLE_REPLY);
7002 vl_api_get_node_graph_t_handler (vl_api_get_node_graph_t * mp)
7006 api_main_t *am = &api_main;
7007 vlib_main_t *vm = vlib_get_main ();
7009 vl_api_get_node_graph_reply_t *rmp;
7011 pthread_mutex_lock (&am->vlib_rp->mutex);
7012 oldheap = svm_push_data_heap (am->vlib_rp);
7015 * Keep the number of memcpy ops to a minimum (e.g. 1).
7017 vec_validate (vector, 16384);
7018 vec_reset_length (vector);
7021 vector = vlib_node_serialize (&vm->node_main, vector,
7022 (u32) ~ 0 /* all threads */ ,
7023 1 /* include nexts */ ,
7024 1 /* include stats */ );
7026 svm_pop_heap (oldheap);
7027 pthread_mutex_unlock (&am->vlib_rp->mutex);
7030 REPLY_MACRO2(VL_API_GET_NODE_GRAPH_REPLY,
7032 rmp->reply_in_shmem = (uword) vector;
7038 vl_api_ioam_enable_t_handler (vl_api_ioam_enable_t * mp)
7041 vl_api_ioam_enable_reply_t *rmp;
7042 clib_error_t *error;
7044 /* Ignoring the profile id as currently a single profile
7046 error = ip6_ioam_enable (mp->trace_enable, mp->pow_enable, mp->trace_ppc);
7049 clib_error_report (error);
7050 rv = clib_error_get_code (error);
7053 REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
7057 vl_api_ioam_disable_t_handler (vl_api_ioam_disable_t * mp)
7060 vl_api_ioam_disable_reply_t *rmp;
7061 clib_error_t *error;
7063 error = clear_ioam_rewrite_fn ();
7066 clib_error_report (error);
7067 rv = clib_error_get_code (error);
7070 REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
7074 vl_api_af_packet_create_t_handler (vl_api_af_packet_create_t * mp)
7076 vlib_main_t *vm = vlib_get_main ();
7077 vl_api_af_packet_create_reply_t *rmp;
7079 u8 *host_if_name = NULL;
7082 host_if_name = format (0, "%s", mp->host_if_name);
7083 vec_add1 (host_if_name, 0);
7085 rv = af_packet_create_if (vm, host_if_name,
7086 mp->use_random_hw_addr ? 0 : mp->hw_addr,
7089 vec_free (host_if_name);
7092 REPLY_MACRO2(VL_API_AF_PACKET_CREATE_REPLY,
7094 rmp->sw_if_index = clib_host_to_net_u32(sw_if_index);
7100 vl_api_af_packet_delete_t_handler (vl_api_af_packet_delete_t * mp)
7102 vlib_main_t *vm = vlib_get_main ();
7103 vl_api_af_packet_delete_reply_t *rmp;
7105 u8 *host_if_name = NULL;
7107 host_if_name = format (0, "%s", mp->host_if_name);
7108 vec_add1 (host_if_name, 0);
7110 rv = af_packet_delete_if (vm, host_if_name);
7112 vec_free (host_if_name);
7114 REPLY_MACRO (VL_API_AF_PACKET_DELETE_REPLY);
7118 vl_api_policer_add_del_t_handler (vl_api_policer_add_del_t * mp)
7120 vlib_main_t *vm = vlib_get_main ();
7121 vl_api_policer_add_del_reply_t *rmp;
7124 sse2_qos_pol_cfg_params_st cfg;
7125 clib_error_t *error;
7128 name = format (0, "%s", mp->name);
7130 memset (&cfg, 0, sizeof (cfg));
7132 cfg.rnd_type = mp->round_type;
7133 cfg.rate_type = mp->rate_type;
7134 cfg.rb.kbps.cir_kbps = mp->cir;
7135 cfg.rb.kbps.eir_kbps = mp->eir;
7136 cfg.rb.kbps.cb_bytes = mp->cb;
7137 cfg.rb.kbps.eb_bytes = mp->eb;
7138 cfg.conform_action.action_type = mp->conform_action_type;
7139 cfg.conform_action.dscp = mp->conform_dscp;
7140 cfg.exceed_action.action_type = mp->exceed_action_type;
7141 cfg.exceed_action.dscp = mp->exceed_dscp;
7142 cfg.violate_action.action_type = mp->violate_action_type;
7143 cfg.violate_action.dscp = mp->violate_dscp;
7144 cfg.color_aware = mp->color_aware;
7146 error = policer_add_del (vm, name, &cfg, &policer_index, mp->is_add);
7149 rv = VNET_API_ERROR_UNSPECIFIED;
7152 REPLY_MACRO2(VL_API_POLICER_ADD_DEL_REPLY,
7154 if (rv == 0 && mp->is_add)
7155 rmp->policer_index = ntohl(policer_index);
7157 rmp->policer_index = ~0;
7163 send_policer_details (u8 * name,
7164 sse2_qos_pol_cfg_params_st * config,
7165 policer_read_response_type_st * templ,
7166 unix_shared_memory_queue_t * q, u32 context)
7168 vl_api_policer_details_t *mp;
7170 mp = vl_msg_api_alloc (sizeof (*mp));
7171 memset (mp, 0, sizeof (*mp));
7172 mp->_vl_msg_id = ntohs (VL_API_POLICER_DETAILS);
7173 mp->context = context;
7174 mp->cir = htonl (config->rb.kbps.cir_kbps);
7175 mp->eir = htonl (config->rb.kbps.eir_kbps);
7176 mp->cb = htonl (config->rb.kbps.cb_bytes);
7177 mp->eb = htonl (config->rb.kbps.eb_bytes);
7178 mp->rate_type = config->rate_type;
7179 mp->round_type = config->rnd_type;
7180 mp->type = config->rfc;
7181 mp->conform_action_type = config->conform_action.action_type;
7182 mp->conform_dscp = config->conform_action.dscp;
7183 mp->exceed_action_type = config->exceed_action.action_type;
7184 mp->exceed_dscp = config->exceed_action.dscp;
7185 mp->violate_action_type = config->violate_action.action_type;
7186 mp->violate_dscp = config->violate_action.dscp;
7187 mp->single_rate = templ->single_rate ? 1 : 0;
7188 mp->color_aware = templ->color_aware ? 1 : 0;
7189 mp->scale = htonl (templ->scale);
7190 mp->cir_tokens_per_period = htonl (templ->cir_tokens_per_period);
7191 mp->pir_tokens_per_period = htonl (templ->pir_tokens_per_period);
7192 mp->current_limit = htonl (templ->current_limit);
7193 mp->current_bucket = htonl (templ->current_bucket);
7194 mp->extended_limit = htonl (templ->extended_limit);
7195 mp->extended_bucket = htonl (templ->extended_bucket);
7196 mp->last_update_time = clib_host_to_net_u64 (templ->last_update_time);
7198 strncpy ((char *) mp->name, (char *) name, ARRAY_LEN (mp->name) - 1);
7200 vl_msg_api_send_shmem (q, (u8 *) & mp);
7204 vl_api_policer_dump_t_handler (vl_api_policer_dump_t * mp)
7206 unix_shared_memory_queue_t *q;
7207 vnet_policer_main_t *pm = &vnet_policer_main;
7213 sse2_qos_pol_cfg_params_st *config;
7214 policer_read_response_type_st *templ;
7216 q = vl_api_client_index_to_input_queue (mp->client_index);
7220 if (mp->match_name_valid)
7222 match_name = format (0, "%s%c", mp->match_name, 0);
7225 if (mp->match_name_valid)
7227 p = hash_get_mem (pm->policer_config_by_name, match_name);
7231 config = pool_elt_at_index (pm->configs, pool_index);
7232 templ = pool_elt_at_index (pm->policer_templates, pool_index);
7233 send_policer_details (match_name, config, templ, q, mp->context);
7239 hash_foreach_pair (hp, pm->policer_config_by_name,
7241 name = (u8 *) hp->key;
7242 pool_index = hp->value[0];
7243 config = pool_elt_at_index (pm->configs, pool_index);
7244 templ = pool_elt_at_index (pm->policer_templates, pool_index);
7245 send_policer_details(name, config, templ, q, mp->context);
7252 vl_api_policer_classify_set_interface_t_handler
7253 (vl_api_policer_classify_set_interface_t * mp)
7255 vlib_main_t *vm = vlib_get_main ();
7256 vl_api_policer_classify_set_interface_reply_t *rmp;
7258 u32 sw_if_index, ip4_table_index, ip6_table_index, l2_table_index;
7260 ip4_table_index = ntohl (mp->ip4_table_index);
7261 ip6_table_index = ntohl (mp->ip6_table_index);
7262 l2_table_index = ntohl (mp->l2_table_index);
7263 sw_if_index = ntohl (mp->sw_if_index);
7265 VALIDATE_SW_IF_INDEX (mp);
7267 rv = vnet_set_policer_classify_intfc (vm, sw_if_index, ip4_table_index,
7268 ip6_table_index, l2_table_index,
7271 BAD_SW_IF_INDEX_LABEL;
7273 REPLY_MACRO (VL_API_POLICER_CLASSIFY_SET_INTERFACE_REPLY);
7277 send_policer_classify_details (u32 sw_if_index,
7279 unix_shared_memory_queue_t * q, u32 context)
7281 vl_api_policer_classify_details_t *mp;
7283 mp = vl_msg_api_alloc (sizeof (*mp));
7284 memset (mp, 0, sizeof (*mp));
7285 mp->_vl_msg_id = ntohs (VL_API_POLICER_CLASSIFY_DETAILS);
7286 mp->context = context;
7287 mp->sw_if_index = htonl (sw_if_index);
7288 mp->table_index = htonl (table_index);
7290 vl_msg_api_send_shmem (q, (u8 *) & mp);
7294 vl_api_policer_classify_dump_t_handler (vl_api_policer_classify_dump_t * mp)
7296 unix_shared_memory_queue_t *q;
7297 policer_classify_main_t *pcm = &policer_classify_main;
7301 q = vl_api_client_index_to_input_queue (mp->client_index);
7305 vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type];
7307 if (vec_len (vec_tbl))
7309 for (i = 0; i < vec_len (vec_tbl); i++)
7311 if (vec_elt (vec_tbl, i) == ~0)
7314 send_policer_classify_details (i, vec_elt (vec_tbl, i), q,
7321 vl_api_netmap_create_t_handler (vl_api_netmap_create_t * mp)
7323 vlib_main_t *vm = vlib_get_main ();
7324 vl_api_netmap_create_reply_t *rmp;
7328 if_name = format (0, "%s", mp->netmap_if_name);
7329 vec_add1 (if_name, 0);
7332 netmap_create_if (vm, if_name, mp->use_random_hw_addr ? 0 : mp->hw_addr,
7333 mp->is_pipe, mp->is_master, 0);
7337 REPLY_MACRO (VL_API_NETMAP_CREATE_REPLY);
7341 vl_api_netmap_delete_t_handler (vl_api_netmap_delete_t * mp)
7343 vlib_main_t *vm = vlib_get_main ();
7344 vl_api_netmap_delete_reply_t *rmp;
7348 if_name = format (0, "%s", mp->netmap_if_name);
7349 vec_add1 (if_name, 0);
7351 rv = netmap_delete_if (vm, if_name);
7355 REPLY_MACRO (VL_API_NETMAP_DELETE_REPLY);
7359 vl_api_mpls_gre_tunnel_details_t_handler (vl_api_mpls_gre_tunnel_details_t *
7362 clib_warning ("BUG");
7366 send_mpls_gre_tunnel_entry (vpe_api_main_t * am,
7367 unix_shared_memory_queue_t * q,
7368 mpls_gre_tunnel_t * gt, u32 index, u32 context)
7370 vl_api_mpls_gre_tunnel_details_t *mp;
7371 mpls_main_t *mm = &mpls_main;
7376 e = pool_elt_at_index (mm->encaps, gt->encap_index);
7377 nlabels = vec_len (e->labels);
7379 mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
7380 memset (mp, 0, sizeof (*mp));
7381 mp->_vl_msg_id = ntohs (VL_API_MPLS_GRE_TUNNEL_DETAILS);
7382 mp->context = context;
7384 mp->tunnel_index = htonl (index);
7385 mp->tunnel_src = gt->tunnel_src.as_u32;
7386 mp->tunnel_dst = gt->tunnel_dst.as_u32;
7387 mp->intfc_address = gt->intfc_address.as_u32;
7388 mp->mask_width = htonl (gt->mask_width);
7389 mp->inner_fib_index = htonl (gt->inner_fib_index);
7390 mp->outer_fib_index = htonl (gt->outer_fib_index);
7391 mp->encap_index = htonl (gt->encap_index);
7392 mp->hw_if_index = htonl (gt->hw_if_index);
7393 mp->l2_only = htonl (gt->l2_only);
7394 mp->nlabels = htonl (nlabels);
7396 for (i = 0; i < nlabels; i++)
7399 htonl (vnet_mpls_uc_get_label
7400 (clib_host_to_net_u32 (e->labels[i].label_exp_s_ttl)));
7403 vl_msg_api_send_shmem (q, (u8 *) & mp);
7407 vl_api_mpls_gre_tunnel_dump_t_handler (vl_api_mpls_gre_tunnel_dump_t * mp)
7409 vpe_api_main_t *am = &vpe_api_main;
7410 unix_shared_memory_queue_t *q;
7411 mpls_main_t *mm = &mpls_main;
7412 mpls_gre_tunnel_t *gt;
7413 u32 index = ntohl (mp->tunnel_index);
7415 q = vl_api_client_index_to_input_queue (mp->client_index);
7421 if (!pool_is_free_index (mm->gre_tunnels, index))
7423 gt = pool_elt_at_index (mm->gre_tunnels, index);
7424 send_mpls_gre_tunnel_entry (am, q, gt, gt - mm->gre_tunnels,
7431 pool_foreach (gt, mm->gre_tunnels,
7433 send_mpls_gre_tunnel_entry (am, q, gt, gt - mm->gre_tunnels,
7441 vl_api_mpls_eth_tunnel_details_t_handler (vl_api_mpls_eth_tunnel_details_t *
7444 clib_warning ("BUG");
7448 send_mpls_eth_tunnel_entry (vpe_api_main_t * am,
7449 unix_shared_memory_queue_t * q,
7450 mpls_eth_tunnel_t * et, u32 index, u32 context)
7452 mpls_main_t *mm = &mpls_main;
7456 vl_api_mpls_eth_tunnel_details_t *mp;
7458 e = pool_elt_at_index (mm->encaps, et->encap_index);
7459 nlabels = vec_len (e->labels);
7461 mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
7462 memset (mp, 0, sizeof (*mp));
7463 mp->_vl_msg_id = ntohs (VL_API_MPLS_ETH_TUNNEL_DETAILS);
7464 mp->context = context;
7466 mp->tunnel_index = htonl (index);
7467 memcpy (mp->tunnel_dst_mac, et->tunnel_dst, 6);
7468 mp->intfc_address = et->intfc_address.as_u32;
7469 mp->tx_sw_if_index = htonl (et->tx_sw_if_index);
7470 mp->inner_fib_index = htonl (et->inner_fib_index);
7471 mp->mask_width = htonl (et->mask_width);
7472 mp->encap_index = htonl (et->encap_index);
7473 mp->hw_if_index = htonl (et->hw_if_index);
7474 mp->l2_only = htonl (et->l2_only);
7475 mp->nlabels = htonl (nlabels);
7477 for (i = 0; i < nlabels; i++)
7480 htonl (vnet_mpls_uc_get_label
7481 (clib_host_to_net_u32 (e->labels[i].label_exp_s_ttl)));
7484 vl_msg_api_send_shmem (q, (u8 *) & mp);
7488 vl_api_mpls_eth_tunnel_dump_t_handler (vl_api_mpls_eth_tunnel_dump_t * mp)
7490 vpe_api_main_t *am = &vpe_api_main;
7491 unix_shared_memory_queue_t *q;
7492 mpls_main_t *mm = &mpls_main;
7493 mpls_eth_tunnel_t *et;
7494 u32 index = ntohl (mp->tunnel_index);
7496 q = vl_api_client_index_to_input_queue (mp->client_index);
7502 if (!pool_is_free_index (mm->eth_tunnels, index))
7504 et = pool_elt_at_index (mm->eth_tunnels, index);
7505 send_mpls_eth_tunnel_entry (am, q, et, et - mm->eth_tunnels,
7512 pool_foreach (et, mm->eth_tunnels,
7514 send_mpls_eth_tunnel_entry (am, q, et, et - mm->eth_tunnels,
7522 vl_api_mpls_fib_encap_details_t_handler (vl_api_mpls_fib_encap_details_t * mp)
7524 clib_warning ("BUG");
7528 send_mpls_fib_encap_details (vpe_api_main_t * am,
7529 unix_shared_memory_queue_t * q,
7530 show_mpls_fib_t * s, u32 context)
7532 vl_api_mpls_fib_encap_details_t *mp;
7533 mpls_main_t *mm = &mpls_main;
7538 e = pool_elt_at_index (mm->encaps, s->entry_index);
7539 nlabels = vec_len (e->labels);
7541 mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
7542 memset (mp, 0, sizeof (*mp));
7543 mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_ENCAP_DETAILS);
7544 mp->context = context;
7546 mp->fib_index = htonl (s->fib_index);
7547 mp->entry_index = htonl (s->entry_index);
7549 mp->s_bit = htonl (s->s_bit);
7551 mp->nlabels = htonl (nlabels);
7553 for (i = 0; i < nlabels; i++)
7556 htonl (vnet_mpls_uc_get_label
7557 (clib_host_to_net_u32 (e->labels[i].label_exp_s_ttl)));
7560 vl_msg_api_send_shmem (q, (u8 *) & mp);
7564 vl_api_mpls_fib_encap_dump_t_handler (vl_api_mpls_fib_encap_dump_t * mp)
7566 vpe_api_main_t *am = &vpe_api_main;
7567 unix_shared_memory_queue_t *q;
7568 vlib_main_t *vm = &vlib_global_main;
7571 show_mpls_fib_t *records = 0;
7573 mpls_main_t *mm = &mpls_main;
7574 ip4_main_t *im = &ip4_main;
7577 q = vl_api_client_index_to_input_queue (mp->client_index);
7582 hash_foreach (key, value, mm->mpls_encap_by_fib_and_dest,
7584 vec_add2 (records, s, 1);
7585 s->fib_index = (u32)(key>>32);
7586 s->dest = (u32)(key & 0xFFFFFFFF);
7587 s->entry_index = (u32) value;
7591 if (0 == vec_len (records))
7593 vlib_cli_output (vm, "MPLS encap table empty");
7597 /* sort output by dst address within fib */
7598 vec_sort_with_function (records, mpls_dest_cmp);
7599 vec_sort_with_function (records, mpls_fib_index_cmp);
7600 vlib_cli_output (vm, "MPLS encap table");
7601 vlib_cli_output (vm, "%=6s%=16s%=16s", "Table", "Dest address", "Labels");
7602 vec_foreach (s, records)
7604 rx_fib = vec_elt_at_index (im->fibs, s->fib_index);
7605 vlib_cli_output (vm, "%=6d%=16U%=16U", rx_fib->table_id,
7606 format_ip4_address, &s->dest, format_mpls_encap_index,
7607 mm, s->entry_index);
7608 send_mpls_fib_encap_details (am, q, s, mp->context);
7616 vl_api_mpls_fib_decap_details_t_handler (vl_api_mpls_fib_decap_details_t * mp)
7618 clib_warning ("BUG");
7622 send_mpls_fib_decap_details (vpe_api_main_t * am,
7623 unix_shared_memory_queue_t * q,
7624 show_mpls_fib_t * s,
7626 u32 tx_table_id, char *swif_tag, u32 context)
7628 vl_api_mpls_fib_decap_details_t *mp;
7630 mp = vl_msg_api_alloc (sizeof (*mp));
7631 memset (mp, 0, sizeof (*mp));
7632 mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_DECAP_DETAILS);
7633 mp->context = context;
7635 mp->fib_index = htonl (s->fib_index);
7636 mp->entry_index = htonl (s->entry_index);
7638 mp->s_bit = htonl (s->s_bit);
7639 mp->label = htonl (s->label);
7640 mp->rx_table_id = htonl (rx_table_id);
7641 mp->tx_table_id = htonl (tx_table_id);
7642 strncpy ((char *) mp->swif_tag,
7643 (char *) swif_tag, ARRAY_LEN (mp->swif_tag) - 1);
7645 vl_msg_api_send_shmem (q, (u8 *) & mp);
7649 vl_api_mpls_fib_decap_dump_t_handler (vl_api_mpls_fib_decap_dump_t * mp)
7651 vpe_api_main_t *am = &vpe_api_main;
7652 unix_shared_memory_queue_t *q;
7653 vlib_main_t *vm = &vlib_global_main;
7656 show_mpls_fib_t *records = 0;
7658 mpls_main_t *mm = &mpls_main;
7659 ip4_main_t *im = &ip4_main;
7665 q = vl_api_client_index_to_input_queue (mp->client_index);
7670 hash_foreach (key, value, mm->mpls_decap_by_rx_fib_and_label,
7672 vec_add2 (records, s, 1);
7673 s->fib_index = (u32)(key>>32);
7674 s->entry_index = (u32) value;
7675 s->label = ((u32) key)>>12;
7676 s->s_bit = (key & (1<<8)) != 0;
7680 if (!vec_len (records))
7682 vlib_cli_output (vm, "MPLS decap table empty");
7686 vec_sort_with_function (records, mpls_label_cmp);
7687 vlib_cli_output (vm, "MPLS decap table");
7688 vlib_cli_output (vm, "%=10s%=15s%=6s%=6s", "RX Table", "TX Table/Intfc",
7690 vec_foreach (s, records)
7693 d = pool_elt_at_index (mm->decaps, s->entry_index);
7694 if (d->next_index == MPLS_INPUT_NEXT_IP4_INPUT)
7696 tx_fib = vec_elt_at_index (im->fibs, d->tx_fib_index);
7697 tx_table_id = tx_fib->table_id;
7702 tx_table_id = d->tx_fib_index;
7705 rx_fib = vec_elt_at_index (im->fibs, s->fib_index);
7707 vlib_cli_output (vm, "%=10d%=10d%=5s%=6d%=6d", rx_fib->table_id,
7708 tx_table_id, swif_tag, s->label, s->s_bit);
7710 send_mpls_fib_decap_details (am, q, s, rx_fib->table_id,
7711 tx_table_id, swif_tag, mp->context);
7719 vl_api_classify_table_ids_t_handler (vl_api_classify_table_ids_t * mp)
7721 unix_shared_memory_queue_t *q;
7723 q = vl_api_client_index_to_input_queue (mp->client_index);
7727 vnet_classify_main_t *cm = &vnet_classify_main;
7728 vnet_classify_table_t *t;
7733 pool_foreach (t, cm->tables,
7735 vec_add1 (table_ids, ntohl(t - cm->tables));
7738 count = vec_len (table_ids);
7740 vl_api_classify_table_ids_reply_t *rmp;
7741 rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp) + count * sizeof (u32));
7742 rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TABLE_IDS_REPLY);
7743 rmp->context = mp->context;
7744 rmp->count = ntohl (count);
7745 clib_memcpy (rmp->ids, table_ids, count * sizeof (u32));
7748 vl_msg_api_send_shmem (q, (u8 *) & rmp);
7750 vec_free (table_ids);
7754 vl_api_classify_table_by_interface_t_handler
7755 (vl_api_classify_table_by_interface_t * mp)
7757 vl_api_classify_table_by_interface_reply_t *rmp;
7760 u32 sw_if_index = ntohl (mp->sw_if_index);
7763 vec_validate (acl, INPUT_ACL_N_TABLES - 1);
7766 VALIDATE_SW_IF_INDEX (mp);
7768 input_acl_main_t *am = &input_acl_main;
7773 for (type = 0; type < INPUT_ACL_N_TABLES; type++)
7775 u32 *vec_tbl = am->classify_table_index_by_sw_if_index[type];
7776 if (vec_len (vec_tbl))
7778 for (if_idx = 0; if_idx < vec_len (vec_tbl); if_idx++)
7780 if (vec_elt (vec_tbl, if_idx) == ~0 || sw_if_index != if_idx)
7784 acl[type] = vec_elt (vec_tbl, if_idx);
7789 BAD_SW_IF_INDEX_LABEL;
7792 REPLY_MACRO2(VL_API_CLASSIFY_TABLE_BY_INTERFACE_REPLY,
7794 rmp->sw_if_index = ntohl(sw_if_index);
7795 rmp->l2_table_id = ntohl(acl[INPUT_ACL_TABLE_L2]);
7796 rmp->ip4_table_id = ntohl(acl[INPUT_ACL_TABLE_IP4]);
7797 rmp->ip6_table_id = ntohl(acl[INPUT_ACL_TABLE_IP6]);
7804 vl_api_classify_table_info_t_handler (vl_api_classify_table_info_t * mp)
7806 unix_shared_memory_queue_t *q;
7808 q = vl_api_client_index_to_input_queue (mp->client_index);
7812 vl_api_classify_table_info_reply_t *rmp = 0;
7814 vnet_classify_main_t *cm = &vnet_classify_main;
7815 u32 table_id = ntohl (mp->table_id);
7816 vnet_classify_table_t *t;
7819 pool_foreach (t, cm->tables,
7821 if (table_id == t - cm->tables)
7823 rmp = vl_msg_api_alloc_as_if_client
7824 (sizeof (*rmp) + t->match_n_vectors * sizeof (u32x4));
7825 rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TABLE_INFO_REPLY);
7826 rmp->context = mp->context;
7827 rmp->table_id = ntohl(table_id);
7828 rmp->nbuckets = ntohl(t->nbuckets);
7829 rmp->match_n_vectors = ntohl(t->match_n_vectors);
7830 rmp->skip_n_vectors = ntohl(t->skip_n_vectors);
7831 rmp->active_sessions = ntohl(t->active_elements);
7832 rmp->next_table_index = ntohl(t->next_table_index);
7833 rmp->miss_next_index = ntohl(t->miss_next_index);
7834 rmp->mask_length = ntohl(t->match_n_vectors * sizeof (u32x4));
7835 clib_memcpy(rmp->mask, t->mask, t->match_n_vectors * sizeof(u32x4));
7844 rmp = vl_msg_api_alloc (sizeof (*rmp));
7845 rmp->_vl_msg_id = ntohs ((VL_API_CLASSIFY_TABLE_INFO_REPLY));
7846 rmp->context = mp->context;
7847 rmp->retval = ntohl (VNET_API_ERROR_CLASSIFY_TABLE_NOT_FOUND);
7850 vl_msg_api_send_shmem (q, (u8 *) & rmp);
7854 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
7857 clib_warning ("BUG");
7861 send_classify_session_details (unix_shared_memory_queue_t * q,
7864 vnet_classify_entry_t * e, u32 context)
7866 vl_api_classify_session_details_t *rmp;
7868 rmp = vl_msg_api_alloc (sizeof (*rmp));
7869 memset (rmp, 0, sizeof (*rmp));
7870 rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_SESSION_DETAILS);
7871 rmp->context = context;
7872 rmp->table_id = ntohl (table_id);
7873 rmp->hit_next_index = ntohl (e->next_index);
7874 rmp->advance = ntohl (e->advance);
7875 rmp->opaque_index = ntohl (e->opaque_index);
7876 rmp->match_length = ntohl (match_length);
7877 clib_memcpy (rmp->match, e->key, match_length);
7879 vl_msg_api_send_shmem (q, (u8 *) & rmp);
7883 vl_api_classify_session_dump_t_handler (vl_api_classify_session_dump_t * mp)
7885 vnet_classify_main_t *cm = &vnet_classify_main;
7886 unix_shared_memory_queue_t *q;
7888 u32 table_id = ntohl (mp->table_id);
7889 vnet_classify_table_t *t;
7891 q = vl_api_client_index_to_input_queue (mp->client_index);
7894 pool_foreach (t, cm->tables,
7896 if (table_id == t - cm->tables)
7898 vnet_classify_bucket_t * b;
7899 vnet_classify_entry_t * v, * save_v;
7902 for (i = 0; i < t->nbuckets; i++)
7904 b = &t->buckets [i];
7908 save_v = vnet_classify_get_entry (t, b->offset);
7909 for (j = 0; j < (1<<b->log2_pages); j++)
7911 for (k = 0; k < t->entries_per_page; k++)
7913 v = vnet_classify_entry_at_index
7914 (t, save_v, j*t->entries_per_page + k);
7915 if (vnet_classify_entry_is_free (v))
7918 send_classify_session_details
7919 (q, table_id, t->match_n_vectors * sizeof (u32x4),
7931 vl_api_ipfix_enable_t_handler (vl_api_ipfix_enable_t * mp)
7933 vlib_main_t *vm = vlib_get_main ();
7934 flow_report_main_t *frm = &flow_report_main;
7935 vl_api_ipfix_enable_reply_t *rmp;
7936 ip4_address_t collector, src;
7937 u16 collector_port = UDP_DST_PORT_ipfix;
7939 u32 template_interval;
7944 memcpy (collector.data, mp->collector_address, sizeof (collector.data));
7945 collector_port = ntohs (mp->collector_port);
7946 if (collector_port == (u16) ~ 0)
7947 collector_port = UDP_DST_PORT_ipfix;
7948 memcpy (src.data, mp->src_address, sizeof (src.data));
7949 fib_id = ntohl (mp->vrf_id);
7951 ip4_main_t *im = &ip4_main;
7952 uword *p = hash_get (im->fib_index_by_table_id, fib_id);
7955 rv = VNET_API_ERROR_NO_SUCH_FIB;
7960 path_mtu = ntohl (mp->path_mtu);
7962 path_mtu = 512; // RFC 7011 section 10.3.3.
7963 template_interval = ntohl (mp->template_interval);
7964 if (template_interval == ~0)
7965 template_interval = 20;
7967 if (collector.as_u32 == 0)
7969 rv = VNET_API_ERROR_INVALID_VALUE;
7973 if (src.as_u32 == 0)
7975 rv = VNET_API_ERROR_INVALID_VALUE;
7979 if (path_mtu > 1450 /* vpp does not support fragmentation */ )
7981 rv = VNET_API_ERROR_INVALID_VALUE;
7987 rv = VNET_API_ERROR_INVALID_VALUE;
7991 /* Reset report streams if we are reconfiguring IP addresses */
7992 if (frm->ipfix_collector.as_u32 != collector.as_u32 ||
7993 frm->src_address.as_u32 != src.as_u32 ||
7994 frm->collector_port != collector_port)
7995 vnet_flow_reports_reset (frm);
7997 frm->ipfix_collector.as_u32 = collector.as_u32;
7998 frm->collector_port = collector_port;
7999 frm->src_address.as_u32 = src.as_u32;
8000 frm->fib_index = fib_index;
8001 frm->path_mtu = path_mtu;
8002 frm->template_interval = template_interval;
8004 /* Turn on the flow reporting process */
8005 vlib_process_signal_event (vm, flow_report_process_node.index, 1, 0);
8008 REPLY_MACRO (VL_API_IPFIX_ENABLE_REPLY);
8012 vl_api_ipfix_dump_t_handler (vl_api_ipfix_dump_t * mp)
8014 flow_report_main_t *frm = &flow_report_main;
8015 unix_shared_memory_queue_t *q;
8016 vl_api_ipfix_details_t *rmp;
8018 q = vl_api_client_index_to_input_queue (mp->client_index);
8022 rmp = vl_msg_api_alloc (sizeof (*rmp));
8023 memset (rmp, 0, sizeof (*rmp));
8024 rmp->_vl_msg_id = ntohs (VL_API_IPFIX_DETAILS);
8025 rmp->context = mp->context;
8026 memcpy (rmp->collector_address, frm->ipfix_collector.data,
8027 sizeof (frm->ipfix_collector.data));
8028 rmp->collector_port = htons (frm->collector_port);
8029 memcpy (rmp->src_address, frm->src_address.data,
8030 sizeof (frm->src_address.data));
8031 rmp->fib_index = htonl (frm->fib_index);
8032 rmp->path_mtu = htonl (frm->path_mtu);
8033 rmp->template_interval = htonl (frm->template_interval);
8035 vl_msg_api_send_shmem (q, (u8 *) & rmp);
8039 vl_api_pg_create_interface_t_handler (vl_api_pg_create_interface_t * mp)
8041 vl_api_pg_create_interface_reply_t *rmp;
8044 pg_main_t *pg = &pg_main;
8045 u32 sw_if_index = pg_interface_add_or_get (pg, ntohl (mp->interface_id));
8048 REPLY_MACRO2(VL_API_PG_CREATE_INTERFACE_REPLY,
8050 rmp->sw_if_index = ntohl(sw_if_index);
8056 vl_api_pg_capture_t_handler (vl_api_pg_capture_t * mp)
8058 vl_api_pg_capture_reply_t *rmp;
8061 vnet_main_t *vnm = vnet_get_main ();
8062 vnet_interface_main_t *im = &vnm->interface_main;
8063 vnet_hw_interface_t *hi = 0;
8065 u8 *intf_name = format (0, "pg%d", ntohl (mp->interface_id), 0);
8066 u32 hw_if_index = ~0;
8067 uword *p = hash_get_mem (im->hw_interface_by_name, intf_name);
8070 vec_free (intf_name);
8072 if (hw_if_index != ~0)
8074 pg_capture_args_t _a, *a = &_a;
8076 u32 len = ntohl (mp->pcap_name_length);
8077 u8 *pcap_file_name = vec_new (u8, len);
8078 clib_memcpy (pcap_file_name, mp->pcap_file_name, len);
8080 hi = vnet_get_sup_hw_interface (vnm, hw_if_index);
8081 a->hw_if_index = hw_if_index;
8082 a->dev_instance = hi->dev_instance;
8083 a->is_enabled = mp->is_enabled;
8084 a->pcap_file_name = pcap_file_name;
8085 a->count = ntohl (mp->count);
8087 clib_error_t *e = pg_capture (a);
8090 clib_error_report (e);
8091 rv = VNET_API_ERROR_CANNOT_CREATE_PCAP_FILE;
8094 vec_free (pcap_file_name);
8096 REPLY_MACRO (VL_API_PG_CAPTURE_REPLY);
8100 vl_api_pg_enable_disable_t_handler (vl_api_pg_enable_disable_t * mp)
8102 vl_api_pg_enable_disable_reply_t *rmp;
8105 pg_main_t *pg = &pg_main;
8106 u32 stream_index = ~0;
8108 int is_enable = mp->is_enabled != 0;
8109 u32 len = ntohl (mp->stream_name_length) - 1;
8113 u8 *stream_name = vec_new (u8, len);
8114 clib_memcpy (stream_name, mp->stream_name, len);
8115 uword *p = hash_get_mem (pg->stream_index_by_name, stream_name);
8118 vec_free (stream_name);
8121 pg_enable_disable (stream_index, is_enable);
8123 REPLY_MACRO (VL_API_PG_ENABLE_DISABLE_REPLY);
8127 vl_api_ip_source_and_port_range_check_add_del_t_handler
8128 (vl_api_ip_source_and_port_range_check_add_del_t * mp)
8130 vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
8133 u8 is_ipv6 = mp->is_ipv6;
8134 u8 is_add = mp->is_add;
8135 u8 mask_length = mp->mask_length;
8136 ip4_address_t ip4_addr;
8137 ip6_address_t ip6_addr;
8139 u16 *high_ports = 0;
8141 u16 tmp_low, tmp_high;
8145 // Validate port range
8146 num_ranges = mp->number_of_ranges;
8147 if (num_ranges > 32)
8148 { // This is size of array in VPE.API
8149 rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
8153 vec_reset_length (low_ports);
8154 vec_reset_length (high_ports);
8156 for (i = 0; i < num_ranges; i++)
8158 tmp_low = mp->low_ports[i];
8159 tmp_high = mp->high_ports[i];
8160 // If tmp_low <= tmp_high then only need to check tmp_low = 0
8161 // If tmp_low <= tmp_high then only need to check tmp_high > 65535
8162 if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535)
8164 rv = VNET_API_ERROR_INVALID_VALUE;
8167 vec_add1 (low_ports, tmp_low);
8168 vec_add1 (high_ports, tmp_high + 1);
8171 // Validate mask_length
8172 if ((is_ipv6 && mask_length > 128) || (!is_ipv6 && mask_length > 32))
8174 rv = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH;
8178 vrf_id = ntohl (mp->vrf_id);
8182 rv = VNET_API_ERROR_INVALID_VALUE;
8189 clib_memcpy (ip6_addr.as_u8, mp->address, sizeof (ip6_addr.as_u8));
8190 rv = ip6_source_and_port_range_check_add_del (&ip6_addr,
8194 high_ports, is_add);
8198 clib_memcpy (ip4_addr.data, mp->address, sizeof (ip4_addr));
8199 rv = ip4_source_and_port_range_check_add_del (&ip4_addr,
8203 high_ports, is_add);
8207 vec_free (low_ports);
8208 vec_free (high_ports);
8209 REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY);
8213 vl_api_ip_source_and_port_range_check_interface_add_del_t_handler
8214 (vl_api_ip_source_and_port_range_check_interface_add_del_t * mp)
8216 vlib_main_t *vm = vlib_get_main ();
8217 vl_api_ip_source_and_port_range_check_interface_add_del_reply_t *rmp;
8218 ip4_main_t *im = &ip4_main;
8221 u32 fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS];
8222 u32 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS];
8226 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT] =
8227 ntohl (mp->tcp_out_vrf_id);
8228 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT] =
8229 ntohl (mp->udp_out_vrf_id);
8230 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN] =
8231 ntohl (mp->tcp_in_vrf_id);
8232 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_IN] =
8233 ntohl (mp->udp_in_vrf_id);
8236 for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
8238 if (vrf_id[i] != 0 && vrf_id[i] != ~0)
8240 p = hash_get (im->fib_index_by_table_id, vrf_id[i]);
8244 rv = VNET_API_ERROR_INVALID_VALUE;
8248 fib_index[i] = p[0];
8253 sw_if_index = ntohl (mp->sw_if_index);
8255 VALIDATE_SW_IF_INDEX (mp);
8258 set_ip_source_and_port_range_check (vm, fib_index, sw_if_index,
8261 BAD_SW_IF_INDEX_LABEL;
8264 REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY);
8268 vl_api_ipsec_gre_add_del_tunnel_t_handler (vl_api_ipsec_gre_add_del_tunnel_t *
8271 vl_api_ipsec_gre_add_del_tunnel_reply_t *rmp;
8273 vnet_ipsec_gre_add_del_tunnel_args_t _a, *a = &_a;
8274 u32 sw_if_index = ~0;
8276 /* Check src & dst are different */
8277 if (memcmp (mp->src_address, mp->dst_address, 4) == 0)
8279 rv = VNET_API_ERROR_SAME_SRC_DST;
8283 memset (a, 0, sizeof (*a));
8285 /* ip addresses sent in network byte order */
8286 clib_memcpy (&(a->src), mp->src_address, 4);
8287 clib_memcpy (&(a->dst), mp->dst_address, 4);
8288 a->is_add = mp->is_add;
8289 a->lsa = ntohl (mp->local_sa_id);
8290 a->rsa = ntohl (mp->remote_sa_id);
8292 rv = vnet_ipsec_gre_add_del_tunnel (a, &sw_if_index);
8296 REPLY_MACRO2(VL_API_GRE_ADD_DEL_TUNNEL_REPLY,
8298 rmp->sw_if_index = ntohl (sw_if_index);
8303 static void send_ipsec_gre_tunnel_details
8304 (ipsec_gre_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
8306 vl_api_ipsec_gre_tunnel_details_t *rmp;
8308 rmp = vl_msg_api_alloc (sizeof (*rmp));
8309 memset (rmp, 0, sizeof (*rmp));
8310 rmp->_vl_msg_id = ntohs (VL_API_IPSEC_GRE_TUNNEL_DETAILS);
8311 clib_memcpy (rmp->src_address, &(t->tunnel_src), 4);
8312 clib_memcpy (rmp->dst_address, &(t->tunnel_dst), 4);
8313 rmp->sw_if_index = htonl (t->sw_if_index);
8314 rmp->local_sa_id = htonl (t->local_sa_id);
8315 rmp->remote_sa_id = htonl (t->remote_sa_id);
8316 rmp->context = context;
8318 vl_msg_api_send_shmem (q, (u8 *) & rmp);
8321 static void vl_api_ipsec_gre_tunnel_dump_t_handler
8322 (vl_api_ipsec_gre_tunnel_dump_t * mp)
8324 unix_shared_memory_queue_t *q;
8325 ipsec_gre_main_t *igm = &ipsec_gre_main;
8326 ipsec_gre_tunnel_t *t;
8329 q = vl_api_client_index_to_input_queue (mp->client_index);
8335 sw_if_index = ntohl (mp->sw_if_index);
8337 if (~0 == sw_if_index)
8340 pool_foreach (t, igm->tunnels,
8342 send_ipsec_gre_tunnel_details(t, q, mp->context);
8348 if ((sw_if_index >= vec_len (igm->tunnel_index_by_sw_if_index)) ||
8349 (~0 == igm->tunnel_index_by_sw_if_index[sw_if_index]))
8353 t = &igm->tunnels[igm->tunnel_index_by_sw_if_index[sw_if_index]];
8354 send_ipsec_gre_tunnel_details (t, q, mp->context);
8359 vl_api_delete_subif_t_handler (vl_api_delete_subif_t * mp)
8361 vl_api_delete_subif_reply_t *rmp;
8364 rv = vnet_delete_sub_interface (ntohl (mp->sw_if_index));
8366 REPLY_MACRO (VL_API_DELETE_SUBIF_REPLY);
8369 #define BOUNCE_HANDLER(nn) \
8370 static void vl_api_##nn##_t_handler ( \
8371 vl_api_##nn##_t *mp) \
8373 vpe_client_registration_t *reg; \
8374 vpe_api_main_t * vam = &vpe_api_main; \
8375 unix_shared_memory_queue_t * q; \
8377 /* One registration only... */ \
8378 pool_foreach(reg, vam->nn##_registrations, \
8380 q = vl_api_client_index_to_input_queue (reg->client_index); \
8383 * If the queue is stuffed, turf the msg and complain \
8384 * It's unlikely that the intended recipient is \
8385 * alive; avoid deadlock at all costs. \
8387 if (q->cursize == q->maxsize) { \
8388 clib_warning ("ERROR: receiver queue full, drop msg"); \
8389 vl_msg_api_free (mp); \
8392 vl_msg_api_send_shmem (q, (u8 *)&mp); \
8396 vl_msg_api_free (mp); \
8401 * Add vpe's API message handlers to the table.
8402 * vlib has alread mapped shared memory and
8403 * added the client registration handlers.
8404 * See .../open-repo/vlib/memclnt_vlib.c:memclnt_process()
8407 static clib_error_t *
8408 vpe_api_hookup (vlib_main_t * vm)
8410 api_main_t *am = &api_main;
8413 vl_msg_api_set_handlers(VL_API_##N, #n, \
8414 vl_api_##n##_t_handler, \
8416 vl_api_##n##_t_endian, \
8417 vl_api_##n##_t_print, \
8418 sizeof(vl_api_##n##_t), 1);
8419 foreach_vpe_api_msg;
8423 * Manually register the sr tunnel add del msg, so we trace
8424 * enough bytes to capture a typical segment list
8426 vl_msg_api_set_handlers (VL_API_SR_TUNNEL_ADD_DEL,
8427 "sr_tunnel_add_del",
8428 vl_api_sr_tunnel_add_del_t_handler,
8430 vl_api_sr_tunnel_add_del_t_endian,
8431 vl_api_sr_tunnel_add_del_t_print, 256, 1);
8435 * Manually register the sr policy add del msg, so we trace
8436 * enough bytes to capture a typical tunnel name list
8438 vl_msg_api_set_handlers (VL_API_SR_POLICY_ADD_DEL,
8439 "sr_policy_add_del",
8440 vl_api_sr_policy_add_del_t_handler,
8442 vl_api_sr_policy_add_del_t_endian,
8443 vl_api_sr_policy_add_del_t_print, 256, 1);
8446 * Trace space for 8 MPLS encap labels, classifier mask+match
8448 am->api_trace_cfg[VL_API_MPLS_ADD_DEL_ENCAP].size += 8 * sizeof (u32);
8449 am->api_trace_cfg[VL_API_CLASSIFY_ADD_DEL_TABLE].size += 5 * sizeof (u32x4);
8450 am->api_trace_cfg[VL_API_CLASSIFY_ADD_DEL_SESSION].size
8451 += 5 * sizeof (u32x4);
8452 am->api_trace_cfg[VL_API_VXLAN_ADD_DEL_TUNNEL].size += 16 * sizeof (u32);
8455 * Thread-safe API messages
8457 am->is_mp_safe[VL_API_IP_ADD_DEL_ROUTE] = 1;
8458 am->is_mp_safe[VL_API_GET_NODE_GRAPH] = 1;
8463 VLIB_API_INIT_FUNCTION (vpe_api_hookup);
8465 static clib_error_t *
8466 vpe_api_init (vlib_main_t * vm)
8468 vpe_api_main_t *am = &vpe_api_main;
8471 am->vnet_main = vnet_get_main ();
8472 am->interface_events_registration_hash = hash_create (0, sizeof (uword));
8473 am->to_netconf_server_registration_hash = hash_create (0, sizeof (uword));
8474 am->from_netconf_server_registration_hash = hash_create (0, sizeof (uword));
8475 am->to_netconf_client_registration_hash = hash_create (0, sizeof (uword));
8476 am->from_netconf_client_registration_hash = hash_create (0, sizeof (uword));
8477 am->oam_events_registration_hash = hash_create (0, sizeof (uword));
8480 vl_set_memory_region_name ("/vpe-api");
8481 vl_enable_disable_memory_api (vm, 1 /* enable it */ );
8486 VLIB_INIT_FUNCTION (vpe_api_init);
8489 static clib_error_t *
8490 api_segment_config (vlib_main_t * vm, unformat_input_t * input)
8493 u64 baseva, size, pvt_heap_size;
8495 const int max_buf_size = 4096;
8497 struct passwd _pw, *pw;
8498 struct group _grp, *grp;
8500 buf = vec_new (char, 128);
8501 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8503 if (unformat (input, "prefix %s", &chroot_path))
8505 vec_add1 (chroot_path, 0);
8506 vl_set_memory_root_path ((char *) chroot_path);
8508 else if (unformat (input, "uid %d", &uid))
8509 vl_set_memory_uid (uid);
8510 else if (unformat (input, "gid %d", &gid))
8511 vl_set_memory_gid (gid);
8512 else if (unformat (input, "baseva %llx", &baseva))
8513 vl_set_global_memory_baseva (baseva);
8514 else if (unformat (input, "global-size %lldM", &size))
8515 vl_set_global_memory_size (size * (1ULL << 20));
8516 else if (unformat (input, "global-size %lldG", &size))
8517 vl_set_global_memory_size (size * (1ULL << 30));
8518 else if (unformat (input, "global-size %lld", &size))
8519 vl_set_global_memory_size (size);
8520 else if (unformat (input, "global-pvt-heap-size %lldM", &pvt_heap_size))
8521 vl_set_global_pvt_heap_size (pvt_heap_size * (1ULL << 20));
8522 else if (unformat (input, "global-pvt-heap-size size %lld",
8524 vl_set_global_pvt_heap_size (pvt_heap_size);
8525 else if (unformat (input, "api-pvt-heap-size %lldM", &pvt_heap_size))
8526 vl_set_api_pvt_heap_size (pvt_heap_size * (1ULL << 20));
8527 else if (unformat (input, "api-pvt-heap-size size %lld",
8529 vl_set_api_pvt_heap_size (pvt_heap_size);
8530 else if (unformat (input, "api-size %lldM", &size))
8531 vl_set_api_memory_size (size * (1ULL << 20));
8532 else if (unformat (input, "api-size %lldG", &size))
8533 vl_set_api_memory_size (size * (1ULL << 30));
8534 else if (unformat (input, "api-size %lld", &size))
8535 vl_set_api_memory_size (size);
8536 else if (unformat (input, "uid %s", &s))
8538 /* lookup the username */
8541 getpwnam_r (s, &_pw, buf, vec_len (buf), &pw)) == ERANGE)
8542 && (vec_len (buf) <= max_buf_size))
8544 vec_resize (buf, vec_len (buf) * 2);
8548 e = clib_error_return_code (0, rv,
8549 CLIB_ERROR_ERRNO_VALID |
8551 "cannot fetch username %s", s);
8559 clib_error_return_fatal (0, "username %s does not exist", s);
8565 vl_set_memory_uid (pw->pw_uid);
8567 else if (unformat (input, "gid %s", &s))
8569 /* lookup the group name */
8572 getgrnam_r (s, &_grp, buf, vec_len (buf), &grp)) == ERANGE)
8573 && (vec_len (buf) <= max_buf_size))
8575 vec_resize (buf, vec_len (buf) * 2);
8579 e = clib_error_return_code (0, rv,
8580 CLIB_ERROR_ERRNO_VALID |
8582 "cannot fetch group %s", s);
8589 e = clib_error_return_fatal (0, "group %s does not exist", s);
8596 vl_set_memory_gid (grp->gr_gid);
8599 return clib_error_return (0, "unknown input `%U'",
8600 format_unformat_error, input);
8605 VLIB_EARLY_CONFIG_FUNCTION (api_segment_config, "api-segment");
8608 get_unformat_vnet_sw_interface (void)
8610 return (void *) &unformat_vnet_sw_interface;
8613 #undef vl_api_version
8614 #define vl_api_version(n,v) static u32 vpe_api_version = v;
8615 #include <vpp-api/vpe.api.h>
8616 #undef vl_api_version
8619 vl_msg_api_version_check (vl_api_memclnt_create_t * mp)
8621 if (clib_host_to_net_u32 (mp->api_versions[0]) != vpe_api_version)
8623 clib_warning ("vpe API mismatch: 0x%08x instead of 0x%08x",
8624 clib_host_to_net_u32 (mp->api_versions[0]),
8632 format_arp_event (u8 * s, va_list * args)
8634 vl_api_ip4_arp_event_t *event = va_arg (*args, vl_api_ip4_arp_event_t *);
8636 s = format (s, "pid %d: ", event->pid);
8638 s = format (s, "bd mac/ip4 binding events");
8640 s = format (s, "resolution for %U", format_ip4_address, &event->address);
8645 format_nd_event (u8 * s, va_list * args)
8647 vl_api_ip6_nd_event_t *event = va_arg (*args, vl_api_ip6_nd_event_t *);
8649 s = format (s, "pid %d: ", event->pid);
8651 s = format (s, "bd mac/ip6 binding events");
8653 s = format (s, "resolution for %U", format_ip6_address, event->address);
8657 static clib_error_t *
8658 show_ip_arp_nd_events_fn (vlib_main_t * vm,
8659 unformat_input_t * input, vlib_cli_command_t * cmd)
8661 vpe_api_main_t *am = &vpe_api_main;
8662 vl_api_ip4_arp_event_t *arp_event;
8663 vl_api_ip6_nd_event_t *nd_event;
8665 if ((pool_elts (am->arp_events) == 0) && (pool_elts (am->nd_events) == 0))
8667 vlib_cli_output (vm, "No active arp or nd event registrations");
8672 pool_foreach (arp_event, am->arp_events,
8674 vlib_cli_output (vm, "%U", format_arp_event, arp_event);
8677 pool_foreach (nd_event, am->nd_events,
8679 vlib_cli_output (vm, "%U", format_nd_event, nd_event);
8687 VLIB_CLI_COMMAND (show_ip_arp_nd_events, static) = {
8688 .path = "show arp-nd-event registrations",
8689 .function = show_ip_arp_nd_events_fn,
8690 .short_help = "Show ip4 arp and ip6 nd event registrations",
8695 * fd.io coding-style-patch-verification: ON
8698 * eval: (c-set-style "gnu")