FD.io VPP  v18.10-32-g1161dda
Vector Packet Processing
nat64_db.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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  * @file
17  * @brief NAT64 DB
18  */
19 #include <nat/nat64_db.h>
20 #include <nat/nat_ipfix_logging.h>
21 #include <nat/nat_inlines.h>
22 #include <vnet/fib/fib_table.h>
23 
24 int
25 nat64_db_init (nat64_db_t * db, u32 bib_buckets, u32 bib_memory_size,
26  u32 st_buckets, u32 st_memory_size,
27  nat64_db_free_addr_port_function_t free_addr_port_cb)
28 {
29  clib_bihash_init_24_8 (&db->bib.in2out, "bib-in2out", bib_buckets,
30  bib_memory_size);
31 
32  clib_bihash_init_24_8 (&db->bib.out2in, "bib-out2in", bib_buckets,
33  bib_memory_size);
34 
35  clib_bihash_init_48_8 (&db->st.in2out, "st-in2out", st_buckets,
36  st_memory_size);
37 
38  clib_bihash_init_48_8 (&db->st.out2in, "st-out2in", st_buckets,
39  st_memory_size);
40 
41  db->free_addr_port_cb = free_addr_port_cb;
42  db->bib.limit = 10 * bib_buckets;
43  db->bib.bib_entries_num = 0;
44  db->st.limit = 10 * st_buckets;
45  db->st.st_entries_num = 0;
46  db->addr_free = 0;
47 
48  return 0;
49 }
50 
51 nat64_db_bib_entry_t *
53  ip4_address_t * out_addr, u16 in_port,
54  u16 out_port, u32 fib_index, u8 proto,
55  u8 is_static)
56 {
57  nat64_db_bib_entry_t *bibe;
58  nat64_db_bib_entry_key_t bibe_key;
60  fib_table_t *fib;
61 
62  if (db->bib.bib_entries_num >= db->bib.limit)
63  {
64  db->free_addr_port_cb (db, out_addr, out_port, proto);
66  return 0;
67  }
68 
69  /* create pool entry */
70  switch (ip_proto_to_snat_proto (proto))
71  {
72 /* *INDENT-OFF* */
73 #define _(N, i, n, s) \
74  case SNAT_PROTOCOL_##N: \
75  pool_get (db->bib._##n##_bib, bibe); \
76  kv.value = bibe - db->bib._##n##_bib; \
77  break;
79 #undef _
80 /* *INDENT-ON* */
81  default:
82  pool_get (db->bib._unk_proto_bib, bibe);
83  kv.value = bibe - db->bib._unk_proto_bib;
84  break;
85  }
86 
87  db->bib.bib_entries_num++;
88 
89  memset (bibe, 0, sizeof (*bibe));
90  bibe->in_addr.as_u64[0] = in_addr->as_u64[0];
91  bibe->in_addr.as_u64[1] = in_addr->as_u64[1];
92  bibe->in_port = in_port;
93  bibe->out_addr.as_u32 = out_addr->as_u32;
94  bibe->out_port = out_port;
95  bibe->fib_index = fib_index;
96  bibe->proto = proto;
97  bibe->is_static = is_static;
98 
99  /* create hash lookup */
100  bibe_key.addr.as_u64[0] = bibe->in_addr.as_u64[0];
101  bibe_key.addr.as_u64[1] = bibe->in_addr.as_u64[1];
102  bibe_key.fib_index = bibe->fib_index;
103  bibe_key.port = bibe->in_port;
104  bibe_key.proto = bibe->proto;
105  bibe_key.rsvd = 0;
106  kv.key[0] = bibe_key.as_u64[0];
107  kv.key[1] = bibe_key.as_u64[1];
108  kv.key[2] = bibe_key.as_u64[2];
109  clib_bihash_add_del_24_8 (&db->bib.in2out, &kv, 1);
110 
111  memset (&bibe_key.addr, 0, sizeof (bibe_key.addr));
112  bibe_key.addr.ip4.as_u32 = bibe->out_addr.as_u32;
113  bibe_key.fib_index = 0;
114  bibe_key.port = bibe->out_port;
115  kv.key[0] = bibe_key.as_u64[0];
116  kv.key[1] = bibe_key.as_u64[1];
117  kv.key[2] = bibe_key.as_u64[2];
118  clib_bihash_add_del_24_8 (&db->bib.out2in, &kv, 1);
119 
120  fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
121  nat_ipfix_logging_nat64_bib (in_addr, out_addr, proto, in_port, out_port,
122  fib->ft_table_id, 1);
123  return bibe;
124 }
125 
126 void
127 nat64_db_bib_entry_free (nat64_db_t * db, nat64_db_bib_entry_t * bibe)
128 {
129  nat64_db_bib_entry_key_t bibe_key;
131  nat64_db_bib_entry_t *bib;
132  u32 *ste_to_be_free = 0, *ste_index, bibe_index;
133  nat64_db_st_entry_t *st, *ste;
134  fib_table_t *fib;
135 
136  switch (ip_proto_to_snat_proto (bibe->proto))
137  {
138 /* *INDENT-OFF* */
139 #define _(N, i, n, s) \
140  case SNAT_PROTOCOL_##N: \
141  bib = db->bib._##n##_bib; \
142  st = db->st._##n##_st; \
143  break;
145 #undef _
146 /* *INDENT-ON* */
147  default:
148  bib = db->bib._unk_proto_bib;
149  st = db->st._unk_proto_st;
150  break;
151  }
152 
153  db->bib.bib_entries_num--;
154 
155  bibe_index = bibe - bib;
156 
157  /* delete ST entries for static BIB entry */
158  if (bibe->is_static)
159  {
160  pool_foreach (ste, st, (
161  {
162  if (ste->bibe_index == bibe_index)
163  vec_add1 (ste_to_be_free, ste - st);}
164  ));
165  vec_foreach (ste_index, ste_to_be_free)
166  nat64_db_st_entry_free (db, pool_elt_at_index (st, ste_index[0]));
167  vec_free (ste_to_be_free);
168  }
169 
170  /* delete hash lookup */
171  bibe_key.addr.as_u64[0] = bibe->in_addr.as_u64[0];
172  bibe_key.addr.as_u64[1] = bibe->in_addr.as_u64[1];
173  bibe_key.fib_index = bibe->fib_index;
174  bibe_key.port = bibe->in_port;
175  bibe_key.proto = bibe->proto;
176  bibe_key.rsvd = 0;
177  kv.key[0] = bibe_key.as_u64[0];
178  kv.key[1] = bibe_key.as_u64[1];
179  kv.key[2] = bibe_key.as_u64[2];
180  clib_bihash_add_del_24_8 (&db->bib.in2out, &kv, 0);
181 
182  memset (&bibe_key.addr, 0, sizeof (bibe_key.addr));
183  bibe_key.addr.ip4.as_u32 = bibe->out_addr.as_u32;
184  bibe_key.fib_index = 0;
185  bibe_key.port = bibe->out_port;
186  kv.key[0] = bibe_key.as_u64[0];
187  kv.key[1] = bibe_key.as_u64[1];
188  kv.key[2] = bibe_key.as_u64[2];
189  clib_bihash_add_del_24_8 (&db->bib.out2in, &kv, 0);
190 
191  if (!db->addr_free)
192  db->free_addr_port_cb (db, &bibe->out_addr, bibe->out_port, bibe->proto);
193 
194  fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
195  nat_ipfix_logging_nat64_bib (&bibe->in_addr, &bibe->out_addr, bibe->proto,
196  bibe->in_port, bibe->out_port,
197  fib->ft_table_id, 0);
198 
199  /* delete from pool */
200  pool_put (bib, bibe);
201 
202 }
203 
204 nat64_db_bib_entry_t *
205 nat64_db_bib_entry_find (nat64_db_t * db, ip46_address_t * addr, u16 port,
206  u8 proto, u32 fib_index, u8 is_ip6)
207 {
208  nat64_db_bib_entry_t *bibe = 0;
209  nat64_db_bib_entry_key_t bibe_key;
210  clib_bihash_kv_24_8_t kv, value;
211  nat64_db_bib_entry_t *bib;
212 
213  switch (ip_proto_to_snat_proto (proto))
214  {
215 /* *INDENT-OFF* */
216 #define _(N, i, n, s) \
217  case SNAT_PROTOCOL_##N: \
218  bib = db->bib._##n##_bib; \
219  break;
221 #undef _
222 /* *INDENT-ON* */
223  default:
224  bib = db->bib._unk_proto_bib;
225  break;
226  }
227 
228  bibe_key.addr.as_u64[0] = addr->as_u64[0];
229  bibe_key.addr.as_u64[1] = addr->as_u64[1];
230  bibe_key.fib_index = fib_index;
231  bibe_key.port = port;
232  bibe_key.proto = proto;
233  bibe_key.rsvd = 0;
234 
235  kv.key[0] = bibe_key.as_u64[0];
236  kv.key[1] = bibe_key.as_u64[1];
237  kv.key[2] = bibe_key.as_u64[2];
238 
239  if (!clib_bihash_search_24_8
240  (is_ip6 ? &db->bib.in2out : &db->bib.out2in, &kv, &value))
241  bibe = pool_elt_at_index (bib, value.value);
242 
243  return bibe;
244 }
245 
246 void
248  nat64_db_bib_walk_fn_t fn, void *ctx)
249 {
250  nat64_db_bib_entry_t *bib, *bibe;
251 
252  if (proto == 255)
253  {
254  /* *INDENT-OFF* */
255  #define _(N, i, n, s) \
256  bib = db->bib._##n##_bib; \
257  pool_foreach (bibe, bib, ({ \
258  if (fn (bibe, ctx)) \
259  return; \
260  }));
262  #undef _
263  bib = db->bib._unk_proto_bib;
264  pool_foreach (bibe, bib, ({
265  if (fn (bibe, ctx))
266  return;
267  }));
268  /* *INDENT-ON* */
269  }
270  else
271  {
272  switch (ip_proto_to_snat_proto (proto))
273  {
274  /* *INDENT-OFF* */
275  #define _(N, i, n, s) \
276  case SNAT_PROTOCOL_##N: \
277  bib = db->bib._##n##_bib; \
278  break;
280  #undef _
281  /* *INDENT-ON* */
282  default:
283  bib = db->bib._unk_proto_bib;
284  break;
285  }
286 
287  /* *INDENT-OFF* */
288  pool_foreach (bibe, bib,
289  ({
290  if (fn (bibe, ctx))
291  return;
292  }));
293  /* *INDENT-ON* */
294  }
295 }
296 
297 nat64_db_bib_entry_t *
298 nat64_db_bib_entry_by_index (nat64_db_t * db, u8 proto, u32 bibe_index)
299 {
300  nat64_db_bib_entry_t *bib;
301 
302  switch (ip_proto_to_snat_proto (proto))
303  {
304 /* *INDENT-OFF* */
305 #define _(N, i, n, s) \
306  case SNAT_PROTOCOL_##N: \
307  bib = db->bib._##n##_bib; \
308  break;
310 #undef _
311 /* *INDENT-ON* */
312  default:
313  bib = db->bib._unk_proto_bib;
314  break;
315  }
316 
317  return pool_elt_at_index (bib, bibe_index);
318 }
319 
320 void
322  nat64_db_st_walk_fn_t fn, void *ctx)
323 {
324  nat64_db_st_entry_t *st, *ste;
325 
326  if (proto == 255)
327  {
328  /* *INDENT-OFF* */
329  #define _(N, i, n, s) \
330  st = db->st._##n##_st; \
331  pool_foreach (ste, st, ({ \
332  if (fn (ste, ctx)) \
333  return; \
334  }));
336  #undef _
337  st = db->st._unk_proto_st;
338  pool_foreach (ste, st, ({
339  if (fn (ste, ctx))
340  return;
341  }));
342  /* *INDENT-ON* */
343  }
344  else
345  {
346  switch (ip_proto_to_snat_proto (proto))
347  {
348  /* *INDENT-OFF* */
349  #define _(N, i, n, s) \
350  case SNAT_PROTOCOL_##N: \
351  st = db->st._##n##_st; \
352  break;
354  #undef _
355  /* *INDENT-ON* */
356  default:
357  st = db->st._unk_proto_st;
358  break;
359  }
360 
361  /* *INDENT-OFF* */
362  pool_foreach (ste, st,
363  ({
364  if (fn (ste, ctx))
365  return;
366  }));
367  /* *INDENT-ON* */
368  }
369 }
370 
371 nat64_db_st_entry_t *
372 nat64_db_st_entry_create (nat64_db_t * db, nat64_db_bib_entry_t * bibe,
373  ip6_address_t * in_r_addr,
374  ip4_address_t * out_r_addr, u16 r_port)
375 {
376  nat64_db_st_entry_t *ste;
377  nat64_db_bib_entry_t *bib;
378  nat64_db_st_entry_key_t ste_key;
380  fib_table_t *fib;
381 
382  if (db->st.st_entries_num >= db->st.limit)
383  {
385  return 0;
386  }
387 
388  /* create pool entry */
389  switch (ip_proto_to_snat_proto (bibe->proto))
390  {
391 /* *INDENT-OFF* */
392 #define _(N, i, n, s) \
393  case SNAT_PROTOCOL_##N: \
394  pool_get (db->st._##n##_st, ste); \
395  kv.value = ste - db->st._##n##_st; \
396  bib = db->bib._##n##_bib; \
397  break;
399 #undef _
400 /* *INDENT-ON* */
401  default:
402  pool_get (db->st._unk_proto_st, ste);
403  kv.value = ste - db->st._unk_proto_st;
404  bib = db->bib._unk_proto_bib;
405  break;
406  }
407 
408  db->st.st_entries_num++;
409 
410  memset (ste, 0, sizeof (*ste));
411  ste->in_r_addr.as_u64[0] = in_r_addr->as_u64[0];
412  ste->in_r_addr.as_u64[1] = in_r_addr->as_u64[1];
413  ste->out_r_addr.as_u32 = out_r_addr->as_u32;
414  ste->r_port = r_port;
415  ste->bibe_index = bibe - bib;
416  ste->proto = bibe->proto;
417 
418  /* increment session number for BIB entry */
419  bibe->ses_num++;
420 
421  /* create hash lookup */
422  memset (&ste_key, 0, sizeof (ste_key));
423  ste_key.l_addr.as_u64[0] = bibe->in_addr.as_u64[0];
424  ste_key.l_addr.as_u64[1] = bibe->in_addr.as_u64[1];
425  ste_key.r_addr.as_u64[0] = ste->in_r_addr.as_u64[0];
426  ste_key.r_addr.as_u64[1] = ste->in_r_addr.as_u64[1];
427  ste_key.fib_index = bibe->fib_index;
428  ste_key.l_port = bibe->in_port;
429  ste_key.r_port = ste->r_port;
430  ste_key.proto = ste->proto;
431  kv.key[0] = ste_key.as_u64[0];
432  kv.key[1] = ste_key.as_u64[1];
433  kv.key[2] = ste_key.as_u64[2];
434  kv.key[3] = ste_key.as_u64[3];
435  kv.key[4] = ste_key.as_u64[4];
436  kv.key[5] = ste_key.as_u64[5];
437  clib_bihash_add_del_48_8 (&db->st.in2out, &kv, 1);
438 
439  memset (&ste_key, 0, sizeof (ste_key));
440  ste_key.l_addr.ip4.as_u32 = bibe->out_addr.as_u32;
441  ste_key.r_addr.ip4.as_u32 = ste->out_r_addr.as_u32;
442  ste_key.l_port = bibe->out_port;
443  ste_key.r_port = ste->r_port;
444  ste_key.proto = ste->proto;
445  kv.key[0] = ste_key.as_u64[0];
446  kv.key[1] = ste_key.as_u64[1];
447  kv.key[2] = ste_key.as_u64[2];
448  kv.key[3] = ste_key.as_u64[3];
449  kv.key[4] = ste_key.as_u64[4];
450  kv.key[5] = ste_key.as_u64[5];
451  clib_bihash_add_del_48_8 (&db->st.out2in, &kv, 1);
452 
453  fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
454  nat_ipfix_logging_nat64_session (&bibe->in_addr, &bibe->out_addr,
455  bibe->proto, bibe->in_port, bibe->out_port,
456  &ste->in_r_addr, &ste->out_r_addr,
457  ste->r_port, ste->r_port, fib->ft_table_id,
458  1);
459 
460  return ste;
461 }
462 
463 void
464 nat64_db_st_entry_free (nat64_db_t * db, nat64_db_st_entry_t * ste)
465 {
466  nat64_db_st_entry_t *st;
467  nat64_db_bib_entry_t *bib, *bibe;
468  nat64_db_st_entry_key_t ste_key;
470  fib_table_t *fib;
471 
472  switch (ip_proto_to_snat_proto (ste->proto))
473  {
474 /* *INDENT-OFF* */
475 #define _(N, i, n, s) \
476  case SNAT_PROTOCOL_##N: \
477  st = db->st._##n##_st; \
478  bib = db->bib._##n##_bib; \
479  break;
481 #undef _
482 /* *INDENT-ON* */
483  default:
484  st = db->st._unk_proto_st;
485  bib = db->bib._unk_proto_bib;
486  break;
487  }
488 
489  bibe = pool_elt_at_index (bib, ste->bibe_index);
490 
491  db->st.st_entries_num--;
492 
493  /* delete hash lookup */
494  memset (&ste_key, 0, sizeof (ste_key));
495  ste_key.l_addr.as_u64[0] = bibe->in_addr.as_u64[0];
496  ste_key.l_addr.as_u64[1] = bibe->in_addr.as_u64[1];
497  ste_key.r_addr.as_u64[0] = ste->in_r_addr.as_u64[0];
498  ste_key.r_addr.as_u64[1] = ste->in_r_addr.as_u64[1];
499  ste_key.fib_index = bibe->fib_index;
500  ste_key.l_port = bibe->in_port;
501  ste_key.r_port = ste->r_port;
502  ste_key.proto = ste->proto;
503  kv.key[0] = ste_key.as_u64[0];
504  kv.key[1] = ste_key.as_u64[1];
505  kv.key[2] = ste_key.as_u64[2];
506  kv.key[3] = ste_key.as_u64[3];
507  kv.key[4] = ste_key.as_u64[4];
508  kv.key[5] = ste_key.as_u64[5];
509  clib_bihash_add_del_48_8 (&db->st.in2out, &kv, 0);
510 
511  memset (&ste_key, 0, sizeof (ste_key));
512  ste_key.l_addr.ip4.as_u32 = bibe->out_addr.as_u32;
513  ste_key.r_addr.ip4.as_u32 = ste->out_r_addr.as_u32;
514  ste_key.l_port = bibe->out_port;
515  ste_key.r_port = ste->r_port;
516  ste_key.proto = ste->proto;
517  kv.key[0] = ste_key.as_u64[0];
518  kv.key[1] = ste_key.as_u64[1];
519  kv.key[2] = ste_key.as_u64[2];
520  kv.key[3] = ste_key.as_u64[3];
521  kv.key[4] = ste_key.as_u64[4];
522  kv.key[5] = ste_key.as_u64[5];
523  clib_bihash_add_del_48_8 (&db->st.out2in, &kv, 0);
524 
525  fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
526  nat_ipfix_logging_nat64_session (&bibe->in_addr, &bibe->out_addr,
527  bibe->proto, bibe->in_port, bibe->out_port,
528  &ste->in_r_addr, &ste->out_r_addr,
529  ste->r_port, ste->r_port, fib->ft_table_id,
530  0);
531 
532  /* delete from pool */
533  pool_put (st, ste);
534 
535  /* decrement session number for BIB entry */
536  bibe->ses_num--;
537 
538  /* delete BIB entry if last session and dynamic */
539  if (!bibe->is_static && !bibe->ses_num)
540  nat64_db_bib_entry_free (db, bibe);
541 }
542 
543 nat64_db_st_entry_t *
544 nat64_db_st_entry_find (nat64_db_t * db, ip46_address_t * l_addr,
545  ip46_address_t * r_addr, u16 l_port, u16 r_port,
546  u8 proto, u32 fib_index, u8 is_ip6)
547 {
548  nat64_db_st_entry_t *ste = 0;
549  nat64_db_st_entry_t *st;
550  nat64_db_st_entry_key_t ste_key;
551  clib_bihash_kv_48_8_t kv, value;
552 
553  switch (ip_proto_to_snat_proto (proto))
554  {
555 /* *INDENT-OFF* */
556 #define _(N, i, n, s) \
557  case SNAT_PROTOCOL_##N: \
558  st = db->st._##n##_st; \
559  break;
561 #undef _
562 /* *INDENT-ON* */
563  default:
564  st = db->st._unk_proto_st;
565  break;
566  }
567 
568  memset (&ste_key, 0, sizeof (ste_key));
569  ste_key.l_addr.as_u64[0] = l_addr->as_u64[0];
570  ste_key.l_addr.as_u64[1] = l_addr->as_u64[1];
571  ste_key.r_addr.as_u64[0] = r_addr->as_u64[0];
572  ste_key.r_addr.as_u64[1] = r_addr->as_u64[1];
573  ste_key.fib_index = fib_index;
574  ste_key.l_port = l_port;
575  ste_key.r_port = r_port;
576  ste_key.proto = proto;
577  kv.key[0] = ste_key.as_u64[0];
578  kv.key[1] = ste_key.as_u64[1];
579  kv.key[2] = ste_key.as_u64[2];
580  kv.key[3] = ste_key.as_u64[3];
581  kv.key[4] = ste_key.as_u64[4];
582  kv.key[5] = ste_key.as_u64[5];
583 
584  if (!clib_bihash_search_48_8
585  (is_ip6 ? &db->st.in2out : &db->st.out2in, &kv, &value))
586  ste = pool_elt_at_index (st, value.value);
587 
588  return ste;
589 }
590 
591 u32
592 nat64_db_st_entry_get_index (nat64_db_t * db, nat64_db_st_entry_t * ste)
593 {
594  nat64_db_st_entry_t *st;
595 
596  switch (ip_proto_to_snat_proto (ste->proto))
597  {
598 /* *INDENT-OFF* */
599 #define _(N, i, n, s) \
600  case SNAT_PROTOCOL_##N: \
601  st = db->st._##n##_st; \
602  break;
604 #undef _
605 /* *INDENT-ON* */
606  default:
607  st = db->st._unk_proto_st;
608  return (u32) ~ 0;
609  }
610 
611  return ste - st;
612 }
613 
614 nat64_db_st_entry_t *
615 nat64_db_st_entry_by_index (nat64_db_t * db, u8 proto, u32 ste_index)
616 {
617  nat64_db_st_entry_t *st;
618 
619  switch (ip_proto_to_snat_proto (proto))
620  {
621 /* *INDENT-OFF* */
622 #define _(N, i, n, s) \
623  case SNAT_PROTOCOL_##N: \
624  st = db->st._##n##_st; \
625  break;
627 #undef _
628 /* *INDENT-ON* */
629  default:
630  st = db->st._unk_proto_st;
631  break;
632  }
633 
634  return pool_elt_at_index (st, ste_index);
635 }
636 
637 void
639 {
640  u32 *ste_to_be_free = 0, *ste_index;
641  nat64_db_st_entry_t *st, *ste;
642 
643 /* *INDENT-OFF* */
644 #define _(N, i, n, s) \
645  st = db->st._##n##_st; \
646  pool_foreach (ste, st, ({\
647  if (i == SNAT_PROTOCOL_TCP && !ste->tcp_state) \
648  continue; \
649  if (ste->expire < now) \
650  vec_add1 (ste_to_be_free, ste - st); \
651  })); \
652  vec_foreach (ste_index, ste_to_be_free) \
653  nat64_db_st_entry_free (db, pool_elt_at_index(st, ste_index[0])); \
654  vec_free (ste_to_be_free); \
655  ste_to_be_free = 0;
657 #undef _
658  st = db->st._unk_proto_st;
659  pool_foreach (ste, st, ({
660  if (ste->expire < now)
661  vec_add1 (ste_to_be_free, ste - st);
662  }));
663  vec_foreach (ste_index, ste_to_be_free)
664  nat64_db_st_entry_free (db, pool_elt_at_index(st, ste_index[0]));
665  vec_free (ste_to_be_free);
666 /* *INDENT-ON* */
667 }
668 
669 void
671 {
672  u32 *ste_to_be_free = 0, *ste_index;
673  nat64_db_st_entry_t *st, *ste;
674  nat64_db_bib_entry_t *bibe;
675 
676  db->addr_free = 1;
677 /* *INDENT-OFF* */
678 #define _(N, i, n, s) \
679  st = db->st._##n##_st; \
680  pool_foreach (ste, st, ({ \
681  bibe = pool_elt_at_index (db->bib._##n##_bib, ste->bibe_index); \
682  if (bibe->out_addr.as_u32 == out_addr->as_u32) \
683  vec_add1 (ste_to_be_free, ste - st); \
684  })); \
685  vec_foreach (ste_index, ste_to_be_free) \
686  nat64_db_st_entry_free (db, pool_elt_at_index(st, ste_index[0])); \
687  vec_free (ste_to_be_free); \
688  ste_to_be_free = 0;
690 #undef _
691  st = db->st._unk_proto_st;
692  pool_foreach (ste, st, ({
693  bibe = pool_elt_at_index (db->bib._unk_proto_bib, ste->bibe_index);
694  if (bibe->out_addr.as_u32 == out_addr->as_u32)
695  vec_add1 (ste_to_be_free, ste - st);
696  }));
697  vec_foreach (ste_index, ste_to_be_free)
698  nat64_db_st_entry_free (db, pool_elt_at_index(st, ste_index[0]));
699  vec_free (ste_to_be_free);
700  db->addr_free = 0;
701 /* *INDENT-ON* */
702 }
703 
704 /*
705  * fd.io coding-style-patch-verification: ON
706  *
707  * Local Variables:
708  * eval: (c-set-style "gnu")
709  * End:
710  */
void nat_ipfix_logging_max_sessions(u32 limit)
Generate maximum session entries exceeded event.
Definition: nat64_db.h:76
int nat64_db_init(nat64_db_t *db, u32 bib_buckets, u32 bib_memory_size, u32 st_buckets, u32 st_memory_size, nat64_db_free_addr_port_function_t free_addr_port_cb)
Initialize NAT64 DB.
Definition: nat64_db.c:25
nat64_db_free_addr_port_function_t free_addr_port_cb
Definition: nat64_db.h:140
u16 l_port
Definition: nat64_db.h:85
u64 as_u64[2]
Definition: ip6_packet.h:51
nat64_db_st_entry_t * nat64_db_st_entry_create(nat64_db_t *db, nat64_db_bib_entry_t *bibe, ip6_address_t *in_r_addr, ip4_address_t *out_r_addr, u16 r_port)
Create new NAT64 session table entry.
Definition: nat64_db.c:372
nat64_db_bib_entry_t * nat64_db_bib_entry_create(nat64_db_t *db, ip6_address_t *in_addr, ip4_address_t *out_addr, u16 in_port, u16 out_port, u32 fib_index, u8 proto, u8 is_static)
Create new NAT64 BIB entry.
Definition: nat64_db.c:52
Definition: nat64_db.h:27
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
nat64_db_bib_entry_t * nat64_db_bib_entry_find(nat64_db_t *db, ip46_address_t *addr, u16 port, u8 proto, u32 fib_index, u8 is_ip6)
Find NAT64 BIB entry.
Definition: nat64_db.c:205
u32 fib_index
Definition: nat64_db.h:84
nat64_db_st_entry_t * nat64_db_st_entry_by_index(nat64_db_t *db, u8 proto, u32 ste_index)
Get ST entry by index and protocol.
Definition: nat64_db.c:615
nat64_db_bib_t bib
Definition: nat64_db.h:138
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:228
vhost_vring_addr_t addr
Definition: vhost_user.h:121
unsigned char u8
Definition: types.h:56
int(* nat64_db_bib_walk_fn_t)(nat64_db_bib_entry_t *bibe, void *ctx)
Call back function when walking NAT64 BIB, non-zero return value stop walk.
Definition: nat64_db.h:193
u32 st_entries_num
Definition: nat64_db.h:123
ip46_address_t l_addr
Definition: nat64_db.h:82
memset(h->entries, 0, sizeof(h->entries[0])*entries)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:443
void nat_ipfix_logging_nat64_bib(ip6_address_t *src_ip, ip4_address_t *nat_src_ip, u8 proto, u16 src_port, u16 nat_src_port, u32 vrf_id, u8 is_create)
Generate NAT64 BIB create and delete events.
u16 r_port
Definition: nat64_db.h:86
clib_bihash_48_8_t in2out
Definition: nat64_db.h:119
u16 port
Definition: nat64_db.h:35
unsigned int u32
Definition: types.h:88
u64 as_u64[6]
Definition: nat64_db.h:90
clib_bihash_24_8_t in2out
Definition: nat64_db.h:69
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:464
void nad64_db_st_free_expired(nat64_db_t *db, u32 now)
Free expired session entries in session tables.
Definition: nat64_db.c:638
long ctx[MAX_CONNS]
Definition: main.c:144
unsigned short u16
Definition: types.h:57
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:274
void nat64_db_bib_entry_free(nat64_db_t *db, nat64_db_bib_entry_t *bibe)
Free NAT64 BIB entry.
Definition: nat64_db.c:127
nat64_db_st_t st
Definition: nat64_db.h:139
u8 addr_free
Definition: nat64_db.h:141
void nat_ipfix_logging_max_bibs(u32 limit)
Generate maximum BIB entries exceeded event.
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:89
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
ip46_address_t addr
Definition: nat64_db.h:33
void(* nat64_db_free_addr_port_function_t)(struct nat64_db_s *db, ip4_address_t *addr, u16 port, u8 proto)
Call back function to free NAT64 pool address and port when BIB entry is deleted. ...
Definition: nat64_db.h:132
u8 proto
Definition: nat64_db.h:87
nat64_db_st_entry_t * nat64_db_st_entry_find(nat64_db_t *db, ip46_address_t *l_addr, ip46_address_t *r_addr, u16 l_port, u16 r_port, u8 proto, u32 fib_index, u8 is_ip6)
Find NAT64 session table entry.
Definition: nat64_db.c:544
void nat64_db_st_walk(nat64_db_t *db, u8 proto, nat64_db_st_walk_fn_t fn, void *ctx)
Walk NAT64 session table.
Definition: nat64_db.c:321
u32 nat64_db_st_entry_get_index(nat64_db_t *db, nat64_db_st_entry_t *ste)
Definition: nat64_db.c:592
u32 fib_index
Definition: nat64_db.h:34
nat64_db_bib_entry_t * nat64_db_bib_entry_by_index(nat64_db_t *db, u8 proto, u32 bibe_index)
Get BIB entry by index and protocol.
Definition: nat64_db.c:298
u32 bib_entries_num
Definition: nat64_db.h:73
void nat64_db_free_out_addr(nat64_db_t *db, ip4_address_t *out_addr)
Free sessions using specific outside address.
Definition: nat64_db.c:670
u8 proto
Definition: nat64_db.h:36
clib_bihash_24_8_t out2in
Definition: nat64_db.h:70
static u32 ip_proto_to_snat_proto(u8 ip_proto)
The NAT inline functions.
Definition: nat_inlines.h:26
fib_table_t * fib_table_get(fib_node_index_t index, fib_protocol_t proto)
Get a pointer to a FIB table.
Definition: fib_table.c:27
void nat64_db_st_entry_free(nat64_db_t *db, nat64_db_st_entry_t *ste)
Free NAT64 session table entry.
Definition: nat64_db.c:464
int(* nat64_db_st_walk_fn_t)(nat64_db_st_entry_t *ste, void *ctx)
Call back function when walking NAT64 session table, non-zero return value stop walk.
Definition: nat64_db.h:290
NAT64 DB.
#define vec_foreach(var, vec)
Vector iterator.
u8 rsvd
Definition: nat64_db.h:37
void nat64_db_bib_walk(nat64_db_t *db, u8 proto, nat64_db_bib_walk_fn_t fn, void *ctx)
Walk NAT64 BIB.
Definition: nat64_db.c:247
u64 as_u64[3]
Definition: nat64_db.h:39
ip46_address_t r_addr
Definition: nat64_db.h:83
A protocol Independent FIB table.
Definition: fib_table.h:69
clib_bihash_48_8_t out2in
Definition: nat64_db.h:120
void nat_ipfix_logging_nat64_session(ip6_address_t *src_ip, ip4_address_t *nat_src_ip, u8 proto, u16 src_port, u16 nat_src_port, ip6_address_t *dst_ip, ip4_address_t *nat_dst_ip, u16 dst_port, u16 nat_dst_port, u32 vrf_id, u8 is_create)
Generate NAT64 session create and delete events.