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;
338 *contents,
vec_len (*contents));
346 return SRP_ERROR_CONTROL_PACKETS_PROCESSED;
358 u32 n_left_from, next_index, * from, * to_next;
360 static u8 * contents;
376 while (n_left_from > 0)
382 while (n_left_from > 0 && n_left_to_next > 0)
384 u32 bi0, l2_len0, l3_len0;
402 error0 = SRP_ERROR_CONTROL_PACKETS_PROCESSED;
404 error0 = s0->
control.version != 0 ? SRP_ERROR_CONTROL_VERSION_NON_ZERO : error0;
411 error0 = save0 != computed0 ? SRP_ERROR_CONTROL_BAD_CHECKSUM : error0;
414 if (error0 == SRP_ERROR_CONTROL_PACKETS_PROCESSED)
432 error0 = SRP_ERROR_UNKNOWN_CONTROL;
439 to_next, n_left_to_next,
451 .name =
"srp-control",
453 .vector_size =
sizeof (
u32),
467 u32 x = va_arg (*args,
u32);
471 #define _(f,n) case SRP_IPS_REQUEST_##f: t = #f; break; 475 return format (s,
"unknown 0x%x", x);
482 u32 x = va_arg (*args,
u32);
486 #define _(f,n) case SRP_IPS_STATUS_##f: t = #f; break; 490 return format (s,
"unknown 0x%x", x);
497 u32 x = va_arg (*args,
u32);
501 #define _(f) case SRP_IPS_STATE_##f: t = #f; break; 505 return format (s,
"unknown 0x%x", x);
512 u32 ring = va_arg (*args,
u32);
520 s =
format (s,
"%U, %U, %U, %s-path",
524 h->is_long_path ?
"long" :
"short");
534 s =
format (s,
"address %U, IPS state %U",
539 s =
format (s,
", %U neighbor %U",
548 u32 hw_if_index = va_arg (*args,
u32);
583 memset (i, 0,
sizeof (i[0]));
586 i->
srp.is_inner_ring = tx_ring;
588 i->
srp.mode = SRP_MODE_control_locally_buffered_for_host;
592 i->
ethernet.
type = clib_host_to_net_u16 (ETHERNET_TYPE_SRP_CONTROL);
596 i->
control.type = SRP_CONTROL_PACKET_TYPE_ips;
695 .name =
"vnet_srp_interface_state",
703 [SRP_IPS_REQUEST_forced_switch] = 1,
704 [SRP_IPS_REQUEST_manual_switch] = 1,
705 [SRP_IPS_REQUEST_signal_fail] = 1,
706 [SRP_IPS_REQUEST_signal_degrade] = 1,
708 return (
int) r <
ARRAY_LEN (t) ? t[r] : 0;
719 int si_needs_broadcast = 0;
733 if (! h->is_long_path)
746 case SRP_IPS_STATE_idle:
750 && h->status == SRP_IPS_STATUS_wrapped)
754 si_needs_broadcast = 1;
760 to_tx[0].request_type = SRP_IPS_REQUEST_idle;
761 to_tx[0].status = SRP_IPS_STATUS_wrapped;
762 to_tx[0].is_long_path = 0;
766 to_tx[1].request_type = h->request_type;
767 to_tx[1].status = SRP_IPS_STATUS_wrapped;
768 to_tx[1].is_long_path = 1;
773 case SRP_IPS_STATE_wrapped:
774 if (! h->is_long_path
775 && h->request_type == SRP_IPS_REQUEST_idle
776 && h->status == SRP_IPS_STATUS_idle)
778 si_needs_broadcast = 1;
785 case SRP_IPS_STATE_pass_thru:
795 if (vm->
mc_main && si_needs_broadcast)
808 int si_needs_broadcast = 0;
810 if (request == SRP_IPS_REQUEST_wait_to_restore)
818 si_needs_broadcast = 1;
835 if (vm->
mc_main && si_needs_broadcast)
870 to_tx[0].request_type = to_tx[1].request_type = SRP_IPS_REQUEST_idle;
871 to_tx[0].status = to_tx[1].status = SRP_IPS_STATUS_idle;
872 to_tx[0].is_long_path = to_tx[1].is_long_path = 0;
877 to_tx[0].request_type =
879 ? SRP_IPS_REQUEST_wait_to_restore
880 : SRP_IPS_REQUEST_signal_fail);
881 to_tx[1].request_type =
883 ? SRP_IPS_REQUEST_wait_to_restore
884 : SRP_IPS_REQUEST_signal_fail);
885 to_tx[0].status = to_tx[1].status = SRP_IPS_STATUS_wrapped;
886 to_tx[0].is_long_path = 0;
887 to_tx[1].is_long_path = 1;
905 maybe_send_ips_message (si);
916 .name =
"srp-ips-process",
917 .state = VLIB_NODE_STATE_DISABLED,
static int requests_switch(srp_ips_request_type_t r)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static u8 * format_srp_input_trace(u8 *s, va_list *va)
f64 wait_to_restore_start_time
void srp_ips_local_request(u32 sw_if_index, srp_ips_request_type_t request)
#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 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 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)
static vlib_node_registration_t srp_input_node
struct _vlib_node_registration vlib_node_registration_t
static void serialize_srp_interface_state_msg(serialize_main_t *m, va_list *va)
#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.
vlib_error_t * errors
Vector of errors for this node.
#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.
static void maybe_send_ips_message(srp_interface_t *si)
format_function_t format_vnet_sw_if_index_name
static u8 * format_srp_ips_state(u8 *s, va_list *args)
static u8 * format_srp_ips_request_type(u8 *s, va_list *args)
static vlib_node_registration_t srp_control_input_node
srp_interface_t * interface_pool
static uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Suspend a vlib cooperative multi-tasking thread for a period of time.
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.
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)
#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)
MC_SERIALIZE_MSG(srp_interface_state_msg, static)
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
static uword srp_topology_packet(vlib_main_t *vm, u32 sw_if_index, u8 **contents)
static clib_error_t * srp_init(vlib_main_t *vm)
static u8 * format_srp_ips_header(u8 *s, va_list *args)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static char * srp_error_strings[]
static void serialize_likely_small_unsigned_integer(serialize_main_t *m, u64 x)
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)
#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX
static u8 * format_srp_interface(u8 *s, va_list *args)
#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)
#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).
serialize_function_t unserialize_f64
vlib_error_t error
Error code for buffers to be enqueued to error handler.
static u8 * format_srp_ring(u8 *s, va_list *args)
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,...)
u32 vlib_buffer_add_data(vlib_main_t *vm, u32 free_list_index, u32 buffer_index, void *data, u32 n_data_bytes)
#define CLIB_PREFETCH(addr, size, type)
#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.
#define clib_memcpy(a, b, c)
static void unserialize_srp_interface_state_msg(serialize_main_t *m, va_list *va)
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)
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.
u8 * format_srp_device(u8 *s, va_list *args)
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
static uword srp_control_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
u32 vlib_register_node(vlib_main_t *vm, vlib_node_registration_t *r)
void srp_ips_rx_packet(u32 sw_if_index, srp_ips_header_t *h)
clib_error_t * unserialize(serialize_main_t *m,...)
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
#define VLIB_NODE_FLAG_TRACE
vlib_node_registration_t srp_ips_process_node
static uword srp_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
static uword vnet_sw_interface_is_admin_up(vnet_main_t *vnm, u32 sw_if_index)
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)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
uword( srp_control_handler_function_t)(vlib_main_t *vm, u32 sw_if_index, u8 **contents)
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static uword srp_ips_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
u16 flags
Copy of main node flags.
static void init_ips_packet(srp_interface_t *si, srp_ring_type_t tx_ring, srp_ips_header_t *i)
srp_interface_config_t config
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
static srp_interface_t * srp_get_interface(u32 sw_if_index, srp_ring_type_t *ring)
static u8 * format_srp_ips_status(u8 *s, va_list *args)