FD.io VPP  v19.08.3-2-gbabecb413
Vector Packet Processing
node.c
Go to the documentation of this file.
1 /*
2  * node.c - skeleton vpp engine plug-in dual-loop node skeleton
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 #include <vlib/vlib.h>
18 #include <vnet/vnet.h>
19 #include <vnet/pg/pg.h>
20 #include <vppinfra/error.h>
21 #include <oddbuf/oddbuf.h>
22 
23 typedef struct
24 {
29 
30 #ifndef CLIB_MARCH_VARIANT
31 
32 /* packet trace format function */
33 static u8 *
34 format_oddbuf_trace (u8 * s, va_list * args)
35 {
36  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
37  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
38  oddbuf_trace_t *t = va_arg (*args, oddbuf_trace_t *);
39 
40  s = format (s, "ODDBUF: sw_if_index %d, next index %d, udp checksum %04x\n",
41  t->sw_if_index, t->next_index, (u32) t->udp_checksum);
42  return s;
43 }
44 
46 
47 #endif /* CLIB_MARCH_VARIANT */
48 
49 #define foreach_oddbuf_error \
50 _(SWAPPED, "Mac swap packets processed")
51 
52 typedef enum
53 {
54 #define _(sym,str) ODDBUF_ERROR_##sym,
56 #undef _
59 
60 #ifndef CLIB_MARCH_VARIANT
61 static char *oddbuf_error_strings[] = {
62 #define _(sym,string) string,
64 #undef _
65 };
66 #endif /* CLIB_MARCH_VARIANT */
67 
68 typedef enum
69 {
73 
74 
77  vlib_node_runtime_t * node, vlib_frame_t * frame,
78  int is_ip4, int is_trace)
79 {
81  u32 n_left_from, *from;
82  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
83  vlib_buffer_t *b0, *b0next;
84  u32 bi;
85  u16 nexts[VLIB_FRAME_SIZE], *next;
86  u16 save_current_length;
87  u32 next0;
88  u8 *src, *dst;
89  int i;
92  udp_header_t *udp;
93 
94 
95  from = vlib_frame_vector_args (frame);
96  n_left_from = frame->n_vectors;
97 
98  vlib_get_buffers (vm, from, bufs, n_left_from);
99  b = bufs;
100  next = nexts;
101 
102  while (n_left_from > 0)
103  {
104  b0 = b[0];
105  vnet_feature_next (&next0, b0);
106  nexts[0] = next0;
107 
108  if (vlib_buffer_alloc (vm, &bi, 1) != 1)
109  {
110  clib_warning ("Buffer alloc fail, skipping");
111  goto skip;
112  }
113 
114  if (om->first_chunk_offset)
115  {
116  memmove (b0->data + b0->current_data + om->first_chunk_offset,
117  b0->data + b0->current_data, b0->current_length);
118  b0->current_data += om->first_chunk_offset;
119  }
120 
121  eh = vlib_buffer_get_current (b0);
122  ip = (ip4_header_t *) (eh + 1);
123  udp = (udp_header_t *) (ip4_next_header (ip));
124 
125  if (1)
126  {
127  save_current_length = vlib_buffer_length_in_chain (vm, b0);
128 
129  b0next = vlib_get_buffer (vm, bi);
130  b0->flags |= VLIB_BUFFER_NEXT_PRESENT;
131  b0->flags &= ~VLIB_BUFFER_TOTAL_LENGTH_VALID;
132  b0->next_buffer = bi;
133 
134  src = b0->data + b0->current_data + b0->current_length -
135  om->n_to_copy;
136  b0next->current_data = om->second_chunk_offset;
137  b0next->current_length = om->n_to_copy;
138  dst = b0next->data + b0next->current_data;
139 
140  for (i = 0; i < om->n_to_copy; i++)
141  dst[i] = src[i];
142 
143  b0->current_length -= om->n_to_copy;
144  b0next->current_length = om->n_to_copy;
145 
146  if (vlib_buffer_length_in_chain (vm, b0) != save_current_length)
147  clib_warning ("OOPS, length incorrect after chunk split...");
148  }
149 
150  udp->checksum = 0;
151  udp->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ip);
152 
153  if (is_trace)
154  {
155  if (b[0]->flags & VLIB_BUFFER_IS_TRACED)
156  {
157  oddbuf_trace_t *t =
158  vlib_add_trace (vm, node, b[0], sizeof (*t));
159  t->next_index = next[0];
160  t->sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
161  t->udp_checksum = clib_net_to_host_u16 (udp->checksum);
162  }
163  }
164 
165  skip:
166  b += 1;
167  next += 1;
168  n_left_from -= 1;
169  }
170 
171  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
172 
173  return frame->n_vectors;
174 }
175 
177  vlib_frame_t * frame)
178 {
179  if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
180  return oddbuf_inline (vm, node, frame, 1 /* is_ip4 */ ,
181  1 /* is_trace */ );
182  else
183  return oddbuf_inline (vm, node, frame, 1 /* is_ip4 */ ,
184  0 /* is_trace */ );
185 }
186 
187 /* *INDENT-OFF* */
188 #ifndef CLIB_MARCH_VARIANT
190 {
191  .name = "oddbuf",
192  .vector_size = sizeof (u32),
193  .format_trace = format_oddbuf_trace,
195 
196  .n_errors = ARRAY_LEN(oddbuf_error_strings),
197  .error_strings = oddbuf_error_strings,
198 
199  .n_next_nodes = ODDBUF_N_NEXT,
200 
201  /* edit / add dispositions here */
202  .next_nodes = {
203  [ODDBUF_NEXT_DROP] = "error-drop",
204  },
205 };
206 #endif /* CLIB_MARCH_VARIANT */
207 /* *INDENT-ON* */
208 
209 /*
210  * fd.io coding-style-patch-verification: ON
211  *
212  * Local Variables:
213  * eval: (c-set-style "gnu")
214  * End:
215  */
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:124
u32 flags
Definition: vhost_user.h:141
#define CLIB_UNUSED(x)
Definition: clib.h:83
static uword oddbuf_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_ip4, int is_trace)
Definition: node.c:76
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:110
#define foreach_oddbuf_error
Definition: node.c:49
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:113
vl_api_address_t src
Definition: gre.api:51
int i
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define VLIB_NODE_FN(node)
Definition: node.h:202
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:366
oddbuf_error_t
Definition: node.c:52
unsigned char u8
Definition: types.h:56
#define always_inline
Definition: clib.h:99
static void * ip4_next_header(ip4_header_t *i)
Definition: ip4_packet.h:241
unsigned int u32
Definition: types.h:88
static u8 * format_oddbuf_trace(u8 *s, va_list *args)
Definition: node.c:34
#define VLIB_FRAME_SIZE
Definition: node.h:378
vl_api_fib_path_type_t type
Definition: fib_types.api:123
unsigned short u16
Definition: types.h:57
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
#define PREDICT_FALSE(x)
Definition: clib.h:112
int second_chunk_offset
Definition: oddbuf.h:39
vl_api_address_t dst
Definition: gre.api:52
static char * oddbuf_error_strings[]
Definition: node.c:61
int first_chunk_offset
Definition: oddbuf.h:40
u32 sw_if_index
Definition: node.c:25
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:397
vlib_main_t * vm
Definition: buffer.c:323
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:332
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:302
oddbuf_next_t
Definition: node.c:68
#define clib_warning(format, args...)
Definition: error.h:59
u8 data[]
Packet data.
Definition: buffer.h:181
#define ARRAY_LEN(x)
Definition: clib.h:63
vlib_node_registration_t oddbuf_node
(constructor) VLIB_REGISTER_NODE (oddbuf_node)
Definition: node.c:45
u16 ip4_tcp_udp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip4_header_t *ip0)
Definition: ip4_forward.c:1299
u32 next_index
Definition: node.c:26
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
struct _vlib_node_registration vlib_node_registration_t
vl_api_address_t ip
Definition: l2.api:489
u32 next_buffer
Next buffer for this linked-list of buffers.
Definition: buffer.h:140
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:244
#define vnet_buffer(b)
Definition: buffer.h:365
u16 udp_checksum
Definition: node.c:27
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
Definition: buffer_funcs.h:244
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:302
static u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Definition: buffer_funcs.h:612
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
Definition: defs.h:46
oddbuf_main_t oddbuf_main
Definition: oddbuf.c:54
int n_to_copy
Definition: oddbuf.h:38