73 [SRP_MODE_reserved0] = {
75 .error = SRP_ERROR_UNKNOWN_MODE,
77 [SRP_MODE_reserved1] = {
79 .error = SRP_ERROR_UNKNOWN_MODE,
81 [SRP_MODE_reserved2] = {
83 .error = SRP_ERROR_UNKNOWN_MODE,
85 [SRP_MODE_reserved3] = {
87 .error = SRP_ERROR_UNKNOWN_MODE,
89 [SRP_MODE_keep_alive] = {
91 .error = SRP_ERROR_KEEP_ALIVE_DROPPED,
97 [SRP_MODE_control_pass_to_host] = {
100 [SRP_MODE_control_locally_buffered_for_host] = {
112 u32 n_left_from, next_index, * from, * to_next;
126 while (n_left_from > 0)
132 while (n_left_from >= 4 && n_left_to_next >= 2)
134 u32 bi0, bi1, sw_if_index0, sw_if_index1;
136 u8 next0, next1, error0, error1;
181 sw_if_index0 = (s0->
mode == SRP_MODE_data
184 sw_if_index1 = (s1->
mode == SRP_MODE_data
191 d0 = srp_input_disposition_by_mode + s0->
mode;
192 d1 = srp_input_disposition_by_mode + s1->
mode;
207 to_next, n_left_to_next,
208 bi0, bi1, next0, next1);
211 while (n_left_from > 0 && n_left_to_next > 0)
213 u32 bi0, sw_if_index0;
239 sw_if_index0 = (s0->
mode == SRP_MODE_data
245 d0 = srp_input_disposition_by_mode + s0->
mode;
256 to_next, n_left_to_next,
276 .vector_size =
sizeof (
u32),
298 srp_topology_header_t * t;
302 t = (
void *) *contents;
304 nb = clib_net_to_host_u16 (t->n_bytes_of_data_that_follows);
305 nmb = (nb -
sizeof (t->originator_address)) /
sizeof (mb[0]);
306 if (
vec_len (*contents) <
sizeof (t[0]) + nmb *
sizeof (mb[0]))
307 return SRP_ERROR_TOPOLOGY_BAD_LENGTH;
314 t = (
void *) *contents;
315 t->n_bytes_of_data_that_follows = clib_host_to_net_u16 (nb +
sizeof (mb[0]));
317 mb = t->bindings + nmb;
336 *contents,
vec_len (*contents));
344 return SRP_ERROR_CONTROL_PACKETS_PROCESSED;
356 u32 n_left_from, next_index, * from, * to_next;
358 static u8 * contents;
374 while (n_left_from > 0)
380 while (n_left_from > 0 && n_left_to_next > 0)
382 u32 bi0, l2_len0, l3_len0;
400 error0 = SRP_ERROR_CONTROL_PACKETS_PROCESSED;
402 error0 = s0->
control.version != 0 ? SRP_ERROR_CONTROL_VERSION_NON_ZERO : error0;
409 error0 = save0 != computed0 ? SRP_ERROR_CONTROL_BAD_CHECKSUM : error0;
412 if (error0 == SRP_ERROR_CONTROL_PACKETS_PROCESSED)
430 error0 = SRP_ERROR_UNKNOWN_CONTROL;
437 to_next, n_left_to_next,
449 .name =
"srp-control",
451 .vector_size =
sizeof (
u32),
465 u32 x = va_arg (*args,
u32);
469 #define _(f,n) case SRP_IPS_REQUEST_##f: t = #f; break; 473 return format (s,
"unknown 0x%x", x);
480 u32 x = va_arg (*args,
u32);
484 #define _(f,n) case SRP_IPS_STATUS_##f: t = #f; break; 488 return format (s,
"unknown 0x%x", x);
495 u32 x = va_arg (*args,
u32);
499 #define _(f) case SRP_IPS_STATE_##f: t = #f; break; 503 return format (s,
"unknown 0x%x", x);
510 u32 ring = va_arg (*args,
u32);
518 s =
format (s,
"%U, %U, %U, %s-path",
532 s =
format (s,
"address %U, IPS state %U",
537 s =
format (s,
", %U neighbor %U",
546 u32 hw_if_index = va_arg (*args,
u32);
581 memset (i, 0,
sizeof (i[0]));
586 i->
srp.
mode = SRP_MODE_control_locally_buffered_for_host;
590 i->
ethernet.
type = clib_host_to_net_u16 (ETHERNET_TYPE_SRP_CONTROL);
594 i->
control.type = SRP_CONTROL_PACKET_TYPE_ips;
693 .name =
"vnet_srp_interface_state",
701 [SRP_IPS_REQUEST_forced_switch] = 1,
702 [SRP_IPS_REQUEST_manual_switch] = 1,
703 [SRP_IPS_REQUEST_signal_fail] = 1,
704 [SRP_IPS_REQUEST_signal_degrade] = 1,
706 return (
int) r <
ARRAY_LEN (t) ? t[r] : 0;
717 int si_needs_broadcast = 0;
744 case SRP_IPS_STATE_idle:
748 && h->
status == SRP_IPS_STATUS_wrapped)
752 si_needs_broadcast = 1;
759 to_tx[0].
status = SRP_IPS_STATUS_wrapped;
765 to_tx[1].
status = SRP_IPS_STATUS_wrapped;
771 case SRP_IPS_STATE_wrapped:
774 && h->
status == SRP_IPS_STATUS_idle)
776 si_needs_broadcast = 1;
783 case SRP_IPS_STATE_pass_thru:
793 if (vm->
mc_main && si_needs_broadcast)
806 int si_needs_broadcast = 0;
808 if (request == SRP_IPS_REQUEST_wait_to_restore)
816 si_needs_broadcast = 1;
833 if (vm->
mc_main && si_needs_broadcast)
869 to_tx[0].
status = to_tx[1].
status = SRP_IPS_STATUS_idle;
877 ? SRP_IPS_REQUEST_wait_to_restore
878 : SRP_IPS_REQUEST_signal_fail);
881 ? SRP_IPS_REQUEST_wait_to_restore
882 : SRP_IPS_REQUEST_signal_fail);
883 to_tx[0].
status = to_tx[1].
status = SRP_IPS_STATUS_wrapped;
903 maybe_send_ips_message (si);
914 .name =
"srp-ips-process",
915 .state = VLIB_NODE_STATE_DISABLED,
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
static uword srp_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
f64 wait_to_restore_start_time
#define foreach_srp_error
sll srl srl sll sra u16x4 i
#define SRP_TOPOLOGY_MAC_BINDING_FLAG_IS_INNER_RING
static u64 unserialize_likely_small_unsigned_integer(serialize_main_t *m)
u8 * format_srp_device(u8 *s, va_list *args)
u8 rx_neighbor_address_valid
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
static f64 vlib_time_now(vlib_main_t *vm)
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
struct _vlib_node_registration vlib_node_registration_t
static u8 * format_srp_ring(u8 *s, va_list *args)
#define STRUCT_OFFSET_OF(t, f)
static void srp_header_compute_parity(srp_header_t *h)
#define pool_is_free(P, E)
Use free bitmap to query whether given element is free.
static uword srp_control_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
#define mc_serialize(mc, msg, args...)
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
format_function_t format_vnet_sw_if_index_name
u32 vlib_register_node(vlib_main_t *vm, vlib_node_registration_t *r)
srp_interface_t * interface_pool
static void serialize_srp_interface_state_msg(serialize_main_t *m, va_list *va)
static uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Suspend a vlib cooperative multi-tasking thread for a period of time.
vnet_main_t * vnet_get_main(void)
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
u8 * format_ethernet_address(u8 *s, va_list *args)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
MC_SERIALIZE_MSG(srp_interface_state_msg, static)
ip_csum_t ip_incremental_checksum(ip_csum_t sum, void *_data, uword n_bytes)
#define VLIB_INIT_FUNCTION(x)
static void * serialize_get(serialize_main_t *m, uword n_bytes)
static void srp_setup_node(vlib_main_t *vm, u32 node_index)
#define clib_warning(format, args...)
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
void srp_ips_rx_packet(u32 sw_if_index, srp_ips_header_t *h)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static void serialize_likely_small_unsigned_integer(serialize_main_t *m, u64 x)
srp_interface_ring_t rings[SRP_N_RING]
static char * srp_error_strings[]
#define foreach_srp_ips_state
vnet_hw_interface_class_t srp_hw_interface_class
srp_hw_wrap_function_t * hw_wrap_function
static void * unserialize_get(serialize_main_t *m, uword n_bytes)
static uword srp_topology_packet(vlib_main_t *vm, u32 sw_if_index, u8 **contents)
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
static srp_interface_t * srp_get_interface(u32 sw_if_index, srp_ring_type_t *ring)
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
void srp_ips_local_request(u32 sw_if_index, srp_ips_request_type_t request)
serialize_function_t unserialize_f64
vlib_error_t error
Error code for buffers to be enqueued to error handler.
uword( srp_control_handler_function_t)(vlib_main_t *vm, u32 sw_if_index, u8 **contents)
static uword vlib_buffer_contents(vlib_main_t *vm, u32 buffer_index, u8 *contents)
Copy buffer contents to memory.
f64 wait_to_restore_idle_delay
u8 rx_neighbor_address[6]
clib_error_t * serialize(serialize_main_t *m,...)
static vlib_node_registration_t srp_control_input_node
#define CLIB_PREFETCH(addr, size, type)
static void tx_ips_packet(srp_interface_t *si, srp_ring_type_t tx_ring, srp_ips_header_t *i)
static uword srp_ips_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
#define clib_memcpy(a, b, c)
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
vlib_node_registration_t srp_ips_process_node
static void unserialize_integer(serialize_main_t *m, void *x, u32 n_bytes)
static void serialize_integer(serialize_main_t *m, u64 x, u32 n_bytes)
static void init_ips_packet(srp_interface_t *si, srp_ring_type_t tx_ring, srp_ips_header_t *i)
#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX
static u8 * format_srp_ips_header(u8 *s, va_list *args)
static u8 * format_srp_input_trace(u8 *s, va_list *va)
u32 vlib_buffer_add_data(vlib_main_t *vm, u32 free_list_index, u32 buffer_index, void *data, u32 n_data_bytes)
clib_error_t * unserialize(serialize_main_t *m,...)
#define VLIB_NODE_FLAG_TRACE
static vlib_node_registration_t srp_input_node
static uword vnet_sw_interface_is_admin_up(vnet_main_t *vnm, u32 sw_if_index)
static void maybe_send_ips_message(srp_interface_t *si)
void vlib_trace_frame_buffers_only(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, uword n_buffers, uword next_buffer_stride, uword n_buffer_data_bytes_in_trace)
static void unserialize_srp_interface_state_msg(serialize_main_t *m, va_list *va)
static u8 * format_srp_interface(u8 *s, va_list *args)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static u8 * format_srp_ips_state(u8 *s, va_list *args)
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
static int requests_switch(srp_ips_request_type_t r)
static clib_error_t * srp_init(vlib_main_t *vm)
static u8 * format_srp_ips_status(u8 *s, va_list *args)
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
srp_interface_config_t config
static u8 * format_srp_ips_request_type(u8 *s, va_list *args)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
srp_ips_state_t current_ips_state
static u16 ip_csum_fold(ip_csum_t c)
serialize_function_t serialize_f64