FD.io VPP  v21.01.1
Vector Packet Processing
gro.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 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 #ifndef included_gro_h
17 #define included_gro_h
18 
19 #include <vlib/vlib.h>
20 #include <vppinfra/error.h>
21 #include <vnet/ip/ip46_address.h>
22 
23 #define GRO_FLOW_TABLE_MAX_SIZE 16
24 #define GRO_FLOW_TABLE_FLUSH 1e-5
25 #define GRO_FLOW_N_BUFFERS 64
26 #define GRO_FLOW_TIMEOUT 1e-5 /* 10 micro-seconds */
27 #define GRO_TO_VECTOR_SIZE(X) (X + GRO_FLOW_TABLE_MAX_SIZE)
28 
29 typedef union
30 {
31  struct
32  {
34  ip46_address_t src_address;
35  ip46_address_t dst_address;
38  };
39 
40  u64 flow_data[5];
43 
44 typedef struct
45 {
51 } gro_flow_t;
52 
53 typedef struct
54 {
64 
67 {
68  to->flow_key.flow_data[0] = from->flow_data[0];
69  to->flow_key.flow_data[1] = from->flow_data[1];
70  to->flow_key.flow_data[2] = from->flow_data[2];
71  to->flow_key.flow_data[3] = from->flow_data[3];
72  to->flow_key.flow_data[4] = from->flow_data[4];
74 }
75 
78 {
79  if (first->flow_data[0] == second->flow_data[0] &&
80  first->flow_data[1] == second->flow_data[1] &&
81  first->flow_data[2] == second->flow_data[2] &&
82  first->flow_data[3] == second->flow_data[3] &&
83  first->flow_data[4] == second->flow_data[4] &&
84  first->flow_data_u32 == second->flow_data_u32)
85  return 1;
86 
87  return 0;
88 }
89 
90 /**
91  * timeout_expire is in between 3 to 10 microseconds
92  * 3e-6 1e-5
93  */
96  f64 timeout_expire)
97 {
98  gro_flow->next_timeout_ts = vlib_time_now (vm) + timeout_expire;
99 }
100 
103 {
104  if (gro_flow->next_timeout_ts < vlib_time_now (vm))
105  return 1;
106  return 0;
107 }
108 
111 {
112  if (gro_flow->n_buffers == 0)
113  {
114  gro_flow->buffer_index = bi0;
115  }
116  gro_flow->n_buffers++;
117 }
118 
120 gro_flow_table_init (gro_flow_table_t ** flow_table, u8 is_l2, u32 node_index)
121 {
122  if (*flow_table)
123  return 0;
124 
125  gro_flow_table_t *flow_table_temp = 0;
126  flow_table_temp =
128  if (!flow_table_temp)
129  return 0;
130  clib_memset (flow_table_temp, 0, sizeof (gro_flow_table_t));
131  flow_table_temp->node_index = node_index;
132  flow_table_temp->is_enable = 1;
133  flow_table_temp->is_l2 = is_l2;
134  *flow_table = flow_table_temp;
135  return 1;
136 }
137 
140  f64 timeout_expire)
141 {
142  if (flow_table)
143  flow_table->timeout_ts = vlib_time_now (vm) + timeout_expire;
144 }
145 
148 {
149  if (flow_table && (flow_table->timeout_ts < vlib_time_now (vm)))
150  return 1;
151  return 0;
152 }
153 
156 {
157  if (flow_table)
158  return flow_table->is_enable;
159 
160  return 0;
161 }
162 
165 {
166  if (flow_table)
167  flow_table->is_enable = is_enable;
168 }
169 
172 {
173  if (flow_table)
174  clib_mem_free (flow_table);
175 }
176 
179 {
180  if (flow_table)
181  flow_table->node_index = node_index;
182 }
183 
186 {
188  {
189  gro_flow_t *gro_flow;
190  u32 i = 0;
191  while (i < GRO_FLOW_TABLE_MAX_SIZE)
192  {
193  gro_flow = &flow_table->gro_flow[i];
194  if (gro_flow->n_buffers == 0)
195  {
196  flow_table->flow_table_size++;
197  return gro_flow;
198  }
199  i++;
200  }
201  }
202 
203  return (0);
204 }
205 
208  gro_flow_key_t * flow_key)
209 {
210  gro_flow_t *gro_flow = 0;
211  u32 i = 0;
212  while (i < GRO_FLOW_TABLE_MAX_SIZE)
213  {
214  gro_flow = &flow_table->gro_flow[i];
215  if (gro_flow_is_equal (flow_key, &gro_flow->flow_key))
216  return gro_flow;
217  i++;
218  }
219  return (0);
220 }
221 
224  gro_flow_key_t * flow_key)
225 {
226  gro_flow_t *gro_flow = 0;
227 
228  gro_flow = gro_flow_table_get_flow (flow_table, flow_key);
229  if (gro_flow)
230  return gro_flow;
231 
232  gro_flow = gro_flow_table_new_flow (flow_table);
233 
234  if (gro_flow)
235  {
236  gro_flow_set_flow_key (gro_flow, flow_key);
237  return gro_flow;
238  }
239 
240  return (0);
241 }
242 
245  gro_flow_t * gro_flow)
246 {
247  if (PREDICT_TRUE (flow_table->flow_table_size > 0))
248  {
249  clib_memset (gro_flow, 0, sizeof (gro_flow_t));
250  flow_table->flow_table_size--;
251  }
252 }
253 
255 gro_flow_table_format (u8 * s, va_list * args)
256 {
257  gro_flow_table_t *flow_table = va_arg (*args, gro_flow_table_t *);
258  u32 indent;
259 
260  if (!flow_table)
261  return s;
262 
263  indent = format_get_indent (s);
264  if (flow_table->is_enable)
265  s = format (s, "packet-coalesce: enable\n");
266  else
267  s = format (s, "packet-coalesce: disable\n");
268 
269  indent += 2;
270 
271  s =
272  format (s,
273  "%Uflow-table: size %u gro-total-vectors %lu gro-n-vectors %u",
274  format_white_space, indent, flow_table->flow_table_size,
275  flow_table->total_vectors, flow_table->n_vectors);
276  if (flow_table->n_vectors)
277  {
278  double average_rate =
279  (double) flow_table->total_vectors / (double) flow_table->n_vectors;
280  s = format (s, " gro-average-rate %.2f", average_rate);
281  }
282  else
283  s = format (s, " gro-average-rate 0.00");
284 
285  return s;
286 }
287 #endif /* included_gro_h */
288 
289 /*
290  * fd.io coding-style-patch-verification: ON
291  *
292  * Local Variables:
293  * eval: (c-set-style "gnu")
294  * End:
295  */
static_always_inline u8 gro_flow_table_is_enable(gro_flow_table_t *flow_table)
Definition: gro.h:155
static_always_inline void gro_flow_store_packet(gro_flow_t *gro_flow, u32 bi0)
Definition: gro.h:110
static_always_inline u8 * gro_flow_table_format(u8 *s, va_list *args)
Definition: gro.h:255
#define PREDICT_TRUE(x)
Definition: clib.h:122
u8 is_enable
Definition: gro.h:59
unsigned long u64
Definition: types.h:89
static_always_inline u8 gro_flow_table_is_timeout(vlib_main_t *vm, gro_flow_table_t *flow_table)
Definition: gro.h:147
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:334
gro_flow_key_t flow_key
Definition: gro.h:46
f64 timeout_ts
Definition: gro.h:55
u16 src_port
Definition: gro.h:36
Definition: gro.h:44
static u32 format_get_indent(u8 *s)
Definition: format.h:72
vlib_main_t * vm
Definition: in2out_ed.c:1580
static_always_inline void gro_flow_set_flow_key(gro_flow_t *to, gro_flow_key_t *from)
Definition: gro.h:66
unsigned char u8
Definition: types.h:56
u16 n_buffers
Definition: gro.h:50
double f64
Definition: types.h:142
ip46_address_t src_address
Definition: gro.h:34
#define static_always_inline
Definition: clib.h:109
#define GRO_FLOW_TABLE_MAX_SIZE
Definition: gro.h:23
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
description fragment has unexpected format
Definition: map.api:433
unsigned int u32
Definition: types.h:88
u32 last_ack_number
Definition: gro.h:48
static heap_elt_t * first(heap_header_t *h)
Definition: heap.c:59
static_always_inline gro_flow_t * gro_flow_table_find_or_add_flow(gro_flow_table_t *flow_table, gro_flow_key_t *flow_key)
Definition: gro.h:223
u64 total_vectors
Definition: gro.h:56
unsigned short u16
Definition: types.h:57
ip46_address_t dst_address
Definition: gro.h:35
static_always_inline gro_flow_t * gro_flow_table_new_flow(gro_flow_table_t *flow_table)
Definition: gro.h:185
gro_flow_t gro_flow[GRO_FLOW_TABLE_MAX_SIZE]
Definition: gro.h:62
u32 buffer_index
Definition: gro.h:49
static_always_inline void gro_flow_table_reset_flow(gro_flow_table_t *flow_table, gro_flow_t *gro_flow)
Definition: gro.h:244
u16 dst_port
Definition: gro.h:37
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
static_always_inline void gro_flow_table_free(gro_flow_table_t *flow_table)
Definition: gro.h:171
static_always_inline u32 gro_flow_table_init(gro_flow_table_t **flow_table, u8 is_l2, u32 node_index)
Definition: gro.h:120
static_always_inline u8 gro_flow_is_timeout(vlib_main_t *vm, gro_flow_t *gro_flow)
Definition: gro.h:102
static_always_inline u8 gro_flow_is_equal(gro_flow_key_t *first, gro_flow_key_t *second)
Definition: gro.h:77
static_always_inline void gro_flow_table_set_timeout(vlib_main_t *vm, gro_flow_table_t *flow_table, f64 timeout_expire)
Definition: gro.h:139
static void clib_mem_free(void *p)
Definition: mem.h:311
static void * clib_mem_alloc(uword size)
Definition: mem.h:253
static_always_inline void gro_flow_set_timeout(vlib_main_t *vm, gro_flow_t *gro_flow, f64 timeout_expire)
timeout_expire is in between 3 to 10 microseconds 3e-6 1e-5
Definition: gro.h:95
u8 flow_table_size
Definition: gro.h:61
u32 n_vectors
Definition: gro.h:57
u64 flow_data[5]
Definition: gro.h:40
u32 flow_data_u32
Definition: gro.h:41
static_always_inline gro_flow_t * gro_flow_table_get_flow(gro_flow_table_t *flow_table, gro_flow_key_t *flow_key)
Definition: gro.h:207
u32 node_index
Definition: gro.h:58
static_always_inline void gro_flow_table_set_is_enable(gro_flow_table_t *flow_table, u8 is_enable)
Definition: gro.h:164
f64 next_timeout_ts
Definition: gro.h:47
static_always_inline void gro_flow_table_set_node_index(gro_flow_table_t *flow_table, u32 node_index)
Definition: gro.h:178
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34