30 #include <vpp/app/version.h> 46 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) 52 #define vl_api_version(n,v) static u32 api_version=(v); 56 #define REPLY_MSG_ID_BASE nsm->msg_id_base 63 #define foreach_nsim_plugin_api_msg \ 64 _(NSIM_ENABLE_DISABLE, nsim_enable_disable) \ 65 _(NSIM_CONFIGURE, nsim_configure) 71 u32 sw_if_index1,
int enable_disable)
78 return VNET_API_ERROR_CANNOT_ENABLE_DISABLE_FEATURE;
83 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
87 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
92 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
96 return VNET_API_ERROR_INVALID_SW_IF_INDEX;
113 sw_if_index0, enable_disable, 0, 0);
115 sw_if_index1, enable_disable, 0, 0);
123 u64 total_buffer_size_in_bytes, per_worker_buffer_size;
124 u64 wheel_slots_per_worker;
127 u32 pagesize = getpagesize ();
130 if (bandwidth == 0.0)
131 return VNET_API_ERROR_INVALID_VALUE;
134 return VNET_API_ERROR_INVALID_VALUE_2;
137 return VNET_API_ERROR_INVALID_VALUE_3;
153 total_buffer_size_in_bytes = (
u32) ((delay * bandwidth) / 8.0) + 0.5;
160 per_worker_buffer_size = total_buffer_size_in_bytes / num_workers;
162 per_worker_buffer_size = total_buffer_size_in_bytes;
164 wheel_slots_per_worker = per_worker_buffer_size / packet_size;
165 wheel_slots_per_worker++;
175 for (i = num_workers ? 1 : 0; i < num_workers + 1; i++)
191 wp->
entries = (
void *) (wp + 1);
200 for (i = num_workers ? 1 : 0; i < num_workers + 1; i++)
205 VLIB_NODE_STATE_POLLING);
223 u32 sw_if_index0 = ~0;
224 u32 sw_if_index1 = ~0;
225 int enable_disable = 1;
236 if (sw_if_index0 == ~0)
245 if (sw_if_index0 == ~0 || sw_if_index1 == ~0)
255 case VNET_API_ERROR_CANNOT_ENABLE_DISABLE_FEATURE:
258 case VNET_API_ERROR_INVALID_SW_IF_INDEX:
260 (0,
"Invalid interface, only works on physical ports");
263 case VNET_API_ERROR_UNIMPLEMENTED:
265 "Device driver doesn't support redirection");
293 .path =
"nsim enable-disable",
295 "nsim enable-disable <interface-name-1> <interface-name-2> [disable]",
304 vl_api_nsim_enable_disable_reply_t *rmp;
319 vl_api_nsim_configure_reply_t *rmp;
321 f64 delay, bandwidth, packet_size;
340 vl_msg_api_set_handlers((VL_API_##N + nsm->msg_id_base), \ 342 vl_api_##n##_t_handler, \ 344 vl_api_##n##_t_endian, \ 345 vl_api_##n##_t_print, \ 346 sizeof(vl_api_##n##_t), 1); 353 #define vl_msg_name_crc_list 355 #undef vl_msg_name_crc_list 360 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n #crc, id + nsm->msg_id_base); 361 foreach_vl_msg_name_crc_nsim;
375 name =
format (0,
"nsim_%08x%c", api_version, 0);
396 .arc_name =
"device-input",
405 .version = VPP_BUILD_VER,
406 .description =
"network delay simulator plugin",
413 f64 *result = va_arg (*args,
f64 *);
416 if (
unformat (input,
"%f us", &tmp))
417 *result = tmp * 1e-6;
418 else if (
unformat (input,
"%f ms", &tmp))
419 *result = tmp * 1e-3;
420 else if (
unformat (input,
"%f sec", &tmp))
431 f64 *result = va_arg (*args,
f64 *);
434 if (
unformat (input,
"%f gbit", &tmp))
436 else if (
unformat (input,
"%f gbyte", &tmp))
448 f64 delay, bandwidth;
449 f64 packet_size = 1500.0;
460 else if (
unformat (input,
"packet-size %f", &packet_size))
470 case VNET_API_ERROR_INVALID_VALUE:
473 case VNET_API_ERROR_INVALID_VALUE_2:
476 case VNET_API_ERROR_INVALID_VALUE_3:
486 vlib_cli_output (vm,
"Configured link delay %.2f ms, %.2f ms round-trip",
490 vlib_cli_output (vm,
"Sim uses %llu bytes per thread, %llu bytes total",
518 .short_help =
"set nsim delay <time> bandwidth <bps> packet-size <nbytes>",
548 "...inserting link delay of %.2f ms, %.2f ms round-trip",
559 (vm,
" Sim uses %llu bytes per thread, %llu bytes total",
588 .short_help =
"Display network delay simulator configuration",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static clib_error_t * nsim_init(vlib_main_t *vm)
#define WHEEL_ENTRY_DATA_SIZE
vnet_main_t * vnet_get_main(void)
vnet_interface_main_t interface_main
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
static int nsim_configure(nsim_main_t *nsm, f64 bandwidth, f64 delay, f64 packet_size)
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
unformat_function_t unformat_vnet_sw_interface
vlib_main_t ** vlib_mains
format_function_t format_vnet_sw_if_index_name
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
#define vlib_worker_thread_barrier_sync(X)
#define VLIB_INIT_FUNCTION(x)
#define clib_error_return(e, args...)
static uword unformat_delay(unformat_input_t *input, va_list *args)
VNET_FEATURE_INIT(nsim, static)
API main structure, used by both vpp and binary API clients.
int nsim_enable_disable(nsim_main_t *nsm, u32 sw_if_index0, u32 sw_if_index1, int enable_disable)
static void vl_api_nsim_configure_t_handler(vl_api_nsim_configure_t *mp)
vlib_node_registration_t nsim_input_node
(constructor) VLIB_REGISTER_NODE (nsim_input_node)
#define vec_free(V)
Free vector's memory (no header).
nsim_wheel_entry_t * entries
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
#define foreach_nsim_plugin_api_msg
#define VLIB_CLI_COMMAND(x,...)
nsim_wheel_t ** wheel_by_thread
static void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
Set node dispatch state.
enable / disable the network delay simulation cross-connect
#define VNET_FEATURES(...)
static void vl_api_nsim_enable_disable_t_handler(vl_api_nsim_enable_disable_t *mp)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vnet_sw_interface_t * sw_interfaces
u32 ** buffer_indices_by_thread
static uword unformat_bandwidth(unformat_input_t *input, va_list *args)
static clib_error_t * nsim_enable_disable_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
vnet_sw_interface_type_t type
static u32 vlib_num_workers()
static clib_error_t * show_nsim_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static void * clib_mem_vm_alloc(uword size)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
static clib_error_t * set_nsim_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u16 vl_msg_api_get_msg_ids(const char *name, int n)
static void setup_message_id_table(nsim_main_t *nsm, api_main_t *am)
static clib_error_t * nsim_plugin_api_hookup(vlib_main_t *vm)