FD.io VPP  v16.06
Vector Packet Processing
buffer_node.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  * buffer_node.h: VLIB buffer handling node helper macros/inlines
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #ifndef included_vlib_buffer_node_h
41 #define included_vlib_buffer_node_h
42 
43 #define vlib_validate_buffer_enqueue_x2(vm,node,next_index,to_next,n_left_to_next,bi0,bi1,next0,next1) \
44 do { \
45  int enqueue_code = (next0 != next_index) + 2*(next1 != next_index); \
46  \
47  if (PREDICT_FALSE (enqueue_code != 0)) \
48  { \
49  switch (enqueue_code) \
50  { \
51  case 1: \
52  /* A B A */ \
53  to_next[-2] = bi1; \
54  to_next -= 1; \
55  n_left_to_next += 1; \
56  vlib_set_next_frame_buffer (vm, node, next0, bi0); \
57  break; \
58  \
59  case 2: \
60  /* A A B */ \
61  to_next -= 1; \
62  n_left_to_next += 1; \
63  vlib_set_next_frame_buffer (vm, node, next1, bi1); \
64  break; \
65  \
66  case 3: \
67  /* A B B or A B C */ \
68  to_next -= 2; \
69  n_left_to_next += 2; \
70  vlib_set_next_frame_buffer (vm, node, next0, bi0); \
71  vlib_set_next_frame_buffer (vm, node, next1, bi1); \
72  if (next0 == next1) \
73  { \
74  vlib_put_next_frame (vm, node, next_index, \
75  n_left_to_next); \
76  next_index = next1; \
77  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); \
78  } \
79  } \
80  } \
81 } while (0)
82 
83 #define vlib_validate_buffer_enqueue_x1(vm,node,next_index,to_next,n_left_to_next,bi0,next0) \
84 do { \
85  if (PREDICT_FALSE (next0 != next_index)) \
86  { \
87  vlib_put_next_frame (vm, node, next_index, n_left_to_next + 1); \
88  next_index = next0; \
89  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); \
90  \
91  to_next[0] = bi0; \
92  to_next += 1; \
93  n_left_to_next -= 1; \
94  } \
95 } while (0)
96 
99  vlib_node_runtime_t * node,
100  vlib_frame_t * frame,
101  uword sizeof_trace,
102  void * opaque1,
103  uword opaque2,
104  void (* two_buffers) (vlib_main_t * vm,
105  void * opaque1,
106  uword opaque2,
107  vlib_buffer_t * b0, vlib_buffer_t * b1,
108  u32 * next0, u32 * next1),
109  void (* one_buffer) (vlib_main_t * vm,
110  void * opaque1,
111  uword opaque2,
112  vlib_buffer_t * b0,
113  u32 * next0))
114 {
115  u32 n_left_from, * from, * to_next;
116  u32 next_index;
117 
118  from = vlib_frame_vector_args (frame);
119  n_left_from = frame->n_vectors;
120  next_index = node->cached_next_index;
121 
122  if (node->flags & VLIB_NODE_FLAG_TRACE)
123  vlib_trace_frame_buffers_only (vm, node, from, frame->n_vectors,
124  /* stride */ 1, sizeof_trace);
125 
126  while (n_left_from > 0)
127  {
128  u32 n_left_to_next;
129 
130  vlib_get_next_frame (vm, node, next_index,
131  to_next, n_left_to_next);
132 
133  while (n_left_from >= 4 && n_left_to_next >= 2)
134  {
135  vlib_buffer_t * p0, * p1;
136  u32 pi0, next0;
137  u32 pi1, next1;
138 
139  /* Prefetch next iteration. */
140  {
141  vlib_buffer_t * p2, * p3;
142 
143  p2 = vlib_get_buffer (vm, from[2]);
144  p3 = vlib_get_buffer (vm, from[3]);
145 
146  vlib_prefetch_buffer_header (p2, LOAD);
147  vlib_prefetch_buffer_header (p3, LOAD);
148 
149  CLIB_PREFETCH (p2->data, 64, LOAD);
150  CLIB_PREFETCH (p3->data, 64, LOAD);
151  }
152 
153  pi0 = to_next[0] = from[0];
154  pi1 = to_next[1] = from[1];
155  from += 2;
156  to_next += 2;
157  n_left_from -= 2;
158  n_left_to_next -= 2;
159 
160  p0 = vlib_get_buffer (vm, pi0);
161  p1 = vlib_get_buffer (vm, pi1);
162 
163  two_buffers (vm, opaque1, opaque2, p0, p1, &next0, &next1);
164 
165  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
166  to_next, n_left_to_next,
167  pi0, pi1, next0, next1);
168  }
169 
170  while (n_left_from > 0 && n_left_to_next > 0)
171  {
172  vlib_buffer_t * p0;
173  u32 pi0, next0;
174 
175  pi0 = from[0];
176  to_next[0] = pi0;
177  from += 1;
178  to_next += 1;
179  n_left_from -= 1;
180  n_left_to_next -= 1;
181 
182  p0 = vlib_get_buffer (vm, pi0);
183 
184  one_buffer (vm, opaque1, opaque2, p0, &next0);
185 
186  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
187  to_next, n_left_to_next,
188  pi0, next0);
189  }
190 
191  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
192  }
193 
194  return frame->n_vectors;
195 }
196 
197 #endif /* included_vlib_buffer_node_h */
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Definition: main.c:459
#define always_inline
Definition: clib.h:84
always_inline void * vlib_frame_vector_args(vlib_frame_t *f)
Definition: node_funcs.h:202
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Definition: buffer_node.h:43
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Definition: buffer_node.h:83
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Definition: node_funcs.h:265
u16 n_vectors
Definition: node.h:307
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:82
u16 cached_next_index
Definition: node.h:422
unsigned int u32
Definition: types.h:88
always_inline uword generic_buffer_node_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, uword sizeof_trace, void *opaque1, uword opaque2, void(*two_buffers)(vlib_main_t *vm, void *opaque1, uword opaque2, vlib_buffer_t *b0, vlib_buffer_t *b1, u32 *next0, u32 *next1), void(*one_buffer)(vlib_main_t *vm, void *opaque1, uword opaque2, vlib_buffer_t *b0, u32 *next0))
Definition: buffer_node.h:98
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:225
u64 uword
Definition: types.h:112
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)
Definition: trace.c:45
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:162
u8 data[0]
Packet data.
Definition: buffer.h:150
always_inline vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:69