75 [SRP_MODE_reserved0] = {
77 .error = SRP_ERROR_UNKNOWN_MODE,
79 [SRP_MODE_reserved1] = {
81 .error = SRP_ERROR_UNKNOWN_MODE,
83 [SRP_MODE_reserved2] = {
85 .error = SRP_ERROR_UNKNOWN_MODE,
87 [SRP_MODE_reserved3] = {
89 .error = SRP_ERROR_UNKNOWN_MODE,
91 [SRP_MODE_keep_alive] = {
93 .error = SRP_ERROR_KEEP_ALIVE_DROPPED,
99 [SRP_MODE_control_pass_to_host] = {
102 [SRP_MODE_control_locally_buffered_for_host] = {
114 u32 n_left_from, next_index, * from, * to_next;
128 while (n_left_from > 0)
134 while (n_left_from >= 4 && n_left_to_next >= 2)
136 u32 bi0, bi1, sw_if_index0, sw_if_index1;
138 u8 next0, next1, error0, error1;
183 sw_if_index0 = (s0->mode == SRP_MODE_data
186 sw_if_index1 = (s1->mode == SRP_MODE_data
193 d0 = srp_input_disposition_by_mode + s0->mode;
194 d1 = srp_input_disposition_by_mode + s1->mode;
209 to_next, n_left_to_next,
210 bi0, bi1, next0, next1);
213 while (n_left_from > 0 && n_left_to_next > 0)
215 u32 bi0, sw_if_index0;
241 sw_if_index0 = (s0->mode == SRP_MODE_data
247 d0 = srp_input_disposition_by_mode + s0->mode;
258 to_next, n_left_to_next,
278 .vector_size =
sizeof (
u32),
300 srp_topology_header_t * t;
304 t = (
void *) *contents;
306 nb = clib_net_to_host_u16 (t->n_bytes_of_data_that_follows);
307 nmb = (nb -
sizeof (t->originator_address)) /
sizeof (mb[0]);
308 if (
vec_len (*contents) <
sizeof (t[0]) + nmb *
sizeof (mb[0]))
309 return SRP_ERROR_TOPOLOGY_BAD_LENGTH;
316 t = (
void *) *contents;
317 t->n_bytes_of_data_that_follows = clib_host_to_net_u16 (nb +
sizeof (mb[0]));
319 mb = t->bindings + nmb;
337 *contents,
vec_len (*contents)))
342 return SRP_ERROR_CONTROL_PACKETS_PROCESSED;
353 return SRP_ERROR_CONTROL_PACKETS_PROCESSED;
365 u32 n_left_from, next_index, * from, * to_next;
367 static u8 * contents;
383 while (n_left_from > 0)
389 while (n_left_from > 0 && n_left_to_next > 0)
391 u32 bi0, l2_len0, l3_len0;
409 error0 = SRP_ERROR_CONTROL_PACKETS_PROCESSED;
411 error0 = s0->
control.version != 0 ? SRP_ERROR_CONTROL_VERSION_NON_ZERO : error0;
418 error0 = save0 != computed0 ? SRP_ERROR_CONTROL_BAD_CHECKSUM : error0;
421 if (error0 == SRP_ERROR_CONTROL_PACKETS_PROCESSED)
439 error0 = SRP_ERROR_UNKNOWN_CONTROL;
446 to_next, n_left_to_next,
458 .name =
"srp-control",
460 .vector_size =
sizeof (
u32),
474 u32 x = va_arg (*args,
u32);
478 #define _(f,n) case SRP_IPS_REQUEST_##f: t = #f; break; 482 return format (s,
"unknown 0x%x", x);
489 u32 x = va_arg (*args,
u32);
493 #define _(f,n) case SRP_IPS_STATUS_##f: t = #f; break; 497 return format (s,
"unknown 0x%x", x);
504 u32 x = va_arg (*args,
u32);
508 #define _(f) case SRP_IPS_STATE_##f: t = #f; break; 512 return format (s,
"unknown 0x%x", x);
519 u32 ring = va_arg (*args,
u32);
527 s =
format (s,
"%U, %U, %U, %s-path",
531 h->is_long_path ?
"long" :
"short");
541 s =
format (s,
"address %U, IPS state %U",
546 s =
format (s,
", %U neighbor %U",
555 u32 hw_if_index = va_arg (*args,
u32);
593 i->
srp.is_inner_ring = tx_ring;
595 i->
srp.mode = SRP_MODE_control_locally_buffered_for_host;
599 i->
ethernet.
type = clib_host_to_net_u16 (ETHERNET_TYPE_SRP_CONTROL);
603 i->
control.type = SRP_CONTROL_PACKET_TYPE_ips;
619 u32 * to_next, bi = ~0;
658 [SRP_IPS_REQUEST_forced_switch] = 1,
659 [SRP_IPS_REQUEST_manual_switch] = 1,
660 [SRP_IPS_REQUEST_signal_fail] = 1,
661 [SRP_IPS_REQUEST_signal_degrade] = 1,
663 return (
int) r <
ARRAY_LEN (t) ? t[r] : 0;
687 if (! h->is_long_path)
700 case SRP_IPS_STATE_idle:
704 && h->status == SRP_IPS_STATUS_wrapped)
713 to_tx[0].request_type = SRP_IPS_REQUEST_idle;
714 to_tx[0].status = SRP_IPS_STATUS_wrapped;
715 to_tx[0].is_long_path = 0;
719 to_tx[1].request_type = h->request_type;
720 to_tx[1].status = SRP_IPS_STATUS_wrapped;
721 to_tx[1].is_long_path = 1;
726 case SRP_IPS_STATE_wrapped:
727 if (! h->is_long_path
728 && h->request_type == SRP_IPS_REQUEST_idle
729 && h->status == SRP_IPS_STATUS_idle)
737 case SRP_IPS_STATE_pass_thru:
758 if (request == SRP_IPS_REQUEST_wait_to_restore)
814 to_tx[0].request_type = to_tx[1].request_type = SRP_IPS_REQUEST_idle;
815 to_tx[0].status = to_tx[1].status = SRP_IPS_STATUS_idle;
816 to_tx[0].is_long_path = to_tx[1].is_long_path = 0;
821 to_tx[0].request_type =
823 ? SRP_IPS_REQUEST_wait_to_restore
824 : SRP_IPS_REQUEST_signal_fail);
825 to_tx[1].request_type =
827 ? SRP_IPS_REQUEST_wait_to_restore
828 : SRP_IPS_REQUEST_signal_fail);
829 to_tx[0].status = to_tx[1].status = SRP_IPS_STATUS_wrapped;
830 to_tx[0].is_long_path = 0;
831 to_tx[1].is_long_path = 1;
849 maybe_send_ips_message (si);
860 .name =
"srp-ips-process",
861 .state = VLIB_NODE_STATE_DISABLED,
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static clib_error_t * srp_init(vlib_main_t *vm)
f64 wait_to_restore_start_time
void srp_ips_rx_packet(u32 sw_if_index, srp_ips_header_t *h)
vlib_node_registration_t srp_ips_process_node
#define foreach_srp_error
#define SRP_TOPOLOGY_MAC_BINDING_FLAG_IS_INNER_RING
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
static uword srp_topology_packet(vlib_main_t *vm, u32 sw_if_index, u8 **contents)
u8 rx_neighbor_address_valid
vnet_main_t * vnet_get_main(void)
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
static u8 * format_srp_ips_request_type(u8 *s, va_list *args)
#define clib_memcpy_fast(a, b, c)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 vlib_time_now(vlib_main_t *vm)
int vlib_buffer_add_data(vlib_main_t *vm, u32 *buffer_index, void *data, u32 n_data_bytes)
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
static vlib_node_registration_t srp_input_node
#define STRUCT_OFFSET_OF(t, f)
static void srp_header_compute_parity(srp_header_t *h)
static u8 * format_srp_ips_header(u8 *s, va_list *args)
static void init_ips_packet(srp_interface_t *si, srp_ring_type_t tx_ring, srp_ips_header_t *i)
vlib_error_t * errors
Vector of errors for this node.
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
static u8 * format_srp_interface(u8 *s, va_list *args)
srp_interface_t * interface_pool
static u8 * format_srp_ips_status(u8 *s, va_list *args)
static uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Suspend a vlib cooperative multi-tasking thread for a period of time.
u8 * format_ethernet_address(u8 *s, va_list *args)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
#define VLIB_INIT_FUNCTION(x)
static u8 * format_srp_ips_state(u8 *s, va_list *args)
static uword srp_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
static void srp_setup_node(vlib_main_t *vm, u32 node_index)
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
vlib_error_t error
Error code for buffers to be enqueued to error handler.
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
srp_interface_ring_t rings[SRP_N_RING]
static void tx_ips_packet(srp_interface_t *si, srp_ring_type_t tx_ring, srp_ips_header_t *i)
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
u32 vlib_register_node(vlib_main_t *vm, vlib_node_registration_t *r)
#define foreach_srp_ips_state
vnet_hw_interface_class_t srp_hw_interface_class
srp_hw_wrap_function_t * hw_wrap_function
#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).
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
static u8 * format_srp_input_trace(u8 *s, va_list *va)
u8 rx_neighbor_address[6]
void srp_ips_local_request(u32 sw_if_index, srp_ips_request_type_t request)
#define CLIB_PREFETCH(addr, size, type)
sll srl srl sll sra u16x4 i
#define clib_warning(format, args...)
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
static uword srp_ips_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
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.
vlib_main_t vlib_node_runtime_t * node
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
uword() srp_control_handler_function_t(vlib_main_t *vm, u32 sw_if_index, u8 **contents)
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
static int requests_switch(srp_ips_request_type_t r)
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)
struct _vlib_node_registration vlib_node_registration_t
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 uword srp_control_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static srp_interface_t * srp_get_interface(u32 sw_if_index, srp_ring_type_t *ring)
static vlib_node_registration_t srp_control_input_node
VLIB buffer representation.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
u16 flags
Copy of main node flags.
static char * srp_error_strings[]
u8 * format_srp_device(u8 *s, va_list *args)
#define VLIB_NODE_FLAG_TRACE
srp_interface_config_t config
static u8 * format_srp_ring(u8 *s, va_list *args)
static ip_csum_t ip_incremental_checksum(ip_csum_t sum, void *_data, uword n_bytes)
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)
vl_api_interface_index_t sw_if_index