aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/cnat/cnat_snat_policy.c5
-rw-r--r--src/plugins/http/http.c12
-rw-r--r--src/plugins/http/http_buffer.c2
-rw-r--r--src/vnet/CMakeLists.txt1
-rw-r--r--src/vnet/crypto/crypto.c91
-rw-r--r--src/vnet/crypto/crypto.h9
-rw-r--r--src/vnet/ipsec/ipsec_api.c8
-rw-r--r--src/vnet/l2/l2_input_node.c5
-rw-r--r--src/vnet/qos/qos_store.c2
-rw-r--r--src/vnet/session/session_lookup.c65
-rw-r--r--src/vnet/session/session_lookup.h3
-rw-r--r--src/vnet/session/transport.c10
-rw-r--r--src/vppinfra/clib.h1
13 files changed, 149 insertions, 65 deletions
diff --git a/src/plugins/cnat/cnat_snat_policy.c b/src/plugins/cnat/cnat_snat_policy.c
index cd9bfef492a..5f15b7d26c9 100644
--- a/src/plugins/cnat/cnat_snat_policy.c
+++ b/src/plugins/cnat/cnat_snat_policy.c
@@ -22,7 +22,8 @@ cnat_snat_policy_main_t cnat_snat_policy_main;
uword
unformat_cnat_snat_interface_map_type (unformat_input_t *input, va_list *args)
{
- u8 *a = va_arg (*args, u8 *);
+ cnat_snat_interface_map_type_t *a =
+ va_arg (*args, cnat_snat_interface_map_type_t *);
if (unformat (input, "include-v4"))
*a = CNAT_SNAT_IF_MAP_INCLUDE_V4;
else if (unformat (input, "include-v6"))
@@ -113,7 +114,7 @@ cnat_snat_policy_add_del_if_command_fn (vlib_main_t *vm,
vnet_main_t *vnm = vnet_get_main ();
int is_add = 1;
u32 sw_if_index = ~0;
- u32 table = 0;
+ cnat_snat_interface_map_type_t table = CNAT_SNAT_IF_MAP_INCLUDE_V4;
int rv;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
diff --git a/src/plugins/http/http.c b/src/plugins/http/http.c
index 69b661d0611..04a4ad3e0a9 100644
--- a/src/plugins/http/http.c
+++ b/src/plugins/http/http.c
@@ -2575,6 +2575,13 @@ http_app_tx_callback (void *session, transport_send_params_t *sp)
hc = http_conn_get_w_thread (as->connection_index, as->thread_index);
+ if (hc->state == HTTP_CONN_STATE_CLOSED)
+ {
+ HTTP_DBG (1, "conn closed");
+ svm_fifo_dequeue_drop_all (as->tx_fifo);
+ return 0;
+ }
+
max_burst_sz = sp->max_burst_size * TRANSPORT_PACER_MIN_MSS;
sp->max_burst_size = max_burst_sz;
@@ -2606,7 +2613,10 @@ http_app_tx_callback (void *session, transport_send_params_t *sp)
if (hc->state == HTTP_CONN_STATE_APP_CLOSED)
{
if (!svm_fifo_max_dequeue_cons (as->tx_fifo))
- http_disconnect_transport (hc);
+ {
+ session_transport_closed_notify (&hc->connection);
+ http_disconnect_transport (hc);
+ }
}
sent = max_burst_sz - sp->max_burst_size;
diff --git a/src/plugins/http/http_buffer.c b/src/plugins/http/http_buffer.c
index bc1b8c08630..909aa538396 100644
--- a/src/plugins/http/http_buffer.c
+++ b/src/plugins/http/http_buffer.c
@@ -67,7 +67,7 @@ buf_fifo_get_segs (http_buffer_t *hb, u32 max_len, u32 *n_segs)
max_len = clib_min (bf->len - bf->offset, (u64) max_len);
- vec_validate (bf->segs, _n_segs);
+ vec_validate (bf->segs, _n_segs - 1);
len = svm_fifo_segments (bf->src, 0, bf->segs, &_n_segs, max_len);
if (len < 0)
diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt
index b6227d45a2a..a071709542a 100644
--- a/src/vnet/CMakeLists.txt
+++ b/src/vnet/CMakeLists.txt
@@ -589,6 +589,7 @@ list(APPEND VNET_HEADERS
ipsec/ipsec_tun.h
ipsec/ipsec_types_api.h
ipsec/ipsec_punt.h
+ ipsec/ipsec_funcs.h
ipsec/esp.h
ipsec/ah.h
)
diff --git a/src/vnet/crypto/crypto.c b/src/vnet/crypto/crypto.c
index 35e7768375d..d1a6a6b12a1 100644
--- a/src/vnet/crypto/crypto.c
+++ b/src/vnet/crypto/crypto.c
@@ -381,17 +381,44 @@ vnet_crypto_register_key_handler (vlib_main_t *vm, u32 engine_index,
return;
}
+static vnet_crypto_key_t *
+vnet_crypoto_key_alloc (u32 length)
+{
+ vnet_crypto_main_t *cm = &crypto_main;
+ u8 expected = 0;
+ vnet_crypto_key_t *k, **kp;
+ u32 alloc_sz = sizeof (vnet_crypto_key_t) + round_pow2 (length, 16);
+
+ while (!__atomic_compare_exchange_n (&cm->keys_lock, &expected, 1, 0,
+ __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))
+ {
+ while (__atomic_load_n (&cm->keys_lock, __ATOMIC_RELAXED))
+ CLIB_PAUSE ();
+ expected = 0;
+ }
+
+ pool_get (cm->keys, kp);
+
+ __atomic_store_n (&cm->keys_lock, 0, __ATOMIC_RELEASE);
+
+ k = clib_mem_alloc_aligned (alloc_sz, alignof (vnet_crypto_key_t));
+ kp[0] = k;
+ *k = (vnet_crypto_key_t){
+ .index = kp - cm->keys,
+ .length = length,
+ };
+
+ return k;
+}
+
u32
vnet_crypto_key_add (vlib_main_t * vm, vnet_crypto_alg_t alg, u8 * data,
u16 length)
{
- u32 index;
vnet_crypto_main_t *cm = &crypto_main;
vnet_crypto_engine_t *engine;
- vnet_crypto_key_t *key, **kp;
+ vnet_crypto_key_t *key;
vnet_crypto_alg_data_t *ad = cm->algs + alg;
- u32 alloc_sz = sizeof (vnet_crypto_key_t) + round_pow2 (length, 16);
- u8 need_barrier_sync = 0;
ASSERT (alg != 0);
@@ -407,29 +434,14 @@ vnet_crypto_key_add (vlib_main_t * vm, vnet_crypto_alg_t alg, u8 * data,
return ~0;
}
- need_barrier_sync = pool_get_will_expand (cm->keys);
- /* If the cm->keys will expand, stop the parade. */
- if (need_barrier_sync)
- vlib_worker_thread_barrier_sync (vm);
-
- pool_get (cm->keys, kp);
-
- if (need_barrier_sync)
- vlib_worker_thread_barrier_release (vm);
+ key = vnet_crypoto_key_alloc (length);
+ key->alg = alg;
- key = clib_mem_alloc_aligned (alloc_sz, _Alignof (vnet_crypto_key_t));
- kp[0] = key;
- index = kp - cm->keys;
- *key = (vnet_crypto_key_t){
- .index = index,
- .alg = alg,
- .length = length,
- };
clib_memcpy (key->data, data, length);
vec_foreach (engine, cm->engines)
if (engine->key_op_handler)
- engine->key_op_handler (VNET_CRYPTO_KEY_OP_ADD, index);
- return index;
+ engine->key_op_handler (VNET_CRYPTO_KEY_OP_ADD, key->index);
+ return key->index;
}
void
@@ -478,10 +490,9 @@ vnet_crypto_key_add_linked (vlib_main_t * vm,
vnet_crypto_key_index_t index_crypto,
vnet_crypto_key_index_t index_integ)
{
- u32 index, need_barrier_sync;
vnet_crypto_main_t *cm = &crypto_main;
vnet_crypto_engine_t *engine;
- vnet_crypto_key_t *key_crypto, *key_integ, *key, **kp;
+ vnet_crypto_key_t *key_crypto, *key_integ, *key;
vnet_crypto_alg_t linked_alg;
key_crypto = cm->keys[index_crypto];
@@ -491,33 +502,17 @@ vnet_crypto_key_add_linked (vlib_main_t * vm,
if (linked_alg == ~0)
return ~0;
- need_barrier_sync = pool_get_will_expand (cm->keys);
- /* If the cm->keys will expand, stop the parade. */
- if (need_barrier_sync)
- vlib_worker_thread_barrier_sync (vm);
-
- pool_get (cm->keys, kp);
-
- if (need_barrier_sync)
- vlib_worker_thread_barrier_release (vm);
-
- key = clib_mem_alloc_aligned (sizeof (vnet_crypto_key_t),
- _Alignof (vnet_crypto_key_t));
- kp[0] = key;
- index = kp - cm->keys;
- *key = (vnet_crypto_key_t){
- .index = index,
- .is_link = 1,
- .index_crypto = index_crypto,
- .index_integ = index_integ,
- .alg = linked_alg,
- };
+ key = vnet_crypoto_key_alloc (0);
+ key->is_link = 1;
+ key->index_crypto = index_crypto;
+ key->index_integ = index_integ;
+ key->alg = linked_alg;
vec_foreach (engine, cm->engines)
if (engine->key_op_handler)
- engine->key_op_handler (VNET_CRYPTO_KEY_OP_ADD, index);
+ engine->key_op_handler (VNET_CRYPTO_KEY_OP_ADD, key->index);
- return index;
+ return key->index;
}
u32
diff --git a/src/vnet/crypto/crypto.h b/src/vnet/crypto/crypto.h
index a4b6ab97620..0a021282b5d 100644
--- a/src/vnet/crypto/crypto.h
+++ b/src/vnet/crypto/crypto.h
@@ -420,16 +420,17 @@ typedef struct
typedef struct
{
- vnet_crypto_alg_data_t algs[VNET_CRYPTO_N_ALGS];
+ vnet_crypto_key_t **keys;
+ u8 keys_lock;
+ u32 crypto_node_index;
vnet_crypto_thread_t *threads;
vnet_crypto_frame_dequeue_t **dequeue_handlers;
- vnet_crypto_op_data_t opt_data[VNET_CRYPTO_N_OP_IDS];
vnet_crypto_engine_t *engines;
- vnet_crypto_key_t **keys;
uword *engine_index_by_name;
uword *alg_index_by_name;
vnet_crypto_async_next_node_t *next_nodes;
- u32 crypto_node_index;
+ vnet_crypto_alg_data_t algs[VNET_CRYPTO_N_ALGS];
+ vnet_crypto_op_data_t opt_data[VNET_CRYPTO_N_OP_IDS];
} vnet_crypto_main_t;
extern vnet_crypto_main_t crypto_main;
diff --git a/src/vnet/ipsec/ipsec_api.c b/src/vnet/ipsec/ipsec_api.c
index 2dd9b9f2b2c..262a8cb8c88 100644
--- a/src/vnet/ipsec/ipsec_api.c
+++ b/src/vnet/ipsec/ipsec_api.c
@@ -1357,8 +1357,12 @@ send_ipsec_sa_v5_details (ipsec_sa_t *sa, void *arg)
mp->last_seq_inbound = clib_host_to_net_u64 (ipsec_sa_get_inb_seq (sa));
if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa) && irt)
- mp->replay_window =
- clib_host_to_net_u64 (ipsec_sa_anti_replay_get_64b_window (irt));
+ {
+ mp->replay_window =
+ clib_host_to_net_u64 (ipsec_sa_anti_replay_get_64b_window (irt));
+ mp->entry.anti_replay_window_size =
+ clib_host_to_net_u32 (IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE (irt));
+ }
if (ort)
thread_index = ort->thread_index;
diff --git a/src/vnet/l2/l2_input_node.c b/src/vnet/l2/l2_input_node.c
index 76b94809eb3..58a541756da 100644
--- a/src/vnet/l2/l2_input_node.c
+++ b/src/vnet/l2/l2_input_node.c
@@ -215,7 +215,10 @@ classify_and_dispatch (l2input_main_t * msm, vlib_buffer_t * b0, u16 * next0)
vnet_buffer (b0)->sw_if_index[VLIB_TX] = config->output_sw_if_index;
}
else
- feat_mask = L2INPUT_FEAT_DROP;
+ {
+ *next0 = L2INPUT_NEXT_DROP;
+ return;
+ }
/* mask out features from bitmap using packet type and bd config */
u32 feature_bitmap = config->feature_bitmap & feat_mask;
diff --git a/src/vnet/qos/qos_store.c b/src/vnet/qos/qos_store.c
index 3424a914e35..8875585f199 100644
--- a/src/vnet/qos/qos_store.c
+++ b/src/vnet/qos/qos_store.c
@@ -181,7 +181,7 @@ qos_store_cli (vlib_main_t * vm,
enable = 1;
else if (unformat (input, "disable"))
enable = 0;
- else if (unformat (input, "value &d", &value))
+ else if (unformat (input, "value %d", &value))
;
else
break;
diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c
index 28a1feb1ed8..7678b0e0761 100644
--- a/src/vnet/session/session_lookup.c
+++ b/src/vnet/session/session_lookup.c
@@ -1380,6 +1380,71 @@ session_lookup_connection (u32 fib_index, ip46_address_t * lcl,
lcl_port, rmt_port, proto);
}
+/**
+ * Lookup exact match 6-tuple amongst established and half-open sessions
+ *
+ * Does not look into session rules table and does not try to find a listener.
+ */
+transport_connection_t *
+session_lookup_6tuple (u32 fib_index, ip46_address_t *lcl, ip46_address_t *rmt,
+ u16 lcl_port, u16 rmt_port, u8 proto, u8 is_ip4)
+{
+ session_table_t *st;
+ session_t *s;
+ int rv;
+
+ if (is_ip4)
+ {
+ session_kv4_t kv4;
+
+ st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
+ if (PREDICT_FALSE (!st))
+ return 0;
+
+ /*
+ * Lookup session amongst established ones
+ */
+ make_v4_ss_kv (&kv4, &lcl->ip4, &rmt->ip4, lcl_port, rmt_port, proto);
+ rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4);
+ if (rv == 0)
+ {
+ s = session_get_from_handle (kv4.value);
+ return transport_get_connection (proto, s->connection_index,
+ s->thread_index);
+ }
+
+ /*
+ * Try half-open connections
+ */
+ rv = clib_bihash_search_inline_16_8 (&st->v4_half_open_hash, &kv4);
+ if (rv == 0)
+ return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF);
+ }
+ else
+ {
+ session_kv6_t kv6;
+
+ st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
+ if (PREDICT_FALSE (!st))
+ return 0;
+
+ make_v6_ss_kv (&kv6, &lcl->ip6, &rmt->ip6, lcl_port, rmt_port, proto);
+ rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6);
+ if (rv == 0)
+ {
+ s = session_get_from_handle (kv6.value);
+ return transport_get_connection (proto, s->connection_index,
+ s->thread_index);
+ }
+
+ /* Try half-open connections */
+ rv = clib_bihash_search_inline_48_8 (&st->v6_half_open_hash, &kv6);
+ if (rv == 0)
+ return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF);
+ }
+ return 0;
+}
+
session_error_t
vnet_session_rule_add_del (session_rule_add_del_args_t *args)
{
diff --git a/src/vnet/session/session_lookup.h b/src/vnet/session/session_lookup.h
index 9f56af20a87..8f9ff7ee9bc 100644
--- a/src/vnet/session/session_lookup.h
+++ b/src/vnet/session/session_lookup.h
@@ -72,6 +72,9 @@ transport_connection_t *session_lookup_connection (u32 fib_index,
ip46_address_t * rmt,
u16 lcl_port, u16 rmt_port,
u8 proto, u8 is_ip4);
+transport_connection_t *
+session_lookup_6tuple (u32 fib_index, ip46_address_t *lcl, ip46_address_t *rmt,
+ u16 lcl_port, u16 rmt_port, u8 proto, u8 is_ip4);
session_t *session_lookup_listener4 (u32 fib_index, ip4_address_t * lcl,
u16 lcl_port, u8 proto, u8 use_wildcard);
session_t *session_lookup_listener6 (u32 fib_index, ip6_address_t * lcl,
diff --git a/src/vnet/session/transport.c b/src/vnet/session/transport.c
index ac9b54f333a..015255ecf08 100644
--- a/src/vnet/session/transport.c
+++ b/src/vnet/session/transport.c
@@ -661,8 +661,8 @@ transport_alloc_local_port (u8 proto, ip46_address_t *lcl_addr,
break;
/* IP:port pair already in use, check if 6-tuple available */
- if (session_lookup_connection (rmt->fib_index, lcl_addr, &rmt->ip, port,
- rmt->port, proto, rmt->is_ip4))
+ if (session_lookup_6tuple (rmt->fib_index, lcl_addr, &rmt->ip, port,
+ rmt->port, proto, rmt->is_ip4))
continue;
/* 6-tuple is available so increment lcl endpoint refcount */
@@ -792,9 +792,9 @@ transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t * rmt_cfg,
return 0;
/* IP:port pair already in use, check if 6-tuple available */
- if (session_lookup_connection (rmt->fib_index, lcl_addr, &rmt->ip,
- rmt_cfg->peer.port, rmt->port, proto,
- rmt->is_ip4))
+ if (session_lookup_6tuple (rmt->fib_index, lcl_addr, &rmt->ip,
+ rmt_cfg->peer.port, rmt->port, proto,
+ rmt->is_ip4))
return SESSION_E_PORTINUSE;
/* 6-tuple is available so increment lcl endpoint refcount */
diff --git a/src/vppinfra/clib.h b/src/vppinfra/clib.h
index 5348738ec6a..cb90da5c1e0 100644
--- a/src/vppinfra/clib.h
+++ b/src/vppinfra/clib.h
@@ -39,6 +39,7 @@
#define included_clib_h
#include <stddef.h>
+#include <stdalign.h>
#if __has_include(<vppinfra/config.h>)
#include <vppinfra/config.h>