35 } sr_replicate_main_t;
37 sr_replicate_main_t sr_replicate_main;
46 } sr_replicate_trace_t;
49 static u8 * format_sr_replicate_trace (
u8 * s, va_list * args)
53 sr_replicate_trace_t * t = va_arg (*args, sr_replicate_trace_t *);
66 (s,
"SR-REPLICATE: next %s ip6 src %U dst %U len %u\n" 67 " rx-fib-id %d tx-fib-id %d\n%U",
77 #define foreach_sr_replicate_error \ 78 _(REPLICATED, "sr packets replicated") \ 79 _(NO_BUFFERS, "error allocating buffers for replicas") \ 80 _(NO_REPLICAS, "no replicas were needed") \ 81 _(NO_BUFFER_DROPS, "sr no buffer drops") 84 #define _(sym,str) SR_REPLICATE_ERROR_##sym, 85 foreach_sr_replicate_error
88 } sr_replicate_error_t;
90 static char * sr_replicate_error_strings[] = {
91 #define _(sym,string) string, 92 foreach_sr_replicate_error
97 SR_REPLICATE_NEXT_IP6_LOOKUP,
99 } sr_replicate_next_t;
106 u32 n_left_from, * from, * to_next;
107 sr_replicate_next_t next_index;
108 int pkts_replicated = 0;
110 int no_buffer_drops = 0;
112 unsigned socket_id = rte_socket_id();
121 while (n_left_from > 0)
126 to_next, n_left_to_next);
128 while (n_left_from > 0 && n_left_to_next > 0)
132 struct rte_mbuf * orig_mb0 = 0, * hdr_mb0 = 0, * clone0 = 0;
133 struct rte_mbuf ** hdr_vec = 0, ** rte_mbuf_vec = 0;
138 int num_replicas = 0;
153 orig_mb0 = rte_mbuf_from_vlib_buffer (b0);
156 - (
i16) orig_mb0->pkt_len;
158 u16 new_data_len0 = (
u16)((
i16) orig_mb0->data_len + delta0);
159 u16 new_pkt_len0 = (
u16)((
i16) orig_mb0->pkt_len + delta0);
161 orig_mb0->data_len = new_data_len0;
162 orig_mb0->pkt_len = new_pkt_len0;
177 b0->
error = node->
errors[SR_REPLICATE_ERROR_NO_REPLICAS];
184 for (i=0; i < num_replicas; i++)
186 hdr_mb0 = rte_pktmbuf_alloc(bm->pktmbuf_pools[socket_id]);
188 if (i < (num_replicas - 1) )
190 clone0 = rte_pktmbuf_clone
191 (orig_mb0, bm->pktmbuf_pools[socket_id]);
199 b0->
error = node->
errors[SR_REPLICATE_ERROR_NO_BUFFERS];
203 rte_pktmbuf_free(rte_mbuf_vec[i]);
209 rte_pktmbuf_free(hdr_vec[i]);
221 for (i=0; i < num_replicas; i++)
228 hdr_mb0 = hdr_vec[
i];
229 clone0 = rte_mbuf_vec[
i];
232 hdr_mb0->pkt_len = hdr_mb0->data_len +
235 hdr_b0 = vlib_buffer_from_rte_mbuf (hdr_mb0);
239 memcpy (hdr_b0->
data, ip0, sizeof (*ip0));
252 hdr_ip0->payload_length = clib_host_to_net_u16(hdr_mb0->data_len);
254 hdr_sr0->
protocol = hdr_ip0->protocol;
255 hdr_ip0->protocol = 43;
264 hdr_mb0->next = clone0;
268 hdr_mb0->pkt_len = (
uint16_t)(hdr_mb0->data_len + clone0->pkt_len);
269 hdr_mb0->nb_segs = (
uint8_t)(clone0->nb_segs + 1);
272 hdr_mb0->port = clone0->port;
273 hdr_mb0->vlan_tci = clone0->vlan_tci;
274 hdr_mb0->vlan_tci_outer = clone0->vlan_tci_outer;
275 hdr_mb0->tx_offload = clone0->tx_offload;
276 hdr_mb0->hash = clone0->hash;
278 hdr_mb0->ol_flags = clone0->ol_flags;
280 __rte_mbuf_sanity_check(hdr_mb0, 1);
284 to_next[0] = hdr_bi0;
288 if (n_left_to_next == 0)
292 to_next, n_left_to_next);
306 tr->tunnel_index = t0 - sm->
tunnels;
309 memcpy (tr->src.as_u8, hdr_ip0->src_address.as_u8,
310 sizeof (tr->src.as_u8));
311 memcpy (tr->dst.as_u8, hdr_ip0->dst_address.as_u8,
312 sizeof (tr->dst.as_u8));
314 if (hdr_ip0->payload_length)
315 tr->length = clib_net_to_host_u16(hdr_ip0->payload_length);
318 tr->next_index = next_index;
319 memcpy (tr->sr, hdr_sr0, sizeof (tr->sr));
328 SR_REPLICATE_ERROR_REPLICATED, pkts_replicated);
331 SR_REPLICATE_ERROR_NO_BUFFER_DROPS, no_buffer_drops);
337 .function = sr_replicate_node_fn,
338 .name =
"sr-replicate",
339 .vector_size =
sizeof (
u32),
340 .format_trace = format_sr_replicate_trace,
343 .n_errors =
ARRAY_LEN(sr_replicate_error_strings),
344 .error_strings = sr_replicate_error_strings,
346 .n_next_nodes = SR_REPLICATE_N_NEXT,
349 [SR_REPLICATE_NEXT_IP6_LOOKUP] =
"ip6-lookup",
355 sr_replicate_main_t *msm = &sr_replicate_main;
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
#define vec_foreach_index(var, v)
Iterate over vector indices.
sll srl srl sll sra u16x4 i
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
vlib_buffer_main_t * buffer_main
always_inline void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
vnet_main_t * vnet_get_main(void)
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
#define VLIB_INIT_FUNCTION(x)
ip6_fib_t * find_ip6_fib_by_table_index_or_id(ip6_main_t *im, u32 table_index_or_id, u32 flags)
Get or create an IPv6 fib.
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
always_inline uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
int vlib_main(vlib_main_t *vm, unformat_input_t *input)
always_inline vlib_buffer_free_list_t * vlib_buffer_get_free_list(vlib_main_t *vm, u32 free_list_index)
always_inline void * vlib_frame_vector_args(vlib_frame_t *f)
#define VLIB_BUFFER_NEXT_PRESENT
#define pool_elt_at_index(p, i)
u16 current_length
Nbytes between current data and the end of this buffer.
unsigned short int uint16_t
always_inline void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
vlib_error_t error
Error code for buffers to be enqueued to error handler.
#define vec_free(V)
Free vector's memory (no header).
void sr_fix_hmac(ip6_sr_main_t *sm, ip6_header_t *ip, ip6_sr_header_t *sr)
#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX
u32 next_buffer
Next buffer for this linked-list of buffers.
ip6_sr_tunnel_t * tunnels
#define VLIB_BUFFER_IS_TRACED
always_inline void vlib_buffer_init_for_free_list(vlib_buffer_t *_dst, vlib_buffer_free_list_t *fl)
#define IP6_ROUTE_FLAG_FIB_INDEX
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
format_function_t format_ip6_sr_header
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
always_inline void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
ip6_sr_policy_t * policies
always_inline void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
#define VLIB_REGISTER_NODE(x,...)
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
always_inline vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
always_inline u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.