FD.io VPP  v21.10.1-2-g0a485f517
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 
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 
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);
201  clib_prefetch_load (v);
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 
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  */
cnat_timestamp_t_::lifetime
u16 lifetime
Definition: cnat_types.h:150
cnat_bihash_t
clib_bihash_40_56_t cnat_bihash_t
Definition: cnat_bihash.h:107
bihash_template.c
cnat_session_t_::cs_ip
ip46_address_t cs_ip[VLIB_N_DIR]
IP 4/6 address in the rx/tx direction.
Definition: cnat_session.h:47
cnat_timestamp_t_::last_seen
f64 last_seen
Definition: cnat_types.h:148
cnat_session_free
void cnat_session_free(cnat_session_t *session)
Free a session & update refcounts.
Definition: cnat_session.c:144
cnat_session_scan
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
format_cnat_session_location
u8 * format_cnat_session_location(u8 *s, va_list *args)
Definition: cnat_session.c:70
BIHASH_KVP_PER_PAGE
#define BIHASH_KVP_PER_PAGE
Definition: bihash_16_8.h:25
cnat_timestamp_exp
static f64 cnat_timestamp_exp(u32 index)
Definition: cnat_inline.h:65
cnat_session_t_::cs_lbi
index_t cs_lbi
The load balance object to use to forward.
Definition: cnat_session.h:89
bihash_template.h
cnat_main
cnat_main_t cnat_main
Definition: cnat_types.c:18
cnat_session.h
CNAT_SESSION_FLAG_NO_CLIENT
@ CNAT_SESSION_FLAG_NO_CLIENT
This session doesn't have a client, do not attempt to free it.
Definition: cnat_session.h:124
cnat_session_walk_ctx_t_::cb
cnat_session_walk_cb_t cb
Definition: cnat_session.c:28
clib_bihash_kv_40_56_t
Definition: cnat_bihash.h:41
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
vlib_cli_command_t::path
char * path
Definition: cli.h:96
u16
unsigned short u16
Definition: types.h:57
cnat_timestamps
cnat_timestamp_t * cnat_timestamps
Definition: cnat_types.c:20
CNAT_LOCATION_INPUT
@ CNAT_LOCATION_INPUT
Definition: cnat_session.h:136
format_cnat_session
u8 * format_cnat_session(u8 *s, va_list *args)
Definition: cnat_session.c:92
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
port
u16 port
Definition: lb_types.api:73
cnat_session_purge
int cnat_session_purge(void)
Purge all the sessions.
Definition: cnat_session.c:159
cnat_session_t_
A session represents the memory of a translation.
Definition: cnat_session.h:37
unformat_input_t
struct _unformat_input_t unformat_input_t
cnat_session_t_::key
struct cnat_session_t_::@645 key
this key sits in the same memory location a 'key' in the bihash kvp
clib_rwlock_reader_lock
static void clib_rwlock_reader_lock(clib_rwlock_t *p)
Definition: lock.h:169
clib_bihash_get_value
static void * clib_bihash_get_value(clib_bihash *h, uword offset)
Get pointer to value page given its clib mheap offset.
cnat_session_t_::cs_af
u8 cs_af
The address family describing the IP addresses.
Definition: cnat_session.h:62
clib_rwlock_reader_unlock
static void clib_rwlock_reader_unlock(clib_rwlock_t *p)
Definition: lock.h:184
h
h
Definition: flowhash_template.h:372
key
typedef key
Definition: ipsec_types.api:91
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
pool_is_free_index
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
pool_foreach
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
cnat_session_walk_ctx_t_::ctx
void * ctx
Definition: cnat_session.c:29
cnat_session_walk_ctx_t
struct cnat_session_walk_ctx_t_ cnat_session_walk_ctx_t
clib_bihash_init
void clib_bihash_init(clib_bihash *h, char *name, u32 nbuckets, uword memory_size)
initialize a bounded index extensible hash table
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
cnat_main_::ts_lock
clib_rwlock_t ts_lock
Definition: cnat_types.h:129
cnat_session_purge_walk_t_
Definition: cnat_session.c:54
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
cnat_client_free_by_ip
void cnat_client_free_by_ip(ip46_address_t *ip, u8 af)
Definition: cnat_client.c:57
format_ip_protocol
format_function_t format_ip_protocol
Definition: format.h:45
if
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
BVT
BVT(clib_bihash)
The table of adjacencies indexed by the rewrite string.
Definition: l2_fib.c:1065
cnat_timestamp_show_cmd
static vlib_cli_command_t cnat_timestamp_show_cmd
(constructor) VLIB_CLI_COMMAND (cnat_timestamp_show_cmd)
Definition: cnat_session.c:272
f64
double f64
Definition: types.h:142
cm
vnet_feature_config_main_t * cm
Definition: nat44_ei_hairpinning.c:594
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
cnat_inline.h
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
cnat_timestamp_t_
Definition: cnat_types.h:145
cnat_session_t_::cs_ts_index
u32 cs_ts_index
Timestamp index this session was last used.
Definition: cnat_session.h:99
cnat_session_t_::cs_proto
ip_protocol_t cs_proto
The IP protocol TCP or UDP only supported.
Definition: cnat_session.h:57
cnat_session_purge_walk
static int cnat_session_purge_walk(BVT(clib_bihash_kv) *key, void *arg)
Definition: cnat_session.c:60
cnat_session_init
static clib_error_t * cnat_session_init(vlib_main_t *vm)
Definition: cnat_session.c:243
cnat_timestamp_t_::refcnt
u16 refcnt
Definition: cnat_types.h:152
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
clib_bihash_value
template key/value backing page structure
Definition: bihash_doc.h:44
cnat_session_t_::cs_loc
u8 cs_loc
input / output / fib session
Definition: cnat_session.h:67
cnat_session_t_::flags
u32 flags
session flags
Definition: cnat_session.h:104
u64
unsigned long u64
Definition: types.h:89
format
description fragment has unexpected format
Definition: map.api:433
cnat_session_walk_cb
static int cnat_session_walk_cb(BVT(clib_bihash_kv) *kv, void *arg)
Definition: cnat_session.c:33
format_ip46_address
format_function_t format_ip46_address
Definition: ip46_address.h:50
ip.h
cnat_session_walk_cb_t
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
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
CNAT_SESSION_FLAG_ALLOC_PORT
@ CNAT_SESSION_FLAG_ALLOC_PORT
This session source port was allocated, free it on cleanup.
Definition: cnat_session.h:120
clib_prefetch_load
static_always_inline void clib_prefetch_load(void *p)
Definition: cache.h:92
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
cnat_session_show_cmd_node
static vlib_cli_command_t cnat_session_show_cmd_node
(constructor) VLIB_CLI_COMMAND (cnat_session_show_cmd_node)
Definition: cnat_session.c:136
cnat_timestamp_free
static void cnat_timestamp_free(u32 index)
Definition: cnat_inline.h:78
cnat_session_purge_walk_ctx_t
struct cnat_session_purge_walk_t_ cnat_session_purge_walk_ctx_t
cnat_session_db
cnat_bihash_t cnat_session_db
The DB of sessions.
Definition: cnat_session.c:23
ip_protocol_t
enum ip_protocol ip_protocol_t
vlib_main_t
Definition: main.h:102
cnat_timestamp_show
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
CNAT_LOCATION_OUTPUT
@ CNAT_LOCATION_OUTPUT
Definition: cnat_session.h:137
clib_bihash_foreach_key_value_pair
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.
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
i
int i
Definition: flowhash_template.h:376
IP46_TYPE_ANY
@ IP46_TYPE_ANY
Definition: ip46_address.h:24
cnat_session_t_::value
struct cnat_session_t_::@646 value
this value sits in the same memory location a 'value' in the bihash kvp
cnat_session_purge_walk_t_::keys
cnat_bihash_kv_t * keys
Definition: cnat_session.c:56
location
u8 location
Definition: cnat.api:121
CNAT_LOCATION_FIB
@ CNAT_LOCATION_FIB
Definition: cnat_session.h:138
vlib_time_now
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:327
vlib_cli_command_t
Definition: cli.h:92
cnat_free_port_cb
void(* cnat_free_port_cb)(u16 port, ip_protocol_t iproto)
Port cleanup callback.
Definition: cnat_session.c:24
cnat_bihash_add_del
#define cnat_bihash_add_del
Definition: cnat_bihash.h:111
cnat_session_walk_ctx_t_
Definition: cnat_session.c:26
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
cnat_session_walk
void cnat_session_walk(cnat_session_walk_cb_t cb, void *ctx)
Walk/visit each of the cnat session.
Definition: cnat_session.c:44
cnat_session_show
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
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
cnat_main_
Definition: cnat_types.h:94
cnat_session_t_::cs_port
u16 cs_port[VLIB_N_DIR]
ports in rx/tx
Definition: cnat_session.h:52