2 *------------------------------------------------------------------
3 * api.c - message handler registration
5 * Copyright (c) 2010-2016 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/ip/ip6_neighbor.h>
56 #include <vnet/unix/tuntap.h>
57 #include <vnet/unix/tapcli.h>
58 #include <vnet/mpls/mpls.h>
59 #include <vnet/mpls/mpls_tunnel.h>
60 #include <vnet/dhcp/proxy.h>
61 #include <vnet/dhcp/client.h>
63 #include <vnet/sr/sr.h>
65 #include <vnet/dhcpv6/proxy.h>
66 #include <vlib/vlib.h>
67 #include <vlib/unix/unix.h>
68 #include <vlibapi/api.h>
69 #include <vlibmemory/api.h>
70 #include <vnet/classify/vnet_classify.h>
71 #include <vnet/classify/input_acl.h>
72 #include <vnet/classify/policer_classify.h>
73 #include <vnet/classify/flow_classify.h>
74 #include <vnet/l2/l2_classify.h>
75 #include <vnet/vxlan/vxlan.h>
76 #include <vnet/gre/gre.h>
77 #include <vnet/l2/l2_vtr.h>
78 #include <vnet/vxlan-gpe/vxlan_gpe.h>
79 #include <vnet/lisp-gpe/lisp_gpe.h>
80 #include <vnet/lisp-gpe/lisp_gpe_fwd_entry.h>
81 #include <vnet/lisp-gpe/lisp_gpe_tenant.h>
82 #include <vnet/lisp-cp/control.h>
83 #include <vnet/map/map.h>
84 #include <vnet/cop/cop.h>
85 #include <vnet/ip/ip6_hop_by_hop.h>
86 #include <vnet/ip/ip_source_and_port_range_check.h>
87 #include <vnet/devices/af_packet/af_packet.h>
88 #include <vnet/policer/policer.h>
89 #include <vnet/devices/netmap/netmap.h>
90 #include <vnet/flow/flow_report.h>
91 #include <vnet/ipsec-gre/ipsec_gre.h>
92 #include <vnet/flow/flow_report_classify.h>
93 #include <vnet/ip/punt.h>
94 #include <vnet/feature/feature.h>
97 #undef __included_bihash_template_h__
98 #include <vnet/l2/l2_fib.h>
101 #include <vnet/devices/dpdk/dpdk.h>
105 #include <vnet/ipsec/ipsec.h>
106 #include <vnet/ipsec/ikev2.h>
108 #include <vnet/devices/virtio/vhost-user.h>
110 #include <stats/stats.h>
113 #include <vnet/ethernet/ethernet.h>
114 #include <vnet/ethernet/arp_packet.h>
115 #include <vnet/interface.h>
117 #include <vnet/l2/l2_fib.h>
118 #include <vnet/l2/l2_bd.h>
119 #include <vpp-api/vpe_msg_enum.h>
120 #include <vnet/span/span.h>
122 #include <vnet/fib/ip6_fib.h>
123 #include <vnet/fib/ip4_fib.h>
124 #include <vnet/fib/fib_api.h>
125 #include <vnet/dpo/drop_dpo.h>
126 #include <vnet/dpo/receive_dpo.h>
127 #include <vnet/dpo/lookup_dpo.h>
128 #include <vnet/dpo/classify_dpo.h>
129 #include <vnet/dpo/ip_null_dpo.h>
131 #define vl_typedefs /* define message structures */
132 #include <vpp-api/vpe_all_api_h.h>
135 #define vl_endianfun /* define message structures */
136 #include <vpp-api/vpe_all_api_h.h>
139 /* instantiate all the print functions we know about */
140 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
142 #include <vpp-api/vpe_all_api_h.h>
145 #include <vlibapi/api_helper_macros.h>
147 #define foreach_vpe_api_msg \
148 _(WANT_OAM_EVENTS, want_oam_events) \
149 _(OAM_ADD_DEL, oam_add_del) \
150 _(MPLS_ROUTE_ADD_DEL, mpls_route_add_del) \
151 _(MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind) \
152 _(IS_ADDRESS_REACHABLE, is_address_reachable) \
153 _(SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable) \
154 _(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath) \
155 _(SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass) \
156 _(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect) \
157 _(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge) \
158 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe) \
159 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport) \
160 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl) \
161 _(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del) \
162 _(BRIDGE_DOMAIN_DUMP, bridge_domain_dump) \
163 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
164 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
165 _(L2FIB_ADD_DEL, l2fib_add_del) \
166 _(L2_FLAGS, l2_flags) \
167 _(BRIDGE_FLAGS, bridge_flags) \
168 _(TAP_CONNECT, tap_connect) \
169 _(TAP_MODIFY, tap_modify) \
170 _(TAP_DELETE, tap_delete) \
171 _(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump) \
172 _(CREATE_VLAN_SUBIF, create_vlan_subif) \
173 _(CREATE_SUBIF, create_subif) \
174 _(MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del) \
175 _(PROXY_ARP_ADD_DEL, proxy_arp_add_del) \
176 _(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable) \
177 _(VNET_GET_SUMMARY_STATS, vnet_get_summary_stats) \
178 _(RESET_FIB, reset_fib) \
179 _(DHCP_PROXY_CONFIG,dhcp_proxy_config) \
180 _(DHCP_PROXY_CONFIG_2,dhcp_proxy_config_2) \
181 _(DHCP_PROXY_SET_VSS,dhcp_proxy_set_vss) \
182 _(DHCP_CLIENT_CONFIG, dhcp_client_config) \
183 _(CREATE_LOOPBACK, create_loopback) \
184 _(CONTROL_PING, control_ping) \
185 _(CLI_REQUEST, cli_request) \
186 _(CLI_INBAND, cli_inband) \
187 _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \
188 _(L2_PATCH_ADD_DEL, l2_patch_add_del) \
189 _(CLASSIFY_ADD_DEL_TABLE, classify_add_del_table) \
190 _(CLASSIFY_ADD_DEL_SESSION, classify_add_del_session) \
191 _(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table) \
192 _(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables) \
193 _(GET_NODE_INDEX, get_node_index) \
194 _(ADD_NODE_NEXT, add_node_next) \
195 _(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel) \
196 _(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies) \
197 _(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable) \
198 _(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key) \
199 _(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump) \
200 _(VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel) \
201 _(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump) \
202 _(GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel) \
203 _(GRE_TUNNEL_DUMP, gre_tunnel_dump) \
204 _(L2_FIB_CLEAR_TABLE, l2_fib_clear_table) \
205 _(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter) \
206 _(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite) \
207 _(CREATE_VHOST_USER_IF, create_vhost_user_if) \
208 _(MODIFY_VHOST_USER_IF, modify_vhost_user_if) \
209 _(DELETE_VHOST_USER_IF, delete_vhost_user_if) \
210 _(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump) \
211 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
212 _(SHOW_VERSION, show_version) \
213 _(L2_FIB_TABLE_DUMP, l2_fib_table_dump) \
214 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
215 _(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel) \
216 _(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump) \
217 _(INTERFACE_NAME_RENUMBER, interface_name_renumber) \
218 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events) \
219 _(WANT_IP6_ND_EVENTS, want_ip6_nd_events) \
220 _(INPUT_ACL_SET_INTERFACE, input_acl_set_interface) \
221 _(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
222 _(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
223 _(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry) \
224 _(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry) \
225 _(IPSEC_SA_SET_KEY, ipsec_sa_set_key) \
226 _(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del) \
227 _(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth) \
228 _(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id) \
229 _(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts) \
230 _(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key) \
231 _(DELETE_LOOPBACK, delete_loopback) \
232 _(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del) \
233 _(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable) \
234 _(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable) \
235 _(GET_NODE_GRAPH, get_node_graph) \
236 _(IOAM_ENABLE, ioam_enable) \
237 _(IOAM_DISABLE, ioam_disable) \
238 _(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set) \
239 _(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator) \
240 _(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid) \
241 _(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry) \
242 _(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver) \
243 _(LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server) \
244 _(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable) \
245 _(LISP_ENABLE_DISABLE, lisp_enable_disable) \
246 _(LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable) \
247 _(LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable) \
248 _(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface) \
249 _(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping) \
250 _(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency) \
251 _(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set) \
252 _(LISP_MAP_REQUEST_MODE, lisp_map_request_mode) \
253 _(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map) \
254 _(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump) \
255 _(LISP_LOCATOR_DUMP, lisp_locator_dump) \
256 _(LISP_EID_TABLE_DUMP, lisp_eid_table_dump) \
257 _(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump) \
258 _(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump) \
259 _(LISP_MAP_SERVER_DUMP, lisp_map_server_dump) \
260 _(LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump) \
261 _(LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump) \
262 _(LISP_ADJACENCIES_GET, lisp_adjacencies_get) \
263 _(SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state) \
264 _(SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state) \
265 _(SHOW_LISP_STATUS, show_lisp_status) \
266 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, \
267 lisp_add_del_map_request_itr_rlocs) \
268 _(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs) \
269 _(SHOW_LISP_PITR, show_lisp_pitr) \
270 _(SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode) \
271 _(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del) \
272 _(AF_PACKET_CREATE, af_packet_create) \
273 _(AF_PACKET_DELETE, af_packet_delete) \
274 _(POLICER_ADD_DEL, policer_add_del) \
275 _(POLICER_DUMP, policer_dump) \
276 _(POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface) \
277 _(POLICER_CLASSIFY_DUMP, policer_classify_dump) \
278 _(NETMAP_CREATE, netmap_create) \
279 _(NETMAP_DELETE, netmap_delete) \
280 _(MPLS_TUNNEL_DUMP, mpls_tunnel_dump) \
281 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
282 _(MPLS_FIB_DUMP, mpls_fib_dump) \
283 _(MPLS_FIB_DETAILS, mpls_fib_details) \
284 _(CLASSIFY_TABLE_IDS,classify_table_ids) \
285 _(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface) \
286 _(CLASSIFY_TABLE_INFO,classify_table_info) \
287 _(CLASSIFY_SESSION_DUMP,classify_session_dump) \
288 _(CLASSIFY_SESSION_DETAILS,classify_session_details) \
289 _(SET_IPFIX_EXPORTER, set_ipfix_exporter) \
290 _(IPFIX_EXPORTER_DUMP, ipfix_exporter_dump) \
291 _(SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream) \
292 _(IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump) \
293 _(IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del) \
294 _(IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump) \
295 _(GET_NEXT_INDEX, get_next_index) \
296 _(PG_CREATE_INTERFACE, pg_create_interface) \
297 _(PG_CAPTURE, pg_capture) \
298 _(PG_ENABLE_DISABLE, pg_enable_disable) \
299 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \
300 ip_source_and_port_range_check_add_del) \
301 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \
302 ip_source_and_port_range_check_interface_add_del) \
303 _(IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel) \
304 _(IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump) \
305 _(DELETE_SUBIF, delete_subif) \
306 _(L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite) \
308 _(FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface) \
309 _(FLOW_CLASSIFY_DUMP, flow_classify_dump) \
310 _(IPSEC_SPD_DUMP, ipsec_spd_dump) \
311 _(FEATURE_ENABLE_DISABLE, feature_enable_disable)
314 #define QUOTE(x) QUOTE_(x)
318 RESOLVE_IP4_ADD_DEL_ROUTE = 1,
319 RESOLVE_IP6_ADD_DEL_ROUTE,
322 static vlib_node_registration_t vpe_resolver_process_node;
323 vpe_api_main_t vpe_api_main;
325 static void send_sw_interface_flags_deleted (vpe_api_main_t * am,
326 unix_shared_memory_queue_t * q,
329 static int arp_change_delete_callback (u32 pool_index, u8 * notused);
330 static int nd_change_delete_callback (u32 pool_index, u8 * notused);
333 /* Clean up all registrations belonging to the indicated client */
335 vl_api_memclnt_delete_callback (u32 client_index)
337 vpe_api_main_t *vam = &vpe_api_main;
338 vpe_client_registration_t *rp;
340 int stats_memclnt_delete_callback (u32 client_index);
342 stats_memclnt_delete_callback (client_index);
345 p = hash_get (vam->a##_registration_hash, client_index); \
347 rp = pool_elt_at_index (vam->a##_registrations, p[0]); \
348 pool_put (vam->a##_registrations, rp); \
349 hash_unset (vam->a##_registration_hash, client_index); \
351 foreach_registration_hash;
356 pub_sub_handler (oam_events, OAM_EVENTS);
358 #define RESOLUTION_EVENT 1
359 #define RESOLUTION_PENDING_EVENT 2
360 #define IP4_ARP_EVENT 3
361 #define IP6_ND_EVENT 4
363 int ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
365 int ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
368 handle_ip4_arp_event (u32 pool_index)
370 vpe_api_main_t *vam = &vpe_api_main;
371 vnet_main_t *vnm = vam->vnet_main;
372 vlib_main_t *vm = vam->vlib_main;
373 vl_api_ip4_arp_event_t *event;
374 vl_api_ip4_arp_event_t *mp;
375 unix_shared_memory_queue_t *q;
377 /* Client can cancel, die, etc. */
378 if (pool_is_free_index (vam->arp_events, pool_index))
381 event = pool_elt_at_index (vam->arp_events, pool_index);
383 q = vl_api_client_index_to_input_queue (event->client_index);
386 (void) vnet_add_del_ip4_arp_change_event
387 (vnm, arp_change_delete_callback,
388 event->pid, &event->address,
389 vpe_resolver_process_node.index, IP4_ARP_EVENT,
390 ~0 /* pool index, notused */ , 0 /* is_add */ );
394 if (q->cursize < q->maxsize)
396 mp = vl_msg_api_alloc (sizeof (*mp));
397 clib_memcpy (mp, event, sizeof (*mp));
398 vl_msg_api_send_shmem (q, (u8 *) & mp);
402 static f64 last_time;
404 * Throttle syslog msgs.
405 * It's pretty tempting to just revoke the registration...
407 if (vlib_time_now (vm) > last_time + 10.0)
409 clib_warning ("arp event for %U to pid %d: queue stuffed!",
410 format_ip4_address, &event->address, event->pid);
411 last_time = vlib_time_now (vm);
417 handle_ip6_nd_event (u32 pool_index)
419 vpe_api_main_t *vam = &vpe_api_main;
420 vnet_main_t *vnm = vam->vnet_main;
421 vlib_main_t *vm = vam->vlib_main;
422 vl_api_ip6_nd_event_t *event;
423 vl_api_ip6_nd_event_t *mp;
424 unix_shared_memory_queue_t *q;
426 /* Client can cancel, die, etc. */
427 if (pool_is_free_index (vam->nd_events, pool_index))
430 event = pool_elt_at_index (vam->nd_events, pool_index);
432 q = vl_api_client_index_to_input_queue (event->client_index);
435 (void) vnet_add_del_ip6_nd_change_event
436 (vnm, nd_change_delete_callback,
437 event->pid, &event->address,
438 vpe_resolver_process_node.index, IP6_ND_EVENT,
439 ~0 /* pool index, notused */ , 0 /* is_add */ );
443 if (q->cursize < q->maxsize)
445 mp = vl_msg_api_alloc (sizeof (*mp));
446 clib_memcpy (mp, event, sizeof (*mp));
447 vl_msg_api_send_shmem (q, (u8 *) & mp);
451 static f64 last_time;
453 * Throttle syslog msgs.
454 * It's pretty tempting to just revoke the registration...
456 if (vlib_time_now (vm) > last_time + 10.0)
458 clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
459 format_ip6_address, &event->address, event->pid);
460 last_time = vlib_time_now (vm);
466 resolver_process (vlib_main_t * vm,
467 vlib_node_runtime_t * rt, vlib_frame_t * f)
470 uword *event_data = 0;
476 vlib_process_wait_for_event_or_clock (vm, timeout);
478 event_type = vlib_process_get_events (vm, &event_data);
482 case RESOLUTION_PENDING_EVENT:
486 case RESOLUTION_EVENT:
487 clib_warning ("resolver: BOGUS TYPE");
491 for (i = 0; i < vec_len (event_data); i++)
492 handle_ip4_arp_event (event_data[i]);
496 for (i = 0; i < vec_len (event_data); i++)
497 handle_ip6_nd_event (event_data[i]);
500 case ~0: /* timeout */
504 vec_reset_length (event_data);
506 return 0; /* or not */
510 VLIB_REGISTER_NODE (vpe_resolver_process_node,static) = {
511 .function = resolver_process,
512 .type = VLIB_NODE_TYPE_PROCESS,
513 .name = "vpe-route-resolver-process",
518 mpls_route_add_del_t_handler (vnet_main_t * vnm,
519 vl_api_mpls_route_add_del_t * mp)
521 u32 fib_index, next_hop_fib_index;
522 mpls_label_t *label_stack = NULL;
523 int rv, ii, n_labels;;
527 .fp_proto = FIB_PROTOCOL_MPLS,
528 .fp_eos = mp->mr_eos,
529 .fp_label = ntohl (mp->mr_label),
533 if (mp->mr_next_hop_proto_is_ip4)
535 pfx.fp_payload_proto = DPO_PROTO_IP4;
539 pfx.fp_payload_proto = DPO_PROTO_IP6;
544 pfx.fp_payload_proto = DPO_PROTO_MPLS;
547 rv = add_del_route_check (FIB_PROTOCOL_MPLS,
549 mp->mr_next_hop_sw_if_index,
550 dpo_proto_to_fib (pfx.fp_payload_proto),
551 mp->mr_next_hop_table_id,
552 mp->mr_create_table_if_needed,
553 &fib_index, &next_hop_fib_index);
559 memset (&nh, 0, sizeof (nh));
561 if (mp->mr_next_hop_proto_is_ip4)
562 memcpy (&nh.ip4, mp->mr_next_hop, sizeof (nh.ip4));
564 memcpy (&nh.ip6, mp->mr_next_hop, sizeof (nh.ip6));
566 n_labels = mp->mr_next_hop_n_out_labels;
569 else if (1 == n_labels)
570 vec_add1 (label_stack, ntohl (mp->mr_next_hop_out_label_stack[0]));
573 vec_validate (label_stack, n_labels - 1);
574 for (ii = 0; ii < n_labels; ii++)
575 label_stack[ii] = ntohl (mp->mr_next_hop_out_label_stack[ii]);
578 return (add_del_route_t_handler (mp->mr_is_multipath, mp->mr_is_add, 0, // mp->is_drop,
579 0, // mp->is_unreach,
580 0, // mp->is_prohibit,
583 mp->mr_classify_table_index,
584 mp->mr_is_resolve_host,
585 mp->mr_is_resolve_attached,
587 mp->mr_next_hop_proto_is_ip4,
588 &nh, ntohl (mp->mr_next_hop_sw_if_index),
590 mp->mr_next_hop_weight,
591 ntohl (mp->mr_next_hop_via_label),
596 vl_api_mpls_route_add_del_t_handler (vl_api_mpls_route_add_del_t * mp)
598 vl_api_mpls_route_add_del_reply_t *rmp;
602 vnm = vnet_get_main ();
605 rv = mpls_route_add_del_t_handler (vnm, mp);
607 rv = (rv == 0) ? vnm->api_errno : rv;
609 REPLY_MACRO (VL_API_MPLS_ROUTE_ADD_DEL_REPLY);
613 mpls_ip_bind_unbind_handler (vnet_main_t * vnm,
614 vl_api_mpls_ip_bind_unbind_t * mp)
616 u32 mpls_fib_index, ip_fib_index;
619 fib_table_find (FIB_PROTOCOL_MPLS, ntohl (mp->mb_mpls_table_id));
621 if (~0 == mpls_fib_index)
623 if (mp->mb_create_table_if_needed)
626 fib_table_find_or_create_and_lock (FIB_PROTOCOL_MPLS,
627 ntohl (mp->mb_mpls_table_id));
630 return VNET_API_ERROR_NO_SUCH_FIB;
633 ip_fib_index = fib_table_find ((mp->mb_is_ip4 ?
636 ntohl (mp->mb_ip_table_id));
637 if (~0 == ip_fib_index)
638 return VNET_API_ERROR_NO_SUCH_FIB;
641 .fp_len = mp->mb_address_length,
646 pfx.fp_proto = FIB_PROTOCOL_IP4;
647 clib_memcpy (&pfx.fp_addr.ip4, mp->mb_address,
648 sizeof (pfx.fp_addr.ip4));
652 pfx.fp_proto = FIB_PROTOCOL_IP6;
653 clib_memcpy (&pfx.fp_addr.ip6, mp->mb_address,
654 sizeof (pfx.fp_addr.ip6));
658 fib_table_entry_local_label_add (ip_fib_index, &pfx,
659 ntohl (mp->mb_label));
661 fib_table_entry_local_label_remove (ip_fib_index, &pfx,
662 ntohl (mp->mb_label));
668 vl_api_mpls_ip_bind_unbind_t_handler (vl_api_mpls_ip_bind_unbind_t * mp)
670 vl_api_mpls_route_add_del_reply_t *rmp;
674 vnm = vnet_get_main ();
677 rv = mpls_ip_bind_unbind_handler (vnm, mp);
679 rv = (rv == 0) ? vnm->api_errno : rv;
681 REPLY_MACRO (VL_API_MPLS_ROUTE_ADD_DEL_REPLY);
685 vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t * mp)
687 vl_api_sw_interface_set_vpath_reply_t *rmp;
689 u32 sw_if_index = ntohl (mp->sw_if_index);
691 VALIDATE_SW_IF_INDEX (mp);
693 l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_VPATH, mp->enable);
694 vnet_feature_enable_disable ("ip4-unicast", "vpath-input-ip4",
695 sw_if_index, mp->enable, 0, 0);
696 vnet_feature_enable_disable ("ip4-multicast", "vpath-input-ip4",
697 sw_if_index, mp->enable, 0, 0);
698 vnet_feature_enable_disable ("ip6-unicast", "vpath-input-ip6",
699 sw_if_index, mp->enable, 0, 0);
700 vnet_feature_enable_disable ("ip6-multicast", "vpath-input-ip6",
701 sw_if_index, mp->enable, 0, 0);
703 BAD_SW_IF_INDEX_LABEL;
705 REPLY_MACRO (VL_API_SW_INTERFACE_SET_VPATH_REPLY);
709 vl_api_sw_interface_set_vxlan_bypass_t_handler
710 (vl_api_sw_interface_set_vxlan_bypass_t * mp)
712 vl_api_sw_interface_set_vxlan_bypass_reply_t *rmp;
714 u32 sw_if_index = ntohl (mp->sw_if_index);
716 VALIDATE_SW_IF_INDEX (mp);
720 /* not yet implemented */
723 vnet_feature_enable_disable ("ip4-unicast", "ip4-vxlan-bypass",
724 sw_if_index, mp->enable, 0, 0);
726 BAD_SW_IF_INDEX_LABEL;
728 REPLY_MACRO (VL_API_SW_INTERFACE_SET_VXLAN_BYPASS_REPLY);
732 vl_api_sw_interface_set_l2_xconnect_t_handler
733 (vl_api_sw_interface_set_l2_xconnect_t * mp)
735 vl_api_sw_interface_set_l2_xconnect_reply_t *rmp;
737 u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
738 u32 tx_sw_if_index = ntohl (mp->tx_sw_if_index);
739 vlib_main_t *vm = vlib_get_main ();
740 vnet_main_t *vnm = vnet_get_main ();
742 VALIDATE_RX_SW_IF_INDEX (mp);
746 VALIDATE_TX_SW_IF_INDEX (mp);
747 rv = set_int_l2_mode (vm, vnm, MODE_L2_XC,
748 rx_sw_if_index, 0, 0, 0, tx_sw_if_index);
752 rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
755 BAD_RX_SW_IF_INDEX_LABEL;
756 BAD_TX_SW_IF_INDEX_LABEL;
758 REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_XCONNECT_REPLY);
762 vl_api_sw_interface_set_l2_bridge_t_handler
763 (vl_api_sw_interface_set_l2_bridge_t * mp)
765 bd_main_t *bdm = &bd_main;
766 vl_api_sw_interface_set_l2_bridge_reply_t *rmp;
768 u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
769 u32 bd_id = ntohl (mp->bd_id);
773 vlib_main_t *vm = vlib_get_main ();
774 vnet_main_t *vnm = vnet_get_main ();
776 VALIDATE_RX_SW_IF_INDEX (mp);
778 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
782 //VALIDATE_TX_SW_IF_INDEX(mp);
783 rv = set_int_l2_mode (vm, vnm, MODE_L2_BRIDGE,
784 rx_sw_if_index, bd_index, bvi, shg, 0);
788 rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
791 BAD_RX_SW_IF_INDEX_LABEL;
793 REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_BRIDGE_REPLY);
797 vl_api_sw_interface_set_dpdk_hqos_pipe_t_handler
798 (vl_api_sw_interface_set_dpdk_hqos_pipe_t * mp)
800 vl_api_sw_interface_set_dpdk_hqos_pipe_reply_t *rmp;
804 dpdk_main_t *dm = &dpdk_main;
807 u32 sw_if_index = ntohl (mp->sw_if_index);
808 u32 subport = ntohl (mp->subport);
809 u32 pipe = ntohl (mp->pipe);
810 u32 profile = ntohl (mp->profile);
811 vnet_hw_interface_t *hw;
813 VALIDATE_SW_IF_INDEX (mp);
815 /* hw_if & dpdk device */
816 hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
818 xd = vec_elt_at_index (dm->devices, hw->dev_instance);
820 rv = rte_sched_pipe_config (xd->hqos_ht->hqos, subport, pipe, profile);
822 BAD_SW_IF_INDEX_LABEL;
824 clib_warning ("setting HQoS pipe parameters without DPDK not implemented");
825 rv = VNET_API_ERROR_UNIMPLEMENTED;
828 REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY);
832 vl_api_sw_interface_set_dpdk_hqos_subport_t_handler
833 (vl_api_sw_interface_set_dpdk_hqos_subport_t * mp)
835 vl_api_sw_interface_set_dpdk_hqos_subport_reply_t *rmp;
839 dpdk_main_t *dm = &dpdk_main;
841 struct rte_sched_subport_params p;
843 u32 sw_if_index = ntohl (mp->sw_if_index);
844 u32 subport = ntohl (mp->subport);
845 p.tb_rate = ntohl (mp->tb_rate);
846 p.tb_size = ntohl (mp->tb_size);
847 p.tc_rate[0] = ntohl (mp->tc_rate[0]);
848 p.tc_rate[1] = ntohl (mp->tc_rate[1]);
849 p.tc_rate[2] = ntohl (mp->tc_rate[2]);
850 p.tc_rate[3] = ntohl (mp->tc_rate[3]);
851 p.tc_period = ntohl (mp->tc_period);
853 vnet_hw_interface_t *hw;
855 VALIDATE_SW_IF_INDEX (mp);
857 /* hw_if & dpdk device */
858 hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
860 xd = vec_elt_at_index (dm->devices, hw->dev_instance);
862 rv = rte_sched_subport_config (xd->hqos_ht->hqos, subport, &p);
864 BAD_SW_IF_INDEX_LABEL;
867 ("setting HQoS subport parameters without DPDK not implemented");
868 rv = VNET_API_ERROR_UNIMPLEMENTED;
871 REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY);
875 vl_api_sw_interface_set_dpdk_hqos_tctbl_t_handler
876 (vl_api_sw_interface_set_dpdk_hqos_tctbl_t * mp)
878 vl_api_sw_interface_set_dpdk_hqos_tctbl_reply_t *rmp;
882 dpdk_main_t *dm = &dpdk_main;
883 vlib_thread_main_t *tm = vlib_get_thread_main ();
886 u32 sw_if_index = ntohl (mp->sw_if_index);
887 u32 entry = ntohl (mp->entry);
888 u32 tc = ntohl (mp->tc);
889 u32 queue = ntohl (mp->queue);
892 vnet_hw_interface_t *hw;
894 VALIDATE_SW_IF_INDEX (mp);
896 /* hw_if & dpdk device */
897 hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
899 xd = vec_elt_at_index (dm->devices, hw->dev_instance);
901 if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE)
903 clib_warning ("invalid traffic class !!");
904 rv = VNET_API_ERROR_INVALID_VALUE;
907 if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS)
909 clib_warning ("invalid queue !!");
910 rv = VNET_API_ERROR_INVALID_VALUE;
914 /* Detect the set of worker threads */
915 uword *p = hash_get_mem (tm->thread_registrations_by_name, "workers");
919 clib_warning ("worker thread registration AWOL !!");
920 rv = VNET_API_ERROR_INVALID_VALUE_2;
924 vlib_thread_registration_t *tr = (vlib_thread_registration_t *) p[0];
925 int worker_thread_first = tr->first_index;
926 int worker_thread_count = tr->count;
928 val = tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
929 for (i = 0; i < worker_thread_count; i++)
930 xd->hqos_wt[worker_thread_first + i].hqos_tc_table[entry] = val;
932 BAD_SW_IF_INDEX_LABEL;
935 clib_warning ("setting HQoS DSCP table entry without DPDK not implemented");
936 rv = VNET_API_ERROR_UNIMPLEMENTED;
939 REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY);
943 vl_api_bridge_domain_add_del_t_handler (vl_api_bridge_domain_add_del_t * mp)
945 vlib_main_t *vm = vlib_get_main ();
946 bd_main_t *bdm = &bd_main;
947 vl_api_bridge_domain_add_del_reply_t *rmp;
949 u32 enable_flags = 0, disable_flags = 0;
950 u32 bd_id = ntohl (mp->bd_id);
955 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
958 enable_flags |= L2_FLOOD;
960 disable_flags |= L2_FLOOD;
963 enable_flags |= L2_UU_FLOOD;
965 disable_flags |= L2_UU_FLOOD;
968 enable_flags |= L2_FWD;
970 disable_flags |= L2_FWD;
973 enable_flags |= L2_ARP_TERM;
975 disable_flags |= L2_ARP_TERM;
978 enable_flags |= L2_LEARN;
980 disable_flags |= L2_LEARN;
983 bd_set_flags (vm, bd_index, enable_flags, 1 /* enable */ );
986 bd_set_flags (vm, bd_index, disable_flags, 0 /* disable */ );
990 rv = bd_delete_bd_index (bdm, bd_id);
992 REPLY_MACRO (VL_API_BRIDGE_DOMAIN_ADD_DEL_REPLY);
996 vl_api_bridge_domain_details_t_handler (vl_api_bridge_domain_details_t * mp)
998 clib_warning ("BUG");
1002 vl_api_bridge_domain_sw_if_details_t_handler
1003 (vl_api_bridge_domain_sw_if_details_t * mp)
1005 clib_warning ("BUG");
1009 send_bridge_domain_details (unix_shared_memory_queue_t * q,
1010 l2_bridge_domain_t * bd_config,
1011 u32 n_sw_ifs, u32 context)
1013 vl_api_bridge_domain_details_t *mp;
1015 mp = vl_msg_api_alloc (sizeof (*mp));
1016 memset (mp, 0, sizeof (*mp));
1017 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_DETAILS);
1018 mp->bd_id = ntohl (bd_config->bd_id);
1019 mp->flood = bd_feature_flood (bd_config);
1020 mp->uu_flood = bd_feature_uu_flood (bd_config);
1021 mp->forward = bd_feature_forward (bd_config);
1022 mp->learn = bd_feature_learn (bd_config);
1023 mp->arp_term = bd_feature_arp_term (bd_config);
1024 mp->bvi_sw_if_index = ntohl (bd_config->bvi_sw_if_index);
1025 mp->n_sw_ifs = ntohl (n_sw_ifs);
1026 mp->context = context;
1028 vl_msg_api_send_shmem (q, (u8 *) & mp);
1032 send_bd_sw_if_details (l2input_main_t * l2im,
1033 unix_shared_memory_queue_t * q,
1034 l2_flood_member_t * member, u32 bd_id, u32 context)
1036 vl_api_bridge_domain_sw_if_details_t *mp;
1037 l2_input_config_t *input_cfg;
1039 mp = vl_msg_api_alloc (sizeof (*mp));
1040 memset (mp, 0, sizeof (*mp));
1041 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_SW_IF_DETAILS);
1042 mp->bd_id = ntohl (bd_id);
1043 mp->sw_if_index = ntohl (member->sw_if_index);
1044 input_cfg = vec_elt_at_index (l2im->configs, member->sw_if_index);
1045 mp->shg = input_cfg->shg;
1046 mp->context = context;
1048 vl_msg_api_send_shmem (q, (u8 *) & mp);
1052 vl_api_bridge_domain_dump_t_handler (vl_api_bridge_domain_dump_t * mp)
1054 bd_main_t *bdm = &bd_main;
1055 l2input_main_t *l2im = &l2input_main;
1056 unix_shared_memory_queue_t *q;
1057 l2_bridge_domain_t *bd_config;
1058 u32 bd_id, bd_index;
1061 q = vl_api_client_index_to_input_queue (mp->client_index);
1066 bd_id = ntohl (mp->bd_id);
1068 bd_index = (bd_id == ~0) ? 0 : bd_find_or_add_bd_index (bdm, bd_id);
1069 end = (bd_id == ~0) ? vec_len (l2im->bd_configs) : bd_index + 1;
1070 for (; bd_index < end; bd_index++)
1072 bd_config = l2input_bd_config_from_index (l2im, bd_index);
1073 /* skip dummy bd_id 0 */
1074 if (bd_config && (bd_config->bd_id > 0))
1077 l2_flood_member_t *m;
1079 n_sw_ifs = vec_len (bd_config->members);
1080 send_bridge_domain_details (q, bd_config, n_sw_ifs, mp->context);
1082 vec_foreach (m, bd_config->members)
1084 send_bd_sw_if_details (l2im, q, m, bd_config->bd_id, mp->context);
1091 vl_api_l2fib_add_del_t_handler (vl_api_l2fib_add_del_t * mp)
1093 bd_main_t *bdm = &bd_main;
1094 l2input_main_t *l2im = &l2input_main;
1095 vl_api_l2fib_add_del_reply_t *rmp;
1098 u32 sw_if_index = ntohl (mp->sw_if_index);
1099 u32 bd_id = ntohl (mp->bd_id);
1108 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1111 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1112 goto bad_sw_if_index;
1118 filter_mac = mp->filter_mac ? 1 : 0;
1119 if (filter_mac == 0)
1121 VALIDATE_SW_IF_INDEX (mp);
1122 if (vec_len (l2im->configs) <= sw_if_index)
1124 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1125 goto bad_sw_if_index;
1129 l2_input_config_t *config;
1130 config = vec_elt_at_index (l2im->configs, sw_if_index);
1131 if (config->bridge == 0)
1133 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1134 goto bad_sw_if_index;
1138 static_mac = mp->static_mac ? 1 : 0;
1139 bvi_mac = mp->bvi_mac ? 1 : 0;
1140 l2fib_add_entry (mac, bd_index, sw_if_index, static_mac, filter_mac,
1145 l2fib_del_entry (mac, bd_index);
1148 BAD_SW_IF_INDEX_LABEL;
1150 REPLY_MACRO (VL_API_L2FIB_ADD_DEL_REPLY);
1154 vl_api_l2_flags_t_handler (vl_api_l2_flags_t * mp)
1156 vl_api_l2_flags_reply_t *rmp;
1158 u32 sw_if_index = ntohl (mp->sw_if_index);
1159 u32 flags = ntohl (mp->feature_bitmap);
1162 VALIDATE_SW_IF_INDEX (mp);
1165 if (flags & L2INPUT_FEAT_ ## a) \
1166 rbm = l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_ ## a, mp->is_set);
1167 foreach_l2input_feat;
1170 BAD_SW_IF_INDEX_LABEL;
1173 REPLY_MACRO2(VL_API_L2_FLAGS_REPLY,
1175 rmp->resulting_feature_bitmap = ntohl(rbm);
1181 vl_api_bridge_flags_t_handler (vl_api_bridge_flags_t * mp)
1183 vlib_main_t *vm = vlib_get_main ();
1184 bd_main_t *bdm = &bd_main;
1185 vl_api_bridge_flags_reply_t *rmp;
1187 u32 bd_id = ntohl (mp->bd_id);
1189 u32 flags = ntohl (mp->feature_bitmap);
1192 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1195 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1201 bd_set_flags (vm, bd_index, flags, mp->is_set);
1205 REPLY_MACRO2(VL_API_BRIDGE_FLAGS_REPLY,
1207 rmp->resulting_feature_bitmap = ntohl(flags);
1213 vl_api_bd_ip_mac_add_del_t_handler (vl_api_bd_ip_mac_add_del_t * mp)
1215 bd_main_t *bdm = &bd_main;
1216 vl_api_bd_ip_mac_add_del_reply_t *rmp;
1218 u32 bd_id = ntohl (mp->bd_id);
1222 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
1225 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1230 if (bd_add_del_ip_mac (bd_index, mp->ip_address,
1231 mp->mac_address, mp->is_ipv6, mp->is_add))
1232 rv = VNET_API_ERROR_UNSPECIFIED;
1235 REPLY_MACRO (VL_API_BD_IP_MAC_ADD_DEL_REPLY);
1239 vl_api_tap_connect_t_handler (vl_api_tap_connect_t * mp)
1241 vlib_main_t *vm = vlib_get_main ();
1243 vl_api_tap_connect_reply_t *rmp;
1244 vnet_main_t *vnm = vnet_get_main ();
1245 unix_shared_memory_queue_t *q;
1246 u32 sw_if_index = (u32) ~ 0;
1249 rv = vnet_tap_connect_renumber (vm, mp->tap_name,
1250 mp->use_random_mac ? 0 : mp->mac_address,
1251 &sw_if_index, mp->renumber,
1252 ntohl (mp->custom_dev_instance));
1254 /* Add tag if supplied */
1255 if (rv == 0 && mp->tag[0])
1257 mp->tag[ARRAY_LEN (mp->tag) - 1] = 0;
1258 tag = format (0, "%s%c", mp->tag, 0);
1259 vnet_set_sw_interface_tag (vnm, tag, sw_if_index);
1262 q = vl_api_client_index_to_input_queue (mp->client_index);
1266 rmp = vl_msg_api_alloc (sizeof (*rmp));
1267 rmp->_vl_msg_id = ntohs (VL_API_TAP_CONNECT_REPLY);
1268 rmp->context = mp->context;
1269 rmp->retval = ntohl (rv);
1270 rmp->sw_if_index = ntohl (sw_if_index);
1272 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1276 vl_api_tap_modify_t_handler (vl_api_tap_modify_t * mp)
1279 vl_api_tap_modify_reply_t *rmp;
1280 unix_shared_memory_queue_t *q;
1281 u32 sw_if_index = (u32) ~ 0;
1282 vlib_main_t *vm = vlib_get_main ();
1284 rv = vnet_tap_modify (vm, ntohl (mp->sw_if_index), mp->tap_name,
1285 mp->use_random_mac ? 0 : mp->mac_address,
1286 &sw_if_index, mp->renumber,
1287 ntohl (mp->custom_dev_instance));
1289 q = vl_api_client_index_to_input_queue (mp->client_index);
1293 rmp = vl_msg_api_alloc (sizeof (*rmp));
1294 rmp->_vl_msg_id = ntohs (VL_API_TAP_MODIFY_REPLY);
1295 rmp->context = mp->context;
1296 rmp->retval = ntohl (rv);
1297 rmp->sw_if_index = ntohl (sw_if_index);
1299 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1303 vl_api_tap_delete_t_handler (vl_api_tap_delete_t * mp)
1305 vlib_main_t *vm = vlib_get_main ();
1307 vpe_api_main_t *vam = &vpe_api_main;
1308 vl_api_tap_delete_reply_t *rmp;
1309 unix_shared_memory_queue_t *q;
1310 u32 sw_if_index = ntohl (mp->sw_if_index);
1312 rv = vnet_tap_delete (vm, sw_if_index);
1315 vnet_main_t *vnm = vnet_get_main ();
1316 vnet_clear_sw_interface_tag (vnm, sw_if_index);
1319 q = vl_api_client_index_to_input_queue (mp->client_index);
1323 rmp = vl_msg_api_alloc (sizeof (*rmp));
1324 rmp->_vl_msg_id = ntohs (VL_API_TAP_DELETE_REPLY);
1325 rmp->context = mp->context;
1326 rmp->retval = ntohl (rv);
1328 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1331 send_sw_interface_flags_deleted (vam, q, sw_if_index);
1335 vl_api_create_vlan_subif_t_handler (vl_api_create_vlan_subif_t * mp)
1337 vl_api_create_vlan_subif_reply_t *rmp;
1338 vnet_main_t *vnm = vnet_get_main ();
1339 u32 hw_if_index, sw_if_index = (u32) ~ 0;
1340 vnet_hw_interface_t *hi;
1343 vnet_sw_interface_t template;
1345 vnet_interface_main_t *im = &vnm->interface_main;
1346 u64 sup_and_sub_key;
1348 unix_shared_memory_queue_t *q;
1349 clib_error_t *error;
1351 VALIDATE_SW_IF_INDEX (mp);
1353 hw_if_index = ntohl (mp->sw_if_index);
1354 hi = vnet_get_hw_interface (vnm, hw_if_index);
1356 id = ntohl (mp->vlan_id);
1357 if (id == 0 || id > 4095)
1359 rv = VNET_API_ERROR_INVALID_VLAN;
1363 sup_and_sub_key = ((u64) (hi->sw_if_index) << 32) | (u64) id;
1365 p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1368 rv = VNET_API_ERROR_VLAN_ALREADY_EXISTS;
1372 kp = clib_mem_alloc (sizeof (*kp));
1373 *kp = sup_and_sub_key;
1375 memset (&template, 0, sizeof (template));
1376 template.type = VNET_SW_INTERFACE_TYPE_SUB;
1377 template.sup_sw_if_index = hi->sw_if_index;
1378 template.sub.id = id;
1379 template.sub.eth.raw_flags = 0;
1380 template.sub.eth.flags.one_tag = 1;
1381 template.sub.eth.outer_vlan_id = id;
1382 template.sub.eth.flags.exact_match = 1;
1384 error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1387 clib_error_report (error);
1388 rv = VNET_API_ERROR_INVALID_REGISTRATION;
1391 hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
1392 hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1394 BAD_SW_IF_INDEX_LABEL;
1397 q = vl_api_client_index_to_input_queue (mp->client_index);
1401 rmp = vl_msg_api_alloc (sizeof (*rmp));
1402 rmp->_vl_msg_id = ntohs (VL_API_CREATE_VLAN_SUBIF_REPLY);
1403 rmp->context = mp->context;
1404 rmp->retval = ntohl (rv);
1405 rmp->sw_if_index = ntohl (sw_if_index);
1406 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1410 vl_api_create_subif_t_handler (vl_api_create_subif_t * mp)
1412 vl_api_create_subif_reply_t *rmp;
1413 vnet_main_t *vnm = vnet_get_main ();
1414 u32 sw_if_index = ~0;
1417 vnet_sw_interface_t *si;
1418 vnet_hw_interface_t *hi;
1419 vnet_sw_interface_t template;
1421 vnet_interface_main_t *im = &vnm->interface_main;
1422 u64 sup_and_sub_key;
1424 clib_error_t *error;
1426 VALIDATE_SW_IF_INDEX (mp);
1428 si = vnet_get_sup_sw_interface (vnm, ntohl (mp->sw_if_index));
1429 hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
1431 if (hi->bond_info == VNET_HW_INTERFACE_BOND_INFO_SLAVE)
1433 rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
1437 sw_if_index = si->sw_if_index;
1438 sub_id = ntohl (mp->sub_id);
1440 sup_and_sub_key = ((u64) (sw_if_index) << 32) | (u64) sub_id;
1442 p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1446 clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
1447 sw_if_index, sub_id);
1448 rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
1452 kp = clib_mem_alloc (sizeof (*kp));
1453 *kp = sup_and_sub_key;
1455 memset (&template, 0, sizeof (template));
1456 template.type = VNET_SW_INTERFACE_TYPE_SUB;
1457 template.sup_sw_if_index = sw_if_index;
1458 template.sub.id = sub_id;
1459 template.sub.eth.flags.no_tags = mp->no_tags;
1460 template.sub.eth.flags.one_tag = mp->one_tag;
1461 template.sub.eth.flags.two_tags = mp->two_tags;
1462 template.sub.eth.flags.dot1ad = mp->dot1ad;
1463 template.sub.eth.flags.exact_match = mp->exact_match;
1464 template.sub.eth.flags.default_sub = mp->default_sub;
1465 template.sub.eth.flags.outer_vlan_id_any = mp->outer_vlan_id_any;
1466 template.sub.eth.flags.inner_vlan_id_any = mp->inner_vlan_id_any;
1467 template.sub.eth.outer_vlan_id = ntohs (mp->outer_vlan_id);
1468 template.sub.eth.inner_vlan_id = ntohs (mp->inner_vlan_id);
1470 error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1473 clib_error_report (error);
1474 rv = VNET_API_ERROR_SUBIF_CREATE_FAILED;
1478 hash_set (hi->sub_interface_sw_if_index_by_id, sub_id, sw_if_index);
1479 hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1481 BAD_SW_IF_INDEX_LABEL;
1486 REPLY_MACRO2(VL_API_CREATE_SUBIF_REPLY,
1488 rmp->sw_if_index = ntohl(sw_if_index);
1494 vl_api_mpls_tunnel_add_del_t_handler (vl_api_mpls_tunnel_add_del_t * mp)
1496 vl_api_mpls_tunnel_add_del_reply_t *rmp;
1498 stats_main_t *sm = &stats_main;
1499 u32 tunnel_sw_if_index;
1502 dslock (sm, 1 /* release hint */ , 5 /* tag */ );
1506 fib_route_path_t rpath, *rpaths = NULL;
1507 mpls_label_t *label_stack = NULL;
1509 memset (&rpath, 0, sizeof (rpath));
1511 if (mp->mt_next_hop_proto_is_ip4)
1513 rpath.frp_proto = FIB_PROTOCOL_IP4;
1514 clib_memcpy (&rpath.frp_addr.ip4,
1515 mp->mt_next_hop, sizeof (rpath.frp_addr.ip4));
1519 rpath.frp_proto = FIB_PROTOCOL_IP6;
1520 clib_memcpy (&rpath.frp_addr.ip6,
1521 mp->mt_next_hop, sizeof (rpath.frp_addr.ip6));
1523 rpath.frp_sw_if_index = ntohl (mp->mt_next_hop_sw_if_index);
1525 for (ii = 0; ii < mp->mt_next_hop_n_out_labels; ii++)
1526 vec_add1 (label_stack, ntohl (mp->mt_next_hop_out_label_stack[ii]));
1528 vec_add1 (rpaths, rpath);
1530 vnet_mpls_tunnel_add (rpaths, label_stack,
1531 mp->mt_l2_only, &tunnel_sw_if_index);
1533 vec_free (label_stack);
1537 tunnel_sw_if_index = ntohl (mp->mt_sw_if_index);
1538 vnet_mpls_tunnel_del (tunnel_sw_if_index);
1544 REPLY_MACRO2(VL_API_MPLS_TUNNEL_ADD_DEL_REPLY,
1546 rmp->sw_if_index = ntohl(tunnel_sw_if_index);
1552 vl_api_proxy_arp_add_del_t_handler (vl_api_proxy_arp_add_del_t * mp)
1554 vl_api_proxy_arp_add_del_reply_t *rmp;
1557 ip4_main_t *im = &ip4_main;
1558 stats_main_t *sm = &stats_main;
1559 int vnet_proxy_arp_add_del (ip4_address_t * lo_addr,
1560 ip4_address_t * hi_addr,
1561 u32 fib_index, int is_del);
1564 dslock (sm, 1 /* release hint */ , 6 /* tag */ );
1566 p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
1570 rv = VNET_API_ERROR_NO_SUCH_FIB;
1576 rv = vnet_proxy_arp_add_del ((ip4_address_t *) mp->low_address,
1577 (ip4_address_t *) mp->hi_address,
1578 fib_index, mp->is_add == 0);
1582 REPLY_MACRO (VL_API_PROXY_ARP_ADD_DEL_REPLY);
1586 vl_api_proxy_arp_intfc_enable_disable_t_handler
1587 (vl_api_proxy_arp_intfc_enable_disable_t * mp)
1590 vnet_main_t *vnm = vnet_get_main ();
1591 vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;
1592 vnet_sw_interface_t *si;
1595 VALIDATE_SW_IF_INDEX (mp);
1597 sw_if_index = ntohl (mp->sw_if_index);
1599 if (pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index))
1601 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1605 si = vnet_get_sw_interface (vnm, sw_if_index);
1609 if (mp->enable_disable)
1610 si->flags |= VNET_SW_INTERFACE_FLAG_PROXY_ARP;
1612 si->flags &= ~VNET_SW_INTERFACE_FLAG_PROXY_ARP;
1614 BAD_SW_IF_INDEX_LABEL;
1617 REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
1621 vl_api_is_address_reachable_t_handler (vl_api_is_address_reachable_t * mp)
1624 vpe_main_t *rm = &vpe_main;
1625 ip4_main_t *im4 = &ip4_main;
1626 ip6_main_t *im6 = &ip6_main;
1627 ip_lookup_main_t *lm;
1633 u32 adj_index, sw_if_index;
1634 vl_api_is_address_reachable_t *rmp;
1635 ip_adjacency_t *adj;
1636 unix_shared_memory_queue_t *q;
1638 q = vl_api_client_index_to_input_queue (mp->client_index);
1641 increment_missing_api_client_counter (rm->vlib_main);
1645 rmp = vl_msg_api_alloc (sizeof (*rmp));
1646 clib_memcpy (rmp, mp, sizeof (*rmp));
1648 sw_if_index = mp->next_hop_sw_if_index;
1649 clib_memcpy (&addr, mp->address, sizeof (addr));
1652 lm = &im6->lookup_main;
1653 adj_index = ip6_fib_lookup (im6, sw_if_index, &addr.ip6);
1657 lm = &im4->lookup_main;
1659 adj_index = ip4_fib_lookup (im4, sw_if_index, &addr.ip4);
1661 if (adj_index == ~0)
1666 adj = ip_get_adjacency (lm, adj_index);
1668 if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE
1669 && adj->rewrite_header.sw_if_index == sw_if_index)
1675 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP
1676 && adj->rewrite_header.sw_if_index == sw_if_index)
1679 ip6_probe_neighbor (rm->vlib_main, &addr.ip6, sw_if_index);
1681 ip4_probe_neighbor (rm->vlib_main, &addr.ip4, sw_if_index);
1683 else if (adj->lookup_next_index == IP_LOOKUP_NEXT_DROP)
1692 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1697 vl_api_sw_interface_set_mpls_enable_t_handler
1698 (vl_api_sw_interface_set_mpls_enable_t * mp)
1700 vl_api_sw_interface_set_mpls_enable_reply_t *rmp;
1703 VALIDATE_SW_IF_INDEX (mp);
1705 mpls_sw_interface_enable_disable (&mpls_main,
1706 ntohl (mp->sw_if_index), mp->enable);
1708 BAD_SW_IF_INDEX_LABEL;
1709 REPLY_MACRO (VL_API_SW_INTERFACE_SET_MPLS_ENABLE_REPLY);
1712 static void send_sw_interface_flags_deleted (vpe_api_main_t * am,
1713 unix_shared_memory_queue_t * q,
1715 __attribute__ ((unused));
1718 send_sw_interface_flags_deleted (vpe_api_main_t * am,
1719 unix_shared_memory_queue_t * q,
1722 vl_api_sw_interface_set_flags_t *mp;
1724 mp = vl_msg_api_alloc (sizeof (*mp));
1725 memset (mp, 0, sizeof (*mp));
1726 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_SET_FLAGS);
1727 mp->sw_if_index = ntohl (sw_if_index);
1729 mp->admin_up_down = 0;
1730 mp->link_up_down = 0;
1732 vl_msg_api_send_shmem (q, (u8 *) & mp);
1736 send_oam_event (oam_target_t * t)
1738 vpe_api_main_t *vam = &vpe_api_main;
1739 unix_shared_memory_queue_t *q;
1740 vpe_client_registration_t *reg;
1741 vl_api_oam_event_t *mp;
1744 pool_foreach(reg, vam->oam_events_registrations,
1746 q = vl_api_client_index_to_input_queue (reg->client_index);
1749 mp = vl_msg_api_alloc (sizeof (*mp));
1750 mp->_vl_msg_id = ntohs (VL_API_OAM_EVENT);
1751 clib_memcpy (mp->dst_address, &t->dst_address,
1752 sizeof (mp->dst_address));
1753 mp->state = t->state;
1754 vl_msg_api_send_shmem (q, (u8 *)&mp);
1761 vl_api_oam_add_del_t_handler (vl_api_oam_add_del_t * mp)
1763 vl_api_oam_add_del_reply_t *rmp;
1766 rv = vpe_oam_add_del_target ((ip4_address_t *) mp->src_address,
1767 (ip4_address_t *) mp->dst_address,
1768 ntohl (mp->vrf_id), (int) (mp->is_add));
1770 REPLY_MACRO (VL_API_OAM_ADD_DEL_REPLY);
1774 vl_api_vnet_get_summary_stats_t_handler (vl_api_vnet_get_summary_stats_t * mp)
1776 stats_main_t *sm = &stats_main;
1777 vnet_interface_main_t *im = sm->interface_main;
1778 vl_api_vnet_summary_stats_reply_t *rmp;
1779 vlib_combined_counter_main_t *cm;
1782 u64 total_pkts[VLIB_N_RX_TX];
1783 u64 total_bytes[VLIB_N_RX_TX];
1785 unix_shared_memory_queue_t *q =
1786 vl_api_client_index_to_input_queue (mp->client_index);
1791 rmp = vl_msg_api_alloc (sizeof (*rmp));
1792 rmp->_vl_msg_id = ntohs (VL_API_VNET_SUMMARY_STATS_REPLY);
1793 rmp->context = mp->context;
1796 memset (total_pkts, 0, sizeof (total_pkts));
1797 memset (total_bytes, 0, sizeof (total_bytes));
1799 vnet_interface_counter_lock (im);
1801 vec_foreach (cm, im->combined_sw_if_counters)
1803 which = cm - im->combined_sw_if_counters;
1805 for (i = 0; i < vec_len (cm->maxi); i++)
1807 vlib_get_combined_counter (cm, i, &v);
1808 total_pkts[which] += v.packets;
1809 total_bytes[which] += v.bytes;
1812 vnet_interface_counter_unlock (im);
1814 rmp->total_pkts[VLIB_RX] = clib_host_to_net_u64 (total_pkts[VLIB_RX]);
1815 rmp->total_bytes[VLIB_RX] = clib_host_to_net_u64 (total_bytes[VLIB_RX]);
1816 rmp->total_pkts[VLIB_TX] = clib_host_to_net_u64 (total_pkts[VLIB_TX]);
1817 rmp->total_bytes[VLIB_TX] = clib_host_to_net_u64 (total_bytes[VLIB_TX]);
1819 clib_host_to_net_u64 (vlib_last_vector_length_per_node (sm->vlib_main));
1821 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1825 typedef CLIB_PACKED (struct {
1826 ip4_address_t address;
1827 u32 address_length: 6;
1833 ip4_reset_fib_t_handler (vl_api_reset_fib_t * mp)
1835 vnet_main_t *vnm = vnet_get_main ();
1836 vnet_interface_main_t *im = &vnm->interface_main;
1837 ip4_main_t *im4 = &ip4_main;
1838 static u32 *sw_if_indices_to_shut;
1839 stats_main_t *sm = &stats_main;
1840 fib_table_t *fib_table;
1844 int rv = VNET_API_ERROR_NO_SUCH_FIB;
1845 u32 target_fib_id = ntohl (mp->vrf_id);
1847 dslock (sm, 1 /* release hint */ , 8 /* tag */ );
1850 pool_foreach (fib_table, im4->fibs,
1852 fib = &fib_table->v4;
1853 vnet_sw_interface_t * si;
1855 if (fib->table_id != target_fib_id)
1858 /* remove any mpls encap/decap labels */
1859 mpls_fib_reset_labels (fib->table_id);
1861 /* remove any proxy arps in this fib */
1862 vnet_proxy_arp_fib_reset (fib->table_id);
1864 /* Set the flow hash for this fib to the default */
1865 vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
1867 vec_reset_length (sw_if_indices_to_shut);
1869 /* Shut down interfaces in this FIB / clean out intfc routes */
1870 pool_foreach (si, im->sw_interfaces,
1872 u32 sw_if_index = si->sw_if_index;
1874 if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
1875 && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
1877 vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
1880 for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
1881 sw_if_index = sw_if_indices_to_shut[i];
1882 // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
1884 u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
1885 flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
1886 vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
1889 fib_table_flush(fib->index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
1890 fib_table_flush(fib->index, FIB_PROTOCOL_IP4, FIB_SOURCE_INTERFACE);
1894 })); /* pool_foreach (fib) */
1902 ip6_reset_fib_t_handler (vl_api_reset_fib_t * mp)
1904 vnet_main_t *vnm = vnet_get_main ();
1905 vnet_interface_main_t *im = &vnm->interface_main;
1906 ip6_main_t *im6 = &ip6_main;
1907 stats_main_t *sm = &stats_main;
1908 static u32 *sw_if_indices_to_shut;
1909 fib_table_t *fib_table;
1913 int rv = VNET_API_ERROR_NO_SUCH_FIB;
1914 u32 target_fib_id = ntohl (mp->vrf_id);
1916 dslock (sm, 1 /* release hint */ , 9 /* tag */ );
1919 pool_foreach (fib_table, im6->fibs,
1921 vnet_sw_interface_t * si;
1922 fib = &(fib_table->v6);
1924 if (fib->table_id != target_fib_id)
1927 vec_reset_length (sw_if_indices_to_shut);
1929 /* Shut down interfaces in this FIB / clean out intfc routes */
1930 pool_foreach (si, im->sw_interfaces,
1932 if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
1934 vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
1937 for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
1938 sw_if_index = sw_if_indices_to_shut[i];
1939 // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
1941 u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
1942 flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
1943 vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
1946 fib_table_flush(fib->index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
1947 fib_table_flush(fib->index, FIB_PROTOCOL_IP6, FIB_SOURCE_INTERFACE);
1951 })); /* pool_foreach (fib) */
1959 vl_api_reset_fib_t_handler (vl_api_reset_fib_t * mp)
1962 vl_api_reset_fib_reply_t *rmp;
1965 rv = ip6_reset_fib_t_handler (mp);
1967 rv = ip4_reset_fib_t_handler (mp);
1969 REPLY_MACRO (VL_API_RESET_FIB_REPLY);
1974 dhcpv4_proxy_config (vl_api_dhcp_proxy_config_t * mp)
1976 vl_api_dhcp_proxy_config_reply_t *rmp;
1979 rv = dhcp_proxy_set_server ((ip4_address_t *) (&mp->dhcp_server),
1980 (ip4_address_t *) (&mp->dhcp_src_address),
1981 (u32) ntohl (mp->vrf_id),
1982 (int) mp->insert_circuit_id,
1983 (int) (mp->is_add == 0));
1985 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_REPLY);
1990 dhcpv6_proxy_config (vl_api_dhcp_proxy_config_t * mp)
1992 vl_api_dhcp_proxy_config_reply_t *rmp;
1995 rv = dhcpv6_proxy_set_server ((ip6_address_t *) (&mp->dhcp_server),
1996 (ip6_address_t *) (&mp->dhcp_src_address),
1997 (u32) ntohl (mp->vrf_id),
1998 (int) mp->insert_circuit_id,
1999 (int) (mp->is_add == 0));
2001 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_REPLY);
2005 dhcpv4_proxy_config_2 (vl_api_dhcp_proxy_config_2_t * mp)
2007 vl_api_dhcp_proxy_config_reply_t *rmp;
2010 rv = dhcp_proxy_set_server_2 ((ip4_address_t *) (&mp->dhcp_server),
2011 (ip4_address_t *) (&mp->dhcp_src_address),
2012 (u32) ntohl (mp->rx_vrf_id),
2013 (u32) ntohl (mp->server_vrf_id),
2014 (int) mp->insert_circuit_id,
2015 (int) (mp->is_add == 0));
2017 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_2_REPLY);
2022 dhcpv6_proxy_config_2 (vl_api_dhcp_proxy_config_2_t * mp)
2024 vl_api_dhcp_proxy_config_reply_t *rmp;
2027 rv = dhcpv6_proxy_set_server_2 ((ip6_address_t *) (&mp->dhcp_server),
2028 (ip6_address_t *) (&mp->dhcp_src_address),
2029 (u32) ntohl (mp->rx_vrf_id),
2030 (u32) ntohl (mp->server_vrf_id),
2031 (int) mp->insert_circuit_id,
2032 (int) (mp->is_add == 0));
2034 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_2_REPLY);
2039 vl_api_dhcp_proxy_set_vss_t_handler (vl_api_dhcp_proxy_set_vss_t * mp)
2041 vl_api_dhcp_proxy_set_vss_reply_t *rmp;
2044 rv = dhcp_proxy_set_option82_vss (ntohl (mp->tbl_id),
2047 (int) mp->is_add == 0);
2049 rv = dhcpv6_proxy_set_vss (ntohl (mp->tbl_id),
2051 ntohl (mp->fib_id), (int) mp->is_add == 0);
2053 REPLY_MACRO (VL_API_DHCP_PROXY_SET_VSS_REPLY);
2057 static void vl_api_dhcp_proxy_config_t_handler
2058 (vl_api_dhcp_proxy_config_t * mp)
2060 if (mp->is_ipv6 == 0)
2061 dhcpv4_proxy_config (mp);
2063 dhcpv6_proxy_config (mp);
2066 static void vl_api_dhcp_proxy_config_2_t_handler
2067 (vl_api_dhcp_proxy_config_2_t * mp)
2069 if (mp->is_ipv6 == 0)
2070 dhcpv4_proxy_config_2 (mp);
2072 dhcpv6_proxy_config_2 (mp);
2076 dhcp_compl_event_callback (u32 client_index, u32 pid, u8 * hostname,
2077 u8 is_ipv6, u8 * host_address, u8 * router_address,
2080 unix_shared_memory_queue_t *q;
2081 vl_api_dhcp_compl_event_t *mp;
2083 q = vl_api_client_index_to_input_queue (client_index);
2087 mp = vl_msg_api_alloc (sizeof (*mp));
2088 mp->client_index = client_index;
2090 mp->is_ipv6 = is_ipv6;
2091 clib_memcpy (&mp->hostname, hostname, vec_len (hostname));
2092 mp->hostname[vec_len (hostname) + 1] = '\n';
2093 clib_memcpy (&mp->host_address[0], host_address, 16);
2094 clib_memcpy (&mp->router_address[0], router_address, 16);
2096 if (NULL != host_mac)
2097 clib_memcpy (&mp->host_mac[0], host_mac, 6);
2099 mp->_vl_msg_id = ntohs (VL_API_DHCP_COMPL_EVENT);
2101 vl_msg_api_send_shmem (q, (u8 *) & mp);
2104 static void vl_api_dhcp_client_config_t_handler
2105 (vl_api_dhcp_client_config_t * mp)
2107 vlib_main_t *vm = vlib_get_main ();
2108 vl_api_dhcp_client_config_reply_t *rmp;
2111 VALIDATE_SW_IF_INDEX (mp);
2113 rv = dhcp_client_config (vm, ntohl (mp->sw_if_index),
2114 mp->hostname, mp->is_add, mp->client_index,
2115 mp->want_dhcp_event ? dhcp_compl_event_callback :
2118 BAD_SW_IF_INDEX_LABEL;
2120 REPLY_MACRO (VL_API_DHCP_CLIENT_CONFIG_REPLY);
2124 vl_api_create_loopback_t_handler (vl_api_create_loopback_t * mp)
2126 vl_api_create_loopback_reply_t *rmp;
2130 rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address);
2133 REPLY_MACRO2(VL_API_CREATE_LOOPBACK_REPLY,
2135 rmp->sw_if_index = ntohl (sw_if_index);
2141 vl_api_delete_loopback_t_handler (vl_api_delete_loopback_t * mp)
2143 vl_api_delete_loopback_reply_t *rmp;
2147 sw_if_index = ntohl (mp->sw_if_index);
2148 rv = vnet_delete_loopback_interface (sw_if_index);
2150 REPLY_MACRO (VL_API_DELETE_LOOPBACK_REPLY);
2154 vl_api_control_ping_t_handler (vl_api_control_ping_t * mp)
2156 vl_api_control_ping_reply_t *rmp;
2160 REPLY_MACRO2(VL_API_CONTROL_PING_REPLY,
2162 rmp->vpe_pid = ntohl (getpid());
2168 shmem_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
2170 u8 **shmem_vecp = (u8 **) arg;
2173 api_main_t *am = &api_main;
2176 shmem_vec = *shmem_vecp;
2178 offset = vec_len (shmem_vec);
2180 pthread_mutex_lock (&am->vlib_rp->mutex);
2181 oldheap = svm_push_data_heap (am->vlib_rp);
2183 vec_validate (shmem_vec, offset + buffer_bytes - 1);
2185 clib_memcpy (shmem_vec + offset, buffer, buffer_bytes);
2187 svm_pop_heap (oldheap);
2188 pthread_mutex_unlock (&am->vlib_rp->mutex);
2190 *shmem_vecp = shmem_vec;
2195 vl_api_cli_request_t_handler (vl_api_cli_request_t * mp)
2197 vl_api_cli_reply_t *rp;
2198 unix_shared_memory_queue_t *q;
2199 vlib_main_t *vm = vlib_get_main ();
2200 api_main_t *am = &api_main;
2201 unformat_input_t input;
2205 q = vl_api_client_index_to_input_queue (mp->client_index);
2209 rp = vl_msg_api_alloc (sizeof (*rp));
2210 rp->_vl_msg_id = ntohs (VL_API_CLI_REPLY);
2211 rp->context = mp->context;
2213 unformat_init_vector (&input, (u8 *) (uword) mp->cmd_in_shmem);
2215 vlib_cli_input (vm, &input, shmem_cli_output, (uword) & shmem_vec);
2217 pthread_mutex_lock (&am->vlib_rp->mutex);
2218 oldheap = svm_push_data_heap (am->vlib_rp);
2220 vec_add1 (shmem_vec, 0);
2222 svm_pop_heap (oldheap);
2223 pthread_mutex_unlock (&am->vlib_rp->mutex);
2225 rp->reply_in_shmem = (uword) shmem_vec;
2227 vl_msg_api_send_shmem (q, (u8 *) & rp);
2231 inband_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
2233 u8 **mem_vecp = (u8 **) arg;
2234 u8 *mem_vec = *mem_vecp;
2235 u32 offset = vec_len (mem_vec);
2237 vec_validate (mem_vec, offset + buffer_bytes - 1);
2238 clib_memcpy (mem_vec + offset, buffer, buffer_bytes);
2239 *mem_vecp = mem_vec;
2243 vl_api_cli_inband_t_handler (vl_api_cli_inband_t * mp)
2245 vl_api_cli_inband_reply_t *rmp;
2247 unix_shared_memory_queue_t *q;
2248 vlib_main_t *vm = vlib_get_main ();
2249 unformat_input_t input;
2252 q = vl_api_client_index_to_input_queue (mp->client_index);
2256 unformat_init_string (&input, (char *) mp->cmd, ntohl (mp->length));
2257 vlib_cli_input (vm, &input, inband_cli_output, (uword) & out_vec);
2259 u32 len = vec_len (out_vec);
2261 REPLY_MACRO3(VL_API_CLI_INBAND_REPLY, len,
2263 rmp->length = htonl (len);
2264 clib_memcpy (rmp->reply, out_vec, len);
2271 vl_api_set_arp_neighbor_limit_t_handler (vl_api_set_arp_neighbor_limit_t * mp)
2274 vl_api_set_arp_neighbor_limit_reply_t *rmp;
2275 vnet_main_t *vnm = vnet_get_main ();
2276 clib_error_t *error;
2281 error = ip6_set_neighbor_limit (ntohl (mp->arp_neighbor_limit));
2283 error = ip4_set_arp_limit (ntohl (mp->arp_neighbor_limit));
2287 clib_error_report (error);
2288 rv = VNET_API_ERROR_UNSPECIFIED;
2292 rv = vnm->api_errno;
2295 REPLY_MACRO (VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
2298 static void vl_api_sr_tunnel_add_del_t_handler
2299 (vl_api_sr_tunnel_add_del_t * mp)
2302 clib_warning ("unimplemented");
2304 ip6_sr_add_del_tunnel_args_t _a, *a = &_a;
2306 vl_api_sr_tunnel_add_del_reply_t *rmp;
2307 ip6_address_t *segments = 0, *seg;
2308 ip6_address_t *tags = 0, *tag;
2309 ip6_address_t *this_address;
2312 if (mp->n_segments == 0)
2318 memset (a, 0, sizeof (*a));
2319 a->src_address = (ip6_address_t *) & mp->src_address;
2320 a->dst_address = (ip6_address_t *) & mp->dst_address;
2321 a->dst_mask_width = mp->dst_mask_width;
2322 a->flags_net_byte_order = mp->flags_net_byte_order;
2323 a->is_del = (mp->is_add == 0);
2324 a->rx_table_id = ntohl (mp->outer_vrf_id);
2325 a->tx_table_id = ntohl (mp->inner_vrf_id);
2327 a->name = format (0, "%s", mp->name);
2328 if (!(vec_len (a->name)))
2331 a->policy_name = format (0, "%s", mp->policy_name);
2332 if (!(vec_len (a->policy_name)))
2335 /* Yank segments and tags out of the API message */
2336 this_address = (ip6_address_t *) mp->segs_and_tags;
2337 for (i = 0; i < mp->n_segments; i++)
2339 vec_add2 (segments, seg, 1);
2340 clib_memcpy (seg->as_u8, this_address->as_u8, sizeof (*this_address));
2343 for (i = 0; i < mp->n_tags; i++)
2345 vec_add2 (tags, tag, 1);
2346 clib_memcpy (tag->as_u8, this_address->as_u8, sizeof (*this_address));
2350 a->segments = segments;
2353 rv = ip6_sr_add_del_tunnel (a);
2357 REPLY_MACRO (VL_API_SR_TUNNEL_ADD_DEL_REPLY);
2361 static void vl_api_sr_policy_add_del_t_handler
2362 (vl_api_sr_policy_add_del_t * mp)
2365 clib_warning ("unimplemented");
2367 ip6_sr_add_del_policy_args_t _a, *a = &_a;
2369 vl_api_sr_policy_add_del_reply_t *rmp;
2372 memset (a, 0, sizeof (*a));
2373 a->is_del = (mp->is_add == 0);
2375 a->name = format (0, "%s", mp->name);
2376 if (!(vec_len (a->name)))
2378 rv = VNET_API_ERROR_NO_SUCH_NODE2;
2382 if (!(mp->tunnel_names[0]))
2384 rv = VNET_API_ERROR_NO_SUCH_NODE2;
2388 // start deserializing tunnel_names
2389 int num_tunnels = mp->tunnel_names[0]; //number of tunnels
2390 u8 *deser_tun_names = mp->tunnel_names;
2391 deser_tun_names += 1; //moving along
2394 int tun_name_len = 0;
2396 for (i = 0; i < num_tunnels; i++)
2398 tun_name_len = *deser_tun_names;
2399 deser_tun_names += 1;
2400 vec_resize (tun_name, tun_name_len);
2401 memcpy (tun_name, deser_tun_names, tun_name_len);
2402 vec_add1 (a->tunnel_names, tun_name);
2403 deser_tun_names += tun_name_len;
2407 rv = ip6_sr_add_del_policy (a);
2411 REPLY_MACRO (VL_API_SR_POLICY_ADD_DEL_REPLY);
2415 static void vl_api_sr_multicast_map_add_del_t_handler
2416 (vl_api_sr_multicast_map_add_del_t * mp)
2419 clib_warning ("unimplemented");
2421 ip6_sr_add_del_multicastmap_args_t _a, *a = &_a;
2423 vl_api_sr_multicast_map_add_del_reply_t *rmp;
2425 memset (a, 0, sizeof (*a));
2426 a->is_del = (mp->is_add == 0);
2428 a->multicast_address = (ip6_address_t *) & mp->multicast_address;
2429 a->policy_name = format (0, "%s", mp->policy_name);
2431 if (a->multicast_address == 0)
2437 if (!(a->policy_name))
2443 #if DPDK > 0 /* Cannot call replicate without DPDK */
2444 rv = ip6_sr_add_del_multicastmap (a);
2446 clib_warning ("multicast replication without DPDK not implemented");
2447 rv = VNET_API_ERROR_UNIMPLEMENTED;
2452 REPLY_MACRO (VL_API_SR_MULTICAST_MAP_ADD_DEL_REPLY);
2456 #define foreach_classify_add_del_table_field \
2461 _(match_n_vectors) \
2462 _(next_table_index) \
2463 _(miss_next_index) \
2464 _(current_data_flag) \
2465 _(current_data_offset)
2467 static void vl_api_classify_add_del_table_t_handler
2468 (vl_api_classify_add_del_table_t * mp)
2470 vl_api_classify_add_del_table_reply_t *rmp;
2471 vnet_classify_main_t *cm = &vnet_classify_main;
2472 vnet_classify_table_t *t;
2476 foreach_classify_add_del_table_field;
2479 #define _(a) a = ntohl(mp->a);
2480 foreach_classify_add_del_table_field;
2483 /* The underlying API fails silently, on purpose, so check here */
2484 if (mp->is_add == 0) /* delete */
2486 if (pool_is_free_index (cm->tables, table_index))
2488 rv = VNET_API_ERROR_NO_SUCH_TABLE;
2492 else /* add or update */
2494 if (table_index != ~0 && pool_is_free_index (cm->tables, table_index))
2498 rv = vnet_classify_add_del_table
2499 (cm, mp->mask, nbuckets, memory_size,
2500 skip_n_vectors, match_n_vectors,
2501 next_table_index, miss_next_index, &table_index,
2502 current_data_flag, current_data_offset, mp->is_add, mp->del_chain);
2506 REPLY_MACRO2(VL_API_CLASSIFY_ADD_DEL_TABLE_REPLY,
2508 if (rv == 0 && mp->is_add)
2510 t = pool_elt_at_index (cm->tables, table_index);
2511 rmp->skip_n_vectors = ntohl(t->skip_n_vectors);
2512 rmp->match_n_vectors = ntohl(t->match_n_vectors);
2513 rmp->new_table_index = ntohl(table_index);
2517 rmp->skip_n_vectors = ~0;
2518 rmp->match_n_vectors = ~0;
2519 rmp->new_table_index = ~0;
2525 static void vl_api_classify_add_del_session_t_handler
2526 (vl_api_classify_add_del_session_t * mp)
2528 vnet_classify_main_t *cm = &vnet_classify_main;
2529 vl_api_classify_add_del_session_reply_t *rmp;
2531 u32 table_index, hit_next_index, opaque_index, metadata;
2535 table_index = ntohl (mp->table_index);
2536 hit_next_index = ntohl (mp->hit_next_index);
2537 opaque_index = ntohl (mp->opaque_index);
2538 advance = ntohl (mp->advance);
2539 action = mp->action;
2540 metadata = ntohl (mp->metadata);
2542 rv = vnet_classify_add_del_session
2543 (cm, table_index, mp->match, hit_next_index, opaque_index,
2544 advance, action, metadata, mp->is_add);
2546 REPLY_MACRO (VL_API_CLASSIFY_ADD_DEL_SESSION_REPLY);
2549 static void vl_api_classify_set_interface_ip_table_t_handler
2550 (vl_api_classify_set_interface_ip_table_t * mp)
2552 vlib_main_t *vm = vlib_get_main ();
2553 vl_api_classify_set_interface_ip_table_reply_t *rmp;
2555 u32 table_index, sw_if_index;
2557 table_index = ntohl (mp->table_index);
2558 sw_if_index = ntohl (mp->sw_if_index);
2560 VALIDATE_SW_IF_INDEX (mp);
2563 rv = vnet_set_ip6_classify_intfc (vm, sw_if_index, table_index);
2565 rv = vnet_set_ip4_classify_intfc (vm, sw_if_index, table_index);
2567 BAD_SW_IF_INDEX_LABEL;
2569 REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY);
2572 static void vl_api_classify_set_interface_l2_tables_t_handler
2573 (vl_api_classify_set_interface_l2_tables_t * mp)
2575 vl_api_classify_set_interface_l2_tables_reply_t *rmp;
2577 u32 sw_if_index, ip4_table_index, ip6_table_index, other_table_index;
2580 ip4_table_index = ntohl (mp->ip4_table_index);
2581 ip6_table_index = ntohl (mp->ip6_table_index);
2582 other_table_index = ntohl (mp->other_table_index);
2583 sw_if_index = ntohl (mp->sw_if_index);
2585 VALIDATE_SW_IF_INDEX (mp);
2588 rv = vnet_l2_input_classify_set_tables (sw_if_index, ip4_table_index,
2592 rv = vnet_l2_output_classify_set_tables (sw_if_index, ip4_table_index,
2598 if (ip4_table_index != ~0 || ip6_table_index != ~0
2599 || other_table_index != ~0)
2605 vnet_l2_input_classify_enable_disable (sw_if_index, enable);
2607 vnet_l2_output_classify_enable_disable (sw_if_index, enable);
2610 BAD_SW_IF_INDEX_LABEL;
2612 REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY);
2616 vl_api_l2_fib_clear_table_t_handler (vl_api_l2_fib_clear_table_t * mp)
2619 vl_api_l2_fib_clear_table_reply_t *rmp;
2621 /* DAW-FIXME: This API should only clear non-static l2fib entries, but
2622 * that is not currently implemented. When that TODO is fixed
2623 * this call should be changed to pass 1 instead of 0.
2625 l2fib_clear_table (0);
2627 REPLY_MACRO (VL_API_L2_FIB_CLEAR_TABLE_REPLY);
2630 extern void l2_efp_filter_configure (vnet_main_t * vnet_main,
2631 u32 sw_if_index, u32 enable);
2634 vl_api_l2_interface_efp_filter_t_handler (vl_api_l2_interface_efp_filter_t *
2638 vl_api_l2_interface_efp_filter_reply_t *rmp;
2639 vnet_main_t *vnm = vnet_get_main ();
2641 // enable/disable the feature
2642 l2_efp_filter_configure (vnm, mp->sw_if_index, mp->enable_disable);
2643 rv = vnm->api_errno;
2645 REPLY_MACRO (VL_API_L2_INTERFACE_EFP_FILTER_REPLY);
2649 vl_api_l2_interface_vlan_tag_rewrite_t_handler
2650 (vl_api_l2_interface_vlan_tag_rewrite_t * mp)
2653 vl_api_l2_interface_vlan_tag_rewrite_reply_t *rmp;
2654 vnet_main_t *vnm = vnet_get_main ();
2655 vlib_main_t *vm = vlib_get_main ();
2658 VALIDATE_SW_IF_INDEX (mp);
2660 vtr_op = ntohl (mp->vtr_op);
2662 /* The L2 code is unsuspicious */
2665 case L2_VTR_DISABLED:
2670 case L2_VTR_TRANSLATE_1_1:
2671 case L2_VTR_TRANSLATE_1_2:
2672 case L2_VTR_TRANSLATE_2_1:
2673 case L2_VTR_TRANSLATE_2_2:
2677 rv = VNET_API_ERROR_INVALID_VALUE;
2678 goto bad_sw_if_index;
2681 rv = l2vtr_configure (vm, vnm, ntohl (mp->sw_if_index), vtr_op,
2682 ntohl (mp->push_dot1q), ntohl (mp->tag1),
2685 BAD_SW_IF_INDEX_LABEL;
2687 REPLY_MACRO (VL_API_L2_INTERFACE_VLAN_TAG_REWRITE_REPLY);
2691 vl_api_create_vhost_user_if_t_handler (vl_api_create_vhost_user_if_t * mp)
2694 vl_api_create_vhost_user_if_reply_t *rmp;
2695 u32 sw_if_index = (u32) ~ 0;
2696 vnet_main_t *vnm = vnet_get_main ();
2697 vlib_main_t *vm = vlib_get_main ();
2699 rv = vhost_user_create_if (vnm, vm, (char *) mp->sock_filename,
2700 mp->is_server, &sw_if_index, (u64) ~ 0,
2701 mp->renumber, ntohl (mp->custom_dev_instance),
2702 (mp->use_custom_mac) ? mp->mac_address : NULL);
2704 /* Remember an interface tag for the new interface */
2707 /* If a tag was supplied... */
2710 /* Make sure it's a proper C-string */
2711 mp->tag[ARRAY_LEN (mp->tag) - 1] = 0;
2712 u8 *tag = format (0, "%s%c", mp->tag, 0);
2713 vnet_set_sw_interface_tag (vnm, tag, sw_if_index);
2718 REPLY_MACRO2(VL_API_CREATE_VHOST_USER_IF_REPLY,
2720 rmp->sw_if_index = ntohl (sw_if_index);
2726 vl_api_modify_vhost_user_if_t_handler (vl_api_modify_vhost_user_if_t * mp)
2729 vl_api_modify_vhost_user_if_reply_t *rmp;
2730 u32 sw_if_index = ntohl (mp->sw_if_index);
2732 vnet_main_t *vnm = vnet_get_main ();
2733 vlib_main_t *vm = vlib_get_main ();
2735 rv = vhost_user_modify_if (vnm, vm, (char *) mp->sock_filename,
2736 mp->is_server, sw_if_index, (u64) ~ 0,
2737 mp->renumber, ntohl (mp->custom_dev_instance));
2739 REPLY_MACRO (VL_API_MODIFY_VHOST_USER_IF_REPLY);
2743 vl_api_delete_vhost_user_if_t_handler (vl_api_delete_vhost_user_if_t * mp)
2746 vl_api_delete_vhost_user_if_reply_t *rmp;
2747 vpe_api_main_t *vam = &vpe_api_main;
2748 u32 sw_if_index = ntohl (mp->sw_if_index);
2750 vnet_main_t *vnm = vnet_get_main ();
2751 vlib_main_t *vm = vlib_get_main ();
2753 rv = vhost_user_delete_if (vnm, vm, sw_if_index);
2755 REPLY_MACRO (VL_API_DELETE_VHOST_USER_IF_REPLY);
2758 unix_shared_memory_queue_t *q =
2759 vl_api_client_index_to_input_queue (mp->client_index);
2763 vnet_clear_sw_interface_tag (vnm, sw_if_index);
2764 send_sw_interface_flags_deleted (vam, q, sw_if_index);
2769 vl_api_sw_interface_vhost_user_details_t_handler
2770 (vl_api_sw_interface_vhost_user_details_t * mp)
2772 clib_warning ("BUG");
2776 send_sw_interface_vhost_user_details (vpe_api_main_t * am,
2777 unix_shared_memory_queue_t * q,
2778 vhost_user_intf_details_t * vui,
2781 vl_api_sw_interface_vhost_user_details_t *mp;
2783 mp = vl_msg_api_alloc (sizeof (*mp));
2784 memset (mp, 0, sizeof (*mp));
2785 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_VHOST_USER_DETAILS);
2786 mp->sw_if_index = ntohl (vui->sw_if_index);
2787 mp->virtio_net_hdr_sz = ntohl (vui->virtio_net_hdr_sz);
2788 mp->features = clib_net_to_host_u64 (vui->features);
2789 mp->is_server = vui->is_server;
2790 mp->num_regions = ntohl (vui->num_regions);
2791 mp->sock_errno = ntohl (vui->sock_errno);
2792 mp->context = context;
2794 strncpy ((char *) mp->sock_filename,
2795 (char *) vui->sock_filename, ARRAY_LEN (mp->sock_filename) - 1);
2796 strncpy ((char *) mp->interface_name,
2797 (char *) vui->if_name, ARRAY_LEN (mp->interface_name) - 1);
2799 vl_msg_api_send_shmem (q, (u8 *) & mp);
2803 vl_api_sw_interface_vhost_user_dump_t_handler
2804 (vl_api_sw_interface_vhost_user_dump_t * mp)
2807 vpe_api_main_t *am = &vpe_api_main;
2808 vnet_main_t *vnm = vnet_get_main ();
2809 vlib_main_t *vm = vlib_get_main ();
2810 vhost_user_intf_details_t *ifaces = NULL;
2811 vhost_user_intf_details_t *vuid = NULL;
2812 unix_shared_memory_queue_t *q;
2814 q = vl_api_client_index_to_input_queue (mp->client_index);
2818 rv = vhost_user_dump_ifs (vnm, vm, &ifaces);
2822 vec_foreach (vuid, ifaces)
2824 send_sw_interface_vhost_user_details (am, q, vuid, mp->context);
2830 send_sw_if_l2tpv3_tunnel_details (vpe_api_main_t * am,
2831 unix_shared_memory_queue_t * q,
2833 l2t_main_t * lm, u32 context)
2835 vl_api_sw_if_l2tpv3_tunnel_details_t *mp;
2837 vnet_sw_interface_t *si = NULL;
2839 si = vnet_get_hw_sw_interface (lm->vnet_main, s->hw_if_index);
2841 if_name = format (if_name, "%U",
2842 format_vnet_sw_interface_name, lm->vnet_main, si);
2844 mp = vl_msg_api_alloc (sizeof (*mp));
2845 memset (mp, 0, sizeof (*mp));
2846 mp->_vl_msg_id = ntohs (VL_API_SW_IF_L2TPV3_TUNNEL_DETAILS);
2847 strncpy ((char *) mp->interface_name,
2848 (char *) if_name, ARRAY_LEN (mp->interface_name) - 1);
2849 mp->sw_if_index = ntohl (si->sw_if_index);
2850 mp->local_session_id = s->local_session_id;
2851 mp->remote_session_id = s->remote_session_id;
2852 mp->local_cookie[0] = s->local_cookie[0];
2853 mp->local_cookie[1] = s->local_cookie[1];
2854 mp->remote_cookie = s->remote_cookie;
2855 clib_memcpy (mp->client_address, &s->client_address,
2856 sizeof (s->client_address));
2857 clib_memcpy (mp->our_address, &s->our_address, sizeof (s->our_address));
2858 mp->l2_sublayer_present = s->l2_sublayer_present;
2859 mp->context = context;
2861 vl_msg_api_send_shmem (q, (u8 *) & mp);
2866 vl_api_sw_if_l2tpv3_tunnel_dump_t_handler (vl_api_sw_if_l2tpv3_tunnel_dump_t *
2869 vpe_api_main_t *am = &vpe_api_main;
2870 l2t_main_t *lm = &l2t_main;
2871 unix_shared_memory_queue_t *q;
2872 l2t_session_t *session;
2874 q = vl_api_client_index_to_input_queue (mp->client_index);
2879 pool_foreach (session, lm->sessions,
2881 send_sw_if_l2tpv3_tunnel_details (am, q, session, lm, mp->context);
2887 send_sw_interface_tap_details (vpe_api_main_t * am,
2888 unix_shared_memory_queue_t * q,
2889 tapcli_interface_details_t * tap_if,
2892 vl_api_sw_interface_tap_details_t *mp;
2893 mp = vl_msg_api_alloc (sizeof (*mp));
2894 memset (mp, 0, sizeof (*mp));
2895 mp->_vl_msg_id = ntohs (VL_API_SW_INTERFACE_TAP_DETAILS);
2896 mp->sw_if_index = ntohl (tap_if->sw_if_index);
2897 strncpy ((char *) mp->dev_name,
2898 (char *) tap_if->dev_name, ARRAY_LEN (mp->dev_name) - 1);
2899 mp->context = context;
2901 vl_msg_api_send_shmem (q, (u8 *) & mp);
2905 vl_api_sw_interface_tap_dump_t_handler (vl_api_sw_interface_tap_dump_t * mp)
2908 vpe_api_main_t *am = &vpe_api_main;
2909 unix_shared_memory_queue_t *q;
2910 tapcli_interface_details_t *tapifs = NULL;
2911 tapcli_interface_details_t *tap_if = NULL;
2913 q = vl_api_client_index_to_input_queue (mp->client_index);
2917 rv = vnet_tap_dump_ifs (&tapifs);
2921 vec_foreach (tap_if, tapifs)
2923 send_sw_interface_tap_details (am, q, tap_if, mp->context);
2930 vl_api_l2_fib_table_entry_t_handler (vl_api_l2_fib_table_entry_t * mp)
2932 clib_warning ("BUG");
2936 send_l2fib_table_entry (vpe_api_main_t * am,
2937 unix_shared_memory_queue_t * q,
2938 l2fib_entry_key_t * l2fe_key,
2939 l2fib_entry_result_t * l2fe_res, u32 context)
2941 vl_api_l2_fib_table_entry_t *mp;
2943 mp = vl_msg_api_alloc (sizeof (*mp));
2944 memset (mp, 0, sizeof (*mp));
2945 mp->_vl_msg_id = ntohs (VL_API_L2_FIB_TABLE_ENTRY);
2948 ntohl (l2input_main.bd_configs[l2fe_key->fields.bd_index].bd_id);
2950 mp->mac = l2fib_make_key (l2fe_key->fields.mac, 0);
2951 mp->sw_if_index = ntohl (l2fe_res->fields.sw_if_index);
2952 mp->static_mac = l2fe_res->fields.static_mac;
2953 mp->filter_mac = l2fe_res->fields.filter;
2954 mp->bvi_mac = l2fe_res->fields.bvi;
2955 mp->context = context;
2957 vl_msg_api_send_shmem (q, (u8 *) & mp);
2961 vl_api_l2_fib_table_dump_t_handler (vl_api_l2_fib_table_dump_t * mp)
2963 vpe_api_main_t *am = &vpe_api_main;
2964 bd_main_t *bdm = &bd_main;
2965 l2fib_entry_key_t *l2fe_key = NULL;
2966 l2fib_entry_result_t *l2fe_res = NULL;
2967 u32 ni, bd_id = ntohl (mp->bd_id);
2969 unix_shared_memory_queue_t *q;
2972 q = vl_api_client_index_to_input_queue (mp->client_index);
2976 /* see l2fib_table_dump: ~0 means "any" */
2981 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
2988 l2fib_table_dump (bd_index, &l2fe_key, &l2fe_res);
2990 vec_foreach_index (ni, l2fe_key)
2992 send_l2fib_table_entry (am, q, vec_elt_at_index (l2fe_key, ni),
2993 vec_elt_at_index (l2fe_res, ni), mp->context);
2995 vec_free (l2fe_key);
2996 vec_free (l2fe_res);
3000 vl_api_show_version_t_handler (vl_api_show_version_t * mp)
3002 vl_api_show_version_reply_t *rmp;
3004 char *vpe_api_get_build_directory (void);
3005 char *vpe_api_get_version (void);
3006 char *vpe_api_get_build_date (void);
3008 unix_shared_memory_queue_t *q =
3009 vl_api_client_index_to_input_queue (mp->client_index);
3015 REPLY_MACRO2(VL_API_SHOW_VERSION_REPLY,
3017 strncpy ((char *) rmp->program, "vpe", ARRAY_LEN(rmp->program)-1);
3018 strncpy ((char *) rmp->build_directory, vpe_api_get_build_directory(),
3019 ARRAY_LEN(rmp->build_directory)-1);
3020 strncpy ((char *) rmp->version, vpe_api_get_version(),
3021 ARRAY_LEN(rmp->version)-1);
3022 strncpy ((char *) rmp->build_date, vpe_api_get_build_date(),
3023 ARRAY_LEN(rmp->build_date)-1);
3029 vl_api_get_node_index_t_handler (vl_api_get_node_index_t * mp)
3031 vlib_main_t *vm = vlib_get_main ();
3032 vl_api_get_node_index_reply_t *rmp;
3035 u32 node_index = ~0;
3037 n = vlib_get_node_by_name (vm, mp->node_name);
3040 rv = VNET_API_ERROR_NO_SUCH_NODE;
3042 node_index = n->index;
3045 REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
3047 rmp->node_index = ntohl(node_index);
3053 vl_api_get_next_index_t_handler (vl_api_get_next_index_t * mp)
3055 vlib_main_t *vm = vlib_get_main ();
3056 vl_api_get_next_index_reply_t *rmp;
3057 vlib_node_t *node, *next_node;
3059 u32 next_node_index = ~0, next_index = ~0;
3062 node = vlib_get_node_by_name (vm, mp->node_name);
3066 rv = VNET_API_ERROR_NO_SUCH_NODE;
3070 next_node = vlib_get_node_by_name (vm, mp->next_name);
3074 rv = VNET_API_ERROR_NO_SUCH_NODE2;
3078 next_node_index = next_node->index;
3080 p = hash_get (node->next_slot_by_node, next_node_index);
3084 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
3092 REPLY_MACRO2(VL_API_GET_NEXT_INDEX_REPLY,
3094 rmp->next_index = ntohl(next_index);
3100 vl_api_add_node_next_t_handler (vl_api_add_node_next_t * mp)
3102 vlib_main_t *vm = vlib_get_main ();
3103 vl_api_add_node_next_reply_t *rmp;
3104 vlib_node_t *n, *next;
3106 u32 next_index = ~0;
3108 n = vlib_get_node_by_name (vm, mp->node_name);
3112 rv = VNET_API_ERROR_NO_SUCH_NODE;
3116 next = vlib_get_node_by_name (vm, mp->next_name);
3119 rv = VNET_API_ERROR_NO_SUCH_NODE2;
3121 next_index = vlib_node_add_next (vm, n->index, next->index);
3125 REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
3127 rmp->next_index = ntohl(next_index);
3132 static void vl_api_l2tpv3_create_tunnel_t_handler
3133 (vl_api_l2tpv3_create_tunnel_t * mp)
3135 vl_api_l2tpv3_create_tunnel_reply_t *rmp;
3136 l2t_main_t *lm = &l2t_main;
3137 u32 sw_if_index = (u32) ~ 0;
3140 if (mp->is_ipv6 != 1)
3142 rv = VNET_API_ERROR_UNIMPLEMENTED;
3146 u32 encap_fib_index;
3148 if (mp->encap_vrf_id != ~0)
3151 ip6_main_t *im = &ip6_main;
3154 hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id))))
3156 rv = VNET_API_ERROR_NO_SUCH_FIB;
3159 encap_fib_index = p[0];
3163 encap_fib_index = ~0;
3166 rv = create_l2tpv3_ipv6_tunnel (lm,
3167 (ip6_address_t *) mp->client_address,
3168 (ip6_address_t *) mp->our_address,
3169 ntohl (mp->local_session_id),
3170 ntohl (mp->remote_session_id),
3171 clib_net_to_host_u64 (mp->local_cookie),
3172 clib_net_to_host_u64 (mp->remote_cookie),
3173 mp->l2_sublayer_present,
3174 encap_fib_index, &sw_if_index);
3178 REPLY_MACRO2(VL_API_L2TPV3_CREATE_TUNNEL_REPLY,
3180 rmp->sw_if_index = ntohl (sw_if_index);
3185 static void vl_api_l2tpv3_set_tunnel_cookies_t_handler
3186 (vl_api_l2tpv3_set_tunnel_cookies_t * mp)
3188 vl_api_l2tpv3_set_tunnel_cookies_reply_t *rmp;
3189 l2t_main_t *lm = &l2t_main;
3192 VALIDATE_SW_IF_INDEX (mp);
3194 rv = l2tpv3_set_tunnel_cookies (lm, ntohl (mp->sw_if_index),
3195 clib_net_to_host_u64 (mp->new_local_cookie),
3196 clib_net_to_host_u64
3197 (mp->new_remote_cookie));
3199 BAD_SW_IF_INDEX_LABEL;
3201 REPLY_MACRO (VL_API_L2TPV3_SET_TUNNEL_COOKIES_REPLY);
3204 static void vl_api_l2tpv3_interface_enable_disable_t_handler
3205 (vl_api_l2tpv3_interface_enable_disable_t * mp)
3208 vnet_main_t *vnm = vnet_get_main ();
3209 vl_api_l2tpv3_interface_enable_disable_reply_t *rmp;
3211 VALIDATE_SW_IF_INDEX (mp);
3213 rv = l2tpv3_interface_enable_disable
3214 (vnm, ntohl (mp->sw_if_index), mp->enable_disable);
3216 BAD_SW_IF_INDEX_LABEL;
3218 REPLY_MACRO (VL_API_L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY);
3221 static void vl_api_l2tpv3_set_lookup_key_t_handler
3222 (vl_api_l2tpv3_set_lookup_key_t * mp)
3225 l2t_main_t *lm = &l2t_main;
3226 vl_api_l2tpv3_set_lookup_key_reply_t *rmp;
3228 if (mp->key > L2T_LOOKUP_SESSION_ID)
3230 rv = VNET_API_ERROR_INVALID_VALUE;
3234 lm->lookup_type = mp->key;
3237 REPLY_MACRO (VL_API_L2TPV3_SET_LOOKUP_KEY_REPLY);
3240 static void vl_api_vxlan_add_del_tunnel_t_handler
3241 (vl_api_vxlan_add_del_tunnel_t * mp)
3243 vl_api_vxlan_add_del_tunnel_reply_t *rmp;
3245 vnet_vxlan_add_del_tunnel_args_t _a, *a = &_a;
3246 u32 encap_fib_index;
3248 ip4_main_t *im = &ip4_main;
3249 u32 sw_if_index = ~0;
3251 p = hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id));
3254 rv = VNET_API_ERROR_NO_SUCH_FIB;
3257 encap_fib_index = p[0];
3258 memset (a, 0, sizeof (*a));
3260 a->is_add = mp->is_add;
3261 a->is_ip6 = mp->is_ipv6;
3263 /* ip addresses sent in network byte order */
3264 ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &a->dst);
3265 ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &a->src);
3267 /* Check src & dst are different */
3268 if (ip46_address_cmp (&a->dst, &a->src) == 0)
3270 rv = VNET_API_ERROR_SAME_SRC_DST;
3273 a->mcast_sw_if_index = ntohl (mp->mcast_sw_if_index);
3274 a->encap_fib_index = encap_fib_index;
3275 a->decap_next_index = ntohl (mp->decap_next_index);
3276 a->vni = ntohl (mp->vni);
3277 rv = vnet_vxlan_add_del_tunnel (a, &sw_if_index);
3281 REPLY_MACRO2(VL_API_VXLAN_ADD_DEL_TUNNEL_REPLY,
3283 rmp->sw_if_index = ntohl (sw_if_index);
3288 static void send_vxlan_tunnel_details
3289 (vxlan_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
3291 vl_api_vxlan_tunnel_details_t *rmp;
3292 ip4_main_t *im4 = &ip4_main;
3293 ip6_main_t *im6 = &ip6_main;
3294 u8 is_ipv6 = !ip46_address_is_ip4 (&t->dst);
3296 rmp = vl_msg_api_alloc (sizeof (*rmp));
3297 memset (rmp, 0, sizeof (*rmp));
3298 rmp->_vl_msg_id = ntohs (VL_API_VXLAN_TUNNEL_DETAILS);
3301 memcpy (rmp->src_address, t->src.ip6.as_u8, 16);
3302 memcpy (rmp->dst_address, t->dst.ip6.as_u8, 16);
3303 rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].ft_table_id);
3307 memcpy (rmp->src_address, t->src.ip4.as_u8, 4);
3308 memcpy (rmp->dst_address, t->dst.ip4.as_u8, 4);
3309 rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id);
3311 rmp->mcast_sw_if_index = htonl (t->mcast_sw_if_index);
3312 rmp->vni = htonl (t->vni);
3313 rmp->decap_next_index = htonl (t->decap_next_index);
3314 rmp->sw_if_index = htonl (t->sw_if_index);
3315 rmp->is_ipv6 = is_ipv6;
3316 rmp->context = context;
3318 vl_msg_api_send_shmem (q, (u8 *) & rmp);
3321 static void vl_api_vxlan_tunnel_dump_t_handler
3322 (vl_api_vxlan_tunnel_dump_t * mp)
3324 unix_shared_memory_queue_t *q;
3325 vxlan_main_t *vxm = &vxlan_main;
3329 q = vl_api_client_index_to_input_queue (mp->client_index);
3335 sw_if_index = ntohl (mp->sw_if_index);
3337 if (~0 == sw_if_index)
3340 pool_foreach (t, vxm->tunnels,
3342 send_vxlan_tunnel_details(t, q, mp->context);
3348 if ((sw_if_index >= vec_len (vxm->tunnel_index_by_sw_if_index)) ||
3349 (~0 == vxm->tunnel_index_by_sw_if_index[sw_if_index]))
3353 t = &vxm->tunnels[vxm->tunnel_index_by_sw_if_index[sw_if_index]];
3354 send_vxlan_tunnel_details (t, q, mp->context);
3358 static void vl_api_gre_add_del_tunnel_t_handler
3359 (vl_api_gre_add_del_tunnel_t * mp)
3361 vl_api_gre_add_del_tunnel_reply_t *rmp;
3363 vnet_gre_add_del_tunnel_args_t _a, *a = &_a;
3366 ip4_main_t *im = &ip4_main;
3367 u32 sw_if_index = ~0;
3369 p = hash_get (im->fib_index_by_table_id, ntohl (mp->outer_fib_id));
3372 rv = VNET_API_ERROR_NO_SUCH_FIB;
3375 outer_fib_id = p[0];
3377 /* Check src & dst are different */
3378 if ((mp->is_ipv6 && memcmp (mp->src_address, mp->dst_address, 16) == 0) ||
3379 (!mp->is_ipv6 && memcmp (mp->src_address, mp->dst_address, 4) == 0))
3381 rv = VNET_API_ERROR_SAME_SRC_DST;
3384 memset (a, 0, sizeof (*a));
3386 a->is_add = mp->is_add;
3389 /* ip addresses sent in network byte order */
3390 clib_memcpy (&(a->src), mp->src_address, 4);
3391 clib_memcpy (&(a->dst), mp->dst_address, 4);
3393 a->outer_fib_id = outer_fib_id;
3394 rv = vnet_gre_add_del_tunnel (a, &sw_if_index);
3398 REPLY_MACRO2(VL_API_GRE_ADD_DEL_TUNNEL_REPLY,
3400 rmp->sw_if_index = ntohl (sw_if_index);
3405 static void send_gre_tunnel_details
3406 (gre_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
3408 vl_api_gre_tunnel_details_t *rmp;
3409 ip4_main_t *im = &ip4_main;
3411 rmp = vl_msg_api_alloc (sizeof (*rmp));
3412 memset (rmp, 0, sizeof (*rmp));
3413 rmp->_vl_msg_id = ntohs (VL_API_GRE_TUNNEL_DETAILS);
3414 clib_memcpy (rmp->src_address, &(t->tunnel_src), 4);
3415 clib_memcpy (rmp->dst_address, &(t->tunnel_dst), 4);
3416 rmp->outer_fib_id = htonl (im->fibs[t->outer_fib_index].ft_table_id);
3417 rmp->teb = (GRE_TUNNEL_TYPE_TEB == t->type);
3418 rmp->sw_if_index = htonl (t->sw_if_index);
3419 rmp->context = context;
3421 vl_msg_api_send_shmem (q, (u8 *) & rmp);
3425 vl_api_gre_tunnel_dump_t_handler (vl_api_gre_tunnel_dump_t * mp)
3427 unix_shared_memory_queue_t *q;
3428 gre_main_t *gm = &gre_main;
3432 q = vl_api_client_index_to_input_queue (mp->client_index);
3438 sw_if_index = ntohl (mp->sw_if_index);
3440 if (~0 == sw_if_index)
3443 pool_foreach (t, gm->tunnels,
3445 send_gre_tunnel_details(t, q, mp->context);
3451 if ((sw_if_index >= vec_len (gm->tunnel_index_by_sw_if_index)) ||
3452 (~0 == gm->tunnel_index_by_sw_if_index[sw_if_index]))
3456 t = &gm->tunnels[gm->tunnel_index_by_sw_if_index[sw_if_index]];
3457 send_gre_tunnel_details (t, q, mp->context);
3462 vl_api_l2_patch_add_del_t_handler (vl_api_l2_patch_add_del_t * mp)
3464 extern int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
3466 vl_api_l2_patch_add_del_reply_t *rmp;
3467 int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
3471 VALIDATE_RX_SW_IF_INDEX (mp);
3472 VALIDATE_TX_SW_IF_INDEX (mp);
3474 rv = vnet_l2_patch_add_del (ntohl (mp->rx_sw_if_index),
3475 ntohl (mp->tx_sw_if_index),
3476 (int) (mp->is_add != 0));
3478 BAD_RX_SW_IF_INDEX_LABEL;
3479 BAD_TX_SW_IF_INDEX_LABEL;
3481 REPLY_MACRO (VL_API_L2_PATCH_ADD_DEL_REPLY);
3485 vl_api_vxlan_gpe_add_del_tunnel_t_handler
3486 (vl_api_vxlan_gpe_add_del_tunnel_t * mp)
3488 vl_api_vxlan_gpe_add_del_tunnel_reply_t *rmp;
3490 vnet_vxlan_gpe_add_del_tunnel_args_t _a, *a = &_a;
3491 u32 encap_fib_index, decap_fib_index;
3494 ip4_main_t *im = &ip4_main;
3495 u32 sw_if_index = ~0;
3498 p = hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id));
3501 rv = VNET_API_ERROR_NO_SUCH_FIB;
3504 encap_fib_index = p[0];
3506 protocol = mp->protocol;
3508 /* Interpret decap_vrf_id as an opaque if sending to other-than-ip4-input */
3509 if (protocol == VXLAN_GPE_INPUT_NEXT_IP4_INPUT)
3511 p = hash_get (im->fib_index_by_table_id, ntohl (mp->decap_vrf_id));
3514 rv = VNET_API_ERROR_NO_SUCH_INNER_FIB;
3517 decap_fib_index = p[0];
3521 decap_fib_index = ntohl (mp->decap_vrf_id);
3524 /* Check src & dst are different */
3525 if ((mp->is_ipv6 && memcmp (mp->local, mp->remote, 16) == 0) ||
3526 (!mp->is_ipv6 && memcmp (mp->local, mp->remote, 4) == 0))
3528 rv = VNET_API_ERROR_SAME_SRC_DST;
3531 memset (a, 0, sizeof (*a));
3533 a->is_add = mp->is_add;
3534 a->is_ip6 = mp->is_ipv6;
3535 /* ip addresses sent in network byte order */
3538 clib_memcpy (&(a->local.ip6), mp->local, 16);
3539 clib_memcpy (&(a->remote.ip6), mp->remote, 16);
3543 clib_memcpy (&(a->local.ip4), mp->local, 4);
3544 clib_memcpy (&(a->remote.ip4), mp->remote, 4);
3546 a->encap_fib_index = encap_fib_index;
3547 a->decap_fib_index = decap_fib_index;
3548 a->protocol = protocol;
3549 a->vni = ntohl (mp->vni);
3550 rv = vnet_vxlan_gpe_add_del_tunnel (a, &sw_if_index);
3554 REPLY_MACRO2(VL_API_VXLAN_GPE_ADD_DEL_TUNNEL_REPLY,
3556 rmp->sw_if_index = ntohl (sw_if_index);
3561 static void send_vxlan_gpe_tunnel_details
3562 (vxlan_gpe_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
3564 vl_api_vxlan_gpe_tunnel_details_t *rmp;
3565 ip4_main_t *im4 = &ip4_main;
3566 ip6_main_t *im6 = &ip6_main;
3567 u8 is_ipv6 = !(t->flags & VXLAN_GPE_TUNNEL_IS_IPV4);
3569 rmp = vl_msg_api_alloc (sizeof (*rmp));
3570 memset (rmp, 0, sizeof (*rmp));
3571 rmp->_vl_msg_id = ntohs (VL_API_VXLAN_GPE_TUNNEL_DETAILS);
3574 memcpy (rmp->local, &(t->local.ip6), 16);
3575 memcpy (rmp->remote, &(t->remote.ip6), 16);
3576 rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].ft_table_id);
3577 rmp->decap_vrf_id = htonl (im6->fibs[t->decap_fib_index].ft_table_id);
3581 memcpy (rmp->local, &(t->local.ip4), 4);
3582 memcpy (rmp->remote, &(t->remote.ip4), 4);
3583 rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id);
3584 rmp->decap_vrf_id = htonl (im4->fibs[t->decap_fib_index].ft_table_id);
3586 rmp->vni = htonl (t->vni);
3587 rmp->protocol = t->protocol;
3588 rmp->sw_if_index = htonl (t->sw_if_index);
3589 rmp->is_ipv6 = is_ipv6;
3590 rmp->context = context;
3592 vl_msg_api_send_shmem (q, (u8 *) & rmp);
3595 static void vl_api_vxlan_gpe_tunnel_dump_t_handler
3596 (vl_api_vxlan_gpe_tunnel_dump_t * mp)
3598 unix_shared_memory_queue_t *q;
3599 vxlan_gpe_main_t *vgm = &vxlan_gpe_main;
3600 vxlan_gpe_tunnel_t *t;
3603 q = vl_api_client_index_to_input_queue (mp->client_index);
3609 sw_if_index = ntohl (mp->sw_if_index);
3611 if (~0 == sw_if_index)
3614 pool_foreach (t, vgm->tunnels,
3616 send_vxlan_gpe_tunnel_details(t, q, mp->context);
3622 if ((sw_if_index >= vec_len (vgm->tunnel_index_by_sw_if_index)) ||
3623 (~0 == vgm->tunnel_index_by_sw_if_index[sw_if_index]))
3627 t = &vgm->tunnels[vgm->tunnel_index_by_sw_if_index[sw_if_index]];
3628 send_vxlan_gpe_tunnel_details (t, q, mp->context);
3632 /** Used for transferring locators via VPP API */
3634 typedef CLIB_PACKED (struct {
3635 u32 sw_if_index; /**< locator sw_if_index */
3636 u8 priority; /**< locator priority */
3637 u8 weight; /**< locator weight */
3642 vl_api_lisp_add_del_locator_set_t_handler (vl_api_lisp_add_del_locator_set_t *
3645 vl_api_lisp_add_del_locator_set_reply_t *rmp;
3647 vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
3649 ls_locator_t *ls_loc;
3650 u32 ls_index = ~0, locator_num;
3651 u8 *locator_name = NULL;
3654 memset (a, 0, sizeof (a[0]));
3656 locator_name = format (0, "%s", mp->locator_set_name);
3658 a->name = locator_name;
3659 a->is_add = mp->is_add;
3661 locator_num = clib_net_to_host_u32 (mp->locator_num);
3663 memset (&locator, 0, sizeof (locator));
3664 for (i = 0; i < locator_num; i++)
3666 ls_loc = &((ls_locator_t *) mp->locators)[i];
3667 VALIDATE_SW_IF_INDEX (ls_loc);
3669 locator.sw_if_index = htonl (ls_loc->sw_if_index);
3670 locator.priority = ls_loc->priority;
3671 locator.weight = ls_loc->weight;
3673 vec_add1 (a->locators, locator);
3676 rv = vnet_lisp_add_del_locator_set (a, &ls_index);
3678 BAD_SW_IF_INDEX_LABEL;
3680 vec_free (locator_name);
3681 vec_free (a->locators);
3684 REPLY_MACRO2 (VL_API_LISP_ADD_DEL_LOCATOR_SET_REPLY,
3686 rmp->ls_index = clib_host_to_net_u32 (ls_index);
3692 vl_api_lisp_add_del_locator_t_handler (vl_api_lisp_add_del_locator_t * mp)
3694 vl_api_lisp_add_del_locator_reply_t *rmp;
3696 locator_t locator, *locators = NULL;
3697 vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
3699 u8 *locator_name = NULL;
3701 memset (&locator, 0, sizeof (locator));
3702 memset (a, 0, sizeof (a[0]));
3704 locator.sw_if_index = ntohl (mp->sw_if_index);
3705 locator.priority = mp->priority;
3706 locator.weight = mp->weight;
3708 vec_add1 (locators, locator);
3710 locator_name = format (0, "%s", mp->locator_set_name);
3712 a->name = locator_name;
3713 a->locators = locators;
3714 a->is_add = mp->is_add;
3717 rv = vnet_lisp_add_del_locator (a, NULL, &ls_index);
3719 vec_free (locators);
3720 vec_free (locator_name);
3722 REPLY_MACRO (VL_API_LISP_ADD_DEL_LOCATOR_REPLY);
3726 unformat_lisp_eid_api (gid_address_t * dst, u32 vni, u8 type, void *src,
3732 gid_address_type (dst) = GID_ADDR_IP_PREFIX;
3733 gid_address_ip_set (dst, src, IP4);
3734 gid_address_ippref_len (dst) = len;
3735 ip_prefix_normalize (&gid_address_ippref (dst));
3738 gid_address_type (dst) = GID_ADDR_IP_PREFIX;
3739 gid_address_ip_set (dst, src, IP6);
3740 gid_address_ippref_len (dst) = len;
3741 ip_prefix_normalize (&gid_address_ippref (dst));
3743 case 2: /* l2 mac */
3744 gid_address_type (dst) = GID_ADDR_MAC;
3745 clib_memcpy (&gid_address_mac (dst), src, 6);
3749 return VNET_API_ERROR_INVALID_VALUE;
3752 gid_address_vni (dst) = vni;
3758 vl_api_lisp_add_del_local_eid_t_handler (vl_api_lisp_add_del_local_eid_t * mp)
3760 vl_api_lisp_add_del_local_eid_reply_t *rmp;
3761 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
3763 gid_address_t _eid, *eid = &_eid;
3765 u32 locator_set_index = ~0, map_index = ~0;
3766 vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
3767 u8 *name = NULL, *key = NULL;
3768 memset (a, 0, sizeof (a[0]));
3769 memset (eid, 0, sizeof (eid[0]));
3771 rv = unformat_lisp_eid_api (eid, clib_net_to_host_u32 (mp->vni),
3772 mp->eid_type, mp->eid, mp->prefix_len);
3776 name = format (0, "%s", mp->locator_set_name);
3777 p = hash_get_mem (lcm->locator_set_index_by_name, name);
3780 rv = VNET_API_ERROR_INVALID_VALUE;
3783 locator_set_index = p[0];
3786 key = format (0, "%s", mp->key);
3788 /* XXX treat batch configuration */
3789 a->is_add = mp->is_add;
3790 gid_address_copy (&a->eid, eid);
3791 a->locator_set_index = locator_set_index;
3794 a->key_id = clib_net_to_host_u16 (mp->key_id);
3796 rv = vnet_lisp_add_del_local_mapping (a, &map_index);
3801 gid_address_free (&a->eid);
3803 REPLY_MACRO (VL_API_LISP_ADD_DEL_LOCAL_EID_REPLY);
3807 vl_api_lisp_eid_table_add_del_map_t_handler
3808 (vl_api_lisp_eid_table_add_del_map_t * mp)
3810 vl_api_lisp_eid_table_add_del_map_reply_t *rmp;
3812 rv = vnet_lisp_eid_table_map (clib_net_to_host_u32 (mp->vni),
3813 clib_net_to_host_u32 (mp->dp_table),
3814 mp->is_l2, mp->is_add);
3815 REPLY_MACRO (VL_API_LISP_EID_TABLE_ADD_DEL_MAP_REPLY)}
3817 /** Used for transferring locators via VPP API */
3819 typedef CLIB_PACKED (struct {
3820 u8 is_ip4; /**< is locator an IPv4 address */
3821 u8 priority; /**< locator priority */
3822 u8 weight; /**< locator weight */
3823 u8 addr[16]; /**< IPv4/IPv6 address */
3827 static locator_pair_t *
3828 unformat_lisp_loc_pairs (void *lcl_locs, void *rmt_locs, u32 rloc_num)
3831 locator_pair_t *pairs = 0, pair;
3834 for (i = 0; i < rloc_num; i++)
3837 r = &((rloc_t *) lcl_locs)[i];
3838 memset (&pair.lcl_loc, 0, sizeof (pair.lcl_loc));
3839 ip_address_set (&pair.lcl_loc, &r->addr, r->is_ip4 ? IP4 : IP6);
3841 /* remote locators */
3842 r = &((rloc_t *) rmt_locs)[i];
3843 memset (&pair.rmt_loc, 0, sizeof (pair.rmt_loc));
3844 ip_address_set (&pair.rmt_loc, &r->addr, r->is_ip4 ? IP4 : IP6);
3846 pair.priority = r->priority;
3847 pair.weight = r->weight;
3849 vec_add1 (pairs, pair);
3855 unformat_lisp_locs (void *rmt_locs, u32 rloc_num)
3858 locator_t *locs = 0, loc;
3861 for (i = 0; i < rloc_num; i++)
3863 /* remote locators */
3864 r = &((rloc_t *) rmt_locs)[i];
3865 memset (&loc, 0, sizeof (loc));
3866 gid_address_ip_set (&loc.address, &r->addr, r->is_ip4 ? IP4 : IP6);
3868 loc.priority = r->priority;
3869 loc.weight = r->weight;
3871 vec_add1 (locs, loc);
3877 vl_api_lisp_gpe_add_del_fwd_entry_t_handler
3878 (vl_api_lisp_gpe_add_del_fwd_entry_t * mp)
3880 vl_api_lisp_gpe_add_del_fwd_entry_reply_t *rmp;
3881 vnet_lisp_gpe_add_del_fwd_entry_args_t _a, *a = &_a;
3882 locator_pair_t *pairs = 0;
3885 memset (a, 0, sizeof (a[0]));
3887 rv = unformat_lisp_eid_api (&a->rmt_eid, mp->vni, mp->eid_type,
3888 mp->rmt_eid, mp->rmt_len);
3889 rv |= unformat_lisp_eid_api (&a->lcl_eid, mp->vni, mp->eid_type,
3890 mp->lcl_eid, mp->lcl_len);
3892 pairs = unformat_lisp_loc_pairs (mp->lcl_locs, mp->rmt_locs, mp->loc_num);
3894 if (rv || 0 == pairs)
3897 a->is_add = mp->is_add;
3898 a->locator_pairs = pairs;
3899 a->dp_table = mp->dp_table;
3901 a->action = mp->action;
3903 rv = vnet_lisp_gpe_add_del_fwd_entry (a, 0);
3906 REPLY_MACRO (VL_API_LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY);
3910 vl_api_lisp_add_del_map_server_t_handler (vl_api_lisp_add_del_map_server_t
3913 vl_api_lisp_add_del_map_server_reply_t *rmp;
3917 memset (&addr, 0, sizeof (addr));
3919 ip_address_set (&addr, mp->ip_address, mp->is_ipv6 ? IP6 : IP4);
3920 rv = vnet_lisp_add_del_map_server (&addr, mp->is_add);
3922 REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_SERVER_REPLY);
3926 vl_api_lisp_add_del_map_resolver_t_handler (vl_api_lisp_add_del_map_resolver_t
3929 vl_api_lisp_add_del_map_resolver_reply_t *rmp;
3931 vnet_lisp_add_del_map_resolver_args_t _a, *a = &_a;
3933 memset (a, 0, sizeof (a[0]));
3935 a->is_add = mp->is_add;
3936 ip_address_set (&a->address, mp->ip_address, mp->is_ipv6 ? IP6 : IP4);
3938 rv = vnet_lisp_add_del_map_resolver (a);
3940 REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_RESOLVER_REPLY);
3944 vl_api_lisp_gpe_enable_disable_t_handler (vl_api_lisp_gpe_enable_disable_t *
3947 vl_api_lisp_gpe_enable_disable_reply_t *rmp;
3949 vnet_lisp_gpe_enable_disable_args_t _a, *a = &_a;
3951 a->is_en = mp->is_en;
3952 vnet_lisp_gpe_enable_disable (a);
3954 REPLY_MACRO (VL_API_LISP_GPE_ENABLE_DISABLE_REPLY);
3958 vl_api_lisp_map_register_enable_disable_t_handler
3959 (vl_api_lisp_map_register_enable_disable_t * mp)
3961 vl_api_lisp_map_register_enable_disable_reply_t *rmp;
3964 vnet_lisp_map_register_enable_disable (mp->is_enabled);
3965 REPLY_MACRO (VL_API_LISP_ENABLE_DISABLE_REPLY);
3969 vl_api_lisp_rloc_probe_enable_disable_t_handler
3970 (vl_api_lisp_rloc_probe_enable_disable_t * mp)
3972 vl_api_lisp_rloc_probe_enable_disable_reply_t *rmp;
3975 vnet_lisp_rloc_probe_enable_disable (mp->is_enabled);
3976 REPLY_MACRO (VL_API_LISP_ENABLE_DISABLE_REPLY);
3980 vl_api_lisp_enable_disable_t_handler (vl_api_lisp_enable_disable_t * mp)
3982 vl_api_lisp_enable_disable_reply_t *rmp;
3985 vnet_lisp_enable_disable (mp->is_en);
3986 REPLY_MACRO (VL_API_LISP_ENABLE_DISABLE_REPLY);
3990 vl_api_lisp_gpe_add_del_iface_t_handler (vl_api_lisp_gpe_add_del_iface_t * mp)
3992 vl_api_lisp_gpe_add_del_iface_reply_t *rmp;
4000 lisp_gpe_tenant_l2_iface_add_or_lock (mp->vni, mp->dp_table))
4004 lisp_gpe_tenant_l2_iface_unlock (mp->vni);
4011 lisp_gpe_tenant_l3_iface_add_or_lock (mp->vni, mp->dp_table))
4015 lisp_gpe_tenant_l3_iface_unlock (mp->vni);
4018 REPLY_MACRO (VL_API_LISP_GPE_ADD_DEL_IFACE_REPLY);
4022 vl_api_show_lisp_map_request_mode_t_handler
4023 (vl_api_show_lisp_map_request_mode_t * mp)
4026 vl_api_show_lisp_map_request_mode_reply_t *rmp;
4029 REPLY_MACRO2(VL_API_SHOW_LISP_MAP_REQUEST_MODE_REPLY,
4031 rmp->mode = vnet_lisp_get_map_request_mode ();
4037 vl_api_lisp_map_request_mode_t_handler (vl_api_lisp_map_request_mode_t * mp)
4039 vl_api_lisp_map_request_mode_reply_t *rmp;
4042 rv = vnet_lisp_set_map_request_mode (mp->mode);
4044 REPLY_MACRO (VL_API_LISP_MAP_REQUEST_MODE_REPLY);
4048 vl_api_lisp_pitr_set_locator_set_t_handler (vl_api_lisp_pitr_set_locator_set_t
4051 vl_api_lisp_pitr_set_locator_set_reply_t *rmp;
4055 ls_name = format (0, "%s", mp->ls_name);
4056 rv = vnet_lisp_pitr_set_locator_set (ls_name, mp->is_add);
4059 REPLY_MACRO (VL_API_LISP_PITR_SET_LOCATOR_SET_REPLY);
4063 vl_api_lisp_add_del_map_request_itr_rlocs_t_handler
4064 (vl_api_lisp_add_del_map_request_itr_rlocs_t * mp)
4066 vl_api_lisp_add_del_map_request_itr_rlocs_reply_t *rmp;
4068 u8 *locator_set_name = NULL;
4069 vnet_lisp_add_del_mreq_itr_rloc_args_t _a, *a = &_a;
4071 locator_set_name = format (0, "%s", mp->locator_set_name);
4073 a->is_add = mp->is_add;
4074 a->locator_set_name = locator_set_name;
4076 rv = vnet_lisp_add_del_mreq_itr_rlocs (a);
4078 vec_free (locator_set_name);
4080 REPLY_MACRO (VL_API_LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY);
4084 vl_api_lisp_add_del_remote_mapping_t_handler
4085 (vl_api_lisp_add_del_remote_mapping_t * mp)
4087 locator_t *rlocs = 0;
4088 vl_api_lisp_add_del_remote_mapping_reply_t *rmp;
4090 gid_address_t _eid, *eid = &_eid;
4091 u32 rloc_num = clib_net_to_host_u32 (mp->rloc_num);
4093 memset (eid, 0, sizeof (eid[0]));
4095 rv = unformat_lisp_eid_api (eid, clib_net_to_host_u32 (mp->vni),
4096 mp->eid_type, mp->eid, mp->eid_len);
4100 rlocs = unformat_lisp_locs (mp->rlocs, rloc_num);
4104 vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
4105 gid_address_copy (&a->reid, eid);
4107 rv = vnet_lisp_add_del_adjacency (a);
4114 /* NOTE: for now this works as a static remote mapping, i.e.,
4115 * not authoritative and ttl infinite. */
4116 rv = vnet_lisp_add_del_mapping (eid, rlocs, mp->action, 0, ~0,
4117 mp->is_add, 1 /* is_static */ , 0);
4120 vnet_lisp_clear_all_remote_adjacencies ();
4125 REPLY_MACRO (VL_API_LISP_ADD_DEL_REMOTE_MAPPING_REPLY);
4129 vl_api_lisp_add_del_adjacency_t_handler (vl_api_lisp_add_del_adjacency_t * mp)
4131 vl_api_lisp_add_del_adjacency_reply_t *rmp;
4132 vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
4135 memset (a, 0, sizeof (a[0]));
4137 rv = unformat_lisp_eid_api (&a->leid, clib_net_to_host_u32 (mp->vni),
4138 mp->eid_type, mp->leid, mp->leid_len);
4139 rv |= unformat_lisp_eid_api (&a->reid, clib_net_to_host_u32 (mp->vni),
4140 mp->eid_type, mp->reid, mp->reid_len);
4145 a->is_add = mp->is_add;
4146 rv = vnet_lisp_add_del_adjacency (a);
4149 REPLY_MACRO (VL_API_LISP_ADD_DEL_ADJACENCY_REPLY);
4153 send_lisp_locator_details (lisp_cp_main_t * lcm,
4155 unix_shared_memory_queue_t * q, u32 context)
4157 vl_api_lisp_locator_details_t *rmp;
4159 rmp = vl_msg_api_alloc (sizeof (*rmp));
4160 memset (rmp, 0, sizeof (*rmp));
4161 rmp->_vl_msg_id = ntohs (VL_API_LISP_LOCATOR_DETAILS);
4162 rmp->context = context;
4164 rmp->local = loc->local;
4167 rmp->sw_if_index = ntohl (loc->sw_if_index);
4171 rmp->is_ipv6 = gid_address_ip_version (&loc->address);
4172 ip_address_copy_addr (rmp->ip_address, &gid_address_ip (&loc->address));
4174 rmp->priority = loc->priority;
4175 rmp->weight = loc->weight;
4177 vl_msg_api_send_shmem (q, (u8 *) & rmp);
4181 vl_api_lisp_locator_dump_t_handler (vl_api_lisp_locator_dump_t * mp)
4184 unix_shared_memory_queue_t *q = 0;
4185 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
4186 locator_set_t *lsit = 0;
4188 u32 ls_index = ~0, *locit = 0;
4191 q = vl_api_client_index_to_input_queue (mp->client_index);
4197 if (mp->is_index_set)
4198 ls_index = htonl (mp->ls_index);
4201 /* make sure we get a proper C-string */
4202 mp->ls_name[sizeof (mp->ls_name) - 1] = 0;
4203 ls_name = format (0, "%s", mp->ls_name);
4204 p = hash_get_mem (lcm->locator_set_index_by_name, ls_name);
4210 if (pool_is_free_index (lcm->locator_set_pool, ls_index))
4213 lsit = pool_elt_at_index (lcm->locator_set_pool, ls_index);
4215 vec_foreach (locit, lsit->locator_indices)
4217 loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
4218 send_lisp_locator_details (lcm, loc, q, mp->context);
4225 send_lisp_locator_set_details (lisp_cp_main_t * lcm,
4226 locator_set_t * lsit,
4227 unix_shared_memory_queue_t * q,
4228 u32 context, u32 ls_index)
4230 vl_api_lisp_locator_set_details_t *rmp;
4233 rmp = vl_msg_api_alloc (sizeof (*rmp));
4234 memset (rmp, 0, sizeof (*rmp));
4235 rmp->_vl_msg_id = ntohs (VL_API_LISP_LOCATOR_SET_DETAILS);
4236 rmp->context = context;
4238 rmp->ls_index = htonl (ls_index);
4241 ASSERT (lsit->name != NULL);
4242 strncpy ((char *) rmp->ls_name, (char *) lsit->name,
4243 vec_len (lsit->name));
4247 str = format (0, "<remote-%d>", ls_index);
4248 strncpy ((char *) rmp->ls_name, (char *) str, vec_len (str));
4252 vl_msg_api_send_shmem (q, (u8 *) & rmp);
4256 vl_api_lisp_locator_set_dump_t_handler (vl_api_lisp_locator_set_dump_t * mp)
4258 unix_shared_memory_queue_t *q = NULL;
4259 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
4260 locator_set_t *lsit = NULL;
4263 q = vl_api_client_index_to_input_queue (mp->client_index);
4269 filter = mp->filter;
4271 pool_foreach (lsit, lcm->locator_set_pool,
4273 if (filter && !((1 == filter && lsit->local) ||
4274 (2 == filter && !lsit->local)))
4278 send_lisp_locator_set_details (lcm, lsit, q, mp->context,
4279 lsit - lcm->locator_set_pool);
4285 lisp_fid_put_api (u8 * dst, fid_address_t * src, u8 * prefix_length)
4287 ASSERT (prefix_length);
4288 ip_prefix_t *ippref = &fid_addr_ippref (src);
4290 switch (fid_addr_type (src))
4292 case FID_ADDR_IP_PREF:
4293 if (ip_prefix_version (ippref) == IP4)
4294 clib_memcpy (dst, &ip_prefix_v4 (ippref), 4);
4296 clib_memcpy (dst, &ip_prefix_v6 (ippref), 16);
4297 prefix_length[0] = ip_prefix_len (ippref);
4301 prefix_length[0] = 0;
4302 clib_memcpy (dst, fid_addr_mac (src), 6);
4306 clib_warning ("Unknown FID type %d!", fid_addr_type (src));
4312 fid_type_to_api_type (fid_address_t * fid)
4314 ip_prefix_t *ippref;
4316 switch (fid_addr_type (fid))
4318 case FID_ADDR_IP_PREF:
4319 ippref = &fid_addr_ippref (fid);
4320 if (ip_prefix_version (ippref) == IP4)
4322 else if (ip_prefix_version (ippref) == IP6)
4335 send_lisp_eid_table_details (mapping_t * mapit,
4336 unix_shared_memory_queue_t * q,
4337 u32 context, u8 filter)
4340 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
4341 locator_set_t *ls = 0;
4342 vl_api_lisp_eid_table_details_t *rmp = NULL;
4343 gid_address_t *gid = NULL;
4345 ip_prefix_t *ip_prefix = NULL;
4349 case 0: /* all mappings */
4352 case 1: /* local only */
4356 case 2: /* remote only */
4361 clib_warning ("Filter error, unknown filter: %d", filter);
4366 ip_prefix = &gid_address_ippref (gid);
4367 mac = gid_address_mac (gid);
4369 rmp = vl_msg_api_alloc (sizeof (*rmp));
4370 memset (rmp, 0, sizeof (*rmp));
4371 rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_DETAILS);
4373 ls = pool_elt_at_index (lcm->locator_set_pool, mapit->locator_set_index);
4374 if (vec_len (ls->locator_indices) == 0)
4375 rmp->locator_set_index = ~0;
4377 rmp->locator_set_index = clib_host_to_net_u32 (mapit->locator_set_index);
4379 rmp->is_local = mapit->local;
4380 rmp->ttl = clib_host_to_net_u32 (mapit->ttl);
4381 rmp->action = mapit->action;
4382 rmp->authoritative = mapit->authoritative;
4384 switch (gid_address_type (gid))
4386 case GID_ADDR_SRC_DST:
4387 rmp->is_src_dst = 1;
4388 fid = &gid_address_sd_src (gid);
4389 rmp->eid_type = fid_type_to_api_type (fid);
4390 lisp_fid_put_api (rmp->seid, &gid_address_sd_src (gid),
4391 &rmp->seid_prefix_len);
4392 lisp_fid_put_api (rmp->eid, &gid_address_sd_dst (gid),
4393 &rmp->eid_prefix_len);
4395 case GID_ADDR_IP_PREFIX:
4396 rmp->eid_prefix_len = ip_prefix_len (ip_prefix);
4397 if (ip_prefix_version (ip_prefix) == IP4)
4399 rmp->eid_type = 0; /* ipv4 type */
4400 clib_memcpy (rmp->eid, &ip_prefix_v4 (ip_prefix),
4401 sizeof (ip_prefix_v4 (ip_prefix)));
4405 rmp->eid_type = 1; /* ipv6 type */
4406 clib_memcpy (rmp->eid, &ip_prefix_v6 (ip_prefix),
4407 sizeof (ip_prefix_v6 (ip_prefix)));
4411 rmp->eid_type = 2; /* l2 mac type */
4412 clib_memcpy (rmp->eid, mac, 6);
4417 rmp->context = context;
4418 rmp->vni = clib_host_to_net_u32 (gid_address_vni (gid));
4419 rmp->key_id = clib_host_to_net_u16 (mapit->key_id);
4420 memcpy (rmp->key, mapit->key, vec_len (mapit->key));
4421 vl_msg_api_send_shmem (q, (u8 *) & rmp);
4425 vl_api_lisp_eid_table_dump_t_handler (vl_api_lisp_eid_table_dump_t * mp)
4428 unix_shared_memory_queue_t *q = NULL;
4429 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
4430 mapping_t *mapit = NULL;
4431 gid_address_t _eid, *eid = &_eid;
4433 q = vl_api_client_index_to_input_queue (mp->client_index);
4441 memset (eid, 0, sizeof (*eid));
4443 unformat_lisp_eid_api (eid, clib_net_to_host_u32 (mp->vni),
4444 mp->eid_type, mp->eid, mp->prefix_length);
4446 mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, eid);
4447 if ((u32) ~ 0 == mi)
4450 mapit = pool_elt_at_index (lcm->mapping_pool, mi);
4451 send_lisp_eid_table_details (mapit, q, mp->context,
4452 0 /* ignore filter */ );
4457 pool_foreach (mapit, lcm->mapping_pool,
4459 send_lisp_eid_table_details(mapit, q, mp->context,
4467 send_lisp_gpe_fwd_entry_details (lisp_gpe_fwd_entry_t * lfe,
4468 unix_shared_memory_queue_t * q, u32 context)
4470 vl_api_lisp_gpe_tunnel_details_t *rmp;
4471 lisp_gpe_main_t *lgm = &lisp_gpe_main;
4473 rmp = vl_msg_api_alloc (sizeof (*rmp));
4474 memset (rmp, 0, sizeof (*rmp));
4475 rmp->_vl_msg_id = ntohs (VL_API_LISP_GPE_TUNNEL_DETAILS);
4477 rmp->tunnels = lfe - lgm->lisp_fwd_entry_pool;
4479 rmp->is_ipv6 = ip_prefix_version (&(lfe->key->rmt.ippref)) == IP6 ? 1 : 0;
4480 ip_address_copy_addr (rmp->source_ip,
4481 &ip_prefix_addr (&(lfe->key->rmt.ippref)));
4482 ip_address_copy_addr (rmp->destination_ip,
4483 &ip_prefix_addr (&(lfe->key->rmt.ippref)));
4485 rmp->encap_fib_id = htonl (0);
4486 rmp->decap_fib_id = htonl (lfe->eid_fib_index);
4487 rmp->iid = htonl (lfe->key->vni);
4488 rmp->context = context;
4490 vl_msg_api_send_shmem (q, (u8 *) & rmp);
4494 vl_api_lisp_gpe_tunnel_dump_t_handler (vl_api_lisp_gpe_tunnel_dump_t * mp)
4496 unix_shared_memory_queue_t *q = NULL;
4497 lisp_gpe_main_t *lgm = &lisp_gpe_main;
4498 lisp_gpe_fwd_entry_t *lfe = NULL;
4500 if (pool_elts (lgm->lisp_fwd_entry_pool) == 0)
4505 q = vl_api_client_index_to_input_queue (mp->client_index);
4512 pool_foreach(lfe, lgm->lisp_fwd_entry_pool,
4514 send_lisp_gpe_fwd_entry_details(lfe, q, mp->context);
4520 send_lisp_map_server_details (ip_address_t * ip,
4521 unix_shared_memory_queue_t * q, u32 context)
4523 vl_api_lisp_map_server_details_t *rmp = NULL;
4525 rmp = vl_msg_api_alloc (sizeof (*rmp));
4526 memset (rmp, 0, sizeof (*rmp));
4527 rmp->_vl_msg_id = ntohs (VL_API_LISP_MAP_SERVER_DETAILS);
4529 switch (ip_addr_version (ip))
4533 clib_memcpy (rmp->ip_address, &ip_addr_v4 (ip),
4534 sizeof (ip_addr_v4 (ip)));
4539 clib_memcpy (rmp->ip_address, &ip_addr_v6 (ip),
4540 sizeof (ip_addr_v6 (ip)));
4546 rmp->context = context;
4548 vl_msg_api_send_shmem (q, (u8 *) & rmp);
4552 vl_api_lisp_map_server_dump_t_handler (vl_api_lisp_map_server_dump_t * mp)
4554 unix_shared_memory_queue_t *q = NULL;
4555 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
4558 q = vl_api_client_index_to_input_queue (mp->client_index);
4564 vec_foreach (mr, lcm->map_servers)
4566 send_lisp_map_server_details (&mr->address, q, mp->context);
4571 send_lisp_map_resolver_details (ip_address_t * ip,
4572 unix_shared_memory_queue_t * q, u32 context)
4574 vl_api_lisp_map_resolver_details_t *rmp = NULL;
4576 rmp = vl_msg_api_alloc (sizeof (*rmp));
4577 memset (rmp, 0, sizeof (*rmp));
4578 rmp->_vl_msg_id = ntohs (VL_API_LISP_MAP_RESOLVER_DETAILS);
4580 switch (ip_addr_version (ip))
4584 clib_memcpy (rmp->ip_address, &ip_addr_v4 (ip),
4585 sizeof (ip_addr_v4 (ip)));
4590 clib_memcpy (rmp->ip_address, &ip_addr_v6 (ip),
4591 sizeof (ip_addr_v6 (ip)));
4597 rmp->context = context;
4599 vl_msg_api_send_shmem (q, (u8 *) & rmp);
4603 vl_api_lisp_map_resolver_dump_t_handler (vl_api_lisp_map_resolver_dump_t * mp)
4605 unix_shared_memory_queue_t *q = NULL;
4606 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
4609 q = vl_api_client_index_to_input_queue (mp->client_index);
4615 vec_foreach (mr, lcm->map_resolvers)
4617 send_lisp_map_resolver_details (&mr->address, q, mp->context);
4622 send_eid_table_map_pair (hash_pair_t * p,
4623 unix_shared_memory_queue_t * q, u32 context)
4625 vl_api_lisp_eid_table_map_details_t *rmp = NULL;
4627 rmp = vl_msg_api_alloc (sizeof (*rmp));
4628 memset (rmp, 0, sizeof (*rmp));
4629 rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_MAP_DETAILS);
4631 rmp->vni = clib_host_to_net_u32 (p->key);
4632 rmp->dp_table = clib_host_to_net_u32 (p->value[0]);
4633 rmp->context = context;
4634 vl_msg_api_send_shmem (q, (u8 *) & rmp);
4638 vl_api_lisp_eid_table_map_dump_t_handler (vl_api_lisp_eid_table_map_dump_t *
4641 unix_shared_memory_queue_t *q = NULL;
4642 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
4644 uword *vni_table = 0;
4646 q = vl_api_client_index_to_input_queue (mp->client_index);
4654 vni_table = lcm->bd_id_by_vni;
4658 vni_table = lcm->table_id_by_vni;
4662 hash_foreach_pair (p, vni_table,
4664 send_eid_table_map_pair (p, q, mp->context);
4670 send_eid_table_vni (u32 vni, unix_shared_memory_queue_t * q, u32 context)
4672 vl_api_lisp_eid_table_vni_details_t *rmp = 0;
4674 rmp = vl_msg_api_alloc (sizeof (*rmp));
4675 memset (rmp, 0, sizeof (*rmp));
4676 rmp->_vl_msg_id = ntohs (VL_API_LISP_EID_TABLE_VNI_DETAILS);
4677 rmp->context = context;
4678 rmp->vni = clib_host_to_net_u32 (vni);
4679 vl_msg_api_send_shmem (q, (u8 *) & rmp);
4683 lisp_adjacency_copy (vl_api_lisp_adjacency_t * dst, lisp_adjacency_t * adjs)
4685 lisp_adjacency_t *adj;
4686 vl_api_lisp_adjacency_t a;
4687 u32 i, n = vec_len (adjs);
4689 for (i = 0; i < n; i++)
4691 adj = vec_elt_at_index (adjs, i);
4692 memset (&a, 0, sizeof (a));
4694 switch (gid_address_type (&adj->reid))
4696 case GID_ADDR_IP_PREFIX:
4697 a.reid_prefix_len = gid_address_ippref_len (&adj->reid);
4698 a.leid_prefix_len = gid_address_ippref_len (&adj->leid);
4699 if (gid_address_ip_version (&adj->reid) == IP4)
4701 a.eid_type = 0; /* ipv4 type */
4702 clib_memcpy (a.reid, &gid_address_ip (&adj->reid), 4);
4703 clib_memcpy (a.leid, &gid_address_ip (&adj->leid), 4);
4707 a.eid_type = 1; /* ipv6 type */
4708 clib_memcpy (a.reid, &gid_address_ip (&adj->reid), 16);
4709 clib_memcpy (a.leid, &gid_address_ip (&adj->leid), 16);
4713 a.eid_type = 2; /* l2 mac type */
4714 mac_copy (a.reid, gid_address_mac (&adj->reid));
4715 mac_copy (a.leid, gid_address_mac (&adj->leid));
4725 vl_api_show_lisp_rloc_probe_state_t_handler
4726 (vl_api_show_lisp_rloc_probe_state_t * mp)
4728 vl_api_show_lisp_rloc_probe_state_reply_t *rmp = 0;
4732 REPLY_MACRO2 (VL_API_SHOW_LISP_RLOC_PROBE_STATE_REPLY,
4734 rmp->is_enabled = vnet_lisp_rloc_probe_state_get ();
4740 vl_api_show_lisp_map_register_state_t_handler
4741 (vl_api_show_lisp_map_register_state_t * mp)
4743 vl_api_show_lisp_map_register_state_reply_t *rmp = 0;
4747 REPLY_MACRO2 (VL_API_SHOW_LISP_MAP_REGISTER_STATE_REPLY,
4749 rmp->is_enabled = vnet_lisp_map_register_state_get ();
4755 vl_api_lisp_adjacencies_get_t_handler (vl_api_lisp_adjacencies_get_t * mp)
4757 vl_api_lisp_adjacencies_get_reply_t *rmp = 0;
4758 lisp_adjacency_t *adjs = 0;
4760 vl_api_lisp_adjacency_t a;
4762 u32 vni = clib_net_to_host_u32 (mp->vni);
4764 adjs = vnet_lisp_adjacencies_get_by_vni (vni);
4765 size = vec_len (adjs) * sizeof (a);
4768 REPLY_MACRO4 (VL_API_LISP_ADJACENCIES_GET_REPLY, size,
4770 rmp->count = clib_host_to_net_u32 (vec_len (adjs));
4771 lisp_adjacency_copy (rmp->adjacencies, adjs);
4779 vl_api_lisp_eid_table_vni_dump_t_handler (vl_api_lisp_eid_table_vni_dump_t *
4784 unix_shared_memory_queue_t *q = 0;
4785 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
4787 q = vl_api_client_index_to_input_queue (mp->client_index);
4794 hash_foreach_pair (p, lcm->table_id_by_vni,
4796 hash_set (vnis, p->key, 0);
4799 hash_foreach_pair (p, lcm->bd_id_by_vni,
4801 hash_set (vnis, p->key, 0);
4804 hash_foreach_pair (p, vnis,
4806 send_eid_table_vni (p->key, q, mp->context);
4814 vl_api_show_lisp_status_t_handler (vl_api_show_lisp_status_t * mp)
4816 unix_shared_memory_queue_t *q = NULL;
4817 vl_api_show_lisp_status_reply_t *rmp = NULL;
4820 q = vl_api_client_index_to_input_queue (mp->client_index);
4827 REPLY_MACRO2(VL_API_SHOW_LISP_STATUS_REPLY,
4829 rmp->gpe_status = vnet_lisp_gpe_enable_disable_status ();
4830 rmp->feature_status = vnet_lisp_enable_disable_status ();
4836 vl_api_lisp_get_map_request_itr_rlocs_t_handler
4837 (vl_api_lisp_get_map_request_itr_rlocs_t * mp)
4839 unix_shared_memory_queue_t *q = NULL;
4840 vl_api_lisp_get_map_request_itr_rlocs_reply_t *rmp = NULL;
4841 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
4842 locator_set_t *loc_set = 0;
4846 q = vl_api_client_index_to_input_queue (mp->client_index);
4852 if (~0 == lcm->mreq_itr_rlocs)
4854 tmp_str = format (0, " ");
4859 pool_elt_at_index (lcm->locator_set_pool, lcm->mreq_itr_rlocs);
4860 tmp_str = format (0, "%s", loc_set->name);
4864 REPLY_MACRO2(VL_API_LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,
4866 strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
4867 ARRAY_LEN(rmp->locator_set_name) - 1);
4875 vl_api_show_lisp_pitr_t_handler (vl_api_show_lisp_pitr_t * mp)
4877 unix_shared_memory_queue_t *q = NULL;
4878 vl_api_show_lisp_pitr_reply_t *rmp = NULL;
4879 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
4881 locator_set_t *ls = 0;
4885 q = vl_api_client_index_to_input_queue (mp->client_index);
4891 if (!lcm->lisp_pitr)
4893 tmp_str = format (0, "N/A");
4897 m = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
4898 if (~0 != m->locator_set_index)
4901 pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
4902 tmp_str = format (0, "%s", ls->name);
4906 tmp_str = format (0, "N/A");
4909 vec_add1 (tmp_str, 0);
4912 REPLY_MACRO2(VL_API_SHOW_LISP_PITR_REPLY,
4914 rmp->status = lcm->lisp_pitr;
4915 strncpy((char *) rmp->locator_set_name, (char *) tmp_str,
4916 ARRAY_LEN(rmp->locator_set_name) - 1);
4922 vl_api_interface_name_renumber_t_handler (vl_api_interface_name_renumber_t *
4925 vl_api_interface_name_renumber_reply_t *rmp;
4928 VALIDATE_SW_IF_INDEX (mp);
4930 rv = vnet_interface_name_renumber
4931 (ntohl (mp->sw_if_index), ntohl (mp->new_show_dev_instance));
4933 BAD_SW_IF_INDEX_LABEL;
4935 REPLY_MACRO (VL_API_INTERFACE_NAME_RENUMBER_REPLY);
4939 arp_change_data_callback (u32 pool_index, u8 * new_mac,
4940 u32 sw_if_index, u32 address)
4942 vpe_api_main_t *am = &vpe_api_main;
4943 vlib_main_t *vm = am->vlib_main;
4944 vl_api_ip4_arp_event_t *event;
4945 static f64 arp_event_last_time;
4946 f64 now = vlib_time_now (vm);
4948 if (pool_is_free_index (am->arp_events, pool_index))
4951 event = pool_elt_at_index (am->arp_events, pool_index);
4953 if (memcmp (&event->new_mac, new_mac, sizeof (event->new_mac)))
4955 clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
4959 if (sw_if_index == event->sw_if_index &&
4961 /* for BD case, also check IP address with 10 sec timeout */
4962 (address == event->address &&
4963 (now - arp_event_last_time) < 10.0)))
4968 arp_event_last_time = now;
4969 event->sw_if_index = sw_if_index;
4971 event->address = address;
4976 nd_change_data_callback (u32 pool_index, u8 * new_mac,
4977 u32 sw_if_index, ip6_address_t * address)
4979 vpe_api_main_t *am = &vpe_api_main;
4980 vlib_main_t *vm = am->vlib_main;
4981 vl_api_ip6_nd_event_t *event;
4982 static f64 nd_event_last_time;
4983 f64 now = vlib_time_now (vm);
4985 if (pool_is_free_index (am->nd_events, pool_index))
4988 event = pool_elt_at_index (am->nd_events, pool_index);
4991 if (memcmp (&event->new_mac, new_mac, sizeof (event->new_mac)))
4993 clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
4997 if (sw_if_index == event->sw_if_index &&
4999 /* for BD case, also check IP address with 10 sec timeout */
5000 (ip6_address_is_equal (address,
5001 (ip6_address_t *) event->address) &&
5002 (now - nd_event_last_time) < 10.0)))
5007 nd_event_last_time = now;
5008 event->sw_if_index = sw_if_index;
5010 clib_memcpy (event->address, address, sizeof (event->address));
5015 arp_change_delete_callback (u32 pool_index, u8 * notused)
5017 vpe_api_main_t *am = &vpe_api_main;
5019 if (pool_is_free_index (am->arp_events, pool_index))
5022 pool_put_index (am->arp_events, pool_index);
5027 nd_change_delete_callback (u32 pool_index, u8 * notused)
5029 vpe_api_main_t *am = &vpe_api_main;
5031 if (pool_is_free_index (am->nd_events, pool_index))
5034 pool_put_index (am->nd_events, pool_index);
5039 vl_api_want_ip4_arp_events_t_handler (vl_api_want_ip4_arp_events_t * mp)
5041 vpe_api_main_t *am = &vpe_api_main;
5042 vnet_main_t *vnm = vnet_get_main ();
5043 vl_api_want_ip4_arp_events_reply_t *rmp;
5044 vl_api_ip4_arp_event_t *event;
5047 if (mp->enable_disable)
5049 pool_get (am->arp_events, event);
5050 memset (event, 0, sizeof (*event));
5052 event->_vl_msg_id = ntohs (VL_API_IP4_ARP_EVENT);
5053 event->client_index = mp->client_index;
5054 event->context = mp->context;
5055 event->address = mp->address;
5056 event->pid = mp->pid;
5057 if (mp->address == 0)
5060 rv = vnet_add_del_ip4_arp_change_event
5061 (vnm, arp_change_data_callback,
5062 mp->pid, &mp->address /* addr, in net byte order */ ,
5063 vpe_resolver_process_node.index,
5064 IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */ );
5068 rv = vnet_add_del_ip4_arp_change_event
5069 (vnm, arp_change_delete_callback,
5070 mp->pid, &mp->address /* addr, in net byte order */ ,
5071 vpe_resolver_process_node.index,
5072 IP4_ARP_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
5074 REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY);
5078 vl_api_want_ip6_nd_events_t_handler (vl_api_want_ip6_nd_events_t * mp)
5080 vpe_api_main_t *am = &vpe_api_main;
5081 vnet_main_t *vnm = vnet_get_main ();
5082 vl_api_want_ip6_nd_events_reply_t *rmp;
5083 vl_api_ip6_nd_event_t *event;
5086 if (mp->enable_disable)
5088 pool_get (am->nd_events, event);
5089 memset (event, 0, sizeof (*event));
5091 event->_vl_msg_id = ntohs (VL_API_IP6_ND_EVENT);
5092 event->client_index = mp->client_index;
5093 event->context = mp->context;
5094 clib_memcpy (event->address, mp->address, 16);
5095 event->pid = mp->pid;
5096 if (ip6_address_is_zero ((ip6_address_t *) mp->address))
5099 rv = vnet_add_del_ip6_nd_change_event
5100 (vnm, nd_change_data_callback,
5101 mp->pid, mp->address /* addr, in net byte order */ ,
5102 vpe_resolver_process_node.index,
5103 IP6_ND_EVENT, event - am->nd_events, 1 /* is_add */ );
5107 rv = vnet_add_del_ip6_nd_change_event
5108 (vnm, nd_change_delete_callback,
5109 mp->pid, mp->address /* addr, in net byte order */ ,
5110 vpe_resolver_process_node.index,
5111 IP6_ND_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
5113 REPLY_MACRO (VL_API_WANT_IP6_ND_EVENTS_REPLY);
5116 static void vl_api_input_acl_set_interface_t_handler
5117 (vl_api_input_acl_set_interface_t * mp)
5119 vlib_main_t *vm = vlib_get_main ();
5120 vl_api_input_acl_set_interface_reply_t *rmp;
5122 u32 sw_if_index, ip4_table_index, ip6_table_index, l2_table_index;
5124 ip4_table_index = ntohl (mp->ip4_table_index);
5125 ip6_table_index = ntohl (mp->ip6_table_index);
5126 l2_table_index = ntohl (mp->l2_table_index);
5127 sw_if_index = ntohl (mp->sw_if_index);
5129 VALIDATE_SW_IF_INDEX (mp);
5131 rv = vnet_set_input_acl_intfc (vm, sw_if_index, ip4_table_index,
5132 ip6_table_index, l2_table_index, mp->is_add);
5134 BAD_SW_IF_INDEX_LABEL;
5136 REPLY_MACRO (VL_API_INPUT_ACL_SET_INTERFACE_REPLY);
5139 static void vl_api_ipsec_spd_add_del_t_handler
5140 (vl_api_ipsec_spd_add_del_t * mp)
5143 clib_warning ("unimplemented");
5146 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
5147 vl_api_ipsec_spd_add_del_reply_t *rmp;
5151 rv = ipsec_add_del_spd (vm, ntohl (mp->spd_id), mp->is_add);
5153 rv = VNET_API_ERROR_UNIMPLEMENTED;
5156 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_REPLY);
5160 static void vl_api_ipsec_interface_add_del_spd_t_handler
5161 (vl_api_ipsec_interface_add_del_spd_t * mp)
5163 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
5164 vl_api_ipsec_interface_add_del_spd_reply_t *rmp;
5166 u32 sw_if_index __attribute__ ((unused));
5167 u32 spd_id __attribute__ ((unused));
5169 sw_if_index = ntohl (mp->sw_if_index);
5170 spd_id = ntohl (mp->spd_id);
5172 VALIDATE_SW_IF_INDEX (mp);
5175 rv = ipsec_set_interface_spd (vm, sw_if_index, spd_id, mp->is_add);
5177 rv = VNET_API_ERROR_UNIMPLEMENTED;
5180 BAD_SW_IF_INDEX_LABEL;
5182 REPLY_MACRO (VL_API_IPSEC_INTERFACE_ADD_DEL_SPD_REPLY);
5185 static void vl_api_ipsec_spd_add_del_entry_t_handler
5186 (vl_api_ipsec_spd_add_del_entry_t * mp)
5188 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
5189 vl_api_ipsec_spd_add_del_entry_reply_t *rmp;
5195 memset (&p, 0, sizeof (p));
5197 p.id = ntohl (mp->spd_id);
5198 p.priority = ntohl (mp->priority);
5199 p.is_outbound = mp->is_outbound;
5200 p.is_ipv6 = mp->is_ipv6;
5202 if (mp->is_ipv6 || mp->is_ip_any)
5204 clib_memcpy (&p.raddr.start, mp->remote_address_start, 16);
5205 clib_memcpy (&p.raddr.stop, mp->remote_address_stop, 16);
5206 clib_memcpy (&p.laddr.start, mp->local_address_start, 16);
5207 clib_memcpy (&p.laddr.stop, mp->local_address_stop, 16);
5211 clib_memcpy (&p.raddr.start.ip4.data, mp->remote_address_start, 4);
5212 clib_memcpy (&p.raddr.stop.ip4.data, mp->remote_address_stop, 4);
5213 clib_memcpy (&p.laddr.start.ip4.data, mp->local_address_start, 4);
5214 clib_memcpy (&p.laddr.stop.ip4.data, mp->local_address_stop, 4);
5216 p.protocol = mp->protocol;
5217 p.rport.start = ntohs (mp->remote_port_start);
5218 p.rport.stop = ntohs (mp->remote_port_stop);
5219 p.lport.start = ntohs (mp->local_port_start);
5220 p.lport.stop = ntohs (mp->local_port_stop);
5221 /* policy action resolve unsupported */
5222 if (mp->policy == IPSEC_POLICY_ACTION_RESOLVE)
5224 clib_warning ("unsupported action: 'resolve'");
5225 rv = VNET_API_ERROR_UNIMPLEMENTED;
5228 p.policy = mp->policy;
5229 p.sa_id = ntohl (mp->sa_id);
5231 rv = ipsec_add_del_policy (vm, &p, mp->is_add);
5238 rv = ipsec_add_del_policy (vm, &p, mp->is_add);
5241 rv = VNET_API_ERROR_UNIMPLEMENTED;
5246 REPLY_MACRO (VL_API_IPSEC_SPD_ADD_DEL_ENTRY_REPLY);
5249 static void vl_api_ipsec_sad_add_del_entry_t_handler
5250 (vl_api_ipsec_sad_add_del_entry_t * mp)
5252 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
5253 vl_api_ipsec_sad_add_del_entry_reply_t *rmp;
5258 memset (&sa, 0, sizeof (sa));
5260 sa.id = ntohl (mp->sad_id);
5261 sa.spi = ntohl (mp->spi);
5262 /* security protocol AH unsupported */
5263 if (mp->protocol == IPSEC_PROTOCOL_AH)
5265 clib_warning ("unsupported security protocol 'AH'");
5266 rv = VNET_API_ERROR_UNIMPLEMENTED;
5269 sa.protocol = mp->protocol;
5270 /* check for unsupported crypto-alg */
5271 if (mp->crypto_algorithm < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
5272 mp->crypto_algorithm >= IPSEC_CRYPTO_N_ALG)
5274 clib_warning ("unsupported crypto-alg: '%U'", format_ipsec_crypto_alg,
5275 mp->crypto_algorithm);
5276 rv = VNET_API_ERROR_UNIMPLEMENTED;
5279 sa.crypto_alg = mp->crypto_algorithm;
5280 sa.crypto_key_len = mp->crypto_key_length;
5281 clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key));
5282 /* check for unsupported integ-alg */
5284 if (mp->integrity_algorithm < IPSEC_INTEG_ALG_NONE ||
5286 if (mp->integrity_algorithm < IPSEC_INTEG_ALG_SHA1_96 ||
5288 mp->integrity_algorithm >= IPSEC_INTEG_N_ALG)
5290 clib_warning ("unsupported integ-alg: '%U'", format_ipsec_integ_alg,
5291 mp->integrity_algorithm);
5292 rv = VNET_API_ERROR_UNIMPLEMENTED;
5297 /*Special cases, aes-gcm-128 encryption */
5298 if (mp->crypto_algorithm == IPSEC_CRYPTO_ALG_AES_GCM_128)
5300 if (mp->integrity_algorithm != IPSEC_INTEG_ALG_NONE
5301 && mp->integrity_algorithm != IPSEC_INTEG_ALG_AES_GCM_128)
5304 ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
5305 rv = VNET_API_ERROR_UNIMPLEMENTED;
5308 else /*set integ-alg internally to aes-gcm-128 */
5309 mp->integrity_algorithm = IPSEC_INTEG_ALG_AES_GCM_128;
5311 else if (mp->integrity_algorithm == IPSEC_INTEG_ALG_AES_GCM_128)
5313 clib_warning ("unsupported integ-alg: aes-gcm-128");
5314 rv = VNET_API_ERROR_UNIMPLEMENTED;
5317 else if (mp->integrity_algorithm == IPSEC_INTEG_ALG_NONE)
5319 clib_warning ("unsupported integ-alg: none");
5320 rv = VNET_API_ERROR_UNIMPLEMENTED;
5325 sa.integ_alg = mp->integrity_algorithm;
5326 sa.integ_key_len = mp->integrity_key_length;
5327 clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key));
5328 sa.use_esn = mp->use_extended_sequence_number;
5329 sa.is_tunnel = mp->is_tunnel;
5330 sa.is_tunnel_ip6 = mp->is_tunnel_ipv6;
5331 if (sa.is_tunnel_ip6)
5333 clib_memcpy (&sa.tunnel_src_addr, mp->tunnel_src_address, 16);
5334 clib_memcpy (&sa.tunnel_dst_addr, mp->tunnel_dst_address, 16);
5338 clib_memcpy (&sa.tunnel_src_addr.ip4.data, mp->tunnel_src_address, 4);
5339 clib_memcpy (&sa.tunnel_dst_addr.ip4.data, mp->tunnel_dst_address, 4);
5342 rv = ipsec_add_del_sa (vm, &sa, mp->is_add);
5344 rv = VNET_API_ERROR_UNIMPLEMENTED;
5349 REPLY_MACRO (VL_API_IPSEC_SAD_ADD_DEL_ENTRY_REPLY);
5353 vl_api_ikev2_profile_add_del_t_handler (vl_api_ikev2_profile_add_del_t * mp)
5355 vl_api_ikev2_profile_add_del_reply_t *rmp;
5359 vlib_main_t *vm = vlib_get_main ();
5360 clib_error_t *error;
5361 u8 *tmp = format (0, "%s", mp->name);
5362 error = ikev2_add_del_profile (vm, tmp, mp->is_add);
5365 rv = VNET_API_ERROR_UNSPECIFIED;
5367 rv = VNET_API_ERROR_UNIMPLEMENTED;
5370 REPLY_MACRO (VL_API_IKEV2_PROFILE_ADD_DEL_REPLY);
5374 vl_api_ikev2_profile_set_auth_t_handler
5375 (vl_api_ikev2_profile_set_auth_t * mp)
5377 vl_api_ikev2_profile_set_auth_reply_t *rmp;
5381 vlib_main_t *vm = vlib_get_main ();
5382 clib_error_t *error;
5383 u8 *tmp = format (0, "%s", mp->name);
5384 u8 *data = vec_new (u8, mp->data_len);
5385 clib_memcpy (data, mp->data, mp->data_len);
5386 error = ikev2_set_profile_auth (vm, tmp, mp->auth_method, data, mp->is_hex);
5390 rv = VNET_API_ERROR_UNSPECIFIED;
5392 rv = VNET_API_ERROR_UNIMPLEMENTED;
5395 REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_AUTH_REPLY);
5399 vl_api_ikev2_profile_set_id_t_handler (vl_api_ikev2_profile_set_id_t * mp)
5401 vl_api_ikev2_profile_add_del_reply_t *rmp;
5405 vlib_main_t *vm = vlib_get_main ();
5406 clib_error_t *error;
5407 u8 *tmp = format (0, "%s", mp->name);
5408 u8 *data = vec_new (u8, mp->data_len);
5409 clib_memcpy (data, mp->data, mp->data_len);
5410 error = ikev2_set_profile_id (vm, tmp, mp->id_type, data, mp->is_local);
5414 rv = VNET_API_ERROR_UNSPECIFIED;
5416 rv = VNET_API_ERROR_UNIMPLEMENTED;
5419 REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_ID_REPLY);
5423 vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp)
5425 vl_api_ikev2_profile_set_ts_reply_t *rmp;
5429 vlib_main_t *vm = vlib_get_main ();
5430 clib_error_t *error;
5431 u8 *tmp = format (0, "%s", mp->name);
5432 error = ikev2_set_profile_ts (vm, tmp, mp->proto, mp->start_port,
5433 mp->end_port, (ip4_address_t) mp->start_addr,
5434 (ip4_address_t) mp->end_addr, mp->is_local);
5437 rv = VNET_API_ERROR_UNSPECIFIED;
5439 rv = VNET_API_ERROR_UNIMPLEMENTED;
5442 REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_TS_REPLY);
5446 vl_api_ikev2_set_local_key_t_handler (vl_api_ikev2_set_local_key_t * mp)
5448 vl_api_ikev2_profile_set_ts_reply_t *rmp;
5452 vlib_main_t *vm = vlib_get_main ();
5453 clib_error_t *error;
5455 error = ikev2_set_local_key (vm, mp->key_file);
5457 rv = VNET_API_ERROR_UNSPECIFIED;
5459 rv = VNET_API_ERROR_UNIMPLEMENTED;
5462 REPLY_MACRO (VL_API_IKEV2_SET_LOCAL_KEY_REPLY);
5466 vl_api_ipsec_sa_set_key_t_handler (vl_api_ipsec_sa_set_key_t * mp)
5468 vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
5469 vl_api_ipsec_sa_set_key_reply_t *rmp;
5473 sa.id = ntohl (mp->sa_id);
5474 sa.crypto_key_len = mp->crypto_key_length;
5475 clib_memcpy (&sa.crypto_key, mp->crypto_key, sizeof (sa.crypto_key));
5476 sa.integ_key_len = mp->integrity_key_length;
5477 clib_memcpy (&sa.integ_key, mp->integrity_key, sizeof (sa.integ_key));
5479 rv = ipsec_set_sa_key (vm, &sa);
5481 rv = VNET_API_ERROR_UNIMPLEMENTED;
5484 REPLY_MACRO (VL_API_IPSEC_SA_SET_KEY_REPLY);
5487 static void vl_api_cop_interface_enable_disable_t_handler
5488 (vl_api_cop_interface_enable_disable_t * mp)
5490 vl_api_cop_interface_enable_disable_reply_t *rmp;
5492 u32 sw_if_index = ntohl (mp->sw_if_index);
5495 VALIDATE_SW_IF_INDEX (mp);
5497 enable_disable = (int) mp->enable_disable;
5499 rv = cop_interface_enable_disable (sw_if_index, enable_disable);
5501 BAD_SW_IF_INDEX_LABEL;
5503 REPLY_MACRO (VL_API_COP_INTERFACE_ENABLE_DISABLE_REPLY);
5506 static void vl_api_cop_whitelist_enable_disable_t_handler
5507 (vl_api_cop_whitelist_enable_disable_t * mp)
5509 vl_api_cop_whitelist_enable_disable_reply_t *rmp;
5510 cop_whitelist_enable_disable_args_t _a, *a = &_a;
5511 u32 sw_if_index = ntohl (mp->sw_if_index);
5514 VALIDATE_SW_IF_INDEX (mp);
5516 a->sw_if_index = sw_if_index;
5519 a->default_cop = mp->default_cop;
5520 a->fib_id = ntohl (mp->fib_id);
5522 rv = cop_whitelist_enable_disable (a);
5524 BAD_SW_IF_INDEX_LABEL;
5526 REPLY_MACRO (VL_API_COP_WHITELIST_ENABLE_DISABLE_REPLY);
5530 vl_api_get_node_graph_t_handler (vl_api_get_node_graph_t * mp)
5534 api_main_t *am = &api_main;
5535 vlib_main_t *vm = vlib_get_main ();
5537 vl_api_get_node_graph_reply_t *rmp;
5539 pthread_mutex_lock (&am->vlib_rp->mutex);
5540 oldheap = svm_push_data_heap (am->vlib_rp);
5543 * Keep the number of memcpy ops to a minimum (e.g. 1).
5545 vec_validate (vector, 16384);
5546 vec_reset_length (vector);
5549 vector = vlib_node_serialize (&vm->node_main, vector,
5550 (u32) ~ 0 /* all threads */ ,
5551 1 /* include nexts */ ,
5552 1 /* include stats */ );
5554 svm_pop_heap (oldheap);
5555 pthread_mutex_unlock (&am->vlib_rp->mutex);
5558 REPLY_MACRO2(VL_API_GET_NODE_GRAPH_REPLY,
5560 rmp->reply_in_shmem = (uword) vector;
5566 vl_api_ioam_enable_t_handler (vl_api_ioam_enable_t * mp)
5569 vl_api_ioam_enable_reply_t *rmp;
5570 clib_error_t *error;
5572 /* Ignoring the profile id as currently a single profile
5574 error = ip6_ioam_enable (mp->trace_enable, mp->pot_enable,
5575 mp->seqno, mp->analyse);
5578 clib_error_report (error);
5579 rv = clib_error_get_code (error);
5582 REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
5586 vl_api_ioam_disable_t_handler (vl_api_ioam_disable_t * mp)
5589 vl_api_ioam_disable_reply_t *rmp;
5590 clib_error_t *error;
5592 error = clear_ioam_rewrite_fn ();
5595 clib_error_report (error);
5596 rv = clib_error_get_code (error);
5599 REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
5603 vl_api_af_packet_create_t_handler (vl_api_af_packet_create_t * mp)
5605 vlib_main_t *vm = vlib_get_main ();
5606 vl_api_af_packet_create_reply_t *rmp;
5608 u8 *host_if_name = NULL;
5611 host_if_name = format (0, "%s", mp->host_if_name);
5612 vec_add1 (host_if_name, 0);
5614 rv = af_packet_create_if (vm, host_if_name,
5615 mp->use_random_hw_addr ? 0 : mp->hw_addr,
5618 vec_free (host_if_name);
5621 REPLY_MACRO2(VL_API_AF_PACKET_CREATE_REPLY,
5623 rmp->sw_if_index = clib_host_to_net_u32(sw_if_index);
5629 vl_api_af_packet_delete_t_handler (vl_api_af_packet_delete_t * mp)
5631 vlib_main_t *vm = vlib_get_main ();
5632 vl_api_af_packet_delete_reply_t *rmp;
5634 u8 *host_if_name = NULL;
5636 host_if_name = format (0, "%s", mp->host_if_name);
5637 vec_add1 (host_if_name, 0);
5639 rv = af_packet_delete_if (vm, host_if_name);
5641 vec_free (host_if_name);
5643 REPLY_MACRO (VL_API_AF_PACKET_DELETE_REPLY);
5647 vl_api_policer_add_del_t_handler (vl_api_policer_add_del_t * mp)
5649 vlib_main_t *vm = vlib_get_main ();
5650 vl_api_policer_add_del_reply_t *rmp;
5653 sse2_qos_pol_cfg_params_st cfg;
5654 clib_error_t *error;
5657 name = format (0, "%s", mp->name);
5659 memset (&cfg, 0, sizeof (cfg));
5661 cfg.rnd_type = mp->round_type;
5662 cfg.rate_type = mp->rate_type;
5663 cfg.rb.kbps.cir_kbps = mp->cir;
5664 cfg.rb.kbps.eir_kbps = mp->eir;
5665 cfg.rb.kbps.cb_bytes = mp->cb;
5666 cfg.rb.kbps.eb_bytes = mp->eb;
5667 cfg.conform_action.action_type = mp->conform_action_type;
5668 cfg.conform_action.dscp = mp->conform_dscp;
5669 cfg.exceed_action.action_type = mp->exceed_action_type;
5670 cfg.exceed_action.dscp = mp->exceed_dscp;
5671 cfg.violate_action.action_type = mp->violate_action_type;
5672 cfg.violate_action.dscp = mp->violate_dscp;
5673 cfg.color_aware = mp->color_aware;
5675 error = policer_add_del (vm, name, &cfg, &policer_index, mp->is_add);
5678 rv = VNET_API_ERROR_UNSPECIFIED;
5681 REPLY_MACRO2(VL_API_POLICER_ADD_DEL_REPLY,
5683 if (rv == 0 && mp->is_add)
5684 rmp->policer_index = ntohl(policer_index);
5686 rmp->policer_index = ~0;
5692 send_policer_details (u8 * name,
5693 sse2_qos_pol_cfg_params_st * config,
5694 policer_read_response_type_st * templ,
5695 unix_shared_memory_queue_t * q, u32 context)
5697 vl_api_policer_details_t *mp;
5699 mp = vl_msg_api_alloc (sizeof (*mp));
5700 memset (mp, 0, sizeof (*mp));
5701 mp->_vl_msg_id = ntohs (VL_API_POLICER_DETAILS);
5702 mp->context = context;
5703 mp->cir = htonl (config->rb.kbps.cir_kbps);
5704 mp->eir = htonl (config->rb.kbps.eir_kbps);
5705 mp->cb = htonl (config->rb.kbps.cb_bytes);
5706 mp->eb = htonl (config->rb.kbps.eb_bytes);
5707 mp->rate_type = config->rate_type;
5708 mp->round_type = config->rnd_type;
5709 mp->type = config->rfc;
5710 mp->conform_action_type = config->conform_action.action_type;
5711 mp->conform_dscp = config->conform_action.dscp;
5712 mp->exceed_action_type = config->exceed_action.action_type;
5713 mp->exceed_dscp = config->exceed_action.dscp;
5714 mp->violate_action_type = config->violate_action.action_type;
5715 mp->violate_dscp = config->violate_action.dscp;
5716 mp->single_rate = templ->single_rate ? 1 : 0;
5717 mp->color_aware = templ->color_aware ? 1 : 0;
5718 mp->scale = htonl (templ->scale);
5719 mp->cir_tokens_per_period = htonl (templ->cir_tokens_per_period);
5720 mp->pir_tokens_per_period = htonl (templ->pir_tokens_per_period);
5721 mp->current_limit = htonl (templ->current_limit);
5722 mp->current_bucket = htonl (templ->current_bucket);
5723 mp->extended_limit = htonl (templ->extended_limit);
5724 mp->extended_bucket = htonl (templ->extended_bucket);
5725 mp->last_update_time = clib_host_to_net_u64 (templ->last_update_time);
5727 strncpy ((char *) mp->name, (char *) name, ARRAY_LEN (mp->name) - 1);
5729 vl_msg_api_send_shmem (q, (u8 *) & mp);
5733 vl_api_policer_dump_t_handler (vl_api_policer_dump_t * mp)
5735 unix_shared_memory_queue_t *q;
5736 vnet_policer_main_t *pm = &vnet_policer_main;
5742 sse2_qos_pol_cfg_params_st *config;
5743 policer_read_response_type_st *templ;
5745 q = vl_api_client_index_to_input_queue (mp->client_index);
5749 if (mp->match_name_valid)
5751 match_name = format (0, "%s%c", mp->match_name, 0);
5754 if (mp->match_name_valid)
5756 p = hash_get_mem (pm->policer_config_by_name, match_name);
5760 config = pool_elt_at_index (pm->configs, pool_index);
5761 templ = pool_elt_at_index (pm->policer_templates, pool_index);
5762 send_policer_details (match_name, config, templ, q, mp->context);
5768 hash_foreach_pair (hp, pm->policer_config_by_name,
5770 name = (u8 *) hp->key;
5771 pool_index = hp->value[0];
5772 config = pool_elt_at_index (pm->configs, pool_index);
5773 templ = pool_elt_at_index (pm->policer_templates, pool_index);
5774 send_policer_details(name, config, templ, q, mp->context);
5781 vl_api_policer_classify_set_interface_t_handler
5782 (vl_api_policer_classify_set_interface_t * mp)
5784 vlib_main_t *vm = vlib_get_main ();
5785 vl_api_policer_classify_set_interface_reply_t *rmp;
5787 u32 sw_if_index, ip4_table_index, ip6_table_index, l2_table_index;
5789 ip4_table_index = ntohl (mp->ip4_table_index);
5790 ip6_table_index = ntohl (mp->ip6_table_index);
5791 l2_table_index = ntohl (mp->l2_table_index);
5792 sw_if_index = ntohl (mp->sw_if_index);
5794 VALIDATE_SW_IF_INDEX (mp);
5796 rv = vnet_set_policer_classify_intfc (vm, sw_if_index, ip4_table_index,
5797 ip6_table_index, l2_table_index,
5800 BAD_SW_IF_INDEX_LABEL;
5802 REPLY_MACRO (VL_API_POLICER_CLASSIFY_SET_INTERFACE_REPLY);
5806 send_policer_classify_details (u32 sw_if_index,
5808 unix_shared_memory_queue_t * q, u32 context)
5810 vl_api_policer_classify_details_t *mp;
5812 mp = vl_msg_api_alloc (sizeof (*mp));
5813 memset (mp, 0, sizeof (*mp));
5814 mp->_vl_msg_id = ntohs (VL_API_POLICER_CLASSIFY_DETAILS);
5815 mp->context = context;
5816 mp->sw_if_index = htonl (sw_if_index);
5817 mp->table_index = htonl (table_index);
5819 vl_msg_api_send_shmem (q, (u8 *) & mp);
5823 vl_api_policer_classify_dump_t_handler (vl_api_policer_classify_dump_t * mp)
5825 unix_shared_memory_queue_t *q;
5826 policer_classify_main_t *pcm = &policer_classify_main;
5830 q = vl_api_client_index_to_input_queue (mp->client_index);
5834 vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type];
5836 if (vec_len (vec_tbl))
5838 for (i = 0; i < vec_len (vec_tbl); i++)
5840 if (vec_elt (vec_tbl, i) == ~0)
5843 send_policer_classify_details (i, vec_elt (vec_tbl, i), q,
5850 vl_api_netmap_create_t_handler (vl_api_netmap_create_t * mp)
5852 vlib_main_t *vm = vlib_get_main ();
5853 vl_api_netmap_create_reply_t *rmp;
5857 if_name = format (0, "%s", mp->netmap_if_name);
5858 vec_add1 (if_name, 0);
5861 netmap_create_if (vm, if_name, mp->use_random_hw_addr ? 0 : mp->hw_addr,
5862 mp->is_pipe, mp->is_master, 0);
5866 REPLY_MACRO (VL_API_NETMAP_CREATE_REPLY);
5870 vl_api_netmap_delete_t_handler (vl_api_netmap_delete_t * mp)
5872 vlib_main_t *vm = vlib_get_main ();
5873 vl_api_netmap_delete_reply_t *rmp;
5877 if_name = format (0, "%s", mp->netmap_if_name);
5878 vec_add1 (if_name, 0);
5880 rv = netmap_delete_if (vm, if_name);
5884 REPLY_MACRO (VL_API_NETMAP_DELETE_REPLY);
5888 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_fib_details_t * mp)
5890 clib_warning ("BUG");
5893 typedef struct mpls_tunnel_send_walk_ctx_t_
5895 unix_shared_memory_queue_t *q;
5898 } mpls_tunnel_send_walk_ctx_t;
5901 send_mpls_tunnel_entry (u32 mti, void *arg)
5903 mpls_tunnel_send_walk_ctx_t *ctx;
5904 vl_api_mpls_tunnel_details_t *mp;
5905 const mpls_tunnel_t *mt;
5910 if (~0 != ctx->index && mti != ctx->index)
5913 mt = mpls_tunnel_get (mti);
5914 nlabels = vec_len (mt->mt_label_stack);
5916 mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
5917 memset (mp, 0, sizeof (*mp));
5918 mp->_vl_msg_id = ntohs (VL_API_MPLS_TUNNEL_DETAILS);
5919 mp->context = ctx->context;
5921 mp->tunnel_index = ntohl (mti);
5922 memcpy (mp->mt_next_hop_out_labels,
5923 mt->mt_label_stack, nlabels * sizeof (u32));
5927 vl_msg_api_send_shmem (ctx->q, (u8 *) & mp);
5931 vl_api_mpls_tunnel_dump_t_handler (vl_api_mpls_tunnel_dump_t * mp)
5933 unix_shared_memory_queue_t *q;
5935 q = vl_api_client_index_to_input_queue (mp->client_index);
5939 mpls_tunnel_send_walk_ctx_t ctx = {
5941 .index = ntohl (mp->tunnel_index),
5942 .context = mp->context,
5944 mpls_tunnel_walk (send_mpls_tunnel_entry, &ctx);
5948 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
5950 clib_warning ("BUG");
5954 vl_api_mpls_fib_details_t_endian (vl_api_mpls_fib_details_t * mp)
5956 clib_warning ("BUG");
5960 vl_api_mpls_fib_details_t_print (vl_api_mpls_fib_details_t * mp)
5962 clib_warning ("BUG");
5966 send_mpls_fib_details (vpe_api_main_t * am,
5967 unix_shared_memory_queue_t * q,
5968 u32 table_id, u32 label, u32 eos,
5969 fib_route_path_encode_t * api_rpaths, u32 context)
5971 vl_api_mpls_fib_details_t *mp;
5972 fib_route_path_encode_t *api_rpath;
5973 vl_api_fib_path2_t *fp;
5976 path_count = vec_len (api_rpaths);
5977 mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
5980 memset (mp, 0, sizeof (*mp));
5981 mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_DETAILS);
5982 mp->context = context;
5984 mp->table_id = htonl (table_id);
5986 mp->label = htonl (label);
5988 mp->count = htonl (path_count);
5990 vec_foreach (api_rpath, api_rpaths)
5992 memset (fp, 0, sizeof (*fp));
5993 fp->weight = htonl (api_rpath->rpath.frp_weight);
5994 fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
5995 copy_fib_next_hop (api_rpath, fp);
5999 vl_msg_api_send_shmem (q, (u8 *) & mp);
6003 vl_api_mpls_fib_dump_t_handler (vl_api_mpls_fib_dump_t * mp)
6005 vpe_api_main_t *am = &vpe_api_main;
6006 unix_shared_memory_queue_t *q;
6007 mpls_main_t *mm = &mpls_main;
6008 fib_table_t *fib_table;
6009 fib_node_index_t lfei, *lfeip, *lfeis = NULL;
6013 fib_route_path_encode_t *api_rpaths;
6015 q = vl_api_client_index_to_input_queue (mp->client_index);
6020 pool_foreach (fib_table, mm->fibs,
6022 hash_foreach(key, lfei, fib_table->mpls.mf_entries,
6024 vec_add1(lfeis, lfei);
6027 vec_sort_with_function(lfeis, fib_entry_cmp_for_sort);
6029 vec_foreach(lfeip, lfeis)
6031 fib_entry_get_prefix(*lfeip, &pfx);
6032 fib_index = fib_entry_get_fib_index(*lfeip);
6033 fib_table = fib_table_get(fib_index, pfx.fp_proto);
6035 fib_entry_encode(*lfeip, &api_rpaths);
6036 send_mpls_fib_details (am, q,
6037 fib_table->ft_table_id,
6042 vec_free(api_rpaths);
6049 vl_api_classify_table_ids_t_handler (vl_api_classify_table_ids_t * mp)
6051 unix_shared_memory_queue_t *q;
6053 q = vl_api_client_index_to_input_queue (mp->client_index);
6057 vnet_classify_main_t *cm = &vnet_classify_main;
6058 vnet_classify_table_t *t;
6063 pool_foreach (t, cm->tables,
6065 vec_add1 (table_ids, ntohl(t - cm->tables));
6068 count = vec_len (table_ids);
6070 vl_api_classify_table_ids_reply_t *rmp;
6071 rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp) + count * sizeof (u32));
6072 rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TABLE_IDS_REPLY);
6073 rmp->context = mp->context;
6074 rmp->count = ntohl (count);
6075 clib_memcpy (rmp->ids, table_ids, count * sizeof (u32));
6078 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6080 vec_free (table_ids);
6084 vl_api_classify_table_by_interface_t_handler
6085 (vl_api_classify_table_by_interface_t * mp)
6087 vl_api_classify_table_by_interface_reply_t *rmp;
6090 u32 sw_if_index = ntohl (mp->sw_if_index);
6093 vec_validate (acl, INPUT_ACL_N_TABLES - 1);
6096 VALIDATE_SW_IF_INDEX (mp);
6098 input_acl_main_t *am = &input_acl_main;
6103 for (type = 0; type < INPUT_ACL_N_TABLES; type++)
6105 u32 *vec_tbl = am->classify_table_index_by_sw_if_index[type];
6106 if (vec_len (vec_tbl))
6108 for (if_idx = 0; if_idx < vec_len (vec_tbl); if_idx++)
6110 if (vec_elt (vec_tbl, if_idx) == ~0 || sw_if_index != if_idx)
6114 acl[type] = vec_elt (vec_tbl, if_idx);
6119 BAD_SW_IF_INDEX_LABEL;
6122 REPLY_MACRO2(VL_API_CLASSIFY_TABLE_BY_INTERFACE_REPLY,
6124 rmp->sw_if_index = ntohl(sw_if_index);
6125 rmp->l2_table_id = ntohl(acl[INPUT_ACL_TABLE_L2]);
6126 rmp->ip4_table_id = ntohl(acl[INPUT_ACL_TABLE_IP4]);
6127 rmp->ip6_table_id = ntohl(acl[INPUT_ACL_TABLE_IP6]);
6134 vl_api_classify_table_info_t_handler (vl_api_classify_table_info_t * mp)
6136 unix_shared_memory_queue_t *q;
6138 q = vl_api_client_index_to_input_queue (mp->client_index);
6142 vl_api_classify_table_info_reply_t *rmp = 0;
6144 vnet_classify_main_t *cm = &vnet_classify_main;
6145 u32 table_id = ntohl (mp->table_id);
6146 vnet_classify_table_t *t;
6149 pool_foreach (t, cm->tables,
6151 if (table_id == t - cm->tables)
6153 rmp = vl_msg_api_alloc_as_if_client
6154 (sizeof (*rmp) + t->match_n_vectors * sizeof (u32x4));
6155 rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TABLE_INFO_REPLY);
6156 rmp->context = mp->context;
6157 rmp->table_id = ntohl(table_id);
6158 rmp->nbuckets = ntohl(t->nbuckets);
6159 rmp->match_n_vectors = ntohl(t->match_n_vectors);
6160 rmp->skip_n_vectors = ntohl(t->skip_n_vectors);
6161 rmp->active_sessions = ntohl(t->active_elements);
6162 rmp->next_table_index = ntohl(t->next_table_index);
6163 rmp->miss_next_index = ntohl(t->miss_next_index);
6164 rmp->mask_length = ntohl(t->match_n_vectors * sizeof (u32x4));
6165 clib_memcpy(rmp->mask, t->mask, t->match_n_vectors * sizeof(u32x4));
6174 rmp = vl_msg_api_alloc (sizeof (*rmp));
6175 rmp->_vl_msg_id = ntohs ((VL_API_CLASSIFY_TABLE_INFO_REPLY));
6176 rmp->context = mp->context;
6177 rmp->retval = ntohl (VNET_API_ERROR_CLASSIFY_TABLE_NOT_FOUND);
6180 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6184 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
6187 clib_warning ("BUG");
6191 send_classify_session_details (unix_shared_memory_queue_t * q,
6194 vnet_classify_entry_t * e, u32 context)
6196 vl_api_classify_session_details_t *rmp;
6198 rmp = vl_msg_api_alloc (sizeof (*rmp));
6199 memset (rmp, 0, sizeof (*rmp));
6200 rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_SESSION_DETAILS);
6201 rmp->context = context;
6202 rmp->table_id = ntohl (table_id);
6203 rmp->hit_next_index = ntohl (e->next_index);
6204 rmp->advance = ntohl (e->advance);
6205 rmp->opaque_index = ntohl (e->opaque_index);
6206 rmp->match_length = ntohl (match_length);
6207 clib_memcpy (rmp->match, e->key, match_length);
6209 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6213 vl_api_classify_session_dump_t_handler (vl_api_classify_session_dump_t * mp)
6215 vnet_classify_main_t *cm = &vnet_classify_main;
6216 unix_shared_memory_queue_t *q;
6218 u32 table_id = ntohl (mp->table_id);
6219 vnet_classify_table_t *t;
6221 q = vl_api_client_index_to_input_queue (mp->client_index);
6226 pool_foreach (t, cm->tables,
6228 if (table_id == t - cm->tables)
6230 vnet_classify_bucket_t * b;
6231 vnet_classify_entry_t * v, * save_v;
6234 for (i = 0; i < t->nbuckets; i++)
6236 b = &t->buckets [i];
6240 save_v = vnet_classify_get_entry (t, b->offset);
6241 for (j = 0; j < (1<<b->log2_pages); j++)
6243 for (k = 0; k < t->entries_per_page; k++)
6245 v = vnet_classify_entry_at_index
6246 (t, save_v, j*t->entries_per_page + k);
6247 if (vnet_classify_entry_is_free (v))
6250 send_classify_session_details
6251 (q, table_id, t->match_n_vectors * sizeof (u32x4),
6263 vl_api_set_ipfix_exporter_t_handler (vl_api_set_ipfix_exporter_t * mp)
6265 vlib_main_t *vm = vlib_get_main ();
6266 flow_report_main_t *frm = &flow_report_main;
6267 vl_api_set_ipfix_exporter_reply_t *rmp;
6268 ip4_address_t collector, src;
6269 u16 collector_port = UDP_DST_PORT_ipfix;
6271 u32 template_interval;
6277 memcpy (collector.data, mp->collector_address, sizeof (collector.data));
6278 collector_port = ntohs (mp->collector_port);
6279 if (collector_port == (u16) ~ 0)
6280 collector_port = UDP_DST_PORT_ipfix;
6281 memcpy (src.data, mp->src_address, sizeof (src.data));
6282 fib_id = ntohl (mp->vrf_id);
6284 ip4_main_t *im = &ip4_main;
6291 uword *p = hash_get (im->fib_index_by_table_id, fib_id);
6294 rv = VNET_API_ERROR_NO_SUCH_FIB;
6300 path_mtu = ntohl (mp->path_mtu);
6302 path_mtu = 512; // RFC 7011 section 10.3.3.
6303 template_interval = ntohl (mp->template_interval);
6304 if (template_interval == ~0)
6305 template_interval = 20;
6306 udp_checksum = mp->udp_checksum;
6308 if (collector.as_u32 == 0)
6310 rv = VNET_API_ERROR_INVALID_VALUE;
6314 if (src.as_u32 == 0)
6316 rv = VNET_API_ERROR_INVALID_VALUE;
6320 if (path_mtu > 1450 /* vpp does not support fragmentation */ )
6322 rv = VNET_API_ERROR_INVALID_VALUE;
6328 rv = VNET_API_ERROR_INVALID_VALUE;
6332 /* Reset report streams if we are reconfiguring IP addresses */
6333 if (frm->ipfix_collector.as_u32 != collector.as_u32 ||
6334 frm->src_address.as_u32 != src.as_u32 ||
6335 frm->collector_port != collector_port)
6336 vnet_flow_reports_reset (frm);
6338 frm->ipfix_collector.as_u32 = collector.as_u32;
6339 frm->collector_port = collector_port;
6340 frm->src_address.as_u32 = src.as_u32;
6341 frm->fib_index = fib_index;
6342 frm->path_mtu = path_mtu;
6343 frm->template_interval = template_interval;
6344 frm->udp_checksum = udp_checksum;
6346 /* Turn on the flow reporting process */
6347 vlib_process_signal_event (vm, flow_report_process_node.index, 1, 0);
6350 REPLY_MACRO (VL_API_SET_IPFIX_EXPORTER_REPLY);
6354 vl_api_ipfix_exporter_dump_t_handler (vl_api_ipfix_exporter_dump_t * mp)
6356 flow_report_main_t *frm = &flow_report_main;
6357 unix_shared_memory_queue_t *q;
6358 vl_api_ipfix_exporter_details_t *rmp;
6359 ip4_main_t *im = &ip4_main;
6362 q = vl_api_client_index_to_input_queue (mp->client_index);
6366 rmp = vl_msg_api_alloc (sizeof (*rmp));
6367 memset (rmp, 0, sizeof (*rmp));
6368 rmp->_vl_msg_id = ntohs (VL_API_IPFIX_EXPORTER_DETAILS);
6369 rmp->context = mp->context;
6370 memcpy (rmp->collector_address, frm->ipfix_collector.data,
6371 sizeof (frm->ipfix_collector.data));
6372 rmp->collector_port = htons (frm->collector_port);
6373 memcpy (rmp->src_address, frm->src_address.data,
6374 sizeof (frm->src_address.data));
6375 if (frm->fib_index == ~0)
6378 vrf_id = im->fibs[frm->fib_index].ft_table_id;
6379 rmp->vrf_id = htonl (vrf_id);
6380 rmp->path_mtu = htonl (frm->path_mtu);
6381 rmp->template_interval = htonl (frm->template_interval);
6382 rmp->udp_checksum = (frm->udp_checksum != 0);
6384 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6388 vl_api_set_ipfix_classify_stream_t_handler
6389 (vl_api_set_ipfix_classify_stream_t * mp)
6391 vl_api_set_ipfix_classify_stream_reply_t *rmp;
6392 flow_report_classify_main_t *fcm = &flow_report_classify_main;
6393 flow_report_main_t *frm = &flow_report_main;
6395 u32 src_port = UDP_DST_PORT_ipfix;
6398 domain_id = ntohl (mp->domain_id);
6399 src_port = ntohs (mp->src_port);
6401 if (fcm->src_port != 0 &&
6402 (fcm->domain_id != domain_id || fcm->src_port != (u16) src_port))
6404 int rv = vnet_stream_change (frm, fcm->domain_id, fcm->src_port,
6405 domain_id, (u16) src_port);
6409 fcm->domain_id = domain_id;
6410 fcm->src_port = (u16) src_port;
6412 REPLY_MACRO (VL_API_SET_IPFIX_CLASSIFY_STREAM_REPLY);
6416 vl_api_ipfix_classify_stream_dump_t_handler
6417 (vl_api_ipfix_classify_stream_dump_t * mp)
6419 flow_report_classify_main_t *fcm = &flow_report_classify_main;
6420 unix_shared_memory_queue_t *q;
6421 vl_api_ipfix_classify_stream_details_t *rmp;
6423 q = vl_api_client_index_to_input_queue (mp->client_index);
6427 rmp = vl_msg_api_alloc (sizeof (*rmp));
6428 memset (rmp, 0, sizeof (*rmp));
6429 rmp->_vl_msg_id = ntohs (VL_API_IPFIX_CLASSIFY_STREAM_DETAILS);
6430 rmp->context = mp->context;
6431 rmp->domain_id = htonl (fcm->domain_id);
6432 rmp->src_port = htons (fcm->src_port);
6434 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6438 vl_api_ipfix_classify_table_add_del_t_handler
6439 (vl_api_ipfix_classify_table_add_del_t * mp)
6441 vl_api_ipfix_classify_table_add_del_reply_t *rmp;
6442 flow_report_classify_main_t *fcm = &flow_report_classify_main;
6443 flow_report_main_t *frm = &flow_report_main;
6444 vnet_flow_report_add_del_args_t args;
6445 ipfix_classify_table_t *table;
6447 u32 classify_table_index;
6449 u8 transport_protocol;
6452 classify_table_index = ntohl (mp->table_id);
6453 ip_version = mp->ip_version;
6454 transport_protocol = mp->transport_protocol;
6455 is_add = mp->is_add;
6457 if (fcm->src_port == 0)
6459 /* call set_ipfix_classify_stream first */
6460 rv = VNET_API_ERROR_UNSPECIFIED;
6464 memset (&args, 0, sizeof (args));
6468 for (i = 0; i < vec_len (fcm->tables); i++)
6469 if (ipfix_classify_table_index_valid (i))
6470 if (fcm->tables[i].classify_table_index == classify_table_index)
6472 table = &fcm->tables[i];
6480 rv = VNET_API_ERROR_VALUE_EXIST;
6483 table = ipfix_classify_add_table ();
6484 table->classify_table_index = classify_table_index;
6490 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
6495 table->ip_version = ip_version;
6496 table->transport_protocol = transport_protocol;
6498 args.opaque.as_uword = table - fcm->tables;
6499 args.rewrite_callback = ipfix_classify_template_rewrite;
6500 args.flow_data_callback = ipfix_classify_send_flows;
6501 args.is_add = is_add;
6502 args.domain_id = fcm->domain_id;
6503 args.src_port = fcm->src_port;
6505 rv = vnet_flow_report_add_del (frm, &args);
6507 /* If deleting, or add failed */
6508 if (is_add == 0 || (rv && is_add))
6509 ipfix_classify_delete_table (table - fcm->tables);
6512 REPLY_MACRO (VL_API_SET_IPFIX_CLASSIFY_STREAM_REPLY);
6516 send_ipfix_classify_table_details (u32 table_index,
6517 unix_shared_memory_queue_t * q,
6520 flow_report_classify_main_t *fcm = &flow_report_classify_main;
6521 vl_api_ipfix_classify_table_details_t *mp;
6523 ipfix_classify_table_t *table = &fcm->tables[table_index];
6525 mp = vl_msg_api_alloc (sizeof (*mp));
6526 memset (mp, 0, sizeof (*mp));
6527 mp->_vl_msg_id = ntohs (VL_API_IPFIX_CLASSIFY_TABLE_DETAILS);
6528 mp->context = context;
6529 mp->table_id = htonl (table->classify_table_index);
6530 mp->ip_version = table->ip_version;
6531 mp->transport_protocol = table->transport_protocol;
6533 vl_msg_api_send_shmem (q, (u8 *) & mp);
6537 vl_api_ipfix_classify_table_dump_t_handler
6538 (vl_api_ipfix_classify_table_dump_t * mp)
6540 flow_report_classify_main_t *fcm = &flow_report_classify_main;
6541 unix_shared_memory_queue_t *q;
6544 q = vl_api_client_index_to_input_queue (mp->client_index);
6548 for (i = 0; i < vec_len (fcm->tables); i++)
6549 if (ipfix_classify_table_index_valid (i))
6550 send_ipfix_classify_table_details (i, q, mp->context);
6554 vl_api_pg_create_interface_t_handler (vl_api_pg_create_interface_t * mp)
6556 vl_api_pg_create_interface_reply_t *rmp;
6559 pg_main_t *pg = &pg_main;
6560 u32 pg_if_id = pg_interface_add_or_get (pg, ntohl (mp->interface_id));
6561 pg_interface_t *pi = pool_elt_at_index (pg->interfaces, pg_if_id);
6564 REPLY_MACRO2(VL_API_PG_CREATE_INTERFACE_REPLY,
6566 rmp->sw_if_index = ntohl(pi->sw_if_index);
6572 vl_api_pg_capture_t_handler (vl_api_pg_capture_t * mp)
6574 vl_api_pg_capture_reply_t *rmp;
6577 vnet_main_t *vnm = vnet_get_main ();
6578 vnet_interface_main_t *im = &vnm->interface_main;
6579 vnet_hw_interface_t *hi = 0;
6581 u8 *intf_name = format (0, "pg%d", ntohl (mp->interface_id), 0);
6582 u32 hw_if_index = ~0;
6583 uword *p = hash_get_mem (im->hw_interface_by_name, intf_name);
6586 vec_free (intf_name);
6588 if (hw_if_index != ~0)
6590 pg_capture_args_t _a, *a = &_a;
6592 u32 len = ntohl (mp->pcap_name_length);
6593 u8 *pcap_file_name = vec_new (u8, len);
6594 clib_memcpy (pcap_file_name, mp->pcap_file_name, len);
6596 hi = vnet_get_sup_hw_interface (vnm, hw_if_index);
6597 a->hw_if_index = hw_if_index;
6598 a->dev_instance = hi->dev_instance;
6599 a->is_enabled = mp->is_enabled;
6600 a->pcap_file_name = pcap_file_name;
6601 a->count = ntohl (mp->count);
6603 clib_error_t *e = pg_capture (a);
6606 clib_error_report (e);
6607 rv = VNET_API_ERROR_CANNOT_CREATE_PCAP_FILE;
6610 vec_free (pcap_file_name);
6612 REPLY_MACRO (VL_API_PG_CAPTURE_REPLY);
6616 vl_api_pg_enable_disable_t_handler (vl_api_pg_enable_disable_t * mp)
6618 vl_api_pg_enable_disable_reply_t *rmp;
6621 pg_main_t *pg = &pg_main;
6622 u32 stream_index = ~0;
6624 int is_enable = mp->is_enabled != 0;
6625 u32 len = ntohl (mp->stream_name_length) - 1;
6629 u8 *stream_name = vec_new (u8, len);
6630 clib_memcpy (stream_name, mp->stream_name, len);
6631 uword *p = hash_get_mem (pg->stream_index_by_name, stream_name);
6634 vec_free (stream_name);
6637 pg_enable_disable (stream_index, is_enable);
6639 REPLY_MACRO (VL_API_PG_ENABLE_DISABLE_REPLY);
6643 vl_api_ip_source_and_port_range_check_add_del_t_handler
6644 (vl_api_ip_source_and_port_range_check_add_del_t * mp)
6646 vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
6649 u8 is_ipv6 = mp->is_ipv6;
6650 u8 is_add = mp->is_add;
6651 u8 mask_length = mp->mask_length;
6652 ip4_address_t ip4_addr;
6653 ip6_address_t ip6_addr;
6655 u16 *high_ports = 0;
6657 u16 tmp_low, tmp_high;
6661 // Validate port range
6662 num_ranges = mp->number_of_ranges;
6663 if (num_ranges > 32)
6664 { // This is size of array in VPE.API
6665 rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
6669 vec_reset_length (low_ports);
6670 vec_reset_length (high_ports);
6672 for (i = 0; i < num_ranges; i++)
6674 tmp_low = mp->low_ports[i];
6675 tmp_high = mp->high_ports[i];
6676 // If tmp_low <= tmp_high then only need to check tmp_low = 0
6677 // If tmp_low <= tmp_high then only need to check tmp_high > 65535
6678 if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535)
6680 rv = VNET_API_ERROR_INVALID_VALUE;
6683 vec_add1 (low_ports, tmp_low);
6684 vec_add1 (high_ports, tmp_high + 1);
6687 // Validate mask_length
6688 if ((is_ipv6 && mask_length > 128) || (!is_ipv6 && mask_length > 32))
6690 rv = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH;
6694 vrf_id = ntohl (mp->vrf_id);
6698 rv = VNET_API_ERROR_INVALID_VALUE;
6705 clib_memcpy (ip6_addr.as_u8, mp->address, sizeof (ip6_addr.as_u8));
6706 rv = ip6_source_and_port_range_check_add_del (&ip6_addr,
6710 high_ports, is_add);
6714 clib_memcpy (ip4_addr.data, mp->address, sizeof (ip4_addr));
6715 rv = ip4_source_and_port_range_check_add_del (&ip4_addr,
6719 high_ports, is_add);
6723 vec_free (low_ports);
6724 vec_free (high_ports);
6725 REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY);
6729 vl_api_ip_source_and_port_range_check_interface_add_del_t_handler
6730 (vl_api_ip_source_and_port_range_check_interface_add_del_t * mp)
6732 vlib_main_t *vm = vlib_get_main ();
6733 vl_api_ip_source_and_port_range_check_interface_add_del_reply_t *rmp;
6734 ip4_main_t *im = &ip4_main;
6737 u32 fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS];
6738 u32 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS];
6742 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT] =
6743 ntohl (mp->tcp_out_vrf_id);
6744 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT] =
6745 ntohl (mp->udp_out_vrf_id);
6746 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN] =
6747 ntohl (mp->tcp_in_vrf_id);
6748 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_IN] =
6749 ntohl (mp->udp_in_vrf_id);
6752 for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
6754 if (vrf_id[i] != 0 && vrf_id[i] != ~0)
6756 p = hash_get (im->fib_index_by_table_id, vrf_id[i]);
6760 rv = VNET_API_ERROR_INVALID_VALUE;
6764 fib_index[i] = p[0];
6769 sw_if_index = ntohl (mp->sw_if_index);
6771 VALIDATE_SW_IF_INDEX (mp);
6774 set_ip_source_and_port_range_check (vm, fib_index, sw_if_index,
6777 BAD_SW_IF_INDEX_LABEL;
6780 REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY);
6784 vl_api_ipsec_gre_add_del_tunnel_t_handler (vl_api_ipsec_gre_add_del_tunnel_t *
6787 vl_api_ipsec_gre_add_del_tunnel_reply_t *rmp;
6789 vnet_ipsec_gre_add_del_tunnel_args_t _a, *a = &_a;
6790 u32 sw_if_index = ~0;
6792 /* Check src & dst are different */
6793 if (memcmp (mp->src_address, mp->dst_address, 4) == 0)
6795 rv = VNET_API_ERROR_SAME_SRC_DST;
6799 memset (a, 0, sizeof (*a));
6801 /* ip addresses sent in network byte order */
6802 clib_memcpy (&(a->src), mp->src_address, 4);
6803 clib_memcpy (&(a->dst), mp->dst_address, 4);
6804 a->is_add = mp->is_add;
6805 a->lsa = ntohl (mp->local_sa_id);
6806 a->rsa = ntohl (mp->remote_sa_id);
6808 rv = vnet_ipsec_gre_add_del_tunnel (a, &sw_if_index);
6812 REPLY_MACRO2(VL_API_GRE_ADD_DEL_TUNNEL_REPLY,
6814 rmp->sw_if_index = ntohl (sw_if_index);
6819 static void send_ipsec_gre_tunnel_details
6820 (ipsec_gre_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
6822 vl_api_ipsec_gre_tunnel_details_t *rmp;
6824 rmp = vl_msg_api_alloc (sizeof (*rmp));
6825 memset (rmp, 0, sizeof (*rmp));
6826 rmp->_vl_msg_id = ntohs (VL_API_IPSEC_GRE_TUNNEL_DETAILS);
6827 clib_memcpy (rmp->src_address, &(t->tunnel_src), 4);
6828 clib_memcpy (rmp->dst_address, &(t->tunnel_dst), 4);
6829 rmp->sw_if_index = htonl (t->sw_if_index);
6830 rmp->local_sa_id = htonl (t->local_sa_id);
6831 rmp->remote_sa_id = htonl (t->remote_sa_id);
6832 rmp->context = context;
6834 vl_msg_api_send_shmem (q, (u8 *) & rmp);
6837 static void vl_api_ipsec_gre_tunnel_dump_t_handler
6838 (vl_api_ipsec_gre_tunnel_dump_t * mp)
6840 unix_shared_memory_queue_t *q;
6841 ipsec_gre_main_t *igm = &ipsec_gre_main;
6842 ipsec_gre_tunnel_t *t;
6845 q = vl_api_client_index_to_input_queue (mp->client_index);
6851 sw_if_index = ntohl (mp->sw_if_index);
6853 if (~0 == sw_if_index)
6856 pool_foreach (t, igm->tunnels,
6858 send_ipsec_gre_tunnel_details(t, q, mp->context);
6864 if ((sw_if_index >= vec_len (igm->tunnel_index_by_sw_if_index)) ||
6865 (~0 == igm->tunnel_index_by_sw_if_index[sw_if_index]))
6869 t = &igm->tunnels[igm->tunnel_index_by_sw_if_index[sw_if_index]];
6870 send_ipsec_gre_tunnel_details (t, q, mp->context);
6875 vl_api_delete_subif_t_handler (vl_api_delete_subif_t * mp)
6877 vl_api_delete_subif_reply_t *rmp;
6880 rv = vnet_delete_sub_interface (ntohl (mp->sw_if_index));
6882 REPLY_MACRO (VL_API_DELETE_SUBIF_REPLY);
6886 vl_api_l2_interface_pbb_tag_rewrite_t_handler
6887 (vl_api_l2_interface_pbb_tag_rewrite_t * mp)
6889 vl_api_l2_interface_pbb_tag_rewrite_reply_t *rmp;
6890 vnet_main_t *vnm = vnet_get_main ();
6891 vlib_main_t *vm = vlib_get_main ();
6895 VALIDATE_SW_IF_INDEX (mp);
6897 vtr_op = ntohl (mp->vtr_op);
6901 case L2_VTR_DISABLED:
6904 case L2_VTR_TRANSLATE_2_1:
6908 rv = VNET_API_ERROR_INVALID_VALUE;
6909 goto bad_sw_if_index;
6912 rv = l2pbb_configure (vm, vnm, ntohl (mp->sw_if_index), vtr_op,
6913 mp->b_dmac, mp->b_smac, ntohs (mp->b_vlanid),
6914 ntohl (mp->i_sid), ntohs (mp->outer_tag));
6916 BAD_SW_IF_INDEX_LABEL;
6918 REPLY_MACRO (VL_API_L2_INTERFACE_PBB_TAG_REWRITE_REPLY);
6922 vl_api_punt_t_handler (vl_api_punt_t * mp)
6924 vl_api_punt_reply_t *rmp;
6925 vlib_main_t *vm = vlib_get_main ();
6927 clib_error_t *error;
6929 error = vnet_punt_add_del (vm, mp->ipv, mp->l4_protocol,
6930 ntohs (mp->l4_port), mp->is_add);
6934 clib_error_report (error);
6937 REPLY_MACRO (VL_API_PUNT_REPLY);
6941 vl_api_flow_classify_set_interface_t_handler
6942 (vl_api_flow_classify_set_interface_t * mp)
6944 vlib_main_t *vm = vlib_get_main ();
6945 vl_api_flow_classify_set_interface_reply_t *rmp;
6947 u32 sw_if_index, ip4_table_index, ip6_table_index;
6949 ip4_table_index = ntohl (mp->ip4_table_index);
6950 ip6_table_index = ntohl (mp->ip6_table_index);
6951 sw_if_index = ntohl (mp->sw_if_index);
6953 VALIDATE_SW_IF_INDEX (mp);
6955 rv = vnet_set_flow_classify_intfc (vm, sw_if_index, ip4_table_index,
6956 ip6_table_index, mp->is_add);
6958 BAD_SW_IF_INDEX_LABEL;
6960 REPLY_MACRO (VL_API_FLOW_CLASSIFY_SET_INTERFACE_REPLY);
6964 send_flow_classify_details (u32 sw_if_index,
6966 unix_shared_memory_queue_t * q, u32 context)
6968 vl_api_flow_classify_details_t *mp;
6970 mp = vl_msg_api_alloc (sizeof (*mp));
6971 memset (mp, 0, sizeof (*mp));
6972 mp->_vl_msg_id = ntohs (VL_API_FLOW_CLASSIFY_DETAILS);
6973 mp->context = context;
6974 mp->sw_if_index = htonl (sw_if_index);
6975 mp->table_index = htonl (table_index);
6977 vl_msg_api_send_shmem (q, (u8 *) & mp);
6981 vl_api_flow_classify_dump_t_handler (vl_api_flow_classify_dump_t * mp)
6983 unix_shared_memory_queue_t *q;
6984 flow_classify_main_t *pcm = &flow_classify_main;
6988 q = vl_api_client_index_to_input_queue (mp->client_index);
6992 vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type];
6994 if (vec_len (vec_tbl))
6996 for (i = 0; i < vec_len (vec_tbl); i++)
6998 if (vec_elt (vec_tbl, i) == ~0)
7001 send_flow_classify_details (i, vec_elt (vec_tbl, i), q,
7008 send_ipsec_spd_details (ipsec_policy_t * p, unix_shared_memory_queue_t * q,
7011 vl_api_ipsec_spd_details_t *mp;
7013 mp = vl_msg_api_alloc (sizeof (*mp));
7014 memset (mp, 0, sizeof (*mp));
7015 mp->_vl_msg_id = ntohs (VL_API_IPSEC_SPD_DETAILS);
7016 mp->context = context;
7018 mp->spd_id = htonl (p->id);
7019 mp->priority = htonl (p->priority);
7020 mp->is_outbound = p->is_outbound;
7021 mp->is_ipv6 = p->is_ipv6;
7024 memcpy (mp->local_start_addr, &p->laddr.start.ip6, 16);
7025 memcpy (mp->local_stop_addr, &p->laddr.stop.ip6, 16);
7026 memcpy (mp->remote_start_addr, &p->raddr.start.ip6, 16);
7027 memcpy (mp->remote_stop_addr, &p->raddr.stop.ip6, 16);
7031 memcpy (mp->local_start_addr, &p->laddr.start.ip4, 4);
7032 memcpy (mp->local_stop_addr, &p->laddr.stop.ip4, 4);
7033 memcpy (mp->remote_start_addr, &p->raddr.start.ip4, 4);
7034 memcpy (mp->remote_stop_addr, &p->raddr.stop.ip4, 4);
7036 mp->local_start_port = htons (p->lport.start);
7037 mp->local_stop_port = htons (p->lport.stop);
7038 mp->remote_start_port = htons (p->rport.start);
7039 mp->remote_stop_port = htons (p->rport.stop);
7040 mp->protocol = p->protocol;
7041 mp->policy = p->policy;
7042 mp->sa_id = htonl (p->sa_id);
7043 mp->bytes = clib_host_to_net_u64 (p->counter.bytes);
7044 mp->packets = clib_host_to_net_u64 (p->counter.packets);
7046 vl_msg_api_send_shmem (q, (u8 *) & mp);
7050 vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp)
7052 unix_shared_memory_queue_t *q;
7053 ipsec_main_t *im = &ipsec_main;
7054 ipsec_policy_t *policy;
7059 q = vl_api_client_index_to_input_queue (mp->client_index);
7063 p = hash_get (im->spd_index_by_spd_id, ntohl (mp->spd_id));
7068 spd = pool_elt_at_index (im->spds, spd_index);
7071 pool_foreach (policy, spd->policies,
7073 if (mp->sa_id == ~(0) || ntohl (mp->sa_id) == policy->sa_id)
7074 send_ipsec_spd_details (policy, q,
7079 clib_warning ("unimplemented");
7084 vl_api_feature_enable_disable_t_handler (vl_api_feature_enable_disable_t * mp)
7086 vl_api_feature_enable_disable_reply_t *rmp;
7088 u8 *arc_name, *feature_name;
7090 VALIDATE_SW_IF_INDEX (mp);
7092 arc_name = format (0, "%s%c", mp->arc_name, 0);
7093 feature_name = format (0, "%s%c", mp->feature_name, 0);
7095 vnet_feature_registration_t *reg;
7097 vnet_get_feature_reg ((const char *) arc_name,
7098 (const char *) feature_name);
7100 rv = VNET_API_ERROR_INVALID_VALUE;
7104 clib_error_t *error = 0;
7106 sw_if_index = ntohl (mp->sw_if_index);
7107 if (reg->enable_disable_cb)
7108 error = reg->enable_disable_cb (sw_if_index, mp->enable);
7110 vnet_feature_enable_disable ((const char *) arc_name,
7111 (const char *) feature_name,
7112 sw_if_index, mp->enable, 0, 0);
7115 clib_error_report (error);
7116 rv = VNET_API_ERROR_CANNOT_ENABLE_DISABLE_FEATURE;
7120 vec_free (feature_name);
7121 vec_free (arc_name);
7123 BAD_SW_IF_INDEX_LABEL;
7125 REPLY_MACRO (VL_API_FEATURE_ENABLE_DISABLE_REPLY);
7128 #define BOUNCE_HANDLER(nn) \
7129 static void vl_api_##nn##_t_handler ( \
7130 vl_api_##nn##_t *mp) \
7132 vpe_client_registration_t *reg; \
7133 vpe_api_main_t * vam = &vpe_api_main; \
7134 unix_shared_memory_queue_t * q; \
7136 /* One registration only... */ \
7137 pool_foreach(reg, vam->nn##_registrations, \
7139 q = vl_api_client_index_to_input_queue (reg->client_index); \
7142 * If the queue is stuffed, turf the msg and complain \
7143 * It's unlikely that the intended recipient is \
7144 * alive; avoid deadlock at all costs. \
7146 if (q->cursize == q->maxsize) { \
7147 clib_warning ("ERROR: receiver queue full, drop msg"); \
7148 vl_msg_api_free (mp); \
7151 vl_msg_api_send_shmem (q, (u8 *)&mp); \
7155 vl_msg_api_free (mp); \
7158 static void setup_message_id_table (api_main_t * am);
7162 * Add vpe's API message handlers to the table.
7163 * vlib has alread mapped shared memory and
7164 * added the client registration handlers.
7165 * See .../open-repo/vlib/memclnt_vlib.c:memclnt_process()
7167 static clib_error_t *
7168 vpe_api_hookup (vlib_main_t * vm)
7170 api_main_t *am = &api_main;
7173 vl_msg_api_set_handlers(VL_API_##N, #n, \
7174 vl_api_##n##_t_handler, \
7176 vl_api_##n##_t_endian, \
7177 vl_api_##n##_t_print, \
7178 sizeof(vl_api_##n##_t), 1);
7179 foreach_vpe_api_msg;
7183 * Manually register the sr tunnel add del msg, so we trace
7184 * enough bytes to capture a typical segment list
7186 vl_msg_api_set_handlers (VL_API_SR_TUNNEL_ADD_DEL,
7187 "sr_tunnel_add_del",
7188 vl_api_sr_tunnel_add_del_t_handler,
7190 vl_api_sr_tunnel_add_del_t_endian,
7191 vl_api_sr_tunnel_add_del_t_print, 256, 1);
7195 * Manually register the sr policy add del msg, so we trace
7196 * enough bytes to capture a typical tunnel name list
7198 vl_msg_api_set_handlers (VL_API_SR_POLICY_ADD_DEL,
7199 "sr_policy_add_del",
7200 vl_api_sr_policy_add_del_t_handler,
7202 vl_api_sr_policy_add_del_t_endian,
7203 vl_api_sr_policy_add_del_t_print, 256, 1);
7206 * Trace space for 8 MPLS encap labels, classifier mask+match
7208 am->api_trace_cfg[VL_API_MPLS_TUNNEL_ADD_DEL].size += 8 * sizeof (u32);
7209 am->api_trace_cfg[VL_API_CLASSIFY_ADD_DEL_TABLE].size += 5 * sizeof (u32x4);
7210 am->api_trace_cfg[VL_API_CLASSIFY_ADD_DEL_SESSION].size
7211 += 5 * sizeof (u32x4);
7212 am->api_trace_cfg[VL_API_VXLAN_ADD_DEL_TUNNEL].size += 16 * sizeof (u32);
7215 * Thread-safe API messages
7217 am->is_mp_safe[VL_API_IP_ADD_DEL_ROUTE] = 1;
7218 am->is_mp_safe[VL_API_GET_NODE_GRAPH] = 1;
7221 * Set up the (msg_name, crc, message-id) table
7223 setup_message_id_table (am);
7228 VLIB_API_INIT_FUNCTION (vpe_api_hookup);
7230 static clib_error_t *
7231 vpe_api_init (vlib_main_t * vm)
7233 vpe_api_main_t *am = &vpe_api_main;
7236 am->vnet_main = vnet_get_main ();
7237 am->interface_events_registration_hash = hash_create (0, sizeof (uword));
7238 am->to_netconf_server_registration_hash = hash_create (0, sizeof (uword));
7239 am->from_netconf_server_registration_hash = hash_create (0, sizeof (uword));
7240 am->to_netconf_client_registration_hash = hash_create (0, sizeof (uword));
7241 am->from_netconf_client_registration_hash = hash_create (0, sizeof (uword));
7242 am->oam_events_registration_hash = hash_create (0, sizeof (uword));
7245 vl_set_memory_region_name ("/vpe-api");
7246 vl_enable_disable_memory_api (vm, 1 /* enable it */ );
7251 VLIB_INIT_FUNCTION (vpe_api_init);
7254 static clib_error_t *
7255 api_segment_config (vlib_main_t * vm, unformat_input_t * input)
7258 u64 baseva, size, pvt_heap_size;
7260 const int max_buf_size = 4096;
7262 struct passwd _pw, *pw;
7263 struct group _grp, *grp;
7265 buf = vec_new (char, 128);
7266 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7268 if (unformat (input, "prefix %s", &chroot_path))
7270 vec_add1 (chroot_path, 0);
7271 vl_set_memory_root_path ((char *) chroot_path);
7273 else if (unformat (input, "uid %d", &uid))
7274 vl_set_memory_uid (uid);
7275 else if (unformat (input, "gid %d", &gid))
7276 vl_set_memory_gid (gid);
7277 else if (unformat (input, "baseva %llx", &baseva))
7278 vl_set_global_memory_baseva (baseva);
7279 else if (unformat (input, "global-size %lldM", &size))
7280 vl_set_global_memory_size (size * (1ULL << 20));
7281 else if (unformat (input, "global-size %lldG", &size))
7282 vl_set_global_memory_size (size * (1ULL << 30));
7283 else if (unformat (input, "global-size %lld", &size))
7284 vl_set_global_memory_size (size);
7285 else if (unformat (input, "global-pvt-heap-size %lldM", &pvt_heap_size))
7286 vl_set_global_pvt_heap_size (pvt_heap_size * (1ULL << 20));
7287 else if (unformat (input, "global-pvt-heap-size size %lld",
7289 vl_set_global_pvt_heap_size (pvt_heap_size);
7290 else if (unformat (input, "api-pvt-heap-size %lldM", &pvt_heap_size))
7291 vl_set_api_pvt_heap_size (pvt_heap_size * (1ULL << 20));
7292 else if (unformat (input, "api-pvt-heap-size size %lld",
7294 vl_set_api_pvt_heap_size (pvt_heap_size);
7295 else if (unformat (input, "api-size %lldM", &size))
7296 vl_set_api_memory_size (size * (1ULL << 20));
7297 else if (unformat (input, "api-size %lldG", &size))
7298 vl_set_api_memory_size (size * (1ULL << 30));
7299 else if (unformat (input, "api-size %lld", &size))
7300 vl_set_api_memory_size (size);
7301 else if (unformat (input, "uid %s", &s))
7303 /* lookup the username */
7306 getpwnam_r (s, &_pw, buf, vec_len (buf), &pw)) == ERANGE)
7307 && (vec_len (buf) <= max_buf_size))
7309 vec_resize (buf, vec_len (buf) * 2);
7313 e = clib_error_return_code (0, rv,
7314 CLIB_ERROR_ERRNO_VALID |
7316 "cannot fetch username %s", s);
7324 clib_error_return_fatal (0, "username %s does not exist", s);
7330 vl_set_memory_uid (pw->pw_uid);
7332 else if (unformat (input, "gid %s", &s))
7334 /* lookup the group name */
7337 getgrnam_r (s, &_grp, buf, vec_len (buf), &grp)) == ERANGE)
7338 && (vec_len (buf) <= max_buf_size))
7340 vec_resize (buf, vec_len (buf) * 2);
7344 e = clib_error_return_code (0, rv,
7345 CLIB_ERROR_ERRNO_VALID |
7347 "cannot fetch group %s", s);
7354 e = clib_error_return_fatal (0, "group %s does not exist", s);
7361 vl_set_memory_gid (grp->gr_gid);
7364 return clib_error_return (0, "unknown input `%U'",
7365 format_unformat_error, input);
7370 VLIB_EARLY_CONFIG_FUNCTION (api_segment_config, "api-segment");
7373 get_unformat_vnet_sw_interface (void)
7375 return (void *) &unformat_vnet_sw_interface;
7379 format_arp_event (u8 * s, va_list * args)
7381 vl_api_ip4_arp_event_t *event = va_arg (*args, vl_api_ip4_arp_event_t *);
7383 s = format (s, "pid %d: ", event->pid);
7385 s = format (s, "bd mac/ip4 binding events");
7387 s = format (s, "resolution for %U", format_ip4_address, &event->address);
7392 format_nd_event (u8 * s, va_list * args)
7394 vl_api_ip6_nd_event_t *event = va_arg (*args, vl_api_ip6_nd_event_t *);
7396 s = format (s, "pid %d: ", event->pid);
7398 s = format (s, "bd mac/ip6 binding events");
7400 s = format (s, "resolution for %U", format_ip6_address, event->address);
7404 static clib_error_t *
7405 show_ip_arp_nd_events_fn (vlib_main_t * vm,
7406 unformat_input_t * input, vlib_cli_command_t * cmd)
7408 vpe_api_main_t *am = &vpe_api_main;
7409 vl_api_ip4_arp_event_t *arp_event;
7410 vl_api_ip6_nd_event_t *nd_event;
7412 if ((pool_elts (am->arp_events) == 0) && (pool_elts (am->nd_events) == 0))
7414 vlib_cli_output (vm, "No active arp or nd event registrations");
7419 pool_foreach (arp_event, am->arp_events,
7421 vlib_cli_output (vm, "%U", format_arp_event, arp_event);
7424 pool_foreach (nd_event, am->nd_events,
7426 vlib_cli_output (vm, "%U", format_nd_event, nd_event);
7434 VLIB_CLI_COMMAND (show_ip_arp_nd_events, static) = {
7435 .path = "show arp-nd-event registrations",
7436 .function = show_ip_arp_nd_events_fn,
7437 .short_help = "Show ip4 arp and ip6 nd event registrations",
7441 #define vl_msg_name_crc_list
7442 #include <vpp-api/vpe_all_api_h.h>
7443 #undef vl_msg_name_crc_list
7446 setup_message_id_table (api_main_t * am)
7448 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
7449 foreach_vl_msg_name_crc_memclnt;
7450 foreach_vl_msg_name_crc_vpe;
7456 * fd.io coding-style-patch-verification: ON
7459 * eval: (c-set-style "gnu")