FD.io VPP  v20.09-rc2-28-g3c5414029
Vector Packet Processing
cnat_node.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 __CNAT_NODE_H__
17 #define __CNAT_NODE_H__
18 
19 #include <vlibmemory/api.h>
20 #include <cnat/cnat_session.h>
21 #include <cnat/cnat_client.h>
22 
25  vlib_buffer_t * b,
26  cnat_node_ctx_t * ctx, int rv,
27  cnat_session_t * session);
28 
29 /**
30  * Inline translation functions
31  */
32 
34 has_ip6_address (ip6_address_t * a)
35 {
36  return ((0 != a->as_u64[0]) || (0 != a->as_u64[1]));
37 }
38 
41  u16 * checksum,
42  ip4_address_t new_addr[VLIB_N_DIR],
43  u16 new_port[VLIB_N_DIR])
44 {
45  u16 old_port[VLIB_N_DIR];
46  ip4_address_t old_addr[VLIB_N_DIR];
47  ip_csum_t sum;
48 
49  old_port[VLIB_TX] = udp->dst_port;
50  old_port[VLIB_RX] = udp->src_port;
51  old_addr[VLIB_TX] = ip4->dst_address;
52  old_addr[VLIB_RX] = ip4->src_address;
53 
54  sum = *checksum;
55  if (new_addr[VLIB_TX].as_u32)
56  sum =
57  ip_csum_update (sum, old_addr[VLIB_TX].as_u32, new_addr[VLIB_TX].as_u32,
58  ip4_header_t, dst_address);
59  if (new_port[VLIB_TX])
60  {
61  udp->dst_port = new_port[VLIB_TX];
62  sum = ip_csum_update (sum, old_port[VLIB_TX], new_port[VLIB_TX],
63  ip4_header_t /* cheat */ ,
64  length /* changed member */ );
65  }
66  if (new_addr[VLIB_RX].as_u32)
67  sum =
68  ip_csum_update (sum, old_addr[VLIB_RX].as_u32, new_addr[VLIB_RX].as_u32,
70 
71  if (new_port[VLIB_RX])
72  {
73  udp->src_port = new_port[VLIB_RX];
74  sum = ip_csum_update (sum, old_port[VLIB_RX], new_port[VLIB_RX],
75  ip4_header_t /* cheat */ ,
76  length /* changed member */ );
77  }
78  *checksum = ip_csum_fold (sum);
79 }
80 
83 {
84  ip4_address_t old_addr[VLIB_N_DIR];
85  ip_csum_t sum;
86 
87  old_addr[VLIB_TX] = ip4->dst_address;
88  old_addr[VLIB_RX] = ip4->src_address;
89 
90  sum = ip4->checksum;
91  if (new_addr[VLIB_TX].as_u32)
92  {
93  ip4->dst_address = new_addr[VLIB_TX];
94  sum =
95  ip_csum_update (sum, old_addr[VLIB_TX].as_u32,
96  new_addr[VLIB_TX].as_u32, ip4_header_t, dst_address);
97  }
98  if (new_addr[VLIB_RX].as_u32)
99  {
100  ip4->src_address = new_addr[VLIB_RX];
101  sum =
102  ip_csum_update (sum, old_addr[VLIB_RX].as_u32,
103  new_addr[VLIB_RX].as_u32, ip4_header_t, src_address);
104  }
105  ip4->checksum = ip_csum_fold (sum);
106 }
107 
110 {
112  if (PREDICT_FALSE (tcp_fin (tcp)))
113  {
115  }
116 
117  if (PREDICT_FALSE (tcp_rst (tcp)))
118  {
120  }
121 
122  if (PREDICT_FALSE (tcp_syn (tcp) && tcp_ack (tcp)))
123  {
125  }
126 }
127 
130  ip4_header_t * ip4, udp_header_t * udp)
131 {
132  tcp_header_t *tcp = (tcp_header_t *) udp;
133  ip4_address_t new_addr[VLIB_N_DIR];
134  u16 new_port[VLIB_N_DIR];
135 
136  new_addr[VLIB_TX] = session->value.cs_ip[VLIB_TX].ip4;
137  new_addr[VLIB_RX] = session->value.cs_ip[VLIB_RX].ip4;
138  new_port[VLIB_TX] = session->value.cs_port[VLIB_TX];
139  new_port[VLIB_RX] = session->value.cs_port[VLIB_RX];
140 
141  if (ip4->protocol == IP_PROTOCOL_TCP)
142  {
143  if (PREDICT_FALSE (tcp->checksum))
144  cnat_ip4_translate_l4 (ip4, udp, &tcp->checksum, new_addr, new_port);
145  else
146  {
147  udp->dst_port = new_port[VLIB_TX];
148  udp->src_port = new_port[VLIB_RX];
149  }
151  }
152  else if (ip4->protocol == IP_PROTOCOL_UDP)
153  {
154  if (PREDICT_FALSE (udp->checksum))
155  cnat_ip4_translate_l4 (ip4, udp, &udp->checksum, new_addr, new_port);
156  else
157  {
158  udp->dst_port = new_port[VLIB_TX];
159  udp->src_port = new_port[VLIB_RX];
160  }
161  }
162 
163  cnat_ip4_translate_l3 (ip4, new_addr);
164 }
165 
167 cnat_ip6_translate_l3 (ip6_header_t * ip6, ip6_address_t new_addr[VLIB_N_DIR])
168 {
169  if (has_ip6_address (&new_addr[VLIB_TX]))
170  ip6_address_copy (&ip6->dst_address, &new_addr[VLIB_TX]);
171  if (has_ip6_address (&new_addr[VLIB_RX]))
172  ip6_address_copy (&ip6->src_address, &new_addr[VLIB_RX]);
173 }
174 
177  u16 * checksum,
178  ip6_address_t new_addr[VLIB_N_DIR],
179  u16 new_port[VLIB_N_DIR])
180 {
181  u16 old_port[VLIB_N_DIR];
182  ip6_address_t old_addr[VLIB_N_DIR];
183  ip_csum_t sum;
184 
185  old_port[VLIB_TX] = udp->dst_port;
186  old_port[VLIB_RX] = udp->src_port;
187  ip6_address_copy (&old_addr[VLIB_TX], &ip6->dst_address);
188  ip6_address_copy (&old_addr[VLIB_RX], &ip6->src_address);
189 
190  sum = *checksum;
191  if (has_ip6_address (&new_addr[VLIB_TX]))
192  {
193  sum = ip_csum_add_even (sum, new_addr[VLIB_TX].as_u64[0]);
194  sum = ip_csum_add_even (sum, new_addr[VLIB_TX].as_u64[1]);
195  sum = ip_csum_sub_even (sum, old_addr[VLIB_TX].as_u64[0]);
196  sum = ip_csum_sub_even (sum, old_addr[VLIB_TX].as_u64[1]);
197  }
198 
199  if (new_port[VLIB_TX])
200  {
201  udp->dst_port = new_port[VLIB_TX];
202  sum = ip_csum_update (sum, old_port[VLIB_TX], new_port[VLIB_TX],
203  ip4_header_t /* cheat */ ,
204  length /* changed member */ );
205  }
206  if (has_ip6_address (&new_addr[VLIB_RX]))
207  {
208  sum = ip_csum_add_even (sum, new_addr[VLIB_RX].as_u64[0]);
209  sum = ip_csum_add_even (sum, new_addr[VLIB_RX].as_u64[1]);
210  sum = ip_csum_sub_even (sum, old_addr[VLIB_RX].as_u64[0]);
211  sum = ip_csum_sub_even (sum, old_addr[VLIB_RX].as_u64[1]);
212  }
213 
214  if (new_port[VLIB_RX])
215  {
216  udp->src_port = new_port[VLIB_RX];
217  sum = ip_csum_update (sum, old_port[VLIB_RX], new_port[VLIB_RX],
218  ip4_header_t /* cheat */ ,
219  length /* changed member */ );
220  }
221  *checksum = ip_csum_fold (sum);
222 }
223 
226  ip6_header_t * ip6, udp_header_t * udp)
227 {
228  tcp_header_t *tcp = (tcp_header_t *) udp;
229  ip6_address_t new_addr[VLIB_N_DIR];
230  u16 new_port[VLIB_N_DIR];
231 
232  ip6_address_copy (&new_addr[VLIB_TX], &session->value.cs_ip[VLIB_TX].ip6);
233  ip6_address_copy (&new_addr[VLIB_RX], &session->value.cs_ip[VLIB_RX].ip6);
234  new_port[VLIB_TX] = session->value.cs_port[VLIB_TX];
235  new_port[VLIB_RX] = session->value.cs_port[VLIB_RX];
236 
237  if (ip6->protocol == IP_PROTOCOL_TCP)
238  {
239  if (PREDICT_FALSE (tcp->checksum))
240  cnat_ip6_translate_l4 (ip6, udp, &tcp->checksum, new_addr, new_port);
241  else
242  {
243  udp->dst_port = new_port[VLIB_TX];
244  udp->src_port = new_port[VLIB_RX];
245  }
247  }
248  else if (ip6->protocol == IP_PROTOCOL_UDP)
249  {
250  if (PREDICT_FALSE (udp->checksum))
251  cnat_ip6_translate_l4 (ip6, udp, &udp->checksum, new_addr, new_port);
252  else
253  {
254  udp->dst_port = new_port[VLIB_TX];
255  udp->src_port = new_port[VLIB_RX];
256  }
257  }
258 
259  cnat_ip6_translate_l3 (ip6, new_addr);
260 }
261 
264  clib_bihash_kv_40_48_t * bkey)
265 {
266  udp_header_t *udp;
267  cnat_session_t *session = (cnat_session_t *) bkey;
268  if (AF_IP4 == af)
269  {
270  ip4_header_t *ip4;
271  ip4 = vlib_buffer_get_current (b);
272  udp = (udp_header_t *) (ip4 + 1);
273  session->key.cs_af = AF_IP4;
274  session->key.__cs_pad[0] = 0;
275  session->key.__cs_pad[1] = 0;
276 
277  ip46_address_set_ip4 (&session->key.cs_ip[VLIB_TX], &ip4->dst_address);
278  ip46_address_set_ip4 (&session->key.cs_ip[VLIB_RX], &ip4->src_address);
279  session->key.cs_port[VLIB_RX] = udp->src_port;
280  session->key.cs_port[VLIB_TX] = udp->dst_port;
281  session->key.cs_proto = ip4->protocol;
282  }
283  else
284  {
285  ip6_header_t *ip6;
286  ip6 = vlib_buffer_get_current (b);
287  udp = (udp_header_t *) (ip6 + 1);
288  session->key.cs_af = AF_IP6;
289  session->key.__cs_pad[0] = 0;
290  session->key.__cs_pad[1] = 0;
291 
292  ip46_address_set_ip6 (&session->key.cs_ip[VLIB_TX], &ip6->dst_address);
293  ip46_address_set_ip6 (&session->key.cs_ip[VLIB_RX], &ip6->src_address);
294  session->key.cs_port[VLIB_RX] = udp->src_port;
295  session->key.cs_port[VLIB_TX] = udp->dst_port;
296  session->key.cs_proto = ip6->protocol;
297  }
298 }
299 
300 /**
301  * Create NAT sessions
302  */
303 
306  u8 rsession_flags)
307 {
308  cnat_client_t *cc;
310  cnat_session_t *rsession = (cnat_session_t *) & rkey;
312  clib_bihash_kv_40_48_t rvalue;
313  int rv;
314 
315  /* create the reverse flow key */
316  ip46_address_copy (&rsession->key.cs_ip[VLIB_RX],
317  &session->value.cs_ip[VLIB_TX]);
318  ip46_address_copy (&rsession->key.cs_ip[VLIB_TX],
319  &session->value.cs_ip[VLIB_RX]);
320  rsession->key.cs_proto = session->key.cs_proto;
321  rsession->key.__cs_pad[0] = 0;
322  rsession->key.__cs_pad[1] = 0;
323  rsession->key.cs_af = ctx->af;
324  rsession->key.cs_port[VLIB_RX] = session->value.cs_port[VLIB_TX];
325  rsession->key.cs_port[VLIB_TX] = session->value.cs_port[VLIB_RX];
326 
327  /* First search for existing reverse session */
328  rv = clib_bihash_search_inline_2_40_48 (&cnat_session_db, &rkey, &rvalue);
329  if (!rv)
330  {
331  /* Reverse session already exists
332  corresponding client should also exist
333  we only need to refcnt the timestamp */
334  cnat_session_t *found_rsession = (cnat_session_t *) & rvalue;
335  session->value.cs_ts_index = found_rsession->value.cs_ts_index;
337  clib_bihash_add_del_40_48 (&cnat_session_db, bkey, 1 /* is_add */ );
338  goto create_rsession;
339  }
340 
341  session->value.cs_ts_index = cnat_timestamp_new (ctx->now);
342  clib_bihash_add_del_40_48 (&cnat_session_db, bkey, 1);
343 
344  /* is this the first time we've seen this source address */
345  cc = (AF_IP4 == ctx->af ?
346  cnat_client_ip4_find (&session->value.cs_ip[VLIB_RX].ip4) :
347  cnat_client_ip6_find (&session->value.cs_ip[VLIB_RX].ip6));
348 
349  if (NULL == cc)
350  {
351  u64 r0 = 17;
352  if (AF_IP4 == ctx->af)
353  r0 = (u64) session->value.cs_ip[VLIB_RX].ip4.as_u32;
354  else
355  {
356  r0 = r0 * 31 + session->value.cs_ip[VLIB_RX].ip6.as_u64[0];
357  r0 = r0 * 31 + session->value.cs_ip[VLIB_RX].ip6.as_u64[1];
358  }
359 
360  /* Rate limit */
361  if (!throttle_check (&cnat_throttle, ctx->thread_index, r0, ctx->seed))
362  {
364  l.addr.version = ctx->af;
365  ip46_address_copy (&l.addr.ip, &session->value.cs_ip[VLIB_RX]);
366  /* fire client create to the main thread */
368  (u8 *) & l, sizeof (l));
369  }
370  else
371  {
372  /* Will still need to count those for session refcnt */
375  [ctx->thread_index]);
377  addr->version = ctx->af;
378  ip46_address_copy (&addr->ip, &session->value.cs_ip[VLIB_RX]);
380  [ctx->thread_index]);
381  }
382  }
383  else
384  {
386  }
387 
388 create_rsession:
389  /* add the reverse flow */
390  ip46_address_copy (&rsession->value.cs_ip[VLIB_RX],
391  &session->key.cs_ip[VLIB_TX]);
392  ip46_address_copy (&rsession->value.cs_ip[VLIB_TX],
393  &session->key.cs_ip[VLIB_RX]);
394  rsession->value.cs_ts_index = session->value.cs_ts_index;
395  rsession->value.cs_lbi = INDEX_INVALID;
396  rsession->value.flags = rsession_flags;
397  rsession->value.cs_port[VLIB_TX] = session->key.cs_port[VLIB_RX];
398  rsession->value.cs_port[VLIB_RX] = session->key.cs_port[VLIB_TX];
399 
400  clib_bihash_add_del_40_48 (&cnat_session_db, &rkey, 1);
401 }
402 
407  cnat_node_sub_t cnat_sub,
408  ip_address_family_t af, u8 do_trace)
409 {
410  u32 n_left, *from, thread_index;
412  vlib_buffer_t **b = bufs;
413  u16 nexts[VLIB_FRAME_SIZE], *next;
414  f64 now;
415  u64 seed;
416 
417  thread_index = vm->thread_index;
418  from = vlib_frame_vector_args (frame);
419  n_left = frame->n_vectors;
420  next = nexts;
421  vlib_get_buffers (vm, from, bufs, n_left);
422  now = vlib_time_now (vm);
423  seed = throttle_seed (&cnat_throttle, thread_index, vlib_time_now (vm));
424  cnat_session_t *session[4];
425  clib_bihash_kv_40_48_t bkey[4], bvalue[4];
426  u64 hash[4];
427  int rv[4];
428 
429  cnat_node_ctx_t ctx = { now, seed, thread_index, af, do_trace };
430 
431  if (n_left >= 8)
432  {
433  /* Kickstart our state */
434  cnat_session_make_key (b[3], af, &bkey[3]);
435  cnat_session_make_key (b[2], af, &bkey[2]);
436  cnat_session_make_key (b[1], af, &bkey[1]);
437  cnat_session_make_key (b[0], af, &bkey[0]);
438 
439  hash[3] = clib_bihash_hash_40_48 (&bkey[3]);
440  hash[2] = clib_bihash_hash_40_48 (&bkey[2]);
441  hash[1] = clib_bihash_hash_40_48 (&bkey[1]);
442  hash[0] = clib_bihash_hash_40_48 (&bkey[0]);
443  }
444 
445  while (n_left >= 8)
446  {
447  if (n_left >= 12)
448  {
449  vlib_prefetch_buffer_header (b[11], LOAD);
450  vlib_prefetch_buffer_header (b[10], LOAD);
451  vlib_prefetch_buffer_header (b[9], LOAD);
452  vlib_prefetch_buffer_header (b[8], LOAD);
453  }
454 
455  rv[3] =
456  clib_bihash_search_inline_2_with_hash_40_48 (&cnat_session_db,
457  hash[3], &bkey[3],
458  &bvalue[3]);
459  session[3] = (cnat_session_t *) (rv[3] ? &bkey[3] : &bvalue[3]);
460  next[3] = cnat_sub (vm, node, b[3], &ctx, rv[3], session[3]);
461 
462  rv[2] =
463  clib_bihash_search_inline_2_with_hash_40_48 (&cnat_session_db,
464  hash[2], &bkey[2],
465  &bvalue[2]);
466  session[2] = (cnat_session_t *) (rv[2] ? &bkey[2] : &bvalue[2]);
467  next[2] = cnat_sub (vm, node, b[2], &ctx, rv[2], session[2]);
468 
469  rv[1] =
470  clib_bihash_search_inline_2_with_hash_40_48 (&cnat_session_db,
471  hash[1], &bkey[1],
472  &bvalue[1]);
473  session[1] = (cnat_session_t *) (rv[1] ? &bkey[1] : &bvalue[1]);
474  next[1] = cnat_sub (vm, node, b[1], &ctx, rv[1], session[1]);
475 
476  rv[0] =
477  clib_bihash_search_inline_2_with_hash_40_48 (&cnat_session_db,
478  hash[0], &bkey[0],
479  &bvalue[0]);
480  session[0] = (cnat_session_t *) (rv[0] ? &bkey[0] : &bvalue[0]);
481  next[0] = cnat_sub (vm, node, b[0], &ctx, rv[0], session[0]);
482 
483  cnat_session_make_key (b[7], af, &bkey[3]);
484  cnat_session_make_key (b[6], af, &bkey[2]);
485  cnat_session_make_key (b[5], af, &bkey[1]);
486  cnat_session_make_key (b[4], af, &bkey[0]);
487 
488  hash[3] = clib_bihash_hash_40_48 (&bkey[3]);
489  hash[2] = clib_bihash_hash_40_48 (&bkey[2]);
490  hash[1] = clib_bihash_hash_40_48 (&bkey[1]);
491  hash[0] = clib_bihash_hash_40_48 (&bkey[0]);
492 
493  clib_bihash_prefetch_bucket_40_48 (&cnat_session_db, hash[3]);
494  clib_bihash_prefetch_bucket_40_48 (&cnat_session_db, hash[2]);
495  clib_bihash_prefetch_bucket_40_48 (&cnat_session_db, hash[1]);
496  clib_bihash_prefetch_bucket_40_48 (&cnat_session_db, hash[0]);
497 
498  clib_bihash_prefetch_data_40_48 (&cnat_session_db, hash[3]);
499  clib_bihash_prefetch_data_40_48 (&cnat_session_db, hash[2]);
500  clib_bihash_prefetch_data_40_48 (&cnat_session_db, hash[1]);
501  clib_bihash_prefetch_data_40_48 (&cnat_session_db, hash[0]);
502 
503  b += 4;
504  next += 4;
505  n_left -= 4;
506  }
507 
508  while (n_left > 0)
509  {
510  cnat_session_make_key (b[0], af, &bkey[0]);
511  rv[0] = clib_bihash_search_inline_2_40_48 (&cnat_session_db,
512  &bkey[0], &bvalue[0]);
513 
514  session[0] = (cnat_session_t *) (rv[0] ? &bkey[0] : &bvalue[0]);
515  next[0] = cnat_sub (vm, node, b[0], &ctx, rv[0], session[0]);
516 
517  b++;
518  next++;
519  n_left--;
520  }
521 
522  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
523 
524  return frame->n_vectors;
525 }
526 
527 /*
528  * fd.io coding-style-patch-verification: ON
529  *
530  * Local Variables:
531  * eval: (c-set-style "gnu")
532  * End:
533  */
534 
535 #endif
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
Definition: lock.h:119
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
Definition: lock.h:80
static void cnat_timestamp_inc_refcnt(u32 index)
Definition: cnat_types.h:190
ip_address_t ** throttle_pool
Definition: cnat_client.h:147
a
Definition: bitmap.h:538
ip4_address_t src_address
Definition: ip4_packet.h:125
#define tcp_rst(_th)
Definition: tcp_packet.h:81
u64 as_u64
Definition: bihash_doc.h:63
unsigned long u64
Definition: types.h:89
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:333
throttle_t cnat_throttle
Definition: cnat_types.c:21
uword(* cnat_node_sub_t)(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t *b, cnat_node_ctx_t *ctx, int rv, cnat_session_t *session)
Definition: cnat_node.h:23
u16 cs_port[VLIB_N_DIR]
ports in rx/tx
Definition: cnat_session.h:53
u32 thread_index
Definition: main.h:249
static_always_inline void cnat_ip4_translate_l4(ip4_header_t *ip4, udp_header_t *udp, u16 *checksum, ip4_address_t new_addr[VLIB_N_DIR], u16 new_port[VLIB_N_DIR])
Definition: cnat_node.h:40
ip46_address_t ip
Definition: ip_types.h:49
static u64 clib_bihash_hash_40_48(const clib_bihash_kv_40_48_t *v)
Definition: bihash_40_48.h:55
uword ip_csum_t
Definition: ip_packet.h:244
vlib_main_t * vm
Definition: in2out_ed.c:1582
#define tcp_fin(_th)
Definition: tcp_packet.h:79
static_always_inline void ip46_address_set_ip6(ip46_address_t *dst, const ip6_address_t *src)
Definition: ip46_address.h:130
static_always_inline void cnat_tcp_update_session_lifetime(tcp_header_t *tcp, u32 index)
Definition: cnat_node.h:109
static_always_inline void cnat_ip6_translate_l4(ip6_header_t *ip6, udp_header_t *udp, u16 *checksum, ip6_address_t new_addr[VLIB_N_DIR], u16 new_port[VLIB_N_DIR])
Definition: cnat_node.h:176
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:252
struct _tcp_header tcp_header_t
vhost_vring_addr_t addr
Definition: vhost_user.h:111
clib_bihash_40_48_t cnat_session_db
The DB of sessions.
Definition: cnat_session.c:23
ip6_address_t src_address
Definition: ip6_packet.h:310
unsigned char u8
Definition: types.h:56
double f64
Definition: types.h:142
static u32 cnat_timestamp_new(f64 t)
Definition: cnat_types.h:175
A session represents the memory of a translation.
Definition: cnat_session.h:38
u8 cs_af
The address family describing the IP addresses.
Definition: cnat_session.h:63
#define static_always_inline
Definition: clib.h:108
vl_api_ip6_address_t ip6
Definition: one.api:424
ip4_address_t dst_address
Definition: ip4_packet.h:125
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:203
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
Definition: vlib_api.c:619
unsigned int u32
Definition: types.h:88
#define VLIB_FRAME_SIZE
Definition: node.h:377
ip46_address_t cs_ip[VLIB_N_DIR]
IP 4/6 address in the rx/tx direction.
Definition: cnat_session.h:48
u32 cs_ts_index
Timestamp index this session was last used.
Definition: cnat_session.h:93
static_always_inline u32 cnat_client_cnt_session(cnat_client_t *cc)
Add a session refcnt to this client.
Definition: cnat_client.h:202
vnet_crypto_main_t * cm
Definition: quic_crypto.c:53
static_always_inline void ip46_address_copy(ip46_address_t *dst, const ip46_address_t *src)
Definition: ip46_address.h:123
long ctx[MAX_CONNS]
Definition: main.c:144
unsigned short u16
Definition: types.h:57
ip_address_t addr
Definition: cnat_client.h:98
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
static u64 throttle_seed(throttle_t *t, u32 thread_index, f64 time_now)
Definition: throttle.h:41
#define PREDICT_FALSE(x)
Definition: clib.h:120
#define always_inline
Definition: ipsec.h:28
vl_api_ip4_address_t ip4
Definition: one.api:376
static_always_inline cnat_client_t * cnat_client_ip4_find(const ip4_address_t *ip)
Find a client from an IP4 address.
Definition: cnat_client.h:157
vl_api_address_union_t src_address
Definition: ip_types.api:111
static_always_inline void cnat_translation_ip6(const cnat_session_t *session, ip6_header_t *ip6, udp_header_t *udp)
Definition: cnat_node.h:225
static_always_inline void cnat_session_make_key(vlib_buffer_t *b, ip_address_family_t af, clib_bihash_kv_40_48_t *bkey)
Definition: cnat_node.h:263
static_always_inline void cnat_ip6_translate_l3(ip6_header_t *ip6, ip6_address_t new_addr[VLIB_N_DIR])
Definition: cnat_node.h:167
u16 n_vectors
Definition: node.h:396
clib_spinlock_t * throttle_pool_lock
Definition: cnat_client.h:148
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_always_inline void cnat_ip4_translate_l3(ip4_header_t *ip4, ip4_address_t new_addr[VLIB_N_DIR])
Definition: cnat_node.h:82
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1582
struct cnat_session_t_::@637 value
this value sits in the same memory location a &#39;value&#39; in the bihash kvp
#define tcp_syn(_th)
Definition: tcp_packet.h:80
static_always_inline void cnat_translation_ip4(const cnat_session_t *session, ip4_header_t *ip4, udp_header_t *udp)
Definition: cnat_node.h:129
void cnat_client_learn(const cnat_learn_arg_t *l)
Called in the main thread by RPC from the workers to learn a new client.
Definition: cnat_client.c:199
#define CNAT_DEFAULT_TCP_RST_TIMEOUT
Definition: cnat_types.h:32
static ip_csum_t ip_csum_sub_even(ip_csum_t c, ip_csum_t x)
Definition: ip_packet.h:272
#define VLIB_N_DIR
Definition: defs.h:57
ip_address_family_t version
Definition: ip_types.h:50
static_always_inline cnat_client_t * cnat_client_ip6_find(const ip6_address_t *ip)
Find a client from an IP6 address.
Definition: cnat_client.h:186
enum ip_address_family_t_ ip_address_family_t
Definition: defs.h:47
ip_protocol_t cs_proto
The IP protocol TCP or UDP only supported.
Definition: cnat_session.h:58
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1583
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
struct cnat_session_t_::@636 key
this key sits in the same memory location a &#39;key&#39; in the bihash kvp
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:297
cnat_main_t cnat_main
Definition: cnat_types.c:18
#define ip_csum_update(sum, old, new, type, field)
Definition: ip_packet.h:294
u32 index
Definition: flow_types.api:221
static void ip6_address_copy(ip6_address_t *dst, const ip6_address_t *src)
Definition: ip6_packet.h:127
cnat_client_db_t cnat_client_db
Definition: cnat_client.c:24
u32 tcp_max_age
Definition: cnat_types.h:108
ip_address_family_t af
Definition: cnat_types.h:147
static_always_inline void cnat_session_create(cnat_session_t *session, cnat_node_ctx_t *ctx, u8 rsession_flags)
Create NAT sessions.
Definition: cnat_node.h:305
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:280
static void cnat_timestamp_set_lifetime(u32 index, u16 lifetime)
Definition: cnat_types.h:208
#define tcp_ack(_th)
Definition: tcp_packet.h:83
static u16 ip_csum_fold(ip_csum_t c)
Definition: ip_packet.h:300
static void ip46_address_set_ip4(ip46_address_t *ip46, const ip4_address_t *ip)
Definition: ip46_address.h:67
static uword cnat_node_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, cnat_node_sub_t cnat_sub, ip_address_family_t af, u8 do_trace)
Definition: cnat_node.h:404
Definition: defs.h:46
static ip_csum_t ip_csum_add_even(ip_csum_t c, ip_csum_t x)
Definition: ip_packet.h:255
ip6_address_t dst_address
Definition: ip6_packet.h:310
A client is a representation of an IP address behind the NAT.
Definition: cnat_client.h:35
static_always_inline u8 has_ip6_address(ip6_address_t *a)
Inline translation functions.
Definition: cnat_node.h:34
static int throttle_check(throttle_t *t, u32 thread_index, u64 hash, u64 seed)
Definition: throttle.h:54