X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fipsec%2Fesp_encrypt.c;h=58e25f6b85ecebf108f19725b4a5018989db50e3;hb=f62a8c013c6e22c012b9d7df2ef463a6370cf1ce;hp=186e122793dd5edce837549da91a43d40b5e166c;hpb=8cdb1a0a698e2a51c9151401de4a57cae2d29d48;p=vpp.git diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c index 186e122793d..58e25f6b85e 100644 --- a/src/vnet/ipsec/esp_encrypt.c +++ b/src/vnet/ipsec/esp_encrypt.c @@ -27,8 +27,7 @@ #define foreach_esp_encrypt_next \ _(DROP, "error-drop") \ -_(IP4_LOOKUP, "ip4-lookup") \ -_(IP6_LOOKUP, "ip6-lookup") \ +_(HANDOFF, "handoff") \ _(INTERFACE_OUTPUT, "interface-output") #define _(v, s) ESP_ENCRYPT_NEXT_##v, @@ -114,7 +113,11 @@ esp_add_footer_and_icv (vlib_buffer_t * b, u8 block_size, u8 icv_sz, } if (pad_bytes) - clib_memcpy_fast ((u8 *) f - pad_bytes, pad_data, pad_bytes); + { + ASSERT (pad_bytes <= ESP_MAX_BLOCK_SIZE); + pad_bytes = clib_min (ESP_MAX_BLOCK_SIZE, pad_bytes); + clib_memcpy_fast ((u8 *) f - pad_bytes, pad_data, pad_bytes); + } f->pad_length = pad_bytes; b->current_length = new_length + icv_sz; @@ -261,7 +264,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, esp_header_t *esp; u8 *payload, *next_hdr_ptr; u16 payload_len; - u32 hdr_len; + u32 hdr_len, config_index; if (n_left > 2) { @@ -277,9 +280,11 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, { /* we are on a ipsec tunnel's feature arc */ u32 next0; + config_index = b[0]->current_config_index; sa_index0 = *(u32 *) vnet_feature_next_with_data (&next0, b[0], sizeof (sa_index0)); + vnet_buffer (b[0])->ipsec.sad_index = sa_index0; next[0] = next0; } else @@ -302,6 +307,25 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, iv_sz = sa0->crypto_iv_size; } + if (PREDICT_FALSE (~0 == sa0->encrypt_thread_index)) + { + /* this is the first packet to use this SA, claim the SA + * for this thread. this could happen simultaneously on + * another thread */ + clib_atomic_cmp_and_swap (&sa0->encrypt_thread_index, ~0, + ipsec_sa_assign_thread (thread_index)); + } + + if (PREDICT_TRUE (thread_index != sa0->encrypt_thread_index)) + { + next[0] = ESP_ENCRYPT_NEXT_HANDOFF; + if (is_tun) + { + b[0]->current_config_index = config_index; + } + goto trace; + } + if (vlib_buffer_chain_linearize (vm, b[0]) != 1) { b[0]->error = node->errors[ESP_ENCRYPT_ERROR_CHAINED_BUFFER]; @@ -565,9 +589,9 @@ VLIB_REGISTER_NODE (esp4_encrypt_node) = { .n_next_nodes = ESP_ENCRYPT_N_NEXT, .next_nodes = { -#define _(s,n) [ESP_ENCRYPT_NEXT_##s] = n, - foreach_esp_encrypt_next -#undef _ + [ESP_ENCRYPT_NEXT_DROP] = "ip4-drop", + [ESP_ENCRYPT_NEXT_HANDOFF] = "esp4-encrypt-handoff", + [ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT] = "interface-output", }, }; /* *INDENT-ON* */ @@ -591,9 +615,9 @@ VLIB_REGISTER_NODE (esp6_encrypt_node) = { .n_next_nodes = ESP_ENCRYPT_N_NEXT, .next_nodes = { -#define _(s,n) [ESP_ENCRYPT_NEXT_##s] = n, - foreach_esp_encrypt_next -#undef _ + [ESP_ENCRYPT_NEXT_DROP] = "ip6-drop", + [ESP_ENCRYPT_NEXT_HANDOFF] = "esp6-encrypt-handoff", + [ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT] = "interface-output", }, }; /* *INDENT-ON* */ @@ -615,9 +639,11 @@ VLIB_REGISTER_NODE (esp4_encrypt_tun_node) = { .n_errors = ARRAY_LEN(esp_encrypt_error_strings), .error_strings = esp_encrypt_error_strings, - .n_next_nodes = 1, + .n_next_nodes = ESP_ENCRYPT_N_NEXT, .next_nodes = { [ESP_ENCRYPT_NEXT_DROP] = "ip4-drop", + [ESP_ENCRYPT_NEXT_HANDOFF] = "esp4-encrypt-handoff", + [ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT] = "error-drop", }, }; @@ -660,9 +686,11 @@ VLIB_REGISTER_NODE (esp6_encrypt_tun_node) = { .n_errors = ARRAY_LEN(esp_encrypt_error_strings), .error_strings = esp_encrypt_error_strings, - .n_next_nodes = 1, + .n_next_nodes = ESP_ENCRYPT_N_NEXT, .next_nodes = { [ESP_ENCRYPT_NEXT_DROP] = "ip6-drop", + [ESP_ENCRYPT_NEXT_HANDOFF] = "esp6-encrypt-handoff", + [ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT] = "error-drop", }, };