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