LCOV - code coverage report
Current view: top level - plugins/nat/nat64 - nat64_db.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 273 340 80.3 %
Date: 2023-07-05 22:20:52 Functions: 13 15 86.7 %

          Line data    Source code
       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
      23          20 : nat64_db_init (nat64_db_t * db, nat64_config_t c,
      24             :                nat64_db_free_addr_port_function_t free_addr_port_cb)
      25             : {
      26          20 :   clib_bihash_init_24_8 (&db->bib.in2out, "bib-in2out", c.bib_buckets,
      27          20 :                          c.bib_memory_size);
      28             : 
      29          20 :   clib_bihash_init_24_8 (&db->bib.out2in, "bib-out2in", c.bib_buckets,
      30          20 :                          c.bib_memory_size);
      31             : 
      32          20 :   clib_bihash_init_48_8 (&db->st.in2out, "st-in2out", c.st_buckets,
      33          20 :                          c.st_memory_size);
      34             : 
      35          20 :   clib_bihash_init_48_8 (&db->st.out2in, "st-out2in", c.st_buckets,
      36          20 :                          c.st_memory_size);
      37             : 
      38          20 :   db->free_addr_port_cb = free_addr_port_cb;
      39          20 :   db->bib.limit = 10 * c.bib_buckets;
      40          20 :   db->bib.bib_entries_num = 0;
      41          20 :   db->st.limit = 10 * c.st_buckets;
      42          20 :   db->st.st_entries_num = 0;
      43          20 :   db->addr_free = 0;
      44             : 
      45          20 :   return 0;
      46             : }
      47             : 
      48             : int
      49          20 : nat64_db_free (nat64_db_t * db)
      50             : {
      51          20 :   clib_bihash_free_24_8 (&db->bib.in2out);
      52          20 :   clib_bihash_free_24_8 (&db->bib.out2in);
      53             : 
      54          20 :   clib_bihash_free_48_8 (&db->st.in2out);
      55          20 :   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);
      61          20 :   foreach_nat_protocol
      62             : #undef _
      63             : /* *INDENT-ON* */
      64             : 
      65          20 :   pool_free (db->bib._unk_proto_bib);
      66          20 :   pool_free (db->st._unk_proto_st);
      67             : 
      68          20 :   return 0;
      69             : }
      70             : 
      71             : nat64_db_bib_entry_t *
      72          39 : nat64_db_bib_entry_create (u32 thread_index, nat64_db_t * db,
      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;
      80             :   clib_bihash_kv_24_8_t kv;
      81             : 
      82          39 :   if (db->bib.bib_entries_num >= db->bib.limit)
      83             :     {
      84           0 :       db->free_addr_port_cb (db, out_addr, out_port, proto);
      85             :       //nat_ipfix_logging_max_bibs (thread_index, db->bib.limit);
      86           0 :       return 0;
      87             :     }
      88             : 
      89             :   /* create pool entry */
      90          39 :   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;
      98          39 :       foreach_nat_protocol
      99             : #undef _
     100             : /* *INDENT-ON* */
     101           0 :     default:
     102           0 :       pool_get (db->bib._unk_proto_bib, bibe);
     103           0 :       kv.value = bibe - db->bib._unk_proto_bib;
     104           0 :       break;
     105             :     }
     106             : 
     107          39 :   db->bib.bib_entries_num++;
     108             : 
     109          39 :   clib_memset (bibe, 0, sizeof (*bibe));
     110          39 :   bibe->in_addr.as_u64[0] = in_addr->as_u64[0];
     111          39 :   bibe->in_addr.as_u64[1] = in_addr->as_u64[1];
     112          39 :   bibe->in_port = in_port;
     113          39 :   bibe->out_addr.as_u32 = out_addr->as_u32;
     114          39 :   bibe->out_port = out_port;
     115          39 :   bibe->fib_index = fib_index;
     116          39 :   bibe->proto = proto;
     117          39 :   bibe->is_static = is_static;
     118             : 
     119             :   /* create hash lookup */
     120          39 :   bibe_key.addr.as_u64[0] = bibe->in_addr.as_u64[0];
     121          39 :   bibe_key.addr.as_u64[1] = bibe->in_addr.as_u64[1];
     122          39 :   bibe_key.fib_index = bibe->fib_index;
     123          39 :   bibe_key.port = bibe->in_port;
     124          39 :   bibe_key.proto = bibe->proto;
     125          39 :   bibe_key.rsvd = 0;
     126          39 :   kv.key[0] = bibe_key.as_u64[0];
     127          39 :   kv.key[1] = bibe_key.as_u64[1];
     128          39 :   kv.key[2] = bibe_key.as_u64[2];
     129          39 :   clib_bihash_add_del_24_8 (&db->bib.in2out, &kv, 1);
     130             : 
     131          39 :   clib_memset (&bibe_key.addr, 0, sizeof (bibe_key.addr));
     132          39 :   bibe_key.addr.ip4.as_u32 = bibe->out_addr.as_u32;
     133          39 :   bibe_key.fib_index = 0;
     134          39 :   bibe_key.port = bibe->out_port;
     135          39 :   kv.key[0] = bibe_key.as_u64[0];
     136          39 :   kv.key[1] = bibe_key.as_u64[1];
     137          39 :   kv.key[2] = bibe_key.as_u64[2];
     138          39 :   clib_bihash_add_del_24_8 (&db->bib.out2in, &kv, 1);
     139             : 
     140          39 :   fib_table_t *fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
     141          39 :   nat_ipfix_logging_nat64_bib (thread_index, in_addr, out_addr, proto,
     142             :                                in_port, out_port, fib->ft_table_id, 1);
     143          39 :   return bibe;
     144             : }
     145             : 
     146             : void
     147           5 : nat64_db_bib_entry_free (u32 thread_index, nat64_db_t * db,
     148             :                          nat64_db_bib_entry_t * bibe)
     149             : {
     150             :   nat64_db_bib_entry_key_t bibe_key;
     151             :   clib_bihash_kv_24_8_t kv;
     152             :   nat64_db_bib_entry_t *bib;
     153           5 :   u32 *ste_to_be_free = 0, *ste_index, bibe_index;
     154             :   nat64_db_st_entry_t *st, *ste;
     155             : 
     156           5 :   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;
     164           5 :       foreach_nat_protocol
     165             : #undef _
     166             : /* *INDENT-ON* */
     167           0 :     default:
     168           0 :       bib = db->bib._unk_proto_bib;
     169           0 :       st = db->st._unk_proto_st;
     170           0 :       break;
     171             :     }
     172             : 
     173           5 :   db->bib.bib_entries_num--;
     174             : 
     175           5 :   bibe_index = bibe - bib;
     176             : 
     177             :   /* delete ST entries for static BIB entry */
     178           5 :   if (bibe->is_static)
     179             :     {
     180           1 :       pool_foreach (ste, st)
     181             :       {
     182           0 :         if (ste->bibe_index == bibe_index)
     183           0 :           vec_add1 (ste_to_be_free, ste - st);
     184             :       }
     185           1 :       vec_foreach (ste_index, ste_to_be_free)
     186           0 :         nat64_db_st_entry_free (thread_index, db,
     187           0 :                                 pool_elt_at_index (st, ste_index[0]));
     188           1 :       vec_free (ste_to_be_free);
     189             :     }
     190             : 
     191             :   /* delete hash lookup */
     192           5 :   bibe_key.addr.as_u64[0] = bibe->in_addr.as_u64[0];
     193           5 :   bibe_key.addr.as_u64[1] = bibe->in_addr.as_u64[1];
     194           5 :   bibe_key.fib_index = bibe->fib_index;
     195           5 :   bibe_key.port = bibe->in_port;
     196           5 :   bibe_key.proto = bibe->proto;
     197           5 :   bibe_key.rsvd = 0;
     198           5 :   kv.key[0] = bibe_key.as_u64[0];
     199           5 :   kv.key[1] = bibe_key.as_u64[1];
     200           5 :   kv.key[2] = bibe_key.as_u64[2];
     201           5 :   clib_bihash_add_del_24_8 (&db->bib.in2out, &kv, 0);
     202             : 
     203           5 :   clib_memset (&bibe_key.addr, 0, sizeof (bibe_key.addr));
     204           5 :   bibe_key.addr.ip4.as_u32 = bibe->out_addr.as_u32;
     205           5 :   bibe_key.fib_index = 0;
     206           5 :   bibe_key.port = bibe->out_port;
     207           5 :   kv.key[0] = bibe_key.as_u64[0];
     208           5 :   kv.key[1] = bibe_key.as_u64[1];
     209           5 :   kv.key[2] = bibe_key.as_u64[2];
     210           5 :   clib_bihash_add_del_24_8 (&db->bib.out2in, &kv, 0);
     211             : 
     212           5 :   if (!db->addr_free)
     213           3 :     db->free_addr_port_cb (db, &bibe->out_addr, bibe->out_port, bibe->proto);
     214             : 
     215           5 :   fib_table_t *fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
     216           5 :   nat_ipfix_logging_nat64_bib (thread_index, &bibe->in_addr, &bibe->out_addr,
     217           5 :                                bibe->proto, bibe->in_port, bibe->out_port,
     218             :                                fib->ft_table_id, 0);
     219             : 
     220             :   /* delete from pool */
     221           5 :   pool_put (bib, bibe);
     222           5 : }
     223             : 
     224             : nat64_db_bib_entry_t *
     225          60 : 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          60 :   nat64_db_bib_entry_t *bibe = 0;
     229             :   nat64_db_bib_entry_key_t bibe_key;
     230             :   clib_bihash_kv_24_8_t kv, value;
     231             :   nat64_db_bib_entry_t *bib;
     232             : 
     233          60 :   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;
     240          60 :       foreach_nat_protocol
     241             : #undef _
     242             : /* *INDENT-ON* */
     243           0 :     default:
     244           0 :       bib = db->bib._unk_proto_bib;
     245           0 :       break;
     246             :     }
     247             : 
     248          60 :   bibe_key.addr.as_u64[0] = addr->as_u64[0];
     249          60 :   bibe_key.addr.as_u64[1] = addr->as_u64[1];
     250          60 :   bibe_key.fib_index = fib_index;
     251          60 :   bibe_key.port = port;
     252          60 :   bibe_key.proto = proto;
     253          60 :   bibe_key.rsvd = 0;
     254             : 
     255          60 :   kv.key[0] = bibe_key.as_u64[0];
     256          60 :   kv.key[1] = bibe_key.as_u64[1];
     257          60 :   kv.key[2] = bibe_key.as_u64[2];
     258             : 
     259          60 :   if (!clib_bihash_search_24_8
     260             :       (is_ip6 ? &db->bib.in2out : &db->bib.out2in, &kv, &value))
     261          19 :     bibe = pool_elt_at_index (bib, value.value);
     262             : 
     263          60 :   return bibe;
     264             : }
     265             : 
     266             : void
     267          22 : nat64_db_bib_walk (nat64_db_t * db, u8 proto,
     268             :                    nat64_db_bib_walk_fn_t fn, void *ctx)
     269             : {
     270             :   nat64_db_bib_entry_t *bib, *bibe;
     271             : 
     272          22 :   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             :       }
     281          54 :       foreach_nat_protocol
     282             :     #undef _
     283          20 :       bib = db->bib._unk_proto_bib;
     284          20 :       pool_foreach (bibe, bib)  {
     285           0 :         if (fn (bibe, ctx))
     286           0 :           return;
     287             :       }
     288             :     /* *INDENT-ON* */
     289             :     }
     290             :   else
     291             :     {
     292           2 :       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;
     299           2 :           foreach_nat_protocol
     300             :     #undef _
     301             :     /* *INDENT-ON* */
     302           0 :         default:
     303           0 :           bib = db->bib._unk_proto_bib;
     304           0 :           break;
     305             :         }
     306             : 
     307             :       /* *INDENT-OFF* */
     308           3 :       pool_foreach (bibe, bib)
     309             :        {
     310           1 :         if (fn (bibe, ctx))
     311           0 :           return;
     312             :       }
     313             :       /* *INDENT-ON* */
     314             :     }
     315             : }
     316             : 
     317             : nat64_db_bib_entry_t *
     318         103 : nat64_db_bib_entry_by_index (nat64_db_t * db, u8 proto, u32 bibe_index)
     319             : {
     320             :   nat64_db_bib_entry_t *bib;
     321             : 
     322         103 :   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;
     329         103 :       foreach_nat_protocol
     330             : #undef _
     331             : /* *INDENT-ON* */
     332           0 :     default:
     333           0 :       bib = db->bib._unk_proto_bib;
     334           0 :       break;
     335             :     }
     336             : 
     337         103 :   return pool_elt_at_index (bib, bibe_index);
     338             : }
     339             : 
     340             : void
     341          28 : nat64_db_st_walk (nat64_db_t * db, u8 proto,
     342             :                   nat64_db_st_walk_fn_t fn, void *ctx)
     343             : {
     344             :   nat64_db_st_entry_t *st, *ste;
     345             : 
     346          28 :   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             :       }
     355          68 :       foreach_nat_protocol
     356             :     #undef _
     357          26 :       st = db->st._unk_proto_st;
     358          26 :       pool_foreach (ste, st)  {
     359           0 :         if (fn (ste, ctx))
     360           0 :           return;
     361             :       }
     362             :     /* *INDENT-ON* */
     363             :     }
     364             :   else
     365             :     {
     366           2 :       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;
     373           2 :           foreach_nat_protocol
     374             :     #undef _
     375             :     /* *INDENT-ON* */
     376           0 :         default:
     377           0 :           st = db->st._unk_proto_st;
     378           0 :           break;
     379             :         }
     380             : 
     381             :       /* *INDENT-OFF* */
     382           2 :       pool_foreach (ste, st)
     383             :        {
     384           2 :         if (fn (ste, ctx))
     385           2 :           return;
     386             :       }
     387             :       /* *INDENT-ON* */
     388             :     }
     389             : }
     390             : 
     391             : nat64_db_st_entry_t *
     392          36 : nat64_db_st_entry_create (u32 thread_index, nat64_db_t * db,
     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;
     400             :   clib_bihash_kv_48_8_t kv;
     401             : 
     402          36 :   if (db->st.st_entries_num >= db->st.limit)
     403             :     {
     404             :       //nat_ipfix_logging_max_sessions (thread_index, db->st.limit);
     405           0 :       return 0;
     406             :     }
     407             : 
     408             :   /* create pool entry */
     409          36 :   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;
     418          36 :       foreach_nat_protocol
     419             : #undef _
     420             : /* *INDENT-ON* */
     421           0 :     default:
     422           0 :       pool_get (db->st._unk_proto_st, ste);
     423           0 :       kv.value = ste - db->st._unk_proto_st;
     424           0 :       bib = db->bib._unk_proto_bib;
     425           0 :       break;
     426             :     }
     427             : 
     428          36 :   db->st.st_entries_num++;
     429             : 
     430          36 :   clib_memset (ste, 0, sizeof (*ste));
     431          36 :   ste->in_r_addr.as_u64[0] = in_r_addr->as_u64[0];
     432          36 :   ste->in_r_addr.as_u64[1] = in_r_addr->as_u64[1];
     433          36 :   ste->out_r_addr.as_u32 = out_r_addr->as_u32;
     434          36 :   ste->r_port = r_port;
     435          36 :   ste->bibe_index = bibe - bib;
     436          36 :   ste->proto = bibe->proto;
     437             : 
     438             :   /* increment session number for BIB entry */
     439          36 :   bibe->ses_num++;
     440             : 
     441             :   /* create hash lookup */
     442          36 :   clib_memset (&ste_key, 0, sizeof (ste_key));
     443          36 :   ste_key.l_addr.as_u64[0] = bibe->in_addr.as_u64[0];
     444          36 :   ste_key.l_addr.as_u64[1] = bibe->in_addr.as_u64[1];
     445          36 :   ste_key.r_addr.as_u64[0] = ste->in_r_addr.as_u64[0];
     446          36 :   ste_key.r_addr.as_u64[1] = ste->in_r_addr.as_u64[1];
     447          36 :   ste_key.fib_index = bibe->fib_index;
     448          36 :   ste_key.l_port = bibe->in_port;
     449          36 :   ste_key.r_port = ste->r_port;
     450          36 :   ste_key.proto = ste->proto;
     451          36 :   kv.key[0] = ste_key.as_u64[0];
     452          36 :   kv.key[1] = ste_key.as_u64[1];
     453          36 :   kv.key[2] = ste_key.as_u64[2];
     454          36 :   kv.key[3] = ste_key.as_u64[3];
     455          36 :   kv.key[4] = ste_key.as_u64[4];
     456          36 :   kv.key[5] = ste_key.as_u64[5];
     457          36 :   clib_bihash_add_del_48_8 (&db->st.in2out, &kv, 1);
     458             : 
     459          36 :   clib_memset (&ste_key, 0, sizeof (ste_key));
     460          36 :   ste_key.l_addr.ip4.as_u32 = bibe->out_addr.as_u32;
     461          36 :   ste_key.r_addr.ip4.as_u32 = ste->out_r_addr.as_u32;
     462          36 :   ste_key.l_port = bibe->out_port;
     463          36 :   ste_key.r_port = ste->r_port;
     464          36 :   ste_key.proto = ste->proto;
     465          36 :   kv.key[0] = ste_key.as_u64[0];
     466          36 :   kv.key[1] = ste_key.as_u64[1];
     467          36 :   kv.key[2] = ste_key.as_u64[2];
     468          36 :   kv.key[3] = ste_key.as_u64[3];
     469          36 :   kv.key[4] = ste_key.as_u64[4];
     470          36 :   kv.key[5] = ste_key.as_u64[5];
     471          36 :   clib_bihash_add_del_48_8 (&db->st.out2in, &kv, 1);
     472             : 
     473          36 :   fib_table_t *fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
     474          36 :   nat_ipfix_logging_nat64_session (thread_index, &bibe->in_addr,
     475          36 :                                    &bibe->out_addr, bibe->proto,
     476          36 :                                    bibe->in_port, bibe->out_port,
     477          36 :                                    &ste->in_r_addr, &ste->out_r_addr,
     478          36 :                                    ste->r_port, ste->r_port, fib->ft_table_id,
     479             :                                    1);
     480          36 :   nat_syslog_nat64_sadd (bibe->fib_index, &bibe->in_addr, bibe->in_port,
     481          36 :                          &bibe->out_addr, bibe->out_port, &ste->out_r_addr,
     482          36 :                          ste->r_port, bibe->proto);
     483          36 :   return ste;
     484             : }
     485             : 
     486             : void
     487           4 : nat64_db_st_entry_free (u32 thread_index,
     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;
     493             :   clib_bihash_kv_48_8_t kv;
     494             : 
     495           4 :   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;
     503           4 :       foreach_nat_protocol
     504             : #undef _
     505             : /* *INDENT-ON* */
     506           0 :     default:
     507           0 :       st = db->st._unk_proto_st;
     508           0 :       bib = db->bib._unk_proto_bib;
     509           0 :       break;
     510             :     }
     511             : 
     512           4 :   bibe = pool_elt_at_index (bib, ste->bibe_index);
     513             : 
     514           4 :   db->st.st_entries_num--;
     515             : 
     516             :   /* delete hash lookup */
     517           4 :   clib_memset (&ste_key, 0, sizeof (ste_key));
     518           4 :   ste_key.l_addr.as_u64[0] = bibe->in_addr.as_u64[0];
     519           4 :   ste_key.l_addr.as_u64[1] = bibe->in_addr.as_u64[1];
     520           4 :   ste_key.r_addr.as_u64[0] = ste->in_r_addr.as_u64[0];
     521           4 :   ste_key.r_addr.as_u64[1] = ste->in_r_addr.as_u64[1];
     522           4 :   ste_key.fib_index = bibe->fib_index;
     523           4 :   ste_key.l_port = bibe->in_port;
     524           4 :   ste_key.r_port = ste->r_port;
     525           4 :   ste_key.proto = ste->proto;
     526           4 :   kv.key[0] = ste_key.as_u64[0];
     527           4 :   kv.key[1] = ste_key.as_u64[1];
     528           4 :   kv.key[2] = ste_key.as_u64[2];
     529           4 :   kv.key[3] = ste_key.as_u64[3];
     530           4 :   kv.key[4] = ste_key.as_u64[4];
     531           4 :   kv.key[5] = ste_key.as_u64[5];
     532           4 :   clib_bihash_add_del_48_8 (&db->st.in2out, &kv, 0);
     533             : 
     534           4 :   clib_memset (&ste_key, 0, sizeof (ste_key));
     535           4 :   ste_key.l_addr.ip4.as_u32 = bibe->out_addr.as_u32;
     536           4 :   ste_key.r_addr.ip4.as_u32 = ste->out_r_addr.as_u32;
     537           4 :   ste_key.l_port = bibe->out_port;
     538           4 :   ste_key.r_port = ste->r_port;
     539           4 :   ste_key.proto = ste->proto;
     540           4 :   kv.key[0] = ste_key.as_u64[0];
     541           4 :   kv.key[1] = ste_key.as_u64[1];
     542           4 :   kv.key[2] = ste_key.as_u64[2];
     543           4 :   kv.key[3] = ste_key.as_u64[3];
     544           4 :   kv.key[4] = ste_key.as_u64[4];
     545           4 :   kv.key[5] = ste_key.as_u64[5];
     546           4 :   clib_bihash_add_del_48_8 (&db->st.out2in, &kv, 0);
     547             : 
     548           4 :   fib_table_t *fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
     549           4 :   nat_ipfix_logging_nat64_session (thread_index, &bibe->in_addr,
     550           4 :                                    &bibe->out_addr, bibe->proto,
     551           4 :                                    bibe->in_port, bibe->out_port,
     552             :                                    &ste->in_r_addr, &ste->out_r_addr,
     553           4 :                                    ste->r_port, ste->r_port, fib->ft_table_id,
     554             :                                    0);
     555           4 :   nat_syslog_nat64_sdel (bibe->fib_index, &bibe->in_addr, bibe->in_port,
     556           4 :                          &bibe->out_addr, bibe->out_port, &ste->out_r_addr,
     557           4 :                          ste->r_port, bibe->proto);
     558             : 
     559             :   /* delete from pool */
     560           4 :   pool_put (st, ste);
     561             : 
     562             :   /* decrement session number for BIB entry */
     563           4 :   bibe->ses_num--;
     564             : 
     565             :   /* delete BIB entry if last session and dynamic */
     566           4 :   if (!bibe->is_static && !bibe->ses_num)
     567           4 :     nat64_db_bib_entry_free (thread_index, db, bibe);
     568           4 : }
     569             : 
     570             : nat64_db_st_entry_t *
     571          97 : 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          97 :   nat64_db_st_entry_t *ste = 0;
     576             :   nat64_db_st_entry_t *st;
     577             :   nat64_db_st_entry_key_t ste_key;
     578             :   clib_bihash_kv_48_8_t kv, value;
     579             : 
     580          97 :   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;
     587          97 :       foreach_nat_protocol
     588             : #undef _
     589             : /* *INDENT-ON* */
     590           0 :     default:
     591           0 :       st = db->st._unk_proto_st;
     592           0 :       break;
     593             :     }
     594             : 
     595          97 :   clib_memset (&ste_key, 0, sizeof (ste_key));
     596          97 :   ste_key.l_addr.as_u64[0] = l_addr->as_u64[0];
     597          97 :   ste_key.l_addr.as_u64[1] = l_addr->as_u64[1];
     598          97 :   ste_key.r_addr.as_u64[0] = r_addr->as_u64[0];
     599          97 :   ste_key.r_addr.as_u64[1] = r_addr->as_u64[1];
     600          97 :   ste_key.fib_index = fib_index;
     601          97 :   ste_key.l_port = l_port;
     602          97 :   ste_key.r_port = r_port;
     603          97 :   ste_key.proto = proto;
     604          97 :   kv.key[0] = ste_key.as_u64[0];
     605          97 :   kv.key[1] = ste_key.as_u64[1];
     606          97 :   kv.key[2] = ste_key.as_u64[2];
     607          97 :   kv.key[3] = ste_key.as_u64[3];
     608          97 :   kv.key[4] = ste_key.as_u64[4];
     609          97 :   kv.key[5] = ste_key.as_u64[5];
     610             : 
     611          97 :   if (!clib_bihash_search_48_8
     612             :       (is_ip6 ? &db->st.in2out : &db->st.out2in, &kv, &value))
     613          59 :     ste = pool_elt_at_index (st, value.value);
     614             : 
     615          97 :   return ste;
     616             : }
     617             : 
     618             : u32
     619           0 : 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           0 :   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;
     630           0 :       foreach_nat_protocol
     631             : #undef _
     632             : /* *INDENT-ON* */
     633           0 :     default:
     634           0 :       st = db->st._unk_proto_st;
     635           0 :       return (u32) ~ 0;
     636             :     }
     637             : 
     638           0 :   return ste - st;
     639             : }
     640             : 
     641             : nat64_db_st_entry_t *
     642           0 : nat64_db_st_entry_by_index (nat64_db_t * db, u8 proto, u32 ste_index)
     643             : {
     644             :   nat64_db_st_entry_t *st;
     645             : 
     646           0 :   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;
     653           0 :       foreach_nat_protocol
     654             : #undef _
     655             : /* *INDENT-ON* */
     656           0 :     default:
     657           0 :       st = db->st._unk_proto_st;
     658           0 :       break;
     659             :     }
     660             : 
     661           0 :   return pool_elt_at_index (st, ste_index);
     662             : }
     663             : 
     664             : void
     665          34 : nad64_db_st_free_expired (u32 thread_index, nat64_db_t * db, u32 now)
     666             : {
     667          34 :   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;
     684          42 :   foreach_nat_protocol
     685             : #undef _
     686          34 :   st = db->st._unk_proto_st;
     687          34 :   pool_foreach (ste, st)  {
     688           0 :     if (ste->expire < now)
     689           0 :       vec_add1 (ste_to_be_free, ste - st);
     690             :   }
     691          34 :   vec_foreach (ste_index, ste_to_be_free)
     692           0 :     nat64_db_st_entry_free (thread_index, db,
     693           0 :                             pool_elt_at_index(st, ste_index[0]));
     694          34 :   vec_free (ste_to_be_free);
     695             : /* *INDENT-ON* */
     696          34 : }
     697             : 
     698             : void
     699           4 : nat64_db_free_out_addr (u32 thread_index,
     700             :                         nat64_db_t * db, ip4_address_t * out_addr)
     701             : {
     702           4 :   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           4 :   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;
     720           8 :   foreach_nat_protocol
     721             : #undef _
     722           4 :   st = db->st._unk_proto_st;
     723           4 :   pool_foreach (ste, st)  {
     724           0 :     bibe = pool_elt_at_index (db->bib._unk_proto_bib, ste->bibe_index);
     725           0 :     if (bibe->out_addr.as_u32 == out_addr->as_u32)
     726           0 :       vec_add1 (ste_to_be_free, ste - st);
     727             :   }
     728           4 :   vec_foreach (ste_index, ste_to_be_free)
     729           0 :     nat64_db_st_entry_free (thread_index, db,
     730           0 :                             pool_elt_at_index(st, ste_index[0]));
     731           4 :   vec_free (ste_to_be_free);
     732           4 :   db->addr_free = 0;
     733             : /* *INDENT-ON* */
     734           4 : }
     735             : 
     736             : /*
     737             :  * fd.io coding-style-patch-verification: ON
     738             :  *
     739             :  * Local Variables:
     740             :  * eval: (c-set-style "gnu")
     741             :  * End:
     742             :  */

Generated by: LCOV version 1.14