diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/cnat/cnat_snat_policy.c | 5 | ||||
-rw-r--r-- | src/plugins/http/http.c | 12 | ||||
-rw-r--r-- | src/plugins/http/http_buffer.c | 2 | ||||
-rw-r--r-- | src/vnet/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/vnet/crypto/crypto.c | 91 | ||||
-rw-r--r-- | src/vnet/crypto/crypto.h | 9 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_api.c | 8 | ||||
-rw-r--r-- | src/vnet/l2/l2_input_node.c | 5 | ||||
-rw-r--r-- | src/vnet/qos/qos_store.c | 2 | ||||
-rw-r--r-- | src/vnet/session/session_lookup.c | 65 | ||||
-rw-r--r-- | src/vnet/session/session_lookup.h | 3 | ||||
-rw-r--r-- | src/vnet/session/transport.c | 10 | ||||
-rw-r--r-- | src/vppinfra/clib.h | 1 |
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> |