FD.io VPP  v21.06-1-gbb7418cf9
Vector Packet Processing
cnat_session.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/ip/ip.h>
17 #include <cnat/cnat_session.h>
18 #include <cnat/cnat_inline.h>
19 
22 
25 
27 {
29  void *ctx;
31 
32 static int
33 cnat_session_walk_cb (BVT (clib_bihash_kv) * kv, void *arg)
34 {
35  cnat_session_t *session = (cnat_session_t *) kv;
37 
38  ctx->cb (session, ctx->ctx);
39 
40  return (BIHASH_WALK_CONTINUE);
41 }
42 
43 void
45 {
47  .cb = cb,
48  .ctx = ctx,
49  };
51  cnat_session_walk_cb, &wctx);
52 }
53 
55 {
58 
59 static int
60 cnat_session_purge_walk (BVT (clib_bihash_kv) * key, void *arg)
61 {
63 
64  vec_add1 (ctx->keys, *key);
65 
66  return (BIHASH_WALK_CONTINUE);
67 }
68 
69 u8 *
70 format_cnat_session_location (u8 *s, va_list *args)
71 {
72  u8 location = va_arg (*args, int);
73  switch (location)
74  {
76  s = format (s, "input");
77  break;
79  s = format (s, "output");
80  break;
81  case CNAT_LOCATION_FIB:
82  s = format (s, "fib");
83  break;
84  default:
85  s = format (s, "unknown");
86  break;
87  }
88  return (s);
89 }
90 
91 u8 *
92 format_cnat_session (u8 * s, va_list * args)
93 {
94  cnat_session_t *sess = va_arg (*args, cnat_session_t *);
95  CLIB_UNUSED (int verbose) = va_arg (*args, int);
96  f64 ts = 0;
99 
100  s = format (
101  s, "session:[%U;%d -> %U;%d, %U] => %U;%d -> %U;%d %U lb:%d age:%f",
103  clib_host_to_net_u16 (sess->key.cs_port[VLIB_RX]), format_ip46_address,
104  &sess->key.cs_ip[VLIB_TX], IP46_TYPE_ANY,
105  clib_host_to_net_u16 (sess->key.cs_port[VLIB_TX]), format_ip_protocol,
107  IP46_TYPE_ANY, clib_host_to_net_u16 (sess->value.cs_port[VLIB_RX]),
109  clib_host_to_net_u16 (sess->value.cs_port[VLIB_TX]),
111 
112  return (s);
113 }
114 
115 static clib_error_t *
117  unformat_input_t * input, vlib_cli_command_t * cmd)
118 {
119  u8 verbose = 0;
121  {
122  if (unformat (input, "verbose"))
123  verbose = 1;
124  else
125  return (clib_error_return (0, "unknown input '%U'",
126  format_unformat_error, input));
127  }
128 
129  vlib_cli_output (vm, "CNat Sessions: now:%f\n%U\n",
130  vlib_time_now (vm),
131  BV (format_bihash), &cnat_session_db, verbose);
132 
133  return (NULL);
134 }
135 
136 VLIB_CLI_COMMAND (cnat_session_show_cmd_node, static) = {
137  .path = "show cnat session",
138  .function = cnat_session_show,
139  .short_help = "show cnat session",
140  .is_mp_safe = 1,
141 };
142 
143 void
145 {
146  cnat_bihash_kv_t *bkey = (cnat_bihash_kv_t *) session;
147  /* age it */
150  session->key.cs_proto);
151  if (!(session->value.flags & CNAT_SESSION_FLAG_NO_CLIENT))
152  cnat_client_free_by_ip (&session->key.cs_ip[VLIB_TX], session->key.cs_af);
154 
155  cnat_bihash_add_del (&cnat_session_db, bkey, 0 /* is_add */);
156 }
157 
158 int
160 {
161  /* flush all the session from the DB */
164 
167 
168  vec_foreach (key, ctx.keys) cnat_session_free ((cnat_session_t *) key);
169 
170  vec_free (ctx.keys);
171 
172  return (0);
173 }
174 
175 u64
176 cnat_session_scan (vlib_main_t * vm, f64 start_time, int i)
177 {
178  BVT (clib_bihash) * h = &cnat_session_db;
179  int j, k;
180 
181  /* Don't scan the l2 fib if it hasn't been instantiated yet */
182  if (alloc_arena (h) == 0)
183  return 0.0;
184 
185  for ( /* caller saves starting point */ ; i < h->nbuckets; i++)
186  {
187  /* allow no more than 100us without a pause */
188  if ((vlib_time_now (vm) - start_time) > 10e-5)
189  return (i);
190 
191  if (i < (h->nbuckets - 3))
192  {
193  BVT (clib_bihash_bucket) * b =
194  BV (clib_bihash_get_bucket) (h, i + 3);
196  b = BV (clib_bihash_get_bucket) (h, i + 1);
197  if (!BV (clib_bihash_bucket_is_empty) (b))
198  {
199  BVT (clib_bihash_value) * v =
200  BV (clib_bihash_get_value) (h, b->offset);
202  }
203  }
204 
205  BVT (clib_bihash_bucket) * b = BV (clib_bihash_get_bucket) (h, i);
206  if (BV (clib_bihash_bucket_is_empty) (b))
207  continue;
208  BVT (clib_bihash_value) * v = BV (clib_bihash_get_value) (h, b->offset);
209  for (j = 0; j < (1 << b->log2_pages); j++)
210  {
211  for (k = 0; k < BIHASH_KVP_PER_PAGE; k++)
212  {
213  if (v->kvp[k].key[0] == ~0ULL && v->kvp[k].value[0] == ~0ULL)
214  continue;
215 
216  cnat_session_t *session = (cnat_session_t *) & v->kvp[k];
217 
218  if (start_time >
220  {
221  /* age it */
222  cnat_session_free (session);
223 
224  /*
225  * Note: we may have just freed the bucket's backing
226  * storage, so check right here...
227  */
228  if (BV (clib_bihash_bucket_is_empty) (b))
229  goto doublebreak;
230  }
231  }
232  v++;
233  }
234  doublebreak:
235  ;
236  }
237 
238  /* start again */
239  return (0);
240 }
241 
242 static clib_error_t *
244 {
247  "CNat Session DB", cm->session_hash_buckets,
248  cm->session_hash_memory);
249  BV (clib_bihash_set_kvp_format_fn) (&cnat_session_db, format_cnat_session);
250 
251  return (NULL);
252 }
253 
255 
256 static clib_error_t *
258  unformat_input_t * input, vlib_cli_command_t * cmd)
259 {
260  cnat_timestamp_t *ts;
263  {
264  vlib_cli_output (vm, "[%d] last_seen:%f lifetime:%u ref:%u",
265  ts - cnat_timestamps, ts->last_seen, ts->lifetime,
266  ts->refcnt);
267  }
269  return (NULL);
270 }
271 
272 VLIB_CLI_COMMAND (cnat_timestamp_show_cmd, static) = {
273  .path = "show cnat timestamp",
274  .function = cnat_timestamp_show,
275  .short_help = "show cnat timestamp",
276  .is_mp_safe = 1,
277 };
278 
279 /*
280  * fd.io coding-style-patch-verification: ON
281  *
282  * Local Variables:
283  * eval: (c-set-style "gnu")
284  * End:
285  */
static void clib_rwlock_reader_lock(clib_rwlock_t *p)
Definition: lock.h:169
format_function_t format_ip_protocol
Definition: format.h:45
struct cnat_session_t_::@635 key
this key sits in the same memory location a &#39;key&#39; in the bihash kvp
#define cnat_bihash_add_del
Definition: cnat_bihash.h:111
u64 cnat_session_scan(vlib_main_t *vm, f64 start_time, int i)
Scan the session DB for expired sessions.
Definition: cnat_session.c:176
#define CLIB_UNUSED(x)
Definition: clib.h:90
This session source port was allocated, free it on cleanup.
Definition: cnat_session.h:120
#define BIHASH_KVP_PER_PAGE
Definition: bihash_16_8.h:25
void(* cnat_free_port_cb)(u16 port, ip_protocol_t iproto)
Port cleanup callback.
Definition: cnat_session.c:24
This session doesn&#39;t have a client, do not attempt to free it.
Definition: cnat_session.h:124
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
unsigned long u64
Definition: types.h:89
static void cnat_timestamp_free(u32 index)
Definition: cnat_inline.h:78
vnet_feature_config_main_t * cm
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:325
u16 cs_port[VLIB_N_DIR]
ports in rx/tx
Definition: cnat_session.h:52
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:607
u8 * format_cnat_session(u8 *s, va_list *args)
Definition: cnat_session.c:92
u32 session_hash_buckets
Definition: cnat_types.h:100
void cnat_session_free(cnat_session_t *session)
Free a session & update refcounts.
Definition: cnat_session.c:144
unsigned char u8
Definition: types.h:56
vlib_buffer_t ** b
double f64
Definition: types.h:142
A session represents the memory of a translation.
Definition: cnat_session.h:37
u8 cs_af
The address family describing the IP addresses.
Definition: cnat_session.h:62
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
int cnat_session_purge(void)
Purge all the sessions.
Definition: cnat_session.c:159
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
struct cnat_session_t_::@636 value
this value sits in the same memory location a &#39;value&#39; in the bihash kvp
cnat_bihash_kv_t * keys
Definition: cnat_session.c:56
description fragment has unexpected format
Definition: map.api:433
#define clib_error_return(e, args...)
Definition: error.h:99
ip46_address_t cs_ip[VLIB_N_DIR]
IP 4/6 address in the rx/tx direction.
Definition: cnat_session.h:47
clib_bihash_40_56_t cnat_bihash_t
Definition: cnat_bihash.h:107
u32 cs_ts_index
Timestamp index this session was last used.
Definition: cnat_session.h:99
enum ip_protocol ip_protocol_t
void clib_bihash_foreach_key_value_pair(clib_bihash *h, clib_bihash_foreach_key_value_pair_cb *callback, void *arg)
Visit active (key,value) pairs in a bi-hash table.
static void clib_rwlock_reader_unlock(clib_rwlock_t *p)
Definition: lock.h:184
static int cnat_session_purge_walk(BVT(clib_bihash_kv) *key, void *arg)
Definition: cnat_session.c:60
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
cnat_timestamp_t * cnat_timestamps
Definition: cnat_types.c:20
static f64 cnat_timestamp_exp(u32 index)
Definition: cnat_inline.h:65
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
void clib_bihash_init(clib_bihash *h, char *name, u32 nbuckets, uword memory_size)
initialize a bounded index extensible hash table
u8 location
Definition: cnat.api:121
index_t cs_lbi
The load balance object to use to forward.
Definition: cnat_session.h:89
format_function_t format_ip46_address
Definition: ip46_address.h:50
BVT(clib_bihash)
The table of adjacencies indexed by the rewrite string.
Definition: l2_fib.c:1069
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
static clib_error_t * cnat_session_init(vlib_main_t *vm)
Definition: cnat_session.c:243
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:395
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
static clib_error_t * cnat_timestamp_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cnat_session.c:257
static int cnat_session_walk_cb(BVT(clib_bihash_kv) *kv, void *arg)
Definition: cnat_session.c:33
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
u32 flags
session flags
Definition: cnat_session.h:104
struct cnat_session_purge_walk_t_ cnat_session_purge_walk_ctx_t
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
void cnat_client_free_by_ip(ip46_address_t *ip, u8 af)
Definition: cnat_client.c:57
uword session_hash_memory
Definition: cnat_types.h:97
clib_rwlock_t ts_lock
Definition: cnat_types.h:129
struct cnat_session_walk_ctx_t_ cnat_session_walk_ctx_t
typedef key
Definition: ipsec_types.api:88
template key/value backing page structure
Definition: bihash_doc.h:44
Definition: defs.h:47
ip_protocol_t cs_proto
The IP protocol TCP or UDP only supported.
Definition: cnat_session.h:57
cnat_bihash_t cnat_session_db
The DB of sessions.
Definition: cnat_session.c:23
u8 cs_loc
input / output / fib session
Definition: cnat_session.h:67
cnat_main_t cnat_main
Definition: cnat_types.c:18
u16 port
Definition: lb_types.api:73
walk_rc_t(* cnat_session_walk_cb_t)(const cnat_session_t *session, void *ctx)
Callback function invoked during a walk of all translations.
Definition: cnat_session.h:163
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
#define vec_foreach(var, vec)
Vector iterator.
cnat_session_walk_cb_t cb
Definition: cnat_session.c:28
static void * clib_bihash_get_value(clib_bihash *h, uword offset)
Get pointer to value page given its clib mheap offset.
static clib_error_t * cnat_session_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cnat_session.c:116
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
u8 * format_cnat_session_location(u8 *s, va_list *args)
Definition: cnat_session.c:70
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
Definition: defs.h:46
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
void cnat_session_walk(cnat_session_walk_cb_t cb, void *ctx)
Walk/visit each of the cnat session.
Definition: cnat_session.c:44