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/ip/ip.h>
53 #include <vnet/ip/ip6.h>
54 #include <vnet/ip/ip6_neighbor.h>
55 #include <vnet/mpls/mpls.h>
56 #include <vnet/mpls/mpls_tunnel.h>
57 #include <vnet/dhcp/proxy.h>
58 #include <vnet/dhcp/client.h>
60 #include <vnet/sr/sr.h>
62 #include <vnet/dhcpv6/proxy.h>
63 #include <vlib/vlib.h>
64 #include <vlib/unix/unix.h>
65 #include <vlibapi/api.h>
66 #include <vlibmemory/api.h>
67 #include <vnet/classify/vnet_classify.h>
68 #include <vnet/classify/input_acl.h>
69 #include <vnet/classify/policer_classify.h>
70 #include <vnet/classify/flow_classify.h>
71 #include <vnet/l2/l2_classify.h>
72 #include <vnet/vxlan/vxlan.h>
73 #include <vnet/l2/l2_vtr.h>
74 #include <vnet/vxlan-gpe/vxlan_gpe.h>
75 #include <vnet/map/map.h>
76 #include <vnet/cop/cop.h>
77 #include <vnet/ip/ip6_hop_by_hop.h>
78 #include <vnet/ip/ip_source_and_port_range_check.h>
79 #include <vnet/policer/policer.h>
80 #include <vnet/flow/flow_report.h>
81 #include <vnet/flow/flow_report_classify.h>
82 #include <vnet/ip/punt.h>
83 #include <vnet/feature/feature.h>
86 #undef __included_bihash_template_h__
87 #include <vnet/l2/l2_fib.h>
89 #include <vpp/stats/stats.h>
90 #include <vpp/oam/oam.h>
92 #include <vnet/ethernet/ethernet.h>
93 #include <vnet/ethernet/arp_packet.h>
94 #include <vnet/interface.h>
95 #include <vnet/l2/l2_fib.h>
96 #include <vnet/l2/l2_bd.h>
97 #include <vpp/api/vpe_msg_enum.h>
98 #include <vnet/span/span.h>
99 #include <vnet/fib/ip6_fib.h>
100 #include <vnet/fib/ip4_fib.h>
101 #include <vnet/fib/fib_api.h>
102 #include <vnet/dpo/drop_dpo.h>
103 #include <vnet/dpo/receive_dpo.h>
104 #include <vnet/dpo/lookup_dpo.h>
105 #include <vnet/dpo/classify_dpo.h>
106 #include <vnet/dpo/ip_null_dpo.h>
107 #define vl_typedefs /* define message structures */
108 #include <vpp/api/vpe_all_api_h.h>
110 #define vl_endianfun /* define message structures */
111 #include <vpp/api/vpe_all_api_h.h>
113 /* instantiate all the print functions we know about */
114 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
116 #include <vpp/api/vpe_all_api_h.h>
118 #include <vlibapi/api_helper_macros.h>
119 #define foreach_vpe_api_msg \
120 _(WANT_OAM_EVENTS, want_oam_events) \
121 _(OAM_ADD_DEL, oam_add_del) \
122 _(MPLS_ROUTE_ADD_DEL, mpls_route_add_del) \
123 _(MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind) \
124 _(IS_ADDRESS_REACHABLE, is_address_reachable) \
125 _(SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable) \
126 _(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath) \
127 _(SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass) \
128 _(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect) \
129 _(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge) \
130 _(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del) \
131 _(BRIDGE_DOMAIN_DUMP, bridge_domain_dump) \
132 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
133 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
134 _(L2FIB_ADD_DEL, l2fib_add_del) \
135 _(L2_FLAGS, l2_flags) \
136 _(BRIDGE_FLAGS, bridge_flags) \
137 _(CREATE_VLAN_SUBIF, create_vlan_subif) \
138 _(CREATE_SUBIF, create_subif) \
139 _(MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del) \
140 _(PROXY_ARP_ADD_DEL, proxy_arp_add_del) \
141 _(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable) \
142 _(VNET_GET_SUMMARY_STATS, vnet_get_summary_stats) \
143 _(RESET_FIB, reset_fib) \
144 _(DHCP_PROXY_CONFIG,dhcp_proxy_config) \
145 _(DHCP_PROXY_CONFIG_2,dhcp_proxy_config_2) \
146 _(DHCP_PROXY_SET_VSS,dhcp_proxy_set_vss) \
147 _(DHCP_CLIENT_CONFIG, dhcp_client_config) \
148 _(CREATE_LOOPBACK, create_loopback) \
149 _(CONTROL_PING, control_ping) \
150 _(CLI_REQUEST, cli_request) \
151 _(CLI_INBAND, cli_inband) \
152 _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \
153 _(L2_PATCH_ADD_DEL, l2_patch_add_del) \
154 _(CLASSIFY_ADD_DEL_TABLE, classify_add_del_table) \
155 _(CLASSIFY_ADD_DEL_SESSION, classify_add_del_session) \
156 _(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table) \
157 _(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables) \
158 _(GET_NODE_INDEX, get_node_index) \
159 _(ADD_NODE_NEXT, add_node_next) \
160 _(VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel) \
161 _(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump) \
162 _(L2_FIB_CLEAR_TABLE, l2_fib_clear_table) \
163 _(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter) \
164 _(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite) \
165 _(SHOW_VERSION, show_version) \
166 _(L2_FIB_TABLE_DUMP, l2_fib_table_dump) \
167 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
168 _(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel) \
169 _(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump) \
170 _(INTERFACE_NAME_RENUMBER, interface_name_renumber) \
171 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events) \
172 _(WANT_IP6_ND_EVENTS, want_ip6_nd_events) \
173 _(INPUT_ACL_SET_INTERFACE, input_acl_set_interface) \
174 _(DELETE_LOOPBACK, delete_loopback) \
175 _(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del) \
176 _(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable) \
177 _(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable) \
178 _(GET_NODE_GRAPH, get_node_graph) \
179 _(IOAM_ENABLE, ioam_enable) \
180 _(IOAM_DISABLE, ioam_disable) \
181 _(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del) \
182 _(POLICER_ADD_DEL, policer_add_del) \
183 _(POLICER_DUMP, policer_dump) \
184 _(POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface) \
185 _(POLICER_CLASSIFY_DUMP, policer_classify_dump) \
186 _(MPLS_TUNNEL_DUMP, mpls_tunnel_dump) \
187 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details) \
188 _(MPLS_FIB_DUMP, mpls_fib_dump) \
189 _(MPLS_FIB_DETAILS, mpls_fib_details) \
190 _(CLASSIFY_TABLE_IDS,classify_table_ids) \
191 _(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface) \
192 _(CLASSIFY_TABLE_INFO,classify_table_info) \
193 _(CLASSIFY_SESSION_DUMP,classify_session_dump) \
194 _(CLASSIFY_SESSION_DETAILS,classify_session_details) \
195 _(SET_IPFIX_EXPORTER, set_ipfix_exporter) \
196 _(IPFIX_EXPORTER_DUMP, ipfix_exporter_dump) \
197 _(SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream) \
198 _(IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump) \
199 _(IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del) \
200 _(IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump) \
201 _(GET_NEXT_INDEX, get_next_index) \
202 _(PG_CREATE_INTERFACE, pg_create_interface) \
203 _(PG_CAPTURE, pg_capture) \
204 _(PG_ENABLE_DISABLE, pg_enable_disable) \
205 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \
206 ip_source_and_port_range_check_add_del) \
207 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \
208 ip_source_and_port_range_check_interface_add_del) \
209 _(DELETE_SUBIF, delete_subif) \
210 _(L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite) \
212 _(FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface) \
213 _(FLOW_CLASSIFY_DUMP, flow_classify_dump) \
214 _(FEATURE_ENABLE_DISABLE, feature_enable_disable)
217 #define QUOTE(x) QUOTE_(x)
220 RESOLVE_IP4_ADD_DEL_ROUTE = 1,
221 RESOLVE_IP6_ADD_DEL_ROUTE,
224 static vlib_node_registration_t vpe_resolver_process_node;
225 vpe_api_main_t vpe_api_main;
227 static int arp_change_delete_callback (u32 pool_index, u8 * notused);
228 static int nd_change_delete_callback (u32 pool_index, u8 * notused);
230 /* Clean up all registrations belonging to the indicated client */
232 vl_api_memclnt_delete_callback (u32 client_index)
234 vpe_api_main_t *vam = &vpe_api_main;
235 vpe_client_registration_t *rp;
237 int stats_memclnt_delete_callback (u32 client_index);
239 stats_memclnt_delete_callback (client_index);
242 p = hash_get (vam->a##_registration_hash, client_index); \
244 rp = pool_elt_at_index (vam->a##_registrations, p[0]); \
245 pool_put (vam->a##_registrations, rp); \
246 hash_unset (vam->a##_registration_hash, client_index); \
248 foreach_registration_hash;
253 pub_sub_handler (oam_events, OAM_EVENTS);
255 #define RESOLUTION_EVENT 1
256 #define RESOLUTION_PENDING_EVENT 2
257 #define IP4_ARP_EVENT 3
258 #define IP6_ND_EVENT 4
260 int ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
262 int ip6_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp);
265 handle_ip4_arp_event (u32 pool_index)
267 vpe_api_main_t *vam = &vpe_api_main;
268 vnet_main_t *vnm = vam->vnet_main;
269 vlib_main_t *vm = vam->vlib_main;
270 vl_api_ip4_arp_event_t *event;
271 vl_api_ip4_arp_event_t *mp;
272 unix_shared_memory_queue_t *q;
274 /* Client can cancel, die, etc. */
275 if (pool_is_free_index (vam->arp_events, pool_index))
278 event = pool_elt_at_index (vam->arp_events, pool_index);
280 q = vl_api_client_index_to_input_queue (event->client_index);
283 (void) vnet_add_del_ip4_arp_change_event
284 (vnm, arp_change_delete_callback,
285 event->pid, &event->address,
286 vpe_resolver_process_node.index, IP4_ARP_EVENT,
287 ~0 /* pool index, notused */ , 0 /* is_add */ );
291 if (q->cursize < q->maxsize)
293 mp = vl_msg_api_alloc (sizeof (*mp));
294 clib_memcpy (mp, event, sizeof (*mp));
295 vl_msg_api_send_shmem (q, (u8 *) & mp);
299 static f64 last_time;
301 * Throttle syslog msgs.
302 * It's pretty tempting to just revoke the registration...
304 if (vlib_time_now (vm) > last_time + 10.0)
306 clib_warning ("arp event for %U to pid %d: queue stuffed!",
307 format_ip4_address, &event->address, event->pid);
308 last_time = vlib_time_now (vm);
314 handle_ip6_nd_event (u32 pool_index)
316 vpe_api_main_t *vam = &vpe_api_main;
317 vnet_main_t *vnm = vam->vnet_main;
318 vlib_main_t *vm = vam->vlib_main;
319 vl_api_ip6_nd_event_t *event;
320 vl_api_ip6_nd_event_t *mp;
321 unix_shared_memory_queue_t *q;
323 /* Client can cancel, die, etc. */
324 if (pool_is_free_index (vam->nd_events, pool_index))
327 event = pool_elt_at_index (vam->nd_events, pool_index);
329 q = vl_api_client_index_to_input_queue (event->client_index);
332 (void) vnet_add_del_ip6_nd_change_event
333 (vnm, nd_change_delete_callback,
334 event->pid, &event->address,
335 vpe_resolver_process_node.index, IP6_ND_EVENT,
336 ~0 /* pool index, notused */ , 0 /* is_add */ );
340 if (q->cursize < q->maxsize)
342 mp = vl_msg_api_alloc (sizeof (*mp));
343 clib_memcpy (mp, event, sizeof (*mp));
344 vl_msg_api_send_shmem (q, (u8 *) & mp);
348 static f64 last_time;
350 * Throttle syslog msgs.
351 * It's pretty tempting to just revoke the registration...
353 if (vlib_time_now (vm) > last_time + 10.0)
355 clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
356 format_ip6_address, &event->address, event->pid);
357 last_time = vlib_time_now (vm);
363 resolver_process (vlib_main_t * vm,
364 vlib_node_runtime_t * rt, vlib_frame_t * f)
367 uword *event_data = 0;
373 vlib_process_wait_for_event_or_clock (vm, timeout);
375 event_type = vlib_process_get_events (vm, &event_data);
379 case RESOLUTION_PENDING_EVENT:
383 case RESOLUTION_EVENT:
384 clib_warning ("resolver: BOGUS TYPE");
388 for (i = 0; i < vec_len (event_data); i++)
389 handle_ip4_arp_event (event_data[i]);
393 for (i = 0; i < vec_len (event_data); i++)
394 handle_ip6_nd_event (event_data[i]);
397 case ~0: /* timeout */
401 vec_reset_length (event_data);
403 return 0; /* or not */
407 VLIB_REGISTER_NODE (vpe_resolver_process_node,static) = {
408 .function = resolver_process,
409 .type = VLIB_NODE_TYPE_PROCESS,
410 .name = "vpe-route-resolver-process",
415 mpls_route_add_del_t_handler (vnet_main_t * vnm,
416 vl_api_mpls_route_add_del_t * mp)
418 u32 fib_index, next_hop_fib_index;
419 mpls_label_t *label_stack = NULL;
420 int rv, ii, n_labels;;
424 .fp_proto = FIB_PROTOCOL_MPLS,
425 .fp_eos = mp->mr_eos,
426 .fp_label = ntohl (mp->mr_label),
430 if (mp->mr_next_hop_proto_is_ip4)
432 pfx.fp_payload_proto = DPO_PROTO_IP4;
436 pfx.fp_payload_proto = DPO_PROTO_IP6;
441 pfx.fp_payload_proto = DPO_PROTO_MPLS;
444 rv = add_del_route_check (FIB_PROTOCOL_MPLS,
446 mp->mr_next_hop_sw_if_index,
447 dpo_proto_to_fib (pfx.fp_payload_proto),
448 mp->mr_next_hop_table_id,
449 mp->mr_create_table_if_needed,
450 &fib_index, &next_hop_fib_index);
456 memset (&nh, 0, sizeof (nh));
458 if (mp->mr_next_hop_proto_is_ip4)
459 memcpy (&nh.ip4, mp->mr_next_hop, sizeof (nh.ip4));
461 memcpy (&nh.ip6, mp->mr_next_hop, sizeof (nh.ip6));
463 n_labels = mp->mr_next_hop_n_out_labels;
466 else if (1 == n_labels)
467 vec_add1 (label_stack, ntohl (mp->mr_next_hop_out_label_stack[0]));
470 vec_validate (label_stack, n_labels - 1);
471 for (ii = 0; ii < n_labels; ii++)
472 label_stack[ii] = ntohl (mp->mr_next_hop_out_label_stack[ii]);
475 return (add_del_route_t_handler (mp->mr_is_multipath, mp->mr_is_add, 0, // mp->is_drop,
476 0, // mp->is_unreach,
477 0, // mp->is_prohibit,
480 mp->mr_classify_table_index,
481 mp->mr_is_resolve_host,
482 mp->mr_is_resolve_attached,
484 mp->mr_next_hop_proto_is_ip4,
485 &nh, ntohl (mp->mr_next_hop_sw_if_index),
487 mp->mr_next_hop_weight,
488 ntohl (mp->mr_next_hop_via_label),
493 vl_api_mpls_route_add_del_t_handler (vl_api_mpls_route_add_del_t * mp)
495 vl_api_mpls_route_add_del_reply_t *rmp;
499 vnm = vnet_get_main ();
502 rv = mpls_route_add_del_t_handler (vnm, mp);
504 rv = (rv == 0) ? vnm->api_errno : rv;
506 REPLY_MACRO (VL_API_MPLS_ROUTE_ADD_DEL_REPLY);
510 mpls_ip_bind_unbind_handler (vnet_main_t * vnm,
511 vl_api_mpls_ip_bind_unbind_t * mp)
513 u32 mpls_fib_index, ip_fib_index;
516 fib_table_find (FIB_PROTOCOL_MPLS, ntohl (mp->mb_mpls_table_id));
518 if (~0 == mpls_fib_index)
520 if (mp->mb_create_table_if_needed)
523 fib_table_find_or_create_and_lock (FIB_PROTOCOL_MPLS,
524 ntohl (mp->mb_mpls_table_id));
527 return VNET_API_ERROR_NO_SUCH_FIB;
530 ip_fib_index = fib_table_find ((mp->mb_is_ip4 ?
533 ntohl (mp->mb_ip_table_id));
534 if (~0 == ip_fib_index)
535 return VNET_API_ERROR_NO_SUCH_FIB;
538 .fp_len = mp->mb_address_length,
543 pfx.fp_proto = FIB_PROTOCOL_IP4;
544 clib_memcpy (&pfx.fp_addr.ip4, mp->mb_address,
545 sizeof (pfx.fp_addr.ip4));
549 pfx.fp_proto = FIB_PROTOCOL_IP6;
550 clib_memcpy (&pfx.fp_addr.ip6, mp->mb_address,
551 sizeof (pfx.fp_addr.ip6));
555 fib_table_entry_local_label_add (ip_fib_index, &pfx,
556 ntohl (mp->mb_label));
558 fib_table_entry_local_label_remove (ip_fib_index, &pfx,
559 ntohl (mp->mb_label));
565 vl_api_mpls_ip_bind_unbind_t_handler (vl_api_mpls_ip_bind_unbind_t * mp)
567 vl_api_mpls_route_add_del_reply_t *rmp;
571 vnm = vnet_get_main ();
574 rv = mpls_ip_bind_unbind_handler (vnm, mp);
576 rv = (rv == 0) ? vnm->api_errno : rv;
578 REPLY_MACRO (VL_API_MPLS_ROUTE_ADD_DEL_REPLY);
582 vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t * mp)
584 vl_api_sw_interface_set_vpath_reply_t *rmp;
586 u32 sw_if_index = ntohl (mp->sw_if_index);
588 VALIDATE_SW_IF_INDEX (mp);
590 l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_VPATH, mp->enable);
591 vnet_feature_enable_disable ("ip4-unicast", "vpath-input-ip4",
592 sw_if_index, mp->enable, 0, 0);
593 vnet_feature_enable_disable ("ip4-multicast", "vpath-input-ip4",
594 sw_if_index, mp->enable, 0, 0);
595 vnet_feature_enable_disable ("ip6-unicast", "vpath-input-ip6",
596 sw_if_index, mp->enable, 0, 0);
597 vnet_feature_enable_disable ("ip6-multicast", "vpath-input-ip6",
598 sw_if_index, mp->enable, 0, 0);
600 BAD_SW_IF_INDEX_LABEL;
602 REPLY_MACRO (VL_API_SW_INTERFACE_SET_VPATH_REPLY);
606 vl_api_sw_interface_set_vxlan_bypass_t_handler
607 (vl_api_sw_interface_set_vxlan_bypass_t * mp)
609 vl_api_sw_interface_set_vxlan_bypass_reply_t *rmp;
611 u32 sw_if_index = ntohl (mp->sw_if_index);
613 VALIDATE_SW_IF_INDEX (mp);
617 /* not yet implemented */
620 vnet_feature_enable_disable ("ip4-unicast", "ip4-vxlan-bypass",
621 sw_if_index, mp->enable, 0, 0);
623 BAD_SW_IF_INDEX_LABEL;
625 REPLY_MACRO (VL_API_SW_INTERFACE_SET_VXLAN_BYPASS_REPLY);
629 vl_api_sw_interface_set_l2_xconnect_t_handler
630 (vl_api_sw_interface_set_l2_xconnect_t * mp)
632 vl_api_sw_interface_set_l2_xconnect_reply_t *rmp;
634 u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
635 u32 tx_sw_if_index = ntohl (mp->tx_sw_if_index);
636 vlib_main_t *vm = vlib_get_main ();
637 vnet_main_t *vnm = vnet_get_main ();
639 VALIDATE_RX_SW_IF_INDEX (mp);
643 VALIDATE_TX_SW_IF_INDEX (mp);
644 rv = set_int_l2_mode (vm, vnm, MODE_L2_XC,
645 rx_sw_if_index, 0, 0, 0, tx_sw_if_index);
649 rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
652 BAD_RX_SW_IF_INDEX_LABEL;
653 BAD_TX_SW_IF_INDEX_LABEL;
655 REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_XCONNECT_REPLY);
659 vl_api_sw_interface_set_l2_bridge_t_handler
660 (vl_api_sw_interface_set_l2_bridge_t * mp)
662 bd_main_t *bdm = &bd_main;
663 vl_api_sw_interface_set_l2_bridge_reply_t *rmp;
665 u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
666 u32 bd_id = ntohl (mp->bd_id);
670 vlib_main_t *vm = vlib_get_main ();
671 vnet_main_t *vnm = vnet_get_main ();
673 VALIDATE_RX_SW_IF_INDEX (mp);
675 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
679 //VALIDATE_TX_SW_IF_INDEX(mp);
680 rv = set_int_l2_mode (vm, vnm, MODE_L2_BRIDGE,
681 rx_sw_if_index, bd_index, bvi, shg, 0);
685 rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
688 BAD_RX_SW_IF_INDEX_LABEL;
690 REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_BRIDGE_REPLY);
694 vl_api_bridge_domain_add_del_t_handler (vl_api_bridge_domain_add_del_t * mp)
696 vlib_main_t *vm = vlib_get_main ();
697 bd_main_t *bdm = &bd_main;
698 vl_api_bridge_domain_add_del_reply_t *rmp;
700 u32 enable_flags = 0, disable_flags = 0;
701 u32 bd_id = ntohl (mp->bd_id);
706 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
709 enable_flags |= L2_FLOOD;
711 disable_flags |= L2_FLOOD;
714 enable_flags |= L2_UU_FLOOD;
716 disable_flags |= L2_UU_FLOOD;
719 enable_flags |= L2_FWD;
721 disable_flags |= L2_FWD;
724 enable_flags |= L2_ARP_TERM;
726 disable_flags |= L2_ARP_TERM;
729 enable_flags |= L2_LEARN;
731 disable_flags |= L2_LEARN;
734 bd_set_flags (vm, bd_index, enable_flags, 1 /* enable */ );
737 bd_set_flags (vm, bd_index, disable_flags, 0 /* disable */ );
739 bd_set_mac_age (vm, bd_index, mp->mac_age);
742 rv = bd_delete_bd_index (bdm, bd_id);
744 REPLY_MACRO (VL_API_BRIDGE_DOMAIN_ADD_DEL_REPLY);
748 vl_api_bridge_domain_details_t_handler (vl_api_bridge_domain_details_t * mp)
750 clib_warning ("BUG");
754 vl_api_bridge_domain_sw_if_details_t_handler
755 (vl_api_bridge_domain_sw_if_details_t * mp)
757 clib_warning ("BUG");
761 send_bridge_domain_details (unix_shared_memory_queue_t * q,
762 l2_bridge_domain_t * bd_config,
763 u32 n_sw_ifs, u32 context)
765 vl_api_bridge_domain_details_t *mp;
767 mp = vl_msg_api_alloc (sizeof (*mp));
768 memset (mp, 0, sizeof (*mp));
769 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_DETAILS);
770 mp->bd_id = ntohl (bd_config->bd_id);
771 mp->flood = bd_feature_flood (bd_config);
772 mp->uu_flood = bd_feature_uu_flood (bd_config);
773 mp->forward = bd_feature_forward (bd_config);
774 mp->learn = bd_feature_learn (bd_config);
775 mp->arp_term = bd_feature_arp_term (bd_config);
776 mp->bvi_sw_if_index = ntohl (bd_config->bvi_sw_if_index);
777 mp->mac_age = bd_config->mac_age;
778 mp->n_sw_ifs = ntohl (n_sw_ifs);
779 mp->context = context;
781 vl_msg_api_send_shmem (q, (u8 *) & mp);
785 send_bd_sw_if_details (l2input_main_t * l2im,
786 unix_shared_memory_queue_t * q,
787 l2_flood_member_t * member, u32 bd_id, u32 context)
789 vl_api_bridge_domain_sw_if_details_t *mp;
790 l2_input_config_t *input_cfg;
792 mp = vl_msg_api_alloc (sizeof (*mp));
793 memset (mp, 0, sizeof (*mp));
794 mp->_vl_msg_id = ntohs (VL_API_BRIDGE_DOMAIN_SW_IF_DETAILS);
795 mp->bd_id = ntohl (bd_id);
796 mp->sw_if_index = ntohl (member->sw_if_index);
797 input_cfg = vec_elt_at_index (l2im->configs, member->sw_if_index);
798 mp->shg = input_cfg->shg;
799 mp->context = context;
801 vl_msg_api_send_shmem (q, (u8 *) & mp);
805 vl_api_bridge_domain_dump_t_handler (vl_api_bridge_domain_dump_t * mp)
807 bd_main_t *bdm = &bd_main;
808 l2input_main_t *l2im = &l2input_main;
809 unix_shared_memory_queue_t *q;
810 l2_bridge_domain_t *bd_config;
814 q = vl_api_client_index_to_input_queue (mp->client_index);
819 bd_id = ntohl (mp->bd_id);
821 bd_index = (bd_id == ~0) ? 0 : bd_find_or_add_bd_index (bdm, bd_id);
822 end = (bd_id == ~0) ? vec_len (l2im->bd_configs) : bd_index + 1;
823 for (; bd_index < end; bd_index++)
825 bd_config = l2input_bd_config_from_index (l2im, bd_index);
826 /* skip dummy bd_id 0 */
827 if (bd_config && (bd_config->bd_id > 0))
830 l2_flood_member_t *m;
832 n_sw_ifs = vec_len (bd_config->members);
833 send_bridge_domain_details (q, bd_config, n_sw_ifs, mp->context);
835 vec_foreach (m, bd_config->members)
837 send_bd_sw_if_details (l2im, q, m, bd_config->bd_id, mp->context);
844 vl_api_l2fib_add_del_t_handler (vl_api_l2fib_add_del_t * mp)
846 bd_main_t *bdm = &bd_main;
847 l2input_main_t *l2im = &l2input_main;
848 vl_api_l2fib_add_del_reply_t *rmp;
851 u32 sw_if_index = ntohl (mp->sw_if_index);
852 u32 bd_id = ntohl (mp->bd_id);
861 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
864 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
865 goto bad_sw_if_index;
871 filter_mac = mp->filter_mac ? 1 : 0;
874 VALIDATE_SW_IF_INDEX (mp);
875 if (vec_len (l2im->configs) <= sw_if_index)
877 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
878 goto bad_sw_if_index;
882 l2_input_config_t *config;
883 config = vec_elt_at_index (l2im->configs, sw_if_index);
884 if (config->bridge == 0)
886 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
887 goto bad_sw_if_index;
891 static_mac = mp->static_mac ? 1 : 0;
892 bvi_mac = mp->bvi_mac ? 1 : 0;
893 l2fib_add_entry (mac, bd_index, sw_if_index, static_mac, filter_mac,
898 l2fib_del_entry (mac, bd_index);
901 BAD_SW_IF_INDEX_LABEL;
903 REPLY_MACRO (VL_API_L2FIB_ADD_DEL_REPLY);
907 vl_api_l2_flags_t_handler (vl_api_l2_flags_t * mp)
909 vl_api_l2_flags_reply_t *rmp;
911 u32 sw_if_index = ntohl (mp->sw_if_index);
912 u32 flags = ntohl (mp->feature_bitmap);
915 VALIDATE_SW_IF_INDEX (mp);
918 if (flags & L2INPUT_FEAT_ ## a) \
919 rbm = l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_ ## a, mp->is_set);
920 foreach_l2input_feat;
923 BAD_SW_IF_INDEX_LABEL;
926 REPLY_MACRO2(VL_API_L2_FLAGS_REPLY,
928 rmp->resulting_feature_bitmap = ntohl(rbm);
934 vl_api_bridge_flags_t_handler (vl_api_bridge_flags_t * mp)
936 vlib_main_t *vm = vlib_get_main ();
937 bd_main_t *bdm = &bd_main;
938 vl_api_bridge_flags_reply_t *rmp;
940 u32 bd_id = ntohl (mp->bd_id);
942 u32 flags = ntohl (mp->feature_bitmap);
945 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
948 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
954 bd_set_flags (vm, bd_index, flags, mp->is_set);
958 REPLY_MACRO2(VL_API_BRIDGE_FLAGS_REPLY,
960 rmp->resulting_feature_bitmap = ntohl(flags);
966 vl_api_bd_ip_mac_add_del_t_handler (vl_api_bd_ip_mac_add_del_t * mp)
968 bd_main_t *bdm = &bd_main;
969 vl_api_bd_ip_mac_add_del_reply_t *rmp;
971 u32 bd_id = ntohl (mp->bd_id);
975 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
978 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
983 if (bd_add_del_ip_mac (bd_index, mp->ip_address,
984 mp->mac_address, mp->is_ipv6, mp->is_add))
985 rv = VNET_API_ERROR_UNSPECIFIED;
988 REPLY_MACRO (VL_API_BD_IP_MAC_ADD_DEL_REPLY);
992 vl_api_create_vlan_subif_t_handler (vl_api_create_vlan_subif_t * mp)
994 vl_api_create_vlan_subif_reply_t *rmp;
995 vnet_main_t *vnm = vnet_get_main ();
996 u32 hw_if_index, sw_if_index = (u32) ~ 0;
997 vnet_hw_interface_t *hi;
1000 vnet_sw_interface_t template;
1002 vnet_interface_main_t *im = &vnm->interface_main;
1003 u64 sup_and_sub_key;
1005 unix_shared_memory_queue_t *q;
1006 clib_error_t *error;
1008 VALIDATE_SW_IF_INDEX (mp);
1010 hw_if_index = ntohl (mp->sw_if_index);
1011 hi = vnet_get_hw_interface (vnm, hw_if_index);
1013 id = ntohl (mp->vlan_id);
1014 if (id == 0 || id > 4095)
1016 rv = VNET_API_ERROR_INVALID_VLAN;
1020 sup_and_sub_key = ((u64) (hi->sw_if_index) << 32) | (u64) id;
1022 p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1025 rv = VNET_API_ERROR_VLAN_ALREADY_EXISTS;
1029 kp = clib_mem_alloc (sizeof (*kp));
1030 *kp = sup_and_sub_key;
1032 memset (&template, 0, sizeof (template));
1033 template.type = VNET_SW_INTERFACE_TYPE_SUB;
1034 template.sup_sw_if_index = hi->sw_if_index;
1035 template.sub.id = id;
1036 template.sub.eth.raw_flags = 0;
1037 template.sub.eth.flags.one_tag = 1;
1038 template.sub.eth.outer_vlan_id = id;
1039 template.sub.eth.flags.exact_match = 1;
1041 error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1044 clib_error_report (error);
1045 rv = VNET_API_ERROR_INVALID_REGISTRATION;
1048 hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
1049 hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1051 BAD_SW_IF_INDEX_LABEL;
1054 q = vl_api_client_index_to_input_queue (mp->client_index);
1058 rmp = vl_msg_api_alloc (sizeof (*rmp));
1059 rmp->_vl_msg_id = ntohs (VL_API_CREATE_VLAN_SUBIF_REPLY);
1060 rmp->context = mp->context;
1061 rmp->retval = ntohl (rv);
1062 rmp->sw_if_index = ntohl (sw_if_index);
1063 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1067 vl_api_create_subif_t_handler (vl_api_create_subif_t * mp)
1069 vl_api_create_subif_reply_t *rmp;
1070 vnet_main_t *vnm = vnet_get_main ();
1071 u32 sw_if_index = ~0;
1074 vnet_sw_interface_t *si;
1075 vnet_hw_interface_t *hi;
1076 vnet_sw_interface_t template;
1078 vnet_interface_main_t *im = &vnm->interface_main;
1079 u64 sup_and_sub_key;
1081 clib_error_t *error;
1083 VALIDATE_SW_IF_INDEX (mp);
1085 si = vnet_get_sup_sw_interface (vnm, ntohl (mp->sw_if_index));
1086 hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
1088 if (hi->bond_info == VNET_HW_INTERFACE_BOND_INFO_SLAVE)
1090 rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
1094 sw_if_index = si->sw_if_index;
1095 sub_id = ntohl (mp->sub_id);
1097 sup_and_sub_key = ((u64) (sw_if_index) << 32) | (u64) sub_id;
1099 p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
1103 clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
1104 sw_if_index, sub_id);
1105 rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
1109 kp = clib_mem_alloc (sizeof (*kp));
1110 *kp = sup_and_sub_key;
1112 memset (&template, 0, sizeof (template));
1113 template.type = VNET_SW_INTERFACE_TYPE_SUB;
1114 template.sup_sw_if_index = sw_if_index;
1115 template.sub.id = sub_id;
1116 template.sub.eth.flags.no_tags = mp->no_tags;
1117 template.sub.eth.flags.one_tag = mp->one_tag;
1118 template.sub.eth.flags.two_tags = mp->two_tags;
1119 template.sub.eth.flags.dot1ad = mp->dot1ad;
1120 template.sub.eth.flags.exact_match = mp->exact_match;
1121 template.sub.eth.flags.default_sub = mp->default_sub;
1122 template.sub.eth.flags.outer_vlan_id_any = mp->outer_vlan_id_any;
1123 template.sub.eth.flags.inner_vlan_id_any = mp->inner_vlan_id_any;
1124 template.sub.eth.outer_vlan_id = ntohs (mp->outer_vlan_id);
1125 template.sub.eth.inner_vlan_id = ntohs (mp->inner_vlan_id);
1127 error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
1130 clib_error_report (error);
1131 rv = VNET_API_ERROR_SUBIF_CREATE_FAILED;
1135 hash_set (hi->sub_interface_sw_if_index_by_id, sub_id, sw_if_index);
1136 hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
1138 BAD_SW_IF_INDEX_LABEL;
1143 REPLY_MACRO2(VL_API_CREATE_SUBIF_REPLY,
1145 rmp->sw_if_index = ntohl(sw_if_index);
1151 vl_api_mpls_tunnel_add_del_t_handler (vl_api_mpls_tunnel_add_del_t * mp)
1153 vl_api_mpls_tunnel_add_del_reply_t *rmp;
1155 stats_main_t *sm = &stats_main;
1156 u32 tunnel_sw_if_index;
1159 dslock (sm, 1 /* release hint */ , 5 /* tag */ );
1163 fib_route_path_t rpath, *rpaths = NULL;
1164 mpls_label_t *label_stack = NULL;
1166 memset (&rpath, 0, sizeof (rpath));
1168 if (mp->mt_next_hop_proto_is_ip4)
1170 rpath.frp_proto = FIB_PROTOCOL_IP4;
1171 clib_memcpy (&rpath.frp_addr.ip4,
1172 mp->mt_next_hop, sizeof (rpath.frp_addr.ip4));
1176 rpath.frp_proto = FIB_PROTOCOL_IP6;
1177 clib_memcpy (&rpath.frp_addr.ip6,
1178 mp->mt_next_hop, sizeof (rpath.frp_addr.ip6));
1180 rpath.frp_sw_if_index = ntohl (mp->mt_next_hop_sw_if_index);
1182 for (ii = 0; ii < mp->mt_next_hop_n_out_labels; ii++)
1183 vec_add1 (label_stack, ntohl (mp->mt_next_hop_out_label_stack[ii]));
1185 vec_add1 (rpaths, rpath);
1187 vnet_mpls_tunnel_add (rpaths, label_stack,
1188 mp->mt_l2_only, &tunnel_sw_if_index);
1190 vec_free (label_stack);
1194 tunnel_sw_if_index = ntohl (mp->mt_sw_if_index);
1195 vnet_mpls_tunnel_del (tunnel_sw_if_index);
1201 REPLY_MACRO2(VL_API_MPLS_TUNNEL_ADD_DEL_REPLY,
1203 rmp->sw_if_index = ntohl(tunnel_sw_if_index);
1209 vl_api_proxy_arp_add_del_t_handler (vl_api_proxy_arp_add_del_t * mp)
1211 vl_api_proxy_arp_add_del_reply_t *rmp;
1214 ip4_main_t *im = &ip4_main;
1215 stats_main_t *sm = &stats_main;
1216 int vnet_proxy_arp_add_del (ip4_address_t * lo_addr,
1217 ip4_address_t * hi_addr,
1218 u32 fib_index, int is_del);
1221 dslock (sm, 1 /* release hint */ , 6 /* tag */ );
1223 p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
1227 rv = VNET_API_ERROR_NO_SUCH_FIB;
1233 rv = vnet_proxy_arp_add_del ((ip4_address_t *) mp->low_address,
1234 (ip4_address_t *) mp->hi_address,
1235 fib_index, mp->is_add == 0);
1239 REPLY_MACRO (VL_API_PROXY_ARP_ADD_DEL_REPLY);
1243 vl_api_proxy_arp_intfc_enable_disable_t_handler
1244 (vl_api_proxy_arp_intfc_enable_disable_t * mp)
1247 vnet_main_t *vnm = vnet_get_main ();
1248 vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;
1249 vnet_sw_interface_t *si;
1252 VALIDATE_SW_IF_INDEX (mp);
1254 sw_if_index = ntohl (mp->sw_if_index);
1256 if (pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index))
1258 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
1262 si = vnet_get_sw_interface (vnm, sw_if_index);
1266 if (mp->enable_disable)
1267 si->flags |= VNET_SW_INTERFACE_FLAG_PROXY_ARP;
1269 si->flags &= ~VNET_SW_INTERFACE_FLAG_PROXY_ARP;
1271 BAD_SW_IF_INDEX_LABEL;
1274 REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
1278 vl_api_is_address_reachable_t_handler (vl_api_is_address_reachable_t * mp)
1281 vpe_main_t *rm = &vpe_main;
1282 ip4_main_t *im4 = &ip4_main;
1283 ip6_main_t *im6 = &ip6_main;
1284 ip_lookup_main_t *lm;
1290 u32 adj_index, sw_if_index;
1291 vl_api_is_address_reachable_t *rmp;
1292 ip_adjacency_t *adj;
1293 unix_shared_memory_queue_t *q;
1295 q = vl_api_client_index_to_input_queue (mp->client_index);
1298 increment_missing_api_client_counter (rm->vlib_main);
1302 rmp = vl_msg_api_alloc (sizeof (*rmp));
1303 clib_memcpy (rmp, mp, sizeof (*rmp));
1305 sw_if_index = mp->next_hop_sw_if_index;
1306 clib_memcpy (&addr, mp->address, sizeof (addr));
1309 lm = &im6->lookup_main;
1310 adj_index = ip6_fib_lookup (im6, sw_if_index, &addr.ip6);
1314 lm = &im4->lookup_main;
1316 adj_index = ip4_fib_lookup (im4, sw_if_index, &addr.ip4);
1318 if (adj_index == ~0)
1323 adj = ip_get_adjacency (lm, adj_index);
1325 if (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE
1326 && adj->rewrite_header.sw_if_index == sw_if_index)
1332 if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP
1333 && adj->rewrite_header.sw_if_index == sw_if_index)
1336 ip6_probe_neighbor (rm->vlib_main, &addr.ip6, sw_if_index);
1338 ip4_probe_neighbor (rm->vlib_main, &addr.ip4, sw_if_index);
1340 else if (adj->lookup_next_index == IP_LOOKUP_NEXT_DROP)
1349 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1354 vl_api_sw_interface_set_mpls_enable_t_handler
1355 (vl_api_sw_interface_set_mpls_enable_t * mp)
1357 vl_api_sw_interface_set_mpls_enable_reply_t *rmp;
1360 VALIDATE_SW_IF_INDEX (mp);
1362 mpls_sw_interface_enable_disable (&mpls_main,
1363 ntohl (mp->sw_if_index), mp->enable);
1365 BAD_SW_IF_INDEX_LABEL;
1366 REPLY_MACRO (VL_API_SW_INTERFACE_SET_MPLS_ENABLE_REPLY);
1370 send_oam_event (oam_target_t * t)
1372 vpe_api_main_t *vam = &vpe_api_main;
1373 unix_shared_memory_queue_t *q;
1374 vpe_client_registration_t *reg;
1375 vl_api_oam_event_t *mp;
1378 pool_foreach(reg, vam->oam_events_registrations,
1380 q = vl_api_client_index_to_input_queue (reg->client_index);
1383 mp = vl_msg_api_alloc (sizeof (*mp));
1384 mp->_vl_msg_id = ntohs (VL_API_OAM_EVENT);
1385 clib_memcpy (mp->dst_address, &t->dst_address,
1386 sizeof (mp->dst_address));
1387 mp->state = t->state;
1388 vl_msg_api_send_shmem (q, (u8 *)&mp);
1395 vl_api_oam_add_del_t_handler (vl_api_oam_add_del_t * mp)
1397 vl_api_oam_add_del_reply_t *rmp;
1400 rv = vpe_oam_add_del_target ((ip4_address_t *) mp->src_address,
1401 (ip4_address_t *) mp->dst_address,
1402 ntohl (mp->vrf_id), (int) (mp->is_add));
1404 REPLY_MACRO (VL_API_OAM_ADD_DEL_REPLY);
1408 vl_api_vnet_get_summary_stats_t_handler (vl_api_vnet_get_summary_stats_t * mp)
1410 stats_main_t *sm = &stats_main;
1411 vnet_interface_main_t *im = sm->interface_main;
1412 vl_api_vnet_summary_stats_reply_t *rmp;
1413 vlib_combined_counter_main_t *cm;
1416 u64 total_pkts[VLIB_N_RX_TX];
1417 u64 total_bytes[VLIB_N_RX_TX];
1419 unix_shared_memory_queue_t *q =
1420 vl_api_client_index_to_input_queue (mp->client_index);
1425 rmp = vl_msg_api_alloc (sizeof (*rmp));
1426 rmp->_vl_msg_id = ntohs (VL_API_VNET_SUMMARY_STATS_REPLY);
1427 rmp->context = mp->context;
1430 memset (total_pkts, 0, sizeof (total_pkts));
1431 memset (total_bytes, 0, sizeof (total_bytes));
1433 vnet_interface_counter_lock (im);
1435 vec_foreach (cm, im->combined_sw_if_counters)
1437 which = cm - im->combined_sw_if_counters;
1439 for (i = 0; i < vec_len (cm->maxi); i++)
1441 vlib_get_combined_counter (cm, i, &v);
1442 total_pkts[which] += v.packets;
1443 total_bytes[which] += v.bytes;
1446 vnet_interface_counter_unlock (im);
1448 rmp->total_pkts[VLIB_RX] = clib_host_to_net_u64 (total_pkts[VLIB_RX]);
1449 rmp->total_bytes[VLIB_RX] = clib_host_to_net_u64 (total_bytes[VLIB_RX]);
1450 rmp->total_pkts[VLIB_TX] = clib_host_to_net_u64 (total_pkts[VLIB_TX]);
1451 rmp->total_bytes[VLIB_TX] = clib_host_to_net_u64 (total_bytes[VLIB_TX]);
1453 clib_host_to_net_u64 (vlib_last_vector_length_per_node (sm->vlib_main));
1455 vl_msg_api_send_shmem (q, (u8 *) & rmp);
1459 typedef CLIB_PACKED (struct {
1460 ip4_address_t address;
1461 u32 address_length: 6;
1467 ip4_reset_fib_t_handler (vl_api_reset_fib_t * mp)
1469 vnet_main_t *vnm = vnet_get_main ();
1470 vnet_interface_main_t *im = &vnm->interface_main;
1471 ip4_main_t *im4 = &ip4_main;
1472 static u32 *sw_if_indices_to_shut;
1473 stats_main_t *sm = &stats_main;
1474 fib_table_t *fib_table;
1478 int rv = VNET_API_ERROR_NO_SUCH_FIB;
1479 u32 target_fib_id = ntohl (mp->vrf_id);
1481 dslock (sm, 1 /* release hint */ , 8 /* tag */ );
1484 pool_foreach (fib_table, im4->fibs,
1486 fib = &fib_table->v4;
1487 vnet_sw_interface_t * si;
1489 if (fib->table_id != target_fib_id)
1492 /* remove any mpls encap/decap labels */
1493 mpls_fib_reset_labels (fib->table_id);
1495 /* remove any proxy arps in this fib */
1496 vnet_proxy_arp_fib_reset (fib->table_id);
1498 /* Set the flow hash for this fib to the default */
1499 vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
1501 vec_reset_length (sw_if_indices_to_shut);
1503 /* Shut down interfaces in this FIB / clean out intfc routes */
1504 pool_foreach (si, im->sw_interfaces,
1506 u32 sw_if_index = si->sw_if_index;
1508 if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
1509 && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
1511 vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
1514 for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
1515 sw_if_index = sw_if_indices_to_shut[i];
1516 // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
1518 u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
1519 flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
1520 vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
1523 fib_table_flush(fib->index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
1524 fib_table_flush(fib->index, FIB_PROTOCOL_IP4, FIB_SOURCE_INTERFACE);
1528 })); /* pool_foreach (fib) */
1536 ip6_reset_fib_t_handler (vl_api_reset_fib_t * mp)
1538 vnet_main_t *vnm = vnet_get_main ();
1539 vnet_interface_main_t *im = &vnm->interface_main;
1540 ip6_main_t *im6 = &ip6_main;
1541 stats_main_t *sm = &stats_main;
1542 static u32 *sw_if_indices_to_shut;
1543 fib_table_t *fib_table;
1547 int rv = VNET_API_ERROR_NO_SUCH_FIB;
1548 u32 target_fib_id = ntohl (mp->vrf_id);
1550 dslock (sm, 1 /* release hint */ , 9 /* tag */ );
1553 pool_foreach (fib_table, im6->fibs,
1555 vnet_sw_interface_t * si;
1556 fib = &(fib_table->v6);
1558 if (fib->table_id != target_fib_id)
1561 vec_reset_length (sw_if_indices_to_shut);
1563 /* Shut down interfaces in this FIB / clean out intfc routes */
1564 pool_foreach (si, im->sw_interfaces,
1566 if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
1568 vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
1571 for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
1572 sw_if_index = sw_if_indices_to_shut[i];
1573 // vec_foreach (sw_if_index, sw_if_indices_to_shut) {
1575 u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
1576 flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
1577 vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
1580 fib_table_flush(fib->index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
1581 fib_table_flush(fib->index, FIB_PROTOCOL_IP6, FIB_SOURCE_INTERFACE);
1585 })); /* pool_foreach (fib) */
1593 vl_api_reset_fib_t_handler (vl_api_reset_fib_t * mp)
1596 vl_api_reset_fib_reply_t *rmp;
1599 rv = ip6_reset_fib_t_handler (mp);
1601 rv = ip4_reset_fib_t_handler (mp);
1603 REPLY_MACRO (VL_API_RESET_FIB_REPLY);
1608 dhcpv4_proxy_config (vl_api_dhcp_proxy_config_t * mp)
1610 vl_api_dhcp_proxy_config_reply_t *rmp;
1613 rv = dhcp_proxy_set_server ((ip4_address_t *) (&mp->dhcp_server),
1614 (ip4_address_t *) (&mp->dhcp_src_address),
1615 (u32) ntohl (mp->vrf_id),
1616 (int) mp->insert_circuit_id,
1617 (int) (mp->is_add == 0));
1619 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_REPLY);
1624 dhcpv6_proxy_config (vl_api_dhcp_proxy_config_t * mp)
1626 vl_api_dhcp_proxy_config_reply_t *rmp;
1629 rv = dhcpv6_proxy_set_server ((ip6_address_t *) (&mp->dhcp_server),
1630 (ip6_address_t *) (&mp->dhcp_src_address),
1631 (u32) ntohl (mp->vrf_id),
1632 (int) mp->insert_circuit_id,
1633 (int) (mp->is_add == 0));
1635 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_REPLY);
1639 dhcpv4_proxy_config_2 (vl_api_dhcp_proxy_config_2_t * mp)
1641 vl_api_dhcp_proxy_config_reply_t *rmp;
1644 rv = dhcp_proxy_set_server_2 ((ip4_address_t *) (&mp->dhcp_server),
1645 (ip4_address_t *) (&mp->dhcp_src_address),
1646 (u32) ntohl (mp->rx_vrf_id),
1647 (u32) ntohl (mp->server_vrf_id),
1648 (int) mp->insert_circuit_id,
1649 (int) (mp->is_add == 0));
1651 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_2_REPLY);
1656 dhcpv6_proxy_config_2 (vl_api_dhcp_proxy_config_2_t * mp)
1658 vl_api_dhcp_proxy_config_reply_t *rmp;
1661 rv = dhcpv6_proxy_set_server_2 ((ip6_address_t *) (&mp->dhcp_server),
1662 (ip6_address_t *) (&mp->dhcp_src_address),
1663 (u32) ntohl (mp->rx_vrf_id),
1664 (u32) ntohl (mp->server_vrf_id),
1665 (int) mp->insert_circuit_id,
1666 (int) (mp->is_add == 0));
1668 REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_2_REPLY);
1673 vl_api_dhcp_proxy_set_vss_t_handler (vl_api_dhcp_proxy_set_vss_t * mp)
1675 vl_api_dhcp_proxy_set_vss_reply_t *rmp;
1678 rv = dhcp_proxy_set_option82_vss (ntohl (mp->tbl_id),
1681 (int) mp->is_add == 0);
1683 rv = dhcpv6_proxy_set_vss (ntohl (mp->tbl_id),
1685 ntohl (mp->fib_id), (int) mp->is_add == 0);
1687 REPLY_MACRO (VL_API_DHCP_PROXY_SET_VSS_REPLY);
1691 static void vl_api_dhcp_proxy_config_t_handler
1692 (vl_api_dhcp_proxy_config_t * mp)
1694 if (mp->is_ipv6 == 0)
1695 dhcpv4_proxy_config (mp);
1697 dhcpv6_proxy_config (mp);
1700 static void vl_api_dhcp_proxy_config_2_t_handler
1701 (vl_api_dhcp_proxy_config_2_t * mp)
1703 if (mp->is_ipv6 == 0)
1704 dhcpv4_proxy_config_2 (mp);
1706 dhcpv6_proxy_config_2 (mp);
1710 dhcp_compl_event_callback (u32 client_index, u32 pid, u8 * hostname,
1711 u8 is_ipv6, u8 * host_address, u8 * router_address,
1714 unix_shared_memory_queue_t *q;
1715 vl_api_dhcp_compl_event_t *mp;
1717 q = vl_api_client_index_to_input_queue (client_index);
1721 mp = vl_msg_api_alloc (sizeof (*mp));
1722 mp->client_index = client_index;
1724 mp->is_ipv6 = is_ipv6;
1725 clib_memcpy (&mp->hostname, hostname, vec_len (hostname));
1726 mp->hostname[vec_len (hostname) + 1] = '\n';
1727 clib_memcpy (&mp->host_address[0], host_address, 16);
1728 clib_memcpy (&mp->router_address[0], router_address, 16);
1730 if (NULL != host_mac)
1731 clib_memcpy (&mp->host_mac[0], host_mac, 6);
1733 mp->_vl_msg_id = ntohs (VL_API_DHCP_COMPL_EVENT);
1735 vl_msg_api_send_shmem (q, (u8 *) & mp);
1738 static void vl_api_dhcp_client_config_t_handler
1739 (vl_api_dhcp_client_config_t * mp)
1741 vlib_main_t *vm = vlib_get_main ();
1742 vl_api_dhcp_client_config_reply_t *rmp;
1745 VALIDATE_SW_IF_INDEX (mp);
1747 rv = dhcp_client_config (vm, ntohl (mp->sw_if_index),
1748 mp->hostname, mp->is_add, mp->client_index,
1749 mp->want_dhcp_event ? dhcp_compl_event_callback :
1752 BAD_SW_IF_INDEX_LABEL;
1754 REPLY_MACRO (VL_API_DHCP_CLIENT_CONFIG_REPLY);
1758 vl_api_create_loopback_t_handler (vl_api_create_loopback_t * mp)
1760 vl_api_create_loopback_reply_t *rmp;
1764 rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address);
1767 REPLY_MACRO2(VL_API_CREATE_LOOPBACK_REPLY,
1769 rmp->sw_if_index = ntohl (sw_if_index);
1775 vl_api_delete_loopback_t_handler (vl_api_delete_loopback_t * mp)
1777 vl_api_delete_loopback_reply_t *rmp;
1781 sw_if_index = ntohl (mp->sw_if_index);
1782 rv = vnet_delete_loopback_interface (sw_if_index);
1784 REPLY_MACRO (VL_API_DELETE_LOOPBACK_REPLY);
1788 vl_api_control_ping_t_handler (vl_api_control_ping_t * mp)
1790 vl_api_control_ping_reply_t *rmp;
1794 REPLY_MACRO2(VL_API_CONTROL_PING_REPLY,
1796 rmp->vpe_pid = ntohl (getpid());
1802 shmem_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
1804 u8 **shmem_vecp = (u8 **) arg;
1807 api_main_t *am = &api_main;
1810 shmem_vec = *shmem_vecp;
1812 offset = vec_len (shmem_vec);
1814 pthread_mutex_lock (&am->vlib_rp->mutex);
1815 oldheap = svm_push_data_heap (am->vlib_rp);
1817 vec_validate (shmem_vec, offset + buffer_bytes - 1);
1819 clib_memcpy (shmem_vec + offset, buffer, buffer_bytes);
1821 svm_pop_heap (oldheap);
1822 pthread_mutex_unlock (&am->vlib_rp->mutex);
1824 *shmem_vecp = shmem_vec;
1829 vl_api_cli_request_t_handler (vl_api_cli_request_t * mp)
1831 vl_api_cli_reply_t *rp;
1832 unix_shared_memory_queue_t *q;
1833 vlib_main_t *vm = vlib_get_main ();
1834 api_main_t *am = &api_main;
1835 unformat_input_t input;
1839 q = vl_api_client_index_to_input_queue (mp->client_index);
1843 rp = vl_msg_api_alloc (sizeof (*rp));
1844 rp->_vl_msg_id = ntohs (VL_API_CLI_REPLY);
1845 rp->context = mp->context;
1847 unformat_init_vector (&input, (u8 *) (uword) mp->cmd_in_shmem);
1849 vlib_cli_input (vm, &input, shmem_cli_output, (uword) & shmem_vec);
1851 pthread_mutex_lock (&am->vlib_rp->mutex);
1852 oldheap = svm_push_data_heap (am->vlib_rp);
1854 vec_add1 (shmem_vec, 0);
1856 svm_pop_heap (oldheap);
1857 pthread_mutex_unlock (&am->vlib_rp->mutex);
1859 rp->reply_in_shmem = (uword) shmem_vec;
1861 vl_msg_api_send_shmem (q, (u8 *) & rp);
1865 inband_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
1867 u8 **mem_vecp = (u8 **) arg;
1868 u8 *mem_vec = *mem_vecp;
1869 u32 offset = vec_len (mem_vec);
1871 vec_validate (mem_vec, offset + buffer_bytes - 1);
1872 clib_memcpy (mem_vec + offset, buffer, buffer_bytes);
1873 *mem_vecp = mem_vec;
1877 vl_api_cli_inband_t_handler (vl_api_cli_inband_t * mp)
1879 vl_api_cli_inband_reply_t *rmp;
1881 unix_shared_memory_queue_t *q;
1882 vlib_main_t *vm = vlib_get_main ();
1883 unformat_input_t input;
1886 q = vl_api_client_index_to_input_queue (mp->client_index);
1890 unformat_init_string (&input, (char *) mp->cmd, ntohl (mp->length));
1891 vlib_cli_input (vm, &input, inband_cli_output, (uword) & out_vec);
1893 u32 len = vec_len (out_vec);
1895 REPLY_MACRO3(VL_API_CLI_INBAND_REPLY, len,
1897 rmp->length = htonl (len);
1898 clib_memcpy (rmp->reply, out_vec, len);
1905 vl_api_set_arp_neighbor_limit_t_handler (vl_api_set_arp_neighbor_limit_t * mp)
1908 vl_api_set_arp_neighbor_limit_reply_t *rmp;
1909 vnet_main_t *vnm = vnet_get_main ();
1910 clib_error_t *error;
1915 error = ip6_set_neighbor_limit (ntohl (mp->arp_neighbor_limit));
1917 error = ip4_set_arp_limit (ntohl (mp->arp_neighbor_limit));
1921 clib_error_report (error);
1922 rv = VNET_API_ERROR_UNSPECIFIED;
1926 rv = vnm->api_errno;
1929 REPLY_MACRO (VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
1932 static void vl_api_sr_tunnel_add_del_t_handler
1933 (vl_api_sr_tunnel_add_del_t * mp)
1936 clib_warning ("unimplemented");
1938 ip6_sr_add_del_tunnel_args_t _a, *a = &_a;
1940 vl_api_sr_tunnel_add_del_reply_t *rmp;
1941 ip6_address_t *segments = 0, *seg;
1942 ip6_address_t *tags = 0, *tag;
1943 ip6_address_t *this_address;
1946 if (mp->n_segments == 0)
1952 memset (a, 0, sizeof (*a));
1953 a->src_address = (ip6_address_t *) & mp->src_address;
1954 a->dst_address = (ip6_address_t *) & mp->dst_address;
1955 a->dst_mask_width = mp->dst_mask_width;
1956 a->flags_net_byte_order = mp->flags_net_byte_order;
1957 a->is_del = (mp->is_add == 0);
1958 a->rx_table_id = ntohl (mp->outer_vrf_id);
1959 a->tx_table_id = ntohl (mp->inner_vrf_id);
1961 a->name = format (0, "%s", mp->name);
1962 if (!(vec_len (a->name)))
1965 a->policy_name = format (0, "%s", mp->policy_name);
1966 if (!(vec_len (a->policy_name)))
1969 /* Yank segments and tags out of the API message */
1970 this_address = (ip6_address_t *) mp->segs_and_tags;
1971 for (i = 0; i < mp->n_segments; i++)
1973 vec_add2 (segments, seg, 1);
1974 clib_memcpy (seg->as_u8, this_address->as_u8, sizeof (*this_address));
1977 for (i = 0; i < mp->n_tags; i++)
1979 vec_add2 (tags, tag, 1);
1980 clib_memcpy (tag->as_u8, this_address->as_u8, sizeof (*this_address));
1984 a->segments = segments;
1987 rv = ip6_sr_add_del_tunnel (a);
1991 REPLY_MACRO (VL_API_SR_TUNNEL_ADD_DEL_REPLY);
1995 static void vl_api_sr_policy_add_del_t_handler
1996 (vl_api_sr_policy_add_del_t * mp)
1999 clib_warning ("unimplemented");
2001 ip6_sr_add_del_policy_args_t _a, *a = &_a;
2003 vl_api_sr_policy_add_del_reply_t *rmp;
2006 memset (a, 0, sizeof (*a));
2007 a->is_del = (mp->is_add == 0);
2009 a->name = format (0, "%s", mp->name);
2010 if (!(vec_len (a->name)))
2012 rv = VNET_API_ERROR_NO_SUCH_NODE2;
2016 if (!(mp->tunnel_names[0]))
2018 rv = VNET_API_ERROR_NO_SUCH_NODE2;
2022 // start deserializing tunnel_names
2023 int num_tunnels = mp->tunnel_names[0]; //number of tunnels
2024 u8 *deser_tun_names = mp->tunnel_names;
2025 deser_tun_names += 1; //moving along
2028 int tun_name_len = 0;
2030 for (i = 0; i < num_tunnels; i++)
2032 tun_name_len = *deser_tun_names;
2033 deser_tun_names += 1;
2034 vec_resize (tun_name, tun_name_len);
2035 memcpy (tun_name, deser_tun_names, tun_name_len);
2036 vec_add1 (a->tunnel_names, tun_name);
2037 deser_tun_names += tun_name_len;
2041 rv = ip6_sr_add_del_policy (a);
2045 REPLY_MACRO (VL_API_SR_POLICY_ADD_DEL_REPLY);
2049 static void vl_api_sr_multicast_map_add_del_t_handler
2050 (vl_api_sr_multicast_map_add_del_t * mp)
2053 clib_warning ("unimplemented");
2055 ip6_sr_add_del_multicastmap_args_t _a, *a = &_a;
2057 vl_api_sr_multicast_map_add_del_reply_t *rmp;
2059 memset (a, 0, sizeof (*a));
2060 a->is_del = (mp->is_add == 0);
2062 a->multicast_address = (ip6_address_t *) & mp->multicast_address;
2063 a->policy_name = format (0, "%s", mp->policy_name);
2065 if (a->multicast_address == 0)
2071 if (!(a->policy_name))
2077 #if DPDK > 0 /* Cannot call replicate without DPDK */
2078 rv = ip6_sr_add_del_multicastmap (a);
2080 clib_warning ("multicast replication without DPDK not implemented");
2081 rv = VNET_API_ERROR_UNIMPLEMENTED;
2086 REPLY_MACRO (VL_API_SR_MULTICAST_MAP_ADD_DEL_REPLY);
2090 #define foreach_classify_add_del_table_field \
2095 _(match_n_vectors) \
2096 _(next_table_index) \
2097 _(miss_next_index) \
2098 _(current_data_flag) \
2099 _(current_data_offset)
2101 static void vl_api_classify_add_del_table_t_handler
2102 (vl_api_classify_add_del_table_t * mp)
2104 vl_api_classify_add_del_table_reply_t *rmp;
2105 vnet_classify_main_t *cm = &vnet_classify_main;
2106 vnet_classify_table_t *t;
2110 foreach_classify_add_del_table_field;
2113 #define _(a) a = ntohl(mp->a);
2114 foreach_classify_add_del_table_field;
2117 /* The underlying API fails silently, on purpose, so check here */
2118 if (mp->is_add == 0) /* delete */
2120 if (pool_is_free_index (cm->tables, table_index))
2122 rv = VNET_API_ERROR_NO_SUCH_TABLE;
2126 else /* add or update */
2128 if (table_index != ~0 && pool_is_free_index (cm->tables, table_index))
2132 rv = vnet_classify_add_del_table
2133 (cm, mp->mask, nbuckets, memory_size,
2134 skip_n_vectors, match_n_vectors,
2135 next_table_index, miss_next_index, &table_index,
2136 current_data_flag, current_data_offset, mp->is_add, mp->del_chain);
2140 REPLY_MACRO2(VL_API_CLASSIFY_ADD_DEL_TABLE_REPLY,
2142 if (rv == 0 && mp->is_add)
2144 t = pool_elt_at_index (cm->tables, table_index);
2145 rmp->skip_n_vectors = ntohl(t->skip_n_vectors);
2146 rmp->match_n_vectors = ntohl(t->match_n_vectors);
2147 rmp->new_table_index = ntohl(table_index);
2151 rmp->skip_n_vectors = ~0;
2152 rmp->match_n_vectors = ~0;
2153 rmp->new_table_index = ~0;
2159 static void vl_api_classify_add_del_session_t_handler
2160 (vl_api_classify_add_del_session_t * mp)
2162 vnet_classify_main_t *cm = &vnet_classify_main;
2163 vl_api_classify_add_del_session_reply_t *rmp;
2165 u32 table_index, hit_next_index, opaque_index, metadata;
2169 table_index = ntohl (mp->table_index);
2170 hit_next_index = ntohl (mp->hit_next_index);
2171 opaque_index = ntohl (mp->opaque_index);
2172 advance = ntohl (mp->advance);
2173 action = mp->action;
2174 metadata = ntohl (mp->metadata);
2176 rv = vnet_classify_add_del_session
2177 (cm, table_index, mp->match, hit_next_index, opaque_index,
2178 advance, action, metadata, mp->is_add);
2180 REPLY_MACRO (VL_API_CLASSIFY_ADD_DEL_SESSION_REPLY);
2183 static void vl_api_classify_set_interface_ip_table_t_handler
2184 (vl_api_classify_set_interface_ip_table_t * mp)
2186 vlib_main_t *vm = vlib_get_main ();
2187 vl_api_classify_set_interface_ip_table_reply_t *rmp;
2189 u32 table_index, sw_if_index;
2191 table_index = ntohl (mp->table_index);
2192 sw_if_index = ntohl (mp->sw_if_index);
2194 VALIDATE_SW_IF_INDEX (mp);
2197 rv = vnet_set_ip6_classify_intfc (vm, sw_if_index, table_index);
2199 rv = vnet_set_ip4_classify_intfc (vm, sw_if_index, table_index);
2201 BAD_SW_IF_INDEX_LABEL;
2203 REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY);
2206 static void vl_api_classify_set_interface_l2_tables_t_handler
2207 (vl_api_classify_set_interface_l2_tables_t * mp)
2209 vl_api_classify_set_interface_l2_tables_reply_t *rmp;
2211 u32 sw_if_index, ip4_table_index, ip6_table_index, other_table_index;
2214 ip4_table_index = ntohl (mp->ip4_table_index);
2215 ip6_table_index = ntohl (mp->ip6_table_index);
2216 other_table_index = ntohl (mp->other_table_index);
2217 sw_if_index = ntohl (mp->sw_if_index);
2219 VALIDATE_SW_IF_INDEX (mp);
2222 rv = vnet_l2_input_classify_set_tables (sw_if_index, ip4_table_index,
2226 rv = vnet_l2_output_classify_set_tables (sw_if_index, ip4_table_index,
2232 if (ip4_table_index != ~0 || ip6_table_index != ~0
2233 || other_table_index != ~0)
2239 vnet_l2_input_classify_enable_disable (sw_if_index, enable);
2241 vnet_l2_output_classify_enable_disable (sw_if_index, enable);
2244 BAD_SW_IF_INDEX_LABEL;
2246 REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY);
2250 vl_api_l2_fib_clear_table_t_handler (vl_api_l2_fib_clear_table_t * mp)
2253 vl_api_l2_fib_clear_table_reply_t *rmp;
2255 /* DAW-FIXME: This API should only clear non-static l2fib entries, but
2256 * that is not currently implemented. When that TODO is fixed
2257 * this call should be changed to pass 1 instead of 0.
2259 l2fib_clear_table (0);
2261 REPLY_MACRO (VL_API_L2_FIB_CLEAR_TABLE_REPLY);
2264 extern void l2_efp_filter_configure (vnet_main_t * vnet_main,
2265 u32 sw_if_index, u32 enable);
2268 vl_api_l2_interface_efp_filter_t_handler (vl_api_l2_interface_efp_filter_t *
2272 vl_api_l2_interface_efp_filter_reply_t *rmp;
2273 vnet_main_t *vnm = vnet_get_main ();
2275 // enable/disable the feature
2276 l2_efp_filter_configure (vnm, mp->sw_if_index, mp->enable_disable);
2277 rv = vnm->api_errno;
2279 REPLY_MACRO (VL_API_L2_INTERFACE_EFP_FILTER_REPLY);
2283 vl_api_l2_interface_vlan_tag_rewrite_t_handler
2284 (vl_api_l2_interface_vlan_tag_rewrite_t * mp)
2287 vl_api_l2_interface_vlan_tag_rewrite_reply_t *rmp;
2288 vnet_main_t *vnm = vnet_get_main ();
2289 vlib_main_t *vm = vlib_get_main ();
2292 VALIDATE_SW_IF_INDEX (mp);
2294 vtr_op = ntohl (mp->vtr_op);
2296 /* The L2 code is unsuspicious */
2299 case L2_VTR_DISABLED:
2304 case L2_VTR_TRANSLATE_1_1:
2305 case L2_VTR_TRANSLATE_1_2:
2306 case L2_VTR_TRANSLATE_2_1:
2307 case L2_VTR_TRANSLATE_2_2:
2311 rv = VNET_API_ERROR_INVALID_VALUE;
2312 goto bad_sw_if_index;
2315 rv = l2vtr_configure (vm, vnm, ntohl (mp->sw_if_index), vtr_op,
2316 ntohl (mp->push_dot1q), ntohl (mp->tag1),
2319 BAD_SW_IF_INDEX_LABEL;
2321 REPLY_MACRO (VL_API_L2_INTERFACE_VLAN_TAG_REWRITE_REPLY);
2325 vl_api_l2_fib_table_entry_t_handler (vl_api_l2_fib_table_entry_t * mp)
2327 clib_warning ("BUG");
2331 send_l2fib_table_entry (vpe_api_main_t * am,
2332 unix_shared_memory_queue_t * q,
2333 l2fib_entry_key_t * l2fe_key,
2334 l2fib_entry_result_t * l2fe_res, u32 context)
2336 vl_api_l2_fib_table_entry_t *mp;
2338 mp = vl_msg_api_alloc (sizeof (*mp));
2339 memset (mp, 0, sizeof (*mp));
2340 mp->_vl_msg_id = ntohs (VL_API_L2_FIB_TABLE_ENTRY);
2343 ntohl (l2input_main.bd_configs[l2fe_key->fields.bd_index].bd_id);
2345 mp->mac = l2fib_make_key (l2fe_key->fields.mac, 0);
2346 mp->sw_if_index = ntohl (l2fe_res->fields.sw_if_index);
2347 mp->static_mac = l2fe_res->fields.static_mac;
2348 mp->filter_mac = l2fe_res->fields.filter;
2349 mp->bvi_mac = l2fe_res->fields.bvi;
2350 mp->context = context;
2352 vl_msg_api_send_shmem (q, (u8 *) & mp);
2356 vl_api_l2_fib_table_dump_t_handler (vl_api_l2_fib_table_dump_t * mp)
2358 vpe_api_main_t *am = &vpe_api_main;
2359 bd_main_t *bdm = &bd_main;
2360 l2fib_entry_key_t *l2fe_key = NULL;
2361 l2fib_entry_result_t *l2fe_res = NULL;
2362 u32 ni, bd_id = ntohl (mp->bd_id);
2364 unix_shared_memory_queue_t *q;
2367 q = vl_api_client_index_to_input_queue (mp->client_index);
2371 /* see l2fib_table_dump: ~0 means "any" */
2376 p = hash_get (bdm->bd_index_by_bd_id, bd_id);
2383 l2fib_table_dump (bd_index, &l2fe_key, &l2fe_res);
2385 vec_foreach_index (ni, l2fe_key)
2387 send_l2fib_table_entry (am, q, vec_elt_at_index (l2fe_key, ni),
2388 vec_elt_at_index (l2fe_res, ni), mp->context);
2390 vec_free (l2fe_key);
2391 vec_free (l2fe_res);
2395 vl_api_show_version_t_handler (vl_api_show_version_t * mp)
2397 vl_api_show_version_reply_t *rmp;
2399 char *vpe_api_get_build_directory (void);
2400 char *vpe_api_get_version (void);
2401 char *vpe_api_get_build_date (void);
2403 unix_shared_memory_queue_t *q =
2404 vl_api_client_index_to_input_queue (mp->client_index);
2410 REPLY_MACRO2(VL_API_SHOW_VERSION_REPLY,
2412 strncpy ((char *) rmp->program, "vpe", ARRAY_LEN(rmp->program)-1);
2413 strncpy ((char *) rmp->build_directory, vpe_api_get_build_directory(),
2414 ARRAY_LEN(rmp->build_directory)-1);
2415 strncpy ((char *) rmp->version, vpe_api_get_version(),
2416 ARRAY_LEN(rmp->version)-1);
2417 strncpy ((char *) rmp->build_date, vpe_api_get_build_date(),
2418 ARRAY_LEN(rmp->build_date)-1);
2424 vl_api_get_node_index_t_handler (vl_api_get_node_index_t * mp)
2426 vlib_main_t *vm = vlib_get_main ();
2427 vl_api_get_node_index_reply_t *rmp;
2430 u32 node_index = ~0;
2432 n = vlib_get_node_by_name (vm, mp->node_name);
2435 rv = VNET_API_ERROR_NO_SUCH_NODE;
2437 node_index = n->index;
2440 REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
2442 rmp->node_index = ntohl(node_index);
2448 vl_api_get_next_index_t_handler (vl_api_get_next_index_t * mp)
2450 vlib_main_t *vm = vlib_get_main ();
2451 vl_api_get_next_index_reply_t *rmp;
2452 vlib_node_t *node, *next_node;
2454 u32 next_node_index = ~0, next_index = ~0;
2457 node = vlib_get_node_by_name (vm, mp->node_name);
2461 rv = VNET_API_ERROR_NO_SUCH_NODE;
2465 next_node = vlib_get_node_by_name (vm, mp->next_name);
2469 rv = VNET_API_ERROR_NO_SUCH_NODE2;
2473 next_node_index = next_node->index;
2475 p = hash_get (node->next_slot_by_node, next_node_index);
2479 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
2487 REPLY_MACRO2(VL_API_GET_NEXT_INDEX_REPLY,
2489 rmp->next_index = ntohl(next_index);
2495 vl_api_add_node_next_t_handler (vl_api_add_node_next_t * mp)
2497 vlib_main_t *vm = vlib_get_main ();
2498 vl_api_add_node_next_reply_t *rmp;
2499 vlib_node_t *n, *next;
2501 u32 next_index = ~0;
2503 n = vlib_get_node_by_name (vm, mp->node_name);
2507 rv = VNET_API_ERROR_NO_SUCH_NODE;
2511 next = vlib_get_node_by_name (vm, mp->next_name);
2514 rv = VNET_API_ERROR_NO_SUCH_NODE2;
2516 next_index = vlib_node_add_next (vm, n->index, next->index);
2520 REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
2522 rmp->next_index = ntohl(next_index);
2527 static void vl_api_vxlan_add_del_tunnel_t_handler
2528 (vl_api_vxlan_add_del_tunnel_t * mp)
2530 vl_api_vxlan_add_del_tunnel_reply_t *rmp;
2532 vnet_vxlan_add_del_tunnel_args_t _a, *a = &_a;
2533 u32 encap_fib_index;
2535 ip4_main_t *im = &ip4_main;
2536 vnet_main_t *vnm = vnet_get_main ();
2537 u32 sw_if_index = ~0;
2539 p = hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id));
2542 rv = VNET_API_ERROR_NO_SUCH_FIB;
2545 encap_fib_index = p[0];
2546 memset (a, 0, sizeof (*a));
2548 a->is_add = mp->is_add;
2549 a->is_ip6 = mp->is_ipv6;
2551 /* ip addresses sent in network byte order */
2552 ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &a->dst);
2553 ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &a->src);
2555 /* Check src & dst are different */
2556 if (ip46_address_cmp (&a->dst, &a->src) == 0)
2558 rv = VNET_API_ERROR_SAME_SRC_DST;
2561 a->mcast_sw_if_index = ntohl (mp->mcast_sw_if_index);
2562 if (ip46_address_is_multicast (&a->dst) &&
2563 pool_is_free_index (vnm->interface_main.sw_interfaces,
2564 a->mcast_sw_if_index))
2566 rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
2569 a->encap_fib_index = encap_fib_index;
2570 a->decap_next_index = ntohl (mp->decap_next_index);
2571 a->vni = ntohl (mp->vni);
2572 rv = vnet_vxlan_add_del_tunnel (a, &sw_if_index);
2576 REPLY_MACRO2(VL_API_VXLAN_ADD_DEL_TUNNEL_REPLY,
2578 rmp->sw_if_index = ntohl (sw_if_index);
2583 static void send_vxlan_tunnel_details
2584 (vxlan_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
2586 vl_api_vxlan_tunnel_details_t *rmp;
2587 ip4_main_t *im4 = &ip4_main;
2588 ip6_main_t *im6 = &ip6_main;
2589 u8 is_ipv6 = !ip46_address_is_ip4 (&t->dst);
2591 rmp = vl_msg_api_alloc (sizeof (*rmp));
2592 memset (rmp, 0, sizeof (*rmp));
2593 rmp->_vl_msg_id = ntohs (VL_API_VXLAN_TUNNEL_DETAILS);
2596 memcpy (rmp->src_address, t->src.ip6.as_u8, 16);
2597 memcpy (rmp->dst_address, t->dst.ip6.as_u8, 16);
2598 rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].ft_table_id);
2602 memcpy (rmp->src_address, t->src.ip4.as_u8, 4);
2603 memcpy (rmp->dst_address, t->dst.ip4.as_u8, 4);
2604 rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id);
2606 rmp->mcast_sw_if_index = htonl (t->mcast_sw_if_index);
2607 rmp->vni = htonl (t->vni);
2608 rmp->decap_next_index = htonl (t->decap_next_index);
2609 rmp->sw_if_index = htonl (t->sw_if_index);
2610 rmp->is_ipv6 = is_ipv6;
2611 rmp->context = context;
2613 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2616 static void vl_api_vxlan_tunnel_dump_t_handler
2617 (vl_api_vxlan_tunnel_dump_t * mp)
2619 unix_shared_memory_queue_t *q;
2620 vxlan_main_t *vxm = &vxlan_main;
2624 q = vl_api_client_index_to_input_queue (mp->client_index);
2630 sw_if_index = ntohl (mp->sw_if_index);
2632 if (~0 == sw_if_index)
2635 pool_foreach (t, vxm->tunnels,
2637 send_vxlan_tunnel_details(t, q, mp->context);
2643 if ((sw_if_index >= vec_len (vxm->tunnel_index_by_sw_if_index)) ||
2644 (~0 == vxm->tunnel_index_by_sw_if_index[sw_if_index]))
2648 t = &vxm->tunnels[vxm->tunnel_index_by_sw_if_index[sw_if_index]];
2649 send_vxlan_tunnel_details (t, q, mp->context);
2654 vl_api_l2_patch_add_del_t_handler (vl_api_l2_patch_add_del_t * mp)
2656 extern int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
2658 vl_api_l2_patch_add_del_reply_t *rmp;
2659 int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
2663 VALIDATE_RX_SW_IF_INDEX (mp);
2664 VALIDATE_TX_SW_IF_INDEX (mp);
2666 rv = vnet_l2_patch_add_del (ntohl (mp->rx_sw_if_index),
2667 ntohl (mp->tx_sw_if_index),
2668 (int) (mp->is_add != 0));
2670 BAD_RX_SW_IF_INDEX_LABEL;
2671 BAD_TX_SW_IF_INDEX_LABEL;
2673 REPLY_MACRO (VL_API_L2_PATCH_ADD_DEL_REPLY);
2677 vl_api_vxlan_gpe_add_del_tunnel_t_handler
2678 (vl_api_vxlan_gpe_add_del_tunnel_t * mp)
2680 vl_api_vxlan_gpe_add_del_tunnel_reply_t *rmp;
2682 vnet_vxlan_gpe_add_del_tunnel_args_t _a, *a = &_a;
2683 u32 encap_fib_index, decap_fib_index;
2686 ip4_main_t *im = &ip4_main;
2687 u32 sw_if_index = ~0;
2690 p = hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id));
2693 rv = VNET_API_ERROR_NO_SUCH_FIB;
2696 encap_fib_index = p[0];
2698 protocol = mp->protocol;
2700 /* Interpret decap_vrf_id as an opaque if sending to other-than-ip4-input */
2701 if (protocol == VXLAN_GPE_INPUT_NEXT_IP4_INPUT)
2703 p = hash_get (im->fib_index_by_table_id, ntohl (mp->decap_vrf_id));
2706 rv = VNET_API_ERROR_NO_SUCH_INNER_FIB;
2709 decap_fib_index = p[0];
2713 decap_fib_index = ntohl (mp->decap_vrf_id);
2716 /* Check src & dst are different */
2717 if ((mp->is_ipv6 && memcmp (mp->local, mp->remote, 16) == 0) ||
2718 (!mp->is_ipv6 && memcmp (mp->local, mp->remote, 4) == 0))
2720 rv = VNET_API_ERROR_SAME_SRC_DST;
2723 memset (a, 0, sizeof (*a));
2725 a->is_add = mp->is_add;
2726 a->is_ip6 = mp->is_ipv6;
2727 /* ip addresses sent in network byte order */
2730 clib_memcpy (&(a->local.ip6), mp->local, 16);
2731 clib_memcpy (&(a->remote.ip6), mp->remote, 16);
2735 clib_memcpy (&(a->local.ip4), mp->local, 4);
2736 clib_memcpy (&(a->remote.ip4), mp->remote, 4);
2738 a->encap_fib_index = encap_fib_index;
2739 a->decap_fib_index = decap_fib_index;
2740 a->protocol = protocol;
2741 a->vni = ntohl (mp->vni);
2742 rv = vnet_vxlan_gpe_add_del_tunnel (a, &sw_if_index);
2746 REPLY_MACRO2(VL_API_VXLAN_GPE_ADD_DEL_TUNNEL_REPLY,
2748 rmp->sw_if_index = ntohl (sw_if_index);
2753 static void send_vxlan_gpe_tunnel_details
2754 (vxlan_gpe_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context)
2756 vl_api_vxlan_gpe_tunnel_details_t *rmp;
2757 ip4_main_t *im4 = &ip4_main;
2758 ip6_main_t *im6 = &ip6_main;
2759 u8 is_ipv6 = !(t->flags & VXLAN_GPE_TUNNEL_IS_IPV4);
2761 rmp = vl_msg_api_alloc (sizeof (*rmp));
2762 memset (rmp, 0, sizeof (*rmp));
2763 rmp->_vl_msg_id = ntohs (VL_API_VXLAN_GPE_TUNNEL_DETAILS);
2766 memcpy (rmp->local, &(t->local.ip6), 16);
2767 memcpy (rmp->remote, &(t->remote.ip6), 16);
2768 rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].ft_table_id);
2769 rmp->decap_vrf_id = htonl (im6->fibs[t->decap_fib_index].ft_table_id);
2773 memcpy (rmp->local, &(t->local.ip4), 4);
2774 memcpy (rmp->remote, &(t->remote.ip4), 4);
2775 rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id);
2776 rmp->decap_vrf_id = htonl (im4->fibs[t->decap_fib_index].ft_table_id);
2778 rmp->vni = htonl (t->vni);
2779 rmp->protocol = t->protocol;
2780 rmp->sw_if_index = htonl (t->sw_if_index);
2781 rmp->is_ipv6 = is_ipv6;
2782 rmp->context = context;
2784 vl_msg_api_send_shmem (q, (u8 *) & rmp);
2787 static void vl_api_vxlan_gpe_tunnel_dump_t_handler
2788 (vl_api_vxlan_gpe_tunnel_dump_t * mp)
2790 unix_shared_memory_queue_t *q;
2791 vxlan_gpe_main_t *vgm = &vxlan_gpe_main;
2792 vxlan_gpe_tunnel_t *t;
2795 q = vl_api_client_index_to_input_queue (mp->client_index);
2801 sw_if_index = ntohl (mp->sw_if_index);
2803 if (~0 == sw_if_index)
2806 pool_foreach (t, vgm->tunnels,
2808 send_vxlan_gpe_tunnel_details(t, q, mp->context);
2814 if ((sw_if_index >= vec_len (vgm->tunnel_index_by_sw_if_index)) ||
2815 (~0 == vgm->tunnel_index_by_sw_if_index[sw_if_index]))
2819 t = &vgm->tunnels[vgm->tunnel_index_by_sw_if_index[sw_if_index]];
2820 send_vxlan_gpe_tunnel_details (t, q, mp->context);
2825 vl_api_interface_name_renumber_t_handler (vl_api_interface_name_renumber_t *
2828 vl_api_interface_name_renumber_reply_t *rmp;
2831 VALIDATE_SW_IF_INDEX (mp);
2833 rv = vnet_interface_name_renumber
2834 (ntohl (mp->sw_if_index), ntohl (mp->new_show_dev_instance));
2836 BAD_SW_IF_INDEX_LABEL;
2838 REPLY_MACRO (VL_API_INTERFACE_NAME_RENUMBER_REPLY);
2842 arp_change_data_callback (u32 pool_index, u8 * new_mac,
2843 u32 sw_if_index, u32 address)
2845 vpe_api_main_t *am = &vpe_api_main;
2846 vlib_main_t *vm = am->vlib_main;
2847 vl_api_ip4_arp_event_t *event;
2848 static f64 arp_event_last_time;
2849 f64 now = vlib_time_now (vm);
2851 if (pool_is_free_index (am->arp_events, pool_index))
2854 event = pool_elt_at_index (am->arp_events, pool_index);
2856 if (memcmp (&event->new_mac, new_mac, sizeof (event->new_mac)))
2858 clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
2862 if (sw_if_index == event->sw_if_index &&
2864 /* for BD case, also check IP address with 10 sec timeout */
2865 (address == event->address &&
2866 (now - arp_event_last_time) < 10.0)))
2871 arp_event_last_time = now;
2872 event->sw_if_index = sw_if_index;
2874 event->address = address;
2879 nd_change_data_callback (u32 pool_index, u8 * new_mac,
2880 u32 sw_if_index, ip6_address_t * address)
2882 vpe_api_main_t *am = &vpe_api_main;
2883 vlib_main_t *vm = am->vlib_main;
2884 vl_api_ip6_nd_event_t *event;
2885 static f64 nd_event_last_time;
2886 f64 now = vlib_time_now (vm);
2888 if (pool_is_free_index (am->nd_events, pool_index))
2891 event = pool_elt_at_index (am->nd_events, pool_index);
2894 if (memcmp (&event->new_mac, new_mac, sizeof (event->new_mac)))
2896 clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
2900 if (sw_if_index == event->sw_if_index &&
2902 /* for BD case, also check IP address with 10 sec timeout */
2903 (ip6_address_is_equal (address,
2904 (ip6_address_t *) event->address) &&
2905 (now - nd_event_last_time) < 10.0)))
2910 nd_event_last_time = now;
2911 event->sw_if_index = sw_if_index;
2913 clib_memcpy (event->address, address, sizeof (event->address));
2918 arp_change_delete_callback (u32 pool_index, u8 * notused)
2920 vpe_api_main_t *am = &vpe_api_main;
2922 if (pool_is_free_index (am->arp_events, pool_index))
2925 pool_put_index (am->arp_events, pool_index);
2930 nd_change_delete_callback (u32 pool_index, u8 * notused)
2932 vpe_api_main_t *am = &vpe_api_main;
2934 if (pool_is_free_index (am->nd_events, pool_index))
2937 pool_put_index (am->nd_events, pool_index);
2942 vl_api_want_ip4_arp_events_t_handler (vl_api_want_ip4_arp_events_t * mp)
2944 vpe_api_main_t *am = &vpe_api_main;
2945 vnet_main_t *vnm = vnet_get_main ();
2946 vl_api_want_ip4_arp_events_reply_t *rmp;
2947 vl_api_ip4_arp_event_t *event;
2950 if (mp->enable_disable)
2952 pool_get (am->arp_events, event);
2953 memset (event, 0, sizeof (*event));
2955 event->_vl_msg_id = ntohs (VL_API_IP4_ARP_EVENT);
2956 event->client_index = mp->client_index;
2957 event->context = mp->context;
2958 event->address = mp->address;
2959 event->pid = mp->pid;
2960 if (mp->address == 0)
2963 rv = vnet_add_del_ip4_arp_change_event
2964 (vnm, arp_change_data_callback,
2965 mp->pid, &mp->address /* addr, in net byte order */ ,
2966 vpe_resolver_process_node.index,
2967 IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */ );
2971 rv = vnet_add_del_ip4_arp_change_event
2972 (vnm, arp_change_delete_callback,
2973 mp->pid, &mp->address /* addr, in net byte order */ ,
2974 vpe_resolver_process_node.index,
2975 IP4_ARP_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
2977 REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY);
2981 vl_api_want_ip6_nd_events_t_handler (vl_api_want_ip6_nd_events_t * mp)
2983 vpe_api_main_t *am = &vpe_api_main;
2984 vnet_main_t *vnm = vnet_get_main ();
2985 vl_api_want_ip6_nd_events_reply_t *rmp;
2986 vl_api_ip6_nd_event_t *event;
2989 if (mp->enable_disable)
2991 pool_get (am->nd_events, event);
2992 memset (event, 0, sizeof (*event));
2994 event->_vl_msg_id = ntohs (VL_API_IP6_ND_EVENT);
2995 event->client_index = mp->client_index;
2996 event->context = mp->context;
2997 clib_memcpy (event->address, mp->address, 16);
2998 event->pid = mp->pid;
2999 if (ip6_address_is_zero ((ip6_address_t *) mp->address))
3002 rv = vnet_add_del_ip6_nd_change_event
3003 (vnm, nd_change_data_callback,
3004 mp->pid, mp->address /* addr, in net byte order */ ,
3005 vpe_resolver_process_node.index,
3006 IP6_ND_EVENT, event - am->nd_events, 1 /* is_add */ );
3010 rv = vnet_add_del_ip6_nd_change_event
3011 (vnm, nd_change_delete_callback,
3012 mp->pid, mp->address /* addr, in net byte order */ ,
3013 vpe_resolver_process_node.index,
3014 IP6_ND_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
3016 REPLY_MACRO (VL_API_WANT_IP6_ND_EVENTS_REPLY);
3019 static void vl_api_input_acl_set_interface_t_handler
3020 (vl_api_input_acl_set_interface_t * mp)
3022 vlib_main_t *vm = vlib_get_main ();
3023 vl_api_input_acl_set_interface_reply_t *rmp;
3025 u32 sw_if_index, ip4_table_index, ip6_table_index, l2_table_index;
3027 ip4_table_index = ntohl (mp->ip4_table_index);
3028 ip6_table_index = ntohl (mp->ip6_table_index);
3029 l2_table_index = ntohl (mp->l2_table_index);
3030 sw_if_index = ntohl (mp->sw_if_index);
3032 VALIDATE_SW_IF_INDEX (mp);
3034 rv = vnet_set_input_acl_intfc (vm, sw_if_index, ip4_table_index,
3035 ip6_table_index, l2_table_index, mp->is_add);
3037 BAD_SW_IF_INDEX_LABEL;
3039 REPLY_MACRO (VL_API_INPUT_ACL_SET_INTERFACE_REPLY);
3042 static void vl_api_cop_interface_enable_disable_t_handler
3043 (vl_api_cop_interface_enable_disable_t * mp)
3045 vl_api_cop_interface_enable_disable_reply_t *rmp;
3047 u32 sw_if_index = ntohl (mp->sw_if_index);
3050 VALIDATE_SW_IF_INDEX (mp);
3052 enable_disable = (int) mp->enable_disable;
3054 rv = cop_interface_enable_disable (sw_if_index, enable_disable);
3056 BAD_SW_IF_INDEX_LABEL;
3058 REPLY_MACRO (VL_API_COP_INTERFACE_ENABLE_DISABLE_REPLY);
3061 static void vl_api_cop_whitelist_enable_disable_t_handler
3062 (vl_api_cop_whitelist_enable_disable_t * mp)
3064 vl_api_cop_whitelist_enable_disable_reply_t *rmp;
3065 cop_whitelist_enable_disable_args_t _a, *a = &_a;
3066 u32 sw_if_index = ntohl (mp->sw_if_index);
3069 VALIDATE_SW_IF_INDEX (mp);
3071 a->sw_if_index = sw_if_index;
3074 a->default_cop = mp->default_cop;
3075 a->fib_id = ntohl (mp->fib_id);
3077 rv = cop_whitelist_enable_disable (a);
3079 BAD_SW_IF_INDEX_LABEL;
3081 REPLY_MACRO (VL_API_COP_WHITELIST_ENABLE_DISABLE_REPLY);
3085 vl_api_get_node_graph_t_handler (vl_api_get_node_graph_t * mp)
3089 api_main_t *am = &api_main;
3090 vlib_main_t *vm = vlib_get_main ();
3092 vl_api_get_node_graph_reply_t *rmp;
3094 pthread_mutex_lock (&am->vlib_rp->mutex);
3095 oldheap = svm_push_data_heap (am->vlib_rp);
3098 * Keep the number of memcpy ops to a minimum (e.g. 1).
3100 vec_validate (vector, 16384);
3101 vec_reset_length (vector);
3104 vector = vlib_node_serialize (&vm->node_main, vector,
3105 (u32) ~ 0 /* all threads */ ,
3106 1 /* include nexts */ ,
3107 1 /* include stats */ );
3109 svm_pop_heap (oldheap);
3110 pthread_mutex_unlock (&am->vlib_rp->mutex);
3113 REPLY_MACRO2(VL_API_GET_NODE_GRAPH_REPLY,
3115 rmp->reply_in_shmem = (uword) vector;
3121 vl_api_ioam_enable_t_handler (vl_api_ioam_enable_t * mp)
3124 vl_api_ioam_enable_reply_t *rmp;
3125 clib_error_t *error;
3127 /* Ignoring the profile id as currently a single profile
3129 error = ip6_ioam_enable (mp->trace_enable, mp->pot_enable,
3130 mp->seqno, mp->analyse);
3133 clib_error_report (error);
3134 rv = clib_error_get_code (error);
3137 REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
3141 vl_api_ioam_disable_t_handler (vl_api_ioam_disable_t * mp)
3144 vl_api_ioam_disable_reply_t *rmp;
3145 clib_error_t *error;
3147 error = clear_ioam_rewrite_fn ();
3150 clib_error_report (error);
3151 rv = clib_error_get_code (error);
3154 REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
3158 vl_api_policer_add_del_t_handler (vl_api_policer_add_del_t * mp)
3160 vlib_main_t *vm = vlib_get_main ();
3161 vl_api_policer_add_del_reply_t *rmp;
3164 sse2_qos_pol_cfg_params_st cfg;
3165 clib_error_t *error;
3168 name = format (0, "%s", mp->name);
3170 memset (&cfg, 0, sizeof (cfg));
3172 cfg.rnd_type = mp->round_type;
3173 cfg.rate_type = mp->rate_type;
3174 cfg.rb.kbps.cir_kbps = mp->cir;
3175 cfg.rb.kbps.eir_kbps = mp->eir;
3176 cfg.rb.kbps.cb_bytes = mp->cb;
3177 cfg.rb.kbps.eb_bytes = mp->eb;
3178 cfg.conform_action.action_type = mp->conform_action_type;
3179 cfg.conform_action.dscp = mp->conform_dscp;
3180 cfg.exceed_action.action_type = mp->exceed_action_type;
3181 cfg.exceed_action.dscp = mp->exceed_dscp;
3182 cfg.violate_action.action_type = mp->violate_action_type;
3183 cfg.violate_action.dscp = mp->violate_dscp;
3184 cfg.color_aware = mp->color_aware;
3186 error = policer_add_del (vm, name, &cfg, &policer_index, mp->is_add);
3189 rv = VNET_API_ERROR_UNSPECIFIED;
3192 REPLY_MACRO2(VL_API_POLICER_ADD_DEL_REPLY,
3194 if (rv == 0 && mp->is_add)
3195 rmp->policer_index = ntohl(policer_index);
3197 rmp->policer_index = ~0;
3203 send_policer_details (u8 * name,
3204 sse2_qos_pol_cfg_params_st * config,
3205 policer_read_response_type_st * templ,
3206 unix_shared_memory_queue_t * q, u32 context)
3208 vl_api_policer_details_t *mp;
3210 mp = vl_msg_api_alloc (sizeof (*mp));
3211 memset (mp, 0, sizeof (*mp));
3212 mp->_vl_msg_id = ntohs (VL_API_POLICER_DETAILS);
3213 mp->context = context;
3214 mp->cir = htonl (config->rb.kbps.cir_kbps);
3215 mp->eir = htonl (config->rb.kbps.eir_kbps);
3216 mp->cb = htonl (config->rb.kbps.cb_bytes);
3217 mp->eb = htonl (config->rb.kbps.eb_bytes);
3218 mp->rate_type = config->rate_type;
3219 mp->round_type = config->rnd_type;
3220 mp->type = config->rfc;
3221 mp->conform_action_type = config->conform_action.action_type;
3222 mp->conform_dscp = config->conform_action.dscp;
3223 mp->exceed_action_type = config->exceed_action.action_type;
3224 mp->exceed_dscp = config->exceed_action.dscp;
3225 mp->violate_action_type = config->violate_action.action_type;
3226 mp->violate_dscp = config->violate_action.dscp;
3227 mp->single_rate = templ->single_rate ? 1 : 0;
3228 mp->color_aware = templ->color_aware ? 1 : 0;
3229 mp->scale = htonl (templ->scale);
3230 mp->cir_tokens_per_period = htonl (templ->cir_tokens_per_period);
3231 mp->pir_tokens_per_period = htonl (templ->pir_tokens_per_period);
3232 mp->current_limit = htonl (templ->current_limit);
3233 mp->current_bucket = htonl (templ->current_bucket);
3234 mp->extended_limit = htonl (templ->extended_limit);
3235 mp->extended_bucket = htonl (templ->extended_bucket);
3236 mp->last_update_time = clib_host_to_net_u64 (templ->last_update_time);
3238 strncpy ((char *) mp->name, (char *) name, ARRAY_LEN (mp->name) - 1);
3240 vl_msg_api_send_shmem (q, (u8 *) & mp);
3244 vl_api_policer_dump_t_handler (vl_api_policer_dump_t * mp)
3246 unix_shared_memory_queue_t *q;
3247 vnet_policer_main_t *pm = &vnet_policer_main;
3253 sse2_qos_pol_cfg_params_st *config;
3254 policer_read_response_type_st *templ;
3256 q = vl_api_client_index_to_input_queue (mp->client_index);
3260 if (mp->match_name_valid)
3262 match_name = format (0, "%s%c", mp->match_name, 0);
3265 if (mp->match_name_valid)
3267 p = hash_get_mem (pm->policer_config_by_name, match_name);
3271 config = pool_elt_at_index (pm->configs, pool_index);
3272 templ = pool_elt_at_index (pm->policer_templates, pool_index);
3273 send_policer_details (match_name, config, templ, q, mp->context);
3279 hash_foreach_pair (hp, pm->policer_config_by_name,
3281 name = (u8 *) hp->key;
3282 pool_index = hp->value[0];
3283 config = pool_elt_at_index (pm->configs, pool_index);
3284 templ = pool_elt_at_index (pm->policer_templates, pool_index);
3285 send_policer_details(name, config, templ, q, mp->context);
3292 vl_api_policer_classify_set_interface_t_handler
3293 (vl_api_policer_classify_set_interface_t * mp)
3295 vlib_main_t *vm = vlib_get_main ();
3296 vl_api_policer_classify_set_interface_reply_t *rmp;
3298 u32 sw_if_index, ip4_table_index, ip6_table_index, l2_table_index;
3300 ip4_table_index = ntohl (mp->ip4_table_index);
3301 ip6_table_index = ntohl (mp->ip6_table_index);
3302 l2_table_index = ntohl (mp->l2_table_index);
3303 sw_if_index = ntohl (mp->sw_if_index);
3305 VALIDATE_SW_IF_INDEX (mp);
3307 rv = vnet_set_policer_classify_intfc (vm, sw_if_index, ip4_table_index,
3308 ip6_table_index, l2_table_index,
3311 BAD_SW_IF_INDEX_LABEL;
3313 REPLY_MACRO (VL_API_POLICER_CLASSIFY_SET_INTERFACE_REPLY);
3317 send_policer_classify_details (u32 sw_if_index,
3319 unix_shared_memory_queue_t * q, u32 context)
3321 vl_api_policer_classify_details_t *mp;
3323 mp = vl_msg_api_alloc (sizeof (*mp));
3324 memset (mp, 0, sizeof (*mp));
3325 mp->_vl_msg_id = ntohs (VL_API_POLICER_CLASSIFY_DETAILS);
3326 mp->context = context;
3327 mp->sw_if_index = htonl (sw_if_index);
3328 mp->table_index = htonl (table_index);
3330 vl_msg_api_send_shmem (q, (u8 *) & mp);
3334 vl_api_policer_classify_dump_t_handler (vl_api_policer_classify_dump_t * mp)
3336 unix_shared_memory_queue_t *q;
3337 policer_classify_main_t *pcm = &policer_classify_main;
3341 q = vl_api_client_index_to_input_queue (mp->client_index);
3345 vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type];
3347 if (vec_len (vec_tbl))
3349 for (i = 0; i < vec_len (vec_tbl); i++)
3351 if (vec_elt (vec_tbl, i) == ~0)
3354 send_policer_classify_details (i, vec_elt (vec_tbl, i), q,
3361 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_fib_details_t * mp)
3363 clib_warning ("BUG");
3366 typedef struct mpls_tunnel_send_walk_ctx_t_
3368 unix_shared_memory_queue_t *q;
3371 } mpls_tunnel_send_walk_ctx_t;
3374 send_mpls_tunnel_entry (u32 mti, void *arg)
3376 mpls_tunnel_send_walk_ctx_t *ctx;
3377 vl_api_mpls_tunnel_details_t *mp;
3378 const mpls_tunnel_t *mt;
3383 if (~0 != ctx->index && mti != ctx->index)
3386 mt = mpls_tunnel_get (mti);
3387 nlabels = vec_len (mt->mt_label_stack);
3389 mp = vl_msg_api_alloc (sizeof (*mp) + nlabels * sizeof (u32));
3390 memset (mp, 0, sizeof (*mp));
3391 mp->_vl_msg_id = ntohs (VL_API_MPLS_TUNNEL_DETAILS);
3392 mp->context = ctx->context;
3394 mp->tunnel_index = ntohl (mti);
3395 memcpy (mp->mt_next_hop_out_labels,
3396 mt->mt_label_stack, nlabels * sizeof (u32));
3400 vl_msg_api_send_shmem (ctx->q, (u8 *) & mp);
3404 vl_api_mpls_tunnel_dump_t_handler (vl_api_mpls_tunnel_dump_t * mp)
3406 unix_shared_memory_queue_t *q;
3408 q = vl_api_client_index_to_input_queue (mp->client_index);
3412 mpls_tunnel_send_walk_ctx_t ctx = {
3414 .index = ntohl (mp->tunnel_index),
3415 .context = mp->context,
3417 mpls_tunnel_walk (send_mpls_tunnel_entry, &ctx);
3421 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
3423 clib_warning ("BUG");
3427 vl_api_mpls_fib_details_t_endian (vl_api_mpls_fib_details_t * mp)
3429 clib_warning ("BUG");
3433 vl_api_mpls_fib_details_t_print (vl_api_mpls_fib_details_t * mp)
3435 clib_warning ("BUG");
3439 send_mpls_fib_details (vpe_api_main_t * am,
3440 unix_shared_memory_queue_t * q,
3441 u32 table_id, u32 label, u32 eos,
3442 fib_route_path_encode_t * api_rpaths, u32 context)
3444 vl_api_mpls_fib_details_t *mp;
3445 fib_route_path_encode_t *api_rpath;
3446 vl_api_fib_path2_t *fp;
3449 path_count = vec_len (api_rpaths);
3450 mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
3453 memset (mp, 0, sizeof (*mp));
3454 mp->_vl_msg_id = ntohs (VL_API_MPLS_FIB_DETAILS);
3455 mp->context = context;
3457 mp->table_id = htonl (table_id);
3459 mp->label = htonl (label);
3461 mp->count = htonl (path_count);
3463 vec_foreach (api_rpath, api_rpaths)
3465 memset (fp, 0, sizeof (*fp));
3466 fp->weight = htonl (api_rpath->rpath.frp_weight);
3467 fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
3468 copy_fib_next_hop (api_rpath, fp);
3472 vl_msg_api_send_shmem (q, (u8 *) & mp);
3476 vl_api_mpls_fib_dump_t_handler (vl_api_mpls_fib_dump_t * mp)
3478 vpe_api_main_t *am = &vpe_api_main;
3479 unix_shared_memory_queue_t *q;
3480 mpls_main_t *mm = &mpls_main;
3481 fib_table_t *fib_table;
3482 fib_node_index_t lfei, *lfeip, *lfeis = NULL;
3486 fib_route_path_encode_t *api_rpaths;
3488 q = vl_api_client_index_to_input_queue (mp->client_index);
3493 pool_foreach (fib_table, mm->fibs,
3495 hash_foreach(key, lfei, fib_table->mpls.mf_entries,
3497 vec_add1(lfeis, lfei);
3500 vec_sort_with_function(lfeis, fib_entry_cmp_for_sort);
3502 vec_foreach(lfeip, lfeis)
3504 fib_entry_get_prefix(*lfeip, &pfx);
3505 fib_index = fib_entry_get_fib_index(*lfeip);
3506 fib_table = fib_table_get(fib_index, pfx.fp_proto);
3508 fib_entry_encode(*lfeip, &api_rpaths);
3509 send_mpls_fib_details (am, q,
3510 fib_table->ft_table_id,
3515 vec_free(api_rpaths);
3522 vl_api_classify_table_ids_t_handler (vl_api_classify_table_ids_t * mp)
3524 unix_shared_memory_queue_t *q;
3526 q = vl_api_client_index_to_input_queue (mp->client_index);
3530 vnet_classify_main_t *cm = &vnet_classify_main;
3531 vnet_classify_table_t *t;
3536 pool_foreach (t, cm->tables,
3538 vec_add1 (table_ids, ntohl(t - cm->tables));
3541 count = vec_len (table_ids);
3543 vl_api_classify_table_ids_reply_t *rmp;
3544 rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp) + count * sizeof (u32));
3545 rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TABLE_IDS_REPLY);
3546 rmp->context = mp->context;
3547 rmp->count = ntohl (count);
3548 clib_memcpy (rmp->ids, table_ids, count * sizeof (u32));
3551 vl_msg_api_send_shmem (q, (u8 *) & rmp);
3553 vec_free (table_ids);
3557 vl_api_classify_table_by_interface_t_handler
3558 (vl_api_classify_table_by_interface_t * mp)
3560 vl_api_classify_table_by_interface_reply_t *rmp;
3563 u32 sw_if_index = ntohl (mp->sw_if_index);
3566 vec_validate (acl, INPUT_ACL_N_TABLES - 1);
3569 VALIDATE_SW_IF_INDEX (mp);
3571 input_acl_main_t *am = &input_acl_main;
3576 for (type = 0; type < INPUT_ACL_N_TABLES; type++)
3578 u32 *vec_tbl = am->classify_table_index_by_sw_if_index[type];
3579 if (vec_len (vec_tbl))
3581 for (if_idx = 0; if_idx < vec_len (vec_tbl); if_idx++)
3583 if (vec_elt (vec_tbl, if_idx) == ~0 || sw_if_index != if_idx)
3587 acl[type] = vec_elt (vec_tbl, if_idx);
3592 BAD_SW_IF_INDEX_LABEL;
3595 REPLY_MACRO2(VL_API_CLASSIFY_TABLE_BY_INTERFACE_REPLY,
3597 rmp->sw_if_index = ntohl(sw_if_index);
3598 rmp->l2_table_id = ntohl(acl[INPUT_ACL_TABLE_L2]);
3599 rmp->ip4_table_id = ntohl(acl[INPUT_ACL_TABLE_IP4]);
3600 rmp->ip6_table_id = ntohl(acl[INPUT_ACL_TABLE_IP6]);
3607 vl_api_classify_table_info_t_handler (vl_api_classify_table_info_t * mp)
3609 unix_shared_memory_queue_t *q;
3611 q = vl_api_client_index_to_input_queue (mp->client_index);
3615 vl_api_classify_table_info_reply_t *rmp = 0;
3617 vnet_classify_main_t *cm = &vnet_classify_main;
3618 u32 table_id = ntohl (mp->table_id);
3619 vnet_classify_table_t *t;
3622 pool_foreach (t, cm->tables,
3624 if (table_id == t - cm->tables)
3626 rmp = vl_msg_api_alloc_as_if_client
3627 (sizeof (*rmp) + t->match_n_vectors * sizeof (u32x4));
3628 rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_TABLE_INFO_REPLY);
3629 rmp->context = mp->context;
3630 rmp->table_id = ntohl(table_id);
3631 rmp->nbuckets = ntohl(t->nbuckets);
3632 rmp->match_n_vectors = ntohl(t->match_n_vectors);
3633 rmp->skip_n_vectors = ntohl(t->skip_n_vectors);
3634 rmp->active_sessions = ntohl(t->active_elements);
3635 rmp->next_table_index = ntohl(t->next_table_index);
3636 rmp->miss_next_index = ntohl(t->miss_next_index);
3637 rmp->mask_length = ntohl(t->match_n_vectors * sizeof (u32x4));
3638 clib_memcpy(rmp->mask, t->mask, t->match_n_vectors * sizeof(u32x4));
3647 rmp = vl_msg_api_alloc (sizeof (*rmp));
3648 rmp->_vl_msg_id = ntohs ((VL_API_CLASSIFY_TABLE_INFO_REPLY));
3649 rmp->context = mp->context;
3650 rmp->retval = ntohl (VNET_API_ERROR_CLASSIFY_TABLE_NOT_FOUND);
3653 vl_msg_api_send_shmem (q, (u8 *) & rmp);
3657 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3660 clib_warning ("BUG");
3664 send_classify_session_details (unix_shared_memory_queue_t * q,
3667 vnet_classify_entry_t * e, u32 context)
3669 vl_api_classify_session_details_t *rmp;
3671 rmp = vl_msg_api_alloc (sizeof (*rmp));
3672 memset (rmp, 0, sizeof (*rmp));
3673 rmp->_vl_msg_id = ntohs (VL_API_CLASSIFY_SESSION_DETAILS);
3674 rmp->context = context;
3675 rmp->table_id = ntohl (table_id);
3676 rmp->hit_next_index = ntohl (e->next_index);
3677 rmp->advance = ntohl (e->advance);
3678 rmp->opaque_index = ntohl (e->opaque_index);
3679 rmp->match_length = ntohl (match_length);
3680 clib_memcpy (rmp->match, e->key, match_length);
3682 vl_msg_api_send_shmem (q, (u8 *) & rmp);
3686 vl_api_classify_session_dump_t_handler (vl_api_classify_session_dump_t * mp)
3688 vnet_classify_main_t *cm = &vnet_classify_main;
3689 unix_shared_memory_queue_t *q;
3691 u32 table_id = ntohl (mp->table_id);
3692 vnet_classify_table_t *t;
3694 q = vl_api_client_index_to_input_queue (mp->client_index);
3699 pool_foreach (t, cm->tables,
3701 if (table_id == t - cm->tables)
3703 vnet_classify_bucket_t * b;
3704 vnet_classify_entry_t * v, * save_v;
3707 for (i = 0; i < t->nbuckets; i++)
3709 b = &t->buckets [i];
3713 save_v = vnet_classify_get_entry (t, b->offset);
3714 for (j = 0; j < (1<<b->log2_pages); j++)
3716 for (k = 0; k < t->entries_per_page; k++)
3718 v = vnet_classify_entry_at_index
3719 (t, save_v, j*t->entries_per_page + k);
3720 if (vnet_classify_entry_is_free (v))
3723 send_classify_session_details
3724 (q, table_id, t->match_n_vectors * sizeof (u32x4),
3736 vl_api_set_ipfix_exporter_t_handler (vl_api_set_ipfix_exporter_t * mp)
3738 vlib_main_t *vm = vlib_get_main ();
3739 flow_report_main_t *frm = &flow_report_main;
3740 vl_api_set_ipfix_exporter_reply_t *rmp;
3741 ip4_address_t collector, src;
3742 u16 collector_port = UDP_DST_PORT_ipfix;
3744 u32 template_interval;
3750 memcpy (collector.data, mp->collector_address, sizeof (collector.data));
3751 collector_port = ntohs (mp->collector_port);
3752 if (collector_port == (u16) ~ 0)
3753 collector_port = UDP_DST_PORT_ipfix;
3754 memcpy (src.data, mp->src_address, sizeof (src.data));
3755 fib_id = ntohl (mp->vrf_id);
3757 ip4_main_t *im = &ip4_main;
3764 uword *p = hash_get (im->fib_index_by_table_id, fib_id);
3767 rv = VNET_API_ERROR_NO_SUCH_FIB;
3773 path_mtu = ntohl (mp->path_mtu);
3775 path_mtu = 512; // RFC 7011 section 10.3.3.
3776 template_interval = ntohl (mp->template_interval);
3777 if (template_interval == ~0)
3778 template_interval = 20;
3779 udp_checksum = mp->udp_checksum;
3781 if (collector.as_u32 == 0)
3783 rv = VNET_API_ERROR_INVALID_VALUE;
3787 if (src.as_u32 == 0)
3789 rv = VNET_API_ERROR_INVALID_VALUE;
3793 if (path_mtu > 1450 /* vpp does not support fragmentation */ )
3795 rv = VNET_API_ERROR_INVALID_VALUE;
3801 rv = VNET_API_ERROR_INVALID_VALUE;
3805 /* Reset report streams if we are reconfiguring IP addresses */
3806 if (frm->ipfix_collector.as_u32 != collector.as_u32 ||
3807 frm->src_address.as_u32 != src.as_u32 ||
3808 frm->collector_port != collector_port)
3809 vnet_flow_reports_reset (frm);
3811 frm->ipfix_collector.as_u32 = collector.as_u32;
3812 frm->collector_port = collector_port;
3813 frm->src_address.as_u32 = src.as_u32;
3814 frm->fib_index = fib_index;
3815 frm->path_mtu = path_mtu;
3816 frm->template_interval = template_interval;
3817 frm->udp_checksum = udp_checksum;
3819 /* Turn on the flow reporting process */
3820 vlib_process_signal_event (vm, flow_report_process_node.index, 1, 0);
3823 REPLY_MACRO (VL_API_SET_IPFIX_EXPORTER_REPLY);
3827 vl_api_ipfix_exporter_dump_t_handler (vl_api_ipfix_exporter_dump_t * mp)
3829 flow_report_main_t *frm = &flow_report_main;
3830 unix_shared_memory_queue_t *q;
3831 vl_api_ipfix_exporter_details_t *rmp;
3832 ip4_main_t *im = &ip4_main;
3835 q = vl_api_client_index_to_input_queue (mp->client_index);
3839 rmp = vl_msg_api_alloc (sizeof (*rmp));
3840 memset (rmp, 0, sizeof (*rmp));
3841 rmp->_vl_msg_id = ntohs (VL_API_IPFIX_EXPORTER_DETAILS);
3842 rmp->context = mp->context;
3843 memcpy (rmp->collector_address, frm->ipfix_collector.data,
3844 sizeof (frm->ipfix_collector.data));
3845 rmp->collector_port = htons (frm->collector_port);
3846 memcpy (rmp->src_address, frm->src_address.data,
3847 sizeof (frm->src_address.data));
3848 if (frm->fib_index == ~0)
3851 vrf_id = im->fibs[frm->fib_index].ft_table_id;
3852 rmp->vrf_id = htonl (vrf_id);
3853 rmp->path_mtu = htonl (frm->path_mtu);
3854 rmp->template_interval = htonl (frm->template_interval);
3855 rmp->udp_checksum = (frm->udp_checksum != 0);
3857 vl_msg_api_send_shmem (q, (u8 *) & rmp);
3861 vl_api_set_ipfix_classify_stream_t_handler
3862 (vl_api_set_ipfix_classify_stream_t * mp)
3864 vl_api_set_ipfix_classify_stream_reply_t *rmp;
3865 flow_report_classify_main_t *fcm = &flow_report_classify_main;
3866 flow_report_main_t *frm = &flow_report_main;
3868 u32 src_port = UDP_DST_PORT_ipfix;
3871 domain_id = ntohl (mp->domain_id);
3872 src_port = ntohs (mp->src_port);
3874 if (fcm->src_port != 0 &&
3875 (fcm->domain_id != domain_id || fcm->src_port != (u16) src_port))
3877 int rv = vnet_stream_change (frm, fcm->domain_id, fcm->src_port,
3878 domain_id, (u16) src_port);
3882 fcm->domain_id = domain_id;
3883 fcm->src_port = (u16) src_port;
3885 REPLY_MACRO (VL_API_SET_IPFIX_CLASSIFY_STREAM_REPLY);
3889 vl_api_ipfix_classify_stream_dump_t_handler
3890 (vl_api_ipfix_classify_stream_dump_t * mp)
3892 flow_report_classify_main_t *fcm = &flow_report_classify_main;
3893 unix_shared_memory_queue_t *q;
3894 vl_api_ipfix_classify_stream_details_t *rmp;
3896 q = vl_api_client_index_to_input_queue (mp->client_index);
3900 rmp = vl_msg_api_alloc (sizeof (*rmp));
3901 memset (rmp, 0, sizeof (*rmp));
3902 rmp->_vl_msg_id = ntohs (VL_API_IPFIX_CLASSIFY_STREAM_DETAILS);
3903 rmp->context = mp->context;
3904 rmp->domain_id = htonl (fcm->domain_id);
3905 rmp->src_port = htons (fcm->src_port);
3907 vl_msg_api_send_shmem (q, (u8 *) & rmp);
3911 vl_api_ipfix_classify_table_add_del_t_handler
3912 (vl_api_ipfix_classify_table_add_del_t * mp)
3914 vl_api_ipfix_classify_table_add_del_reply_t *rmp;
3915 flow_report_classify_main_t *fcm = &flow_report_classify_main;
3916 flow_report_main_t *frm = &flow_report_main;
3917 vnet_flow_report_add_del_args_t args;
3918 ipfix_classify_table_t *table;
3920 u32 classify_table_index;
3922 u8 transport_protocol;
3925 classify_table_index = ntohl (mp->table_id);
3926 ip_version = mp->ip_version;
3927 transport_protocol = mp->transport_protocol;
3928 is_add = mp->is_add;
3930 if (fcm->src_port == 0)
3932 /* call set_ipfix_classify_stream first */
3933 rv = VNET_API_ERROR_UNSPECIFIED;
3937 memset (&args, 0, sizeof (args));
3941 for (i = 0; i < vec_len (fcm->tables); i++)
3942 if (ipfix_classify_table_index_valid (i))
3943 if (fcm->tables[i].classify_table_index == classify_table_index)
3945 table = &fcm->tables[i];
3953 rv = VNET_API_ERROR_VALUE_EXIST;
3956 table = ipfix_classify_add_table ();
3957 table->classify_table_index = classify_table_index;
3963 rv = VNET_API_ERROR_NO_SUCH_ENTRY;
3968 table->ip_version = ip_version;
3969 table->transport_protocol = transport_protocol;
3971 args.opaque.as_uword = table - fcm->tables;
3972 args.rewrite_callback = ipfix_classify_template_rewrite;
3973 args.flow_data_callback = ipfix_classify_send_flows;
3974 args.is_add = is_add;
3975 args.domain_id = fcm->domain_id;
3976 args.src_port = fcm->src_port;
3978 rv = vnet_flow_report_add_del (frm, &args);
3980 /* If deleting, or add failed */
3981 if (is_add == 0 || (rv && is_add))
3982 ipfix_classify_delete_table (table - fcm->tables);
3985 REPLY_MACRO (VL_API_SET_IPFIX_CLASSIFY_STREAM_REPLY);
3989 send_ipfix_classify_table_details (u32 table_index,
3990 unix_shared_memory_queue_t * q,
3993 flow_report_classify_main_t *fcm = &flow_report_classify_main;
3994 vl_api_ipfix_classify_table_details_t *mp;
3996 ipfix_classify_table_t *table = &fcm->tables[table_index];
3998 mp = vl_msg_api_alloc (sizeof (*mp));
3999 memset (mp, 0, sizeof (*mp));
4000 mp->_vl_msg_id = ntohs (VL_API_IPFIX_CLASSIFY_TABLE_DETAILS);
4001 mp->context = context;
4002 mp->table_id = htonl (table->classify_table_index);
4003 mp->ip_version = table->ip_version;
4004 mp->transport_protocol = table->transport_protocol;
4006 vl_msg_api_send_shmem (q, (u8 *) & mp);
4010 vl_api_ipfix_classify_table_dump_t_handler
4011 (vl_api_ipfix_classify_table_dump_t * mp)
4013 flow_report_classify_main_t *fcm = &flow_report_classify_main;
4014 unix_shared_memory_queue_t *q;
4017 q = vl_api_client_index_to_input_queue (mp->client_index);
4021 for (i = 0; i < vec_len (fcm->tables); i++)
4022 if (ipfix_classify_table_index_valid (i))
4023 send_ipfix_classify_table_details (i, q, mp->context);
4027 vl_api_pg_create_interface_t_handler (vl_api_pg_create_interface_t * mp)
4029 vl_api_pg_create_interface_reply_t *rmp;
4032 pg_main_t *pg = &pg_main;
4033 u32 pg_if_id = pg_interface_add_or_get (pg, ntohl (mp->interface_id));
4034 pg_interface_t *pi = pool_elt_at_index (pg->interfaces, pg_if_id);
4037 REPLY_MACRO2(VL_API_PG_CREATE_INTERFACE_REPLY,
4039 rmp->sw_if_index = ntohl(pi->sw_if_index);
4045 vl_api_pg_capture_t_handler (vl_api_pg_capture_t * mp)
4047 vl_api_pg_capture_reply_t *rmp;
4050 vnet_main_t *vnm = vnet_get_main ();
4051 vnet_interface_main_t *im = &vnm->interface_main;
4052 vnet_hw_interface_t *hi = 0;
4054 u8 *intf_name = format (0, "pg%d", ntohl (mp->interface_id), 0);
4055 u32 hw_if_index = ~0;
4056 uword *p = hash_get_mem (im->hw_interface_by_name, intf_name);
4059 vec_free (intf_name);
4061 if (hw_if_index != ~0)
4063 pg_capture_args_t _a, *a = &_a;
4065 u32 len = ntohl (mp->pcap_name_length);
4066 u8 *pcap_file_name = vec_new (u8, len);
4067 clib_memcpy (pcap_file_name, mp->pcap_file_name, len);
4069 hi = vnet_get_sup_hw_interface (vnm, hw_if_index);
4070 a->hw_if_index = hw_if_index;
4071 a->dev_instance = hi->dev_instance;
4072 a->is_enabled = mp->is_enabled;
4073 a->pcap_file_name = pcap_file_name;
4074 a->count = ntohl (mp->count);
4076 clib_error_t *e = pg_capture (a);
4079 clib_error_report (e);
4080 rv = VNET_API_ERROR_CANNOT_CREATE_PCAP_FILE;
4083 vec_free (pcap_file_name);
4085 REPLY_MACRO (VL_API_PG_CAPTURE_REPLY);
4089 vl_api_pg_enable_disable_t_handler (vl_api_pg_enable_disable_t * mp)
4091 vl_api_pg_enable_disable_reply_t *rmp;
4094 pg_main_t *pg = &pg_main;
4095 u32 stream_index = ~0;
4097 int is_enable = mp->is_enabled != 0;
4098 u32 len = ntohl (mp->stream_name_length) - 1;
4102 u8 *stream_name = vec_new (u8, len);
4103 clib_memcpy (stream_name, mp->stream_name, len);
4104 uword *p = hash_get_mem (pg->stream_index_by_name, stream_name);
4107 vec_free (stream_name);
4110 pg_enable_disable (stream_index, is_enable);
4112 REPLY_MACRO (VL_API_PG_ENABLE_DISABLE_REPLY);
4116 vl_api_ip_source_and_port_range_check_add_del_t_handler
4117 (vl_api_ip_source_and_port_range_check_add_del_t * mp)
4119 vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
4122 u8 is_ipv6 = mp->is_ipv6;
4123 u8 is_add = mp->is_add;
4124 u8 mask_length = mp->mask_length;
4125 ip4_address_t ip4_addr;
4126 ip6_address_t ip6_addr;
4128 u16 *high_ports = 0;
4130 u16 tmp_low, tmp_high;
4134 // Validate port range
4135 num_ranges = mp->number_of_ranges;
4136 if (num_ranges > 32)
4137 { // This is size of array in VPE.API
4138 rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
4142 vec_reset_length (low_ports);
4143 vec_reset_length (high_ports);
4145 for (i = 0; i < num_ranges; i++)
4147 tmp_low = mp->low_ports[i];
4148 tmp_high = mp->high_ports[i];
4149 // If tmp_low <= tmp_high then only need to check tmp_low = 0
4150 // If tmp_low <= tmp_high then only need to check tmp_high > 65535
4151 if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535)
4153 rv = VNET_API_ERROR_INVALID_VALUE;
4156 vec_add1 (low_ports, tmp_low);
4157 vec_add1 (high_ports, tmp_high + 1);
4160 // Validate mask_length
4161 if ((is_ipv6 && mask_length > 128) || (!is_ipv6 && mask_length > 32))
4163 rv = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH;
4167 vrf_id = ntohl (mp->vrf_id);
4171 rv = VNET_API_ERROR_INVALID_VALUE;
4178 clib_memcpy (ip6_addr.as_u8, mp->address, sizeof (ip6_addr.as_u8));
4179 rv = ip6_source_and_port_range_check_add_del (&ip6_addr,
4183 high_ports, is_add);
4187 clib_memcpy (ip4_addr.data, mp->address, sizeof (ip4_addr));
4188 rv = ip4_source_and_port_range_check_add_del (&ip4_addr,
4192 high_ports, is_add);
4196 vec_free (low_ports);
4197 vec_free (high_ports);
4198 REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY);
4202 vl_api_ip_source_and_port_range_check_interface_add_del_t_handler
4203 (vl_api_ip_source_and_port_range_check_interface_add_del_t * mp)
4205 vlib_main_t *vm = vlib_get_main ();
4206 vl_api_ip_source_and_port_range_check_interface_add_del_reply_t *rmp;
4207 ip4_main_t *im = &ip4_main;
4210 u32 fib_index[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS];
4211 u32 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS];
4215 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_OUT] =
4216 ntohl (mp->tcp_out_vrf_id);
4217 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_OUT] =
4218 ntohl (mp->udp_out_vrf_id);
4219 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_TCP_IN] =
4220 ntohl (mp->tcp_in_vrf_id);
4221 vrf_id[IP_SOURCE_AND_PORT_RANGE_CHECK_PROTOCOL_UDP_IN] =
4222 ntohl (mp->udp_in_vrf_id);
4225 for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
4227 if (vrf_id[i] != 0 && vrf_id[i] != ~0)
4229 p = hash_get (im->fib_index_by_table_id, vrf_id[i]);
4233 rv = VNET_API_ERROR_INVALID_VALUE;
4237 fib_index[i] = p[0];
4242 sw_if_index = ntohl (mp->sw_if_index);
4244 VALIDATE_SW_IF_INDEX (mp);
4247 set_ip_source_and_port_range_check (vm, fib_index, sw_if_index,
4250 BAD_SW_IF_INDEX_LABEL;
4253 REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY);
4257 vl_api_delete_subif_t_handler (vl_api_delete_subif_t * mp)
4259 vl_api_delete_subif_reply_t *rmp;
4262 rv = vnet_delete_sub_interface (ntohl (mp->sw_if_index));
4264 REPLY_MACRO (VL_API_DELETE_SUBIF_REPLY);
4268 vl_api_l2_interface_pbb_tag_rewrite_t_handler
4269 (vl_api_l2_interface_pbb_tag_rewrite_t * mp)
4271 vl_api_l2_interface_pbb_tag_rewrite_reply_t *rmp;
4272 vnet_main_t *vnm = vnet_get_main ();
4273 vlib_main_t *vm = vlib_get_main ();
4277 VALIDATE_SW_IF_INDEX (mp);
4279 vtr_op = ntohl (mp->vtr_op);
4283 case L2_VTR_DISABLED:
4286 case L2_VTR_TRANSLATE_2_1:
4290 rv = VNET_API_ERROR_INVALID_VALUE;
4291 goto bad_sw_if_index;
4294 rv = l2pbb_configure (vm, vnm, ntohl (mp->sw_if_index), vtr_op,
4295 mp->b_dmac, mp->b_smac, ntohs (mp->b_vlanid),
4296 ntohl (mp->i_sid), ntohs (mp->outer_tag));
4298 BAD_SW_IF_INDEX_LABEL;
4300 REPLY_MACRO (VL_API_L2_INTERFACE_PBB_TAG_REWRITE_REPLY);
4305 vl_api_punt_t_handler (vl_api_punt_t * mp)
4307 vl_api_punt_reply_t *rmp;
4308 vlib_main_t *vm = vlib_get_main ();
4310 clib_error_t *error;
4312 error = vnet_punt_add_del (vm, mp->ipv, mp->l4_protocol,
4313 ntohs (mp->l4_port), mp->is_add);
4317 clib_error_report (error);
4320 REPLY_MACRO (VL_API_PUNT_REPLY);
4324 vl_api_flow_classify_set_interface_t_handler
4325 (vl_api_flow_classify_set_interface_t * mp)
4327 vlib_main_t *vm = vlib_get_main ();
4328 vl_api_flow_classify_set_interface_reply_t *rmp;
4330 u32 sw_if_index, ip4_table_index, ip6_table_index;
4332 ip4_table_index = ntohl (mp->ip4_table_index);
4333 ip6_table_index = ntohl (mp->ip6_table_index);
4334 sw_if_index = ntohl (mp->sw_if_index);
4336 VALIDATE_SW_IF_INDEX (mp);
4338 rv = vnet_set_flow_classify_intfc (vm, sw_if_index, ip4_table_index,
4339 ip6_table_index, mp->is_add);
4341 BAD_SW_IF_INDEX_LABEL;
4343 REPLY_MACRO (VL_API_FLOW_CLASSIFY_SET_INTERFACE_REPLY);
4347 send_flow_classify_details (u32 sw_if_index,
4349 unix_shared_memory_queue_t * q, u32 context)
4351 vl_api_flow_classify_details_t *mp;
4353 mp = vl_msg_api_alloc (sizeof (*mp));
4354 memset (mp, 0, sizeof (*mp));
4355 mp->_vl_msg_id = ntohs (VL_API_FLOW_CLASSIFY_DETAILS);
4356 mp->context = context;
4357 mp->sw_if_index = htonl (sw_if_index);
4358 mp->table_index = htonl (table_index);
4360 vl_msg_api_send_shmem (q, (u8 *) & mp);
4364 vl_api_flow_classify_dump_t_handler (vl_api_flow_classify_dump_t * mp)
4366 unix_shared_memory_queue_t *q;
4367 flow_classify_main_t *pcm = &flow_classify_main;
4371 q = vl_api_client_index_to_input_queue (mp->client_index);
4375 vec_tbl = pcm->classify_table_index_by_sw_if_index[mp->type];
4377 if (vec_len (vec_tbl))
4379 for (i = 0; i < vec_len (vec_tbl); i++)
4381 if (vec_elt (vec_tbl, i) == ~0)
4384 send_flow_classify_details (i, vec_elt (vec_tbl, i), q,
4391 vl_api_feature_enable_disable_t_handler (vl_api_feature_enable_disable_t * mp)
4393 vl_api_feature_enable_disable_reply_t *rmp;
4395 u8 *arc_name, *feature_name;
4397 VALIDATE_SW_IF_INDEX (mp);
4399 arc_name = format (0, "%s%c", mp->arc_name, 0);
4400 feature_name = format (0, "%s%c", mp->feature_name, 0);
4402 vnet_feature_registration_t *reg;
4404 vnet_get_feature_reg ((const char *) arc_name,
4405 (const char *) feature_name);
4407 rv = VNET_API_ERROR_INVALID_VALUE;
4411 clib_error_t *error = 0;
4413 sw_if_index = ntohl (mp->sw_if_index);
4414 if (reg->enable_disable_cb)
4415 error = reg->enable_disable_cb (sw_if_index, mp->enable);
4417 vnet_feature_enable_disable ((const char *) arc_name,
4418 (const char *) feature_name,
4419 sw_if_index, mp->enable, 0, 0);
4422 clib_error_report (error);
4423 rv = VNET_API_ERROR_CANNOT_ENABLE_DISABLE_FEATURE;
4427 vec_free (feature_name);
4428 vec_free (arc_name);
4430 BAD_SW_IF_INDEX_LABEL;
4432 REPLY_MACRO (VL_API_FEATURE_ENABLE_DISABLE_REPLY);
4435 #define BOUNCE_HANDLER(nn) \
4436 static void vl_api_##nn##_t_handler ( \
4437 vl_api_##nn##_t *mp) \
4439 vpe_client_registration_t *reg; \
4440 vpe_api_main_t * vam = &vpe_api_main; \
4441 unix_shared_memory_queue_t * q; \
4443 /* One registration only... */ \
4444 pool_foreach(reg, vam->nn##_registrations, \
4446 q = vl_api_client_index_to_input_queue (reg->client_index); \
4449 * If the queue is stuffed, turf the msg and complain \
4450 * It's unlikely that the intended recipient is \
4451 * alive; avoid deadlock at all costs. \
4453 if (q->cursize == q->maxsize) { \
4454 clib_warning ("ERROR: receiver queue full, drop msg"); \
4455 vl_msg_api_free (mp); \
4458 vl_msg_api_send_shmem (q, (u8 *)&mp); \
4462 vl_msg_api_free (mp); \
4465 static void setup_message_id_table (api_main_t * am);
4469 * Add vpe's API message handlers to the table.
4470 * vlib has alread mapped shared memory and
4471 * added the client registration handlers.
4472 * See .../open-repo/vlib/memclnt_vlib.c:memclnt_process()
4474 static clib_error_t *
4475 vpe_api_hookup (vlib_main_t * vm)
4477 api_main_t *am = &api_main;
4480 vl_msg_api_set_handlers(VL_API_##N, #n, \
4481 vl_api_##n##_t_handler, \
4483 vl_api_##n##_t_endian, \
4484 vl_api_##n##_t_print, \
4485 sizeof(vl_api_##n##_t), 1);
4486 foreach_vpe_api_msg;
4490 * Manually register the sr tunnel add del msg, so we trace
4491 * enough bytes to capture a typical segment list
4493 vl_msg_api_set_handlers (VL_API_SR_TUNNEL_ADD_DEL,
4494 "sr_tunnel_add_del",
4495 vl_api_sr_tunnel_add_del_t_handler,
4497 vl_api_sr_tunnel_add_del_t_endian,
4498 vl_api_sr_tunnel_add_del_t_print, 256, 1);
4502 * Manually register the sr policy add del msg, so we trace
4503 * enough bytes to capture a typical tunnel name list
4505 vl_msg_api_set_handlers (VL_API_SR_POLICY_ADD_DEL,
4506 "sr_policy_add_del",
4507 vl_api_sr_policy_add_del_t_handler,
4509 vl_api_sr_policy_add_del_t_endian,
4510 vl_api_sr_policy_add_del_t_print, 256, 1);
4513 * Trace space for 8 MPLS encap labels, classifier mask+match
4515 am->api_trace_cfg[VL_API_MPLS_TUNNEL_ADD_DEL].size += 8 * sizeof (u32);
4516 am->api_trace_cfg[VL_API_CLASSIFY_ADD_DEL_TABLE].size += 5 * sizeof (u32x4);
4517 am->api_trace_cfg[VL_API_CLASSIFY_ADD_DEL_SESSION].size
4518 += 5 * sizeof (u32x4);
4519 am->api_trace_cfg[VL_API_VXLAN_ADD_DEL_TUNNEL].size += 16 * sizeof (u32);
4522 * Thread-safe API messages
4524 am->is_mp_safe[VL_API_IP_ADD_DEL_ROUTE] = 1;
4525 am->is_mp_safe[VL_API_GET_NODE_GRAPH] = 1;
4528 * Set up the (msg_name, crc, message-id) table
4530 setup_message_id_table (am);
4535 VLIB_API_INIT_FUNCTION (vpe_api_hookup);
4537 static clib_error_t *
4538 vpe_api_init (vlib_main_t * vm)
4540 vpe_api_main_t *am = &vpe_api_main;
4543 am->vnet_main = vnet_get_main ();
4544 am->interface_events_registration_hash = hash_create (0, sizeof (uword));
4545 am->to_netconf_server_registration_hash = hash_create (0, sizeof (uword));
4546 am->from_netconf_server_registration_hash = hash_create (0, sizeof (uword));
4547 am->to_netconf_client_registration_hash = hash_create (0, sizeof (uword));
4548 am->from_netconf_client_registration_hash = hash_create (0, sizeof (uword));
4549 am->oam_events_registration_hash = hash_create (0, sizeof (uword));
4550 am->bfd_events_registration_hash = hash_create (0, sizeof (uword));
4553 vl_set_memory_region_name ("/vpe-api");
4554 vl_enable_disable_memory_api (vm, 1 /* enable it */ );
4559 VLIB_INIT_FUNCTION (vpe_api_init);
4562 static clib_error_t *
4563 api_segment_config (vlib_main_t * vm, unformat_input_t * input)
4566 u64 baseva, size, pvt_heap_size;
4568 const int max_buf_size = 4096;
4570 struct passwd _pw, *pw;
4571 struct group _grp, *grp;
4573 buf = vec_new (char, 128);
4574 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
4576 if (unformat (input, "prefix %s", &chroot_path))
4578 vec_add1 (chroot_path, 0);
4579 vl_set_memory_root_path ((char *) chroot_path);
4581 else if (unformat (input, "uid %d", &uid))
4582 vl_set_memory_uid (uid);
4583 else if (unformat (input, "gid %d", &gid))
4584 vl_set_memory_gid (gid);
4585 else if (unformat (input, "baseva %llx", &baseva))
4586 vl_set_global_memory_baseva (baseva);
4587 else if (unformat (input, "global-size %lldM", &size))
4588 vl_set_global_memory_size (size * (1ULL << 20));
4589 else if (unformat (input, "global-size %lldG", &size))
4590 vl_set_global_memory_size (size * (1ULL << 30));
4591 else if (unformat (input, "global-size %lld", &size))
4592 vl_set_global_memory_size (size);
4593 else if (unformat (input, "global-pvt-heap-size %lldM", &pvt_heap_size))
4594 vl_set_global_pvt_heap_size (pvt_heap_size * (1ULL << 20));
4595 else if (unformat (input, "global-pvt-heap-size size %lld",
4597 vl_set_global_pvt_heap_size (pvt_heap_size);
4598 else if (unformat (input, "api-pvt-heap-size %lldM", &pvt_heap_size))
4599 vl_set_api_pvt_heap_size (pvt_heap_size * (1ULL << 20));
4600 else if (unformat (input, "api-pvt-heap-size size %lld",
4602 vl_set_api_pvt_heap_size (pvt_heap_size);
4603 else if (unformat (input, "api-size %lldM", &size))
4604 vl_set_api_memory_size (size * (1ULL << 20));
4605 else if (unformat (input, "api-size %lldG", &size))
4606 vl_set_api_memory_size (size * (1ULL << 30));
4607 else if (unformat (input, "api-size %lld", &size))
4608 vl_set_api_memory_size (size);
4609 else if (unformat (input, "uid %s", &s))
4611 /* lookup the username */
4614 getpwnam_r (s, &_pw, buf, vec_len (buf), &pw)) == ERANGE)
4615 && (vec_len (buf) <= max_buf_size))
4617 vec_resize (buf, vec_len (buf) * 2);
4621 e = clib_error_return_code (0, rv,
4622 CLIB_ERROR_ERRNO_VALID |
4624 "cannot fetch username %s", s);
4632 clib_error_return_fatal (0, "username %s does not exist", s);
4638 vl_set_memory_uid (pw->pw_uid);
4640 else if (unformat (input, "gid %s", &s))
4642 /* lookup the group name */
4645 getgrnam_r (s, &_grp, buf, vec_len (buf), &grp)) == ERANGE)
4646 && (vec_len (buf) <= max_buf_size))
4648 vec_resize (buf, vec_len (buf) * 2);
4652 e = clib_error_return_code (0, rv,
4653 CLIB_ERROR_ERRNO_VALID |
4655 "cannot fetch group %s", s);
4662 e = clib_error_return_fatal (0, "group %s does not exist", s);
4669 vl_set_memory_gid (grp->gr_gid);
4672 return clib_error_return (0, "unknown input `%U'",
4673 format_unformat_error, input);
4678 VLIB_EARLY_CONFIG_FUNCTION (api_segment_config, "api-segment");
4681 get_unformat_vnet_sw_interface (void)
4683 return (void *) &unformat_vnet_sw_interface;
4687 format_arp_event (u8 * s, va_list * args)
4689 vl_api_ip4_arp_event_t *event = va_arg (*args, vl_api_ip4_arp_event_t *);
4691 s = format (s, "pid %d: ", event->pid);
4693 s = format (s, "bd mac/ip4 binding events");
4695 s = format (s, "resolution for %U", format_ip4_address, &event->address);
4700 format_nd_event (u8 * s, va_list * args)
4702 vl_api_ip6_nd_event_t *event = va_arg (*args, vl_api_ip6_nd_event_t *);
4704 s = format (s, "pid %d: ", event->pid);
4706 s = format (s, "bd mac/ip6 binding events");
4708 s = format (s, "resolution for %U", format_ip6_address, event->address);
4712 static clib_error_t *
4713 show_ip_arp_nd_events_fn (vlib_main_t * vm,
4714 unformat_input_t * input, vlib_cli_command_t * cmd)
4716 vpe_api_main_t *am = &vpe_api_main;
4717 vl_api_ip4_arp_event_t *arp_event;
4718 vl_api_ip6_nd_event_t *nd_event;
4720 if ((pool_elts (am->arp_events) == 0) && (pool_elts (am->nd_events) == 0))
4722 vlib_cli_output (vm, "No active arp or nd event registrations");
4727 pool_foreach (arp_event, am->arp_events,
4729 vlib_cli_output (vm, "%U", format_arp_event, arp_event);
4732 pool_foreach (nd_event, am->nd_events,
4734 vlib_cli_output (vm, "%U", format_nd_event, nd_event);
4742 VLIB_CLI_COMMAND (show_ip_arp_nd_events, static) = {
4743 .path = "show arp-nd-event registrations",
4744 .function = show_ip_arp_nd_events_fn,
4745 .short_help = "Show ip4 arp and ip6 nd event registrations",
4749 #define vl_msg_name_crc_list
4750 #include <vpp/api/vpe_all_api_h.h>
4751 #undef vl_msg_name_crc_list
4754 setup_message_id_table (api_main_t * am)
4756 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
4757 foreach_vl_msg_name_crc_memclnt;
4758 foreach_vl_msg_name_crc_vpe;
4764 * fd.io coding-style-patch-verification: ON
4767 * eval: (c-set-style "gnu")