FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
nsim_input.c
Go to the documentation of this file.
1 /*
2  * nsim.c - skeleton vpp engine plug-in
3  *
4  * Copyright (c) <current-year> <your-organization>
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vlib/vlib.h>
19 #include <vnet/vnet.h>
20 #include <vnet/pg/pg.h>
21 #include <vppinfra/error.h>
22 #include <nsim/nsim.h>
23 
24 typedef struct
25 {
29 
30 #ifndef CLIB_MARCH_VARIANT
31 /* packet trace format function */
32 static u8 *
33 format_nsim_tx_trace (u8 * s, va_list * args)
34 {
35  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
36  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
37  nsim_tx_trace_t *t = va_arg (*args, nsim_tx_trace_t *);
38 
39  s = format (s, "NSIM: tx at %.6f next_index %d", t->expired, t->next_index);
40  return s;
41 }
42 #endif /* CLIB_MARCH_VARIANT */
43 
44 #define foreach_nsim_tx_error \
45 _(TRANSMITTED, "Packets transmitted")
46 
47 typedef enum
48 {
49 #define _(sym,str) NSIM_TX_ERROR_##sym,
51 #undef _
54 
55 #ifndef CLIB_MARCH_VARIANT
56 static char *nsim_tx_error_strings[] = {
57 #define _(sym,string) string,
59 #undef _
60 };
61 #endif /* CLIB_MARCH_VARIANT */
62 
63 typedef enum
64 {
67 } nsim_next_t;
68 
71  vlib_frame_t * f, int is_trace)
72 {
73  nsim_main_t *nsm = &nsim_main;
76  f64 now;
77 
78  /* Nothing on the scheduler wheel? */
79  if (wp->cursize == 0)
80  return 0;
81 
82  /* First entry on the wheel isn't expired? */
83  ep = wp->entries + wp->head;
84  now = vlib_time_now (vm);
85  if (ep->tx_time > now)
86  return 0;
87 
88  u32 n_burst = clib_min (wp->cursize, NSIM_MAX_TX_BURST), n_tx_packets = 0;
89  u32 froms[NSIM_MAX_TX_BURST], *from;
90  u16 nexts[NSIM_MAX_TX_BURST], *next;
91 
92  from = froms;
93  next = nexts;
94  while (n_tx_packets < n_burst && ep->tx_time <= now)
95  {
96  /* prefetch one line / 2 entries ahead */
97  if ((((uword) ep) & (CLIB_CACHE_LINE_BYTES - 1)) == 0)
98  CLIB_PREFETCH ((ep + 2), CLIB_CACHE_LINE_BYTES, LOAD);
99 
100  ep = wp->entries + wp->head;
101  from[0] = ep->buffer_index;
102  next[0] = ep->output_next_index;
103 
104  wp->head++;
105  if (wp->head == wp->wheel_size)
106  wp->head = 0;
107 
108  from += 1;
109  next += 1;
110  n_tx_packets++;
111  }
112 
113  wp->cursize -= n_tx_packets;
114  vlib_buffer_enqueue_to_next (vm, node, froms, nexts, n_tx_packets);
116  NSIM_TX_ERROR_TRANSMITTED, n_tx_packets);
117  return n_tx_packets;
118 }
119 
122 {
123  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
124  return nsim_input_inline (vm, node, frame, 1 /* is_trace */ );
125  else
126  return nsim_input_inline (vm, node, frame, 0 /* is_trace */ );
127 
128 }
129 
130 /* *INDENT-OFF* */
131 #ifndef CLIB_MARCH_VARIANT
133 {
134  .type = VLIB_NODE_TYPE_INPUT,
135  .name = "nsim-wheel",
136 
137  /* Will be enabled if/when the feature is configured */
138  .state = VLIB_NODE_STATE_DISABLED,
139 
140  .format_trace = format_nsim_tx_trace,
141 
142  .n_errors = NSIM_TX_N_ERROR,
143  .error_strings = nsim_tx_error_strings,
144 };
145 #endif /* CLIB_MARCH_VARIANT */
146 /* *INDENT-ON* */
147 
148 /*
149  * fd.io coding-style-patch-verification: ON
150  *
151  * Local Variables:
152  * eval: (c-set-style "gnu")
153  * End:
154  */
static char * nsim_tx_error_strings[]
Definition: nsim_input.c:56
#define clib_min(x, y)
Definition: clib.h:327
#define CLIB_UNUSED(x)
Definition: clib.h:87
Definition: nsim.h:30
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:333
u32 thread_index
Definition: main.h:249
vlib_main_t * vm
Definition: in2out_ed.c:1582
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define VLIB_NODE_FN(node)
Definition: node.h:202
unsigned char u8
Definition: types.h:56
double f64
Definition: types.h:142
static u8 * format_nsim_tx_trace(u8 *s, va_list *args)
Definition: nsim_input.c:33
u32 cursize
Definition: nsim.h:43
unsigned int u32
Definition: types.h:88
nsim_tx_error_t
Definition: nsim_input.c:47
#define foreach_nsim_tx_error
Definition: nsim_input.c:44
unsigned short u16
Definition: types.h:57
nsim_next_t
Definition: nsim_input.c:63
#define NSIM_MAX_TX_BURST
max packets in a tx burst
Definition: nsim.h:28
#define PREDICT_FALSE(x)
Definition: clib.h:120
#define always_inline
Definition: ipsec.h:28
u32 node_index
Node index.
Definition: node.h:487
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1231
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
static_always_inline void vlib_buffer_enqueue_to_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 *nexts, uword count)
Definition: buffer_node.h:339
static uword nsim_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *f, int is_trace)
Definition: nsim_input.c:70
nsim_wheel_entry_t * entries
Definition: nsim.h:46
u32 head
Definition: nsim.h:44
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1582
nsim_wheel_t ** wheel_by_thread
Definition: nsim.h:99
vlib_node_registration_t nsim_input_node
(constructor) VLIB_REGISTER_NODE (nsim_input_node)
Definition: nsim_input.c:132
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1583
f64 tx_time
Definition: nsim.h:32
u64 uword
Definition: types.h:112
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:301
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
u32 wheel_size
Definition: nsim.h:42
nsim_main_t nsim_main
Definition: nsim.c:39