diff options
author | Neale Ranns <nranns@cisco.com> | 2020-05-12 13:33:56 +0000 |
---|---|---|
committer | Andrew Yourtchenko <ayourtch@gmail.com> | 2020-05-13 11:15:57 +0000 |
commit | b1fd80f0999e4dbbebdbc2471aeab2cad418ca4d (patch) | |
tree | 9d717e9982e829bfe6a0322be78df41edc5223e1 /src/vnet | |
parent | 103d355db504527cc6fa1d563ce6976b8490d22c (diff) |
ipsec: Support 4o6 and 6o4 for SPD tunnel mode SAs
Type: feature
the es4-encrypt and esp6-encrypt nodes need to be siblings so they both have the same edges for the DPO on which the tunnel mode SA stacks.
Signed-off-by: Neale Ranns <nranns@cisco.com>
Change-Id: I2126589135a1df6c95ee14503dfde9ff406df60a
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/ipsec/esp_encrypt.c | 76 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_cli.c | 27 |
2 files changed, 65 insertions, 38 deletions
diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c index 15f590acbdb..e9feb8b40a1 100644 --- a/src/vnet/ipsec/esp_encrypt.c +++ b/src/vnet/ipsec/esp_encrypt.c @@ -27,9 +27,11 @@ #include <vnet/ipsec/esp.h> #define foreach_esp_encrypt_next \ -_(DROP, "error-drop") \ +_(DROP4, "ip4-drop") \ +_(DROP6, "ip6-drop") \ _(PENDING, "pending") \ -_(HANDOFF, "handoff") \ +_(HANDOFF4, "handoff4") \ +_(HANDOFF6, "handoff6") \ _(INTERFACE_OUTPUT, "interface-output") #define _(v, s) ESP_ENCRYPT_NEXT_##v, @@ -235,7 +237,8 @@ esp_get_ip6_hdr_len (ip6_header_t * ip6, ip6_ext_header_t ** ext_hdr) static_always_inline void esp_process_chained_ops (vlib_main_t * vm, vlib_node_runtime_t * node, vnet_crypto_op_t * ops, vlib_buffer_t * b[], - u16 * nexts, vnet_crypto_op_chunk_t * chunks) + u16 * nexts, vnet_crypto_op_chunk_t * chunks, + u16 drop_next) { u32 n_fail, n_ops = vec_len (ops); vnet_crypto_op_t *op = ops; @@ -253,7 +256,7 @@ esp_process_chained_ops (vlib_main_t * vm, vlib_node_runtime_t * node, { u32 bi = op->user_data; b[bi]->error = node->errors[ESP_ENCRYPT_ERROR_CRYPTO_ENGINE_ERROR]; - nexts[bi] = ESP_ENCRYPT_NEXT_DROP; + nexts[bi] = drop_next; n_fail--; } op++; @@ -262,7 +265,8 @@ esp_process_chained_ops (vlib_main_t * vm, vlib_node_runtime_t * node, static_always_inline void esp_process_ops (vlib_main_t * vm, vlib_node_runtime_t * node, - vnet_crypto_op_t * ops, vlib_buffer_t * b[], u16 * nexts) + vnet_crypto_op_t * ops, vlib_buffer_t * b[], u16 * nexts, + u16 drop_next) { u32 n_fail, n_ops = vec_len (ops); vnet_crypto_op_t *op = ops; @@ -280,7 +284,7 @@ esp_process_ops (vlib_main_t * vm, vlib_node_runtime_t * node, { u32 bi = op->user_data; b[bi]->error = node->errors[ESP_ENCRYPT_ERROR_CRYPTO_ENGINE_ERROR]; - nexts[bi] = ESP_ENCRYPT_NEXT_DROP; + nexts[bi] = drop_next; n_fail--; } op++; @@ -555,13 +559,14 @@ out: /* when submitting a frame is failed, drop all buffers in the frame */ static_always_inline void esp_async_recycle_failed_submit (vnet_crypto_async_frame_t * f, - vlib_buffer_t ** b, u16 * next) + vlib_buffer_t ** b, u16 * next, + u16 drop_next) { u32 n_drop = f->n_elts; while (--n_drop) { (b - n_drop)[0]->error = ESP_ENCRYPT_ERROR_CRYPTO_ENGINE_ERROR; - (next - n_drop)[0] = ESP_ENCRYPT_NEXT_DROP; + (next - n_drop)[0] = drop_next; } vnet_crypto_async_reset_frame (f); } @@ -590,6 +595,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vnet_crypto_async_frame_t *async_frame = 0; int is_async = im->async_mode; vnet_crypto_async_op_id_t last_async_op = ~0; + u16 drop_next = (is_ip6 ? ESP_ENCRYPT_NEXT_DROP6 : ESP_ENCRYPT_NEXT_DROP4); vlib_get_buffers (vm, from, b, n_left); if (!is_async) @@ -653,7 +659,8 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, { if (vnet_crypto_async_submit_open_frame (vm, async_frame) < 0) - esp_async_recycle_failed_submit (async_frame, b, next); + esp_async_recycle_failed_submit (async_frame, b, + next, drop_next); } async_frame = vnet_crypto_async_get_frame (vm, sa0->crypto_async_enc_op_id); @@ -672,7 +679,8 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, if (PREDICT_TRUE (thread_index != sa0->encrypt_thread_index)) { - next[0] = ESP_ENCRYPT_NEXT_HANDOFF; + next[0] = (is_ip6 ? + ESP_ENCRYPT_NEXT_HANDOFF6 : ESP_ENCRYPT_NEXT_HANDOFF4); goto trace; } @@ -681,7 +689,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, if (n_bufs == 0) { b[0]->error = node->errors[ESP_ENCRYPT_ERROR_NO_BUFFERS]; - next[0] = ESP_ENCRYPT_NEXT_DROP; + next[0] = drop_next; goto trace; } @@ -703,7 +711,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, if (PREDICT_FALSE (esp_seq_advance (sa0))) { b[0]->error = node->errors[ESP_ENCRYPT_ERROR_SEQ_CYCLED]; - next[0] = ESP_ENCRYPT_NEXT_DROP; + next[0] = drop_next; goto trace; } @@ -721,7 +729,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, if (!next_hdr_ptr) { b[0]->error = node->errors[ESP_ENCRYPT_ERROR_NO_BUFFERS]; - next[0] = ESP_ENCRYPT_NEXT_DROP; + next[0] = drop_next; goto trace; } b[0]->flags &= ~VLIB_BUFFER_TOTAL_LENGTH_VALID; @@ -884,7 +892,8 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, icv_sz, from[b - bufs], next, hdr_len, async_next, lb)) { - esp_async_recycle_failed_submit (async_frame, b, next); + esp_async_recycle_failed_submit (async_frame, b, next, + drop_next); goto trace; } } @@ -924,18 +933,18 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, current_sa_bytes); if (!is_async) { - esp_process_ops (vm, node, ptd->crypto_ops, bufs, nexts); + esp_process_ops (vm, node, ptd->crypto_ops, bufs, nexts, drop_next); esp_process_chained_ops (vm, node, ptd->chained_crypto_ops, bufs, nexts, - ptd->chunks); + ptd->chunks, drop_next); - esp_process_ops (vm, node, ptd->integ_ops, bufs, nexts); + esp_process_ops (vm, node, ptd->integ_ops, bufs, nexts, drop_next); esp_process_chained_ops (vm, node, ptd->chained_integ_ops, bufs, nexts, - ptd->chunks); + ptd->chunks, drop_next); } else if (async_frame && async_frame->n_elts) { if (vnet_crypto_async_submit_open_frame (vm, async_frame) < 0) - esp_async_recycle_failed_submit (async_frame, b, next); + esp_async_recycle_failed_submit (async_frame, b, next, drop_next); } vlib_node_increment_counter (vm, node->node_index, @@ -1051,8 +1060,10 @@ VLIB_REGISTER_NODE (esp4_encrypt_node) = { .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_DROP4] = "ip4-drop", + [ESP_ENCRYPT_NEXT_DROP6] = "ip6-drop", + [ESP_ENCRYPT_NEXT_HANDOFF4] = "esp4-encrypt-handoff", + [ESP_ENCRYPT_NEXT_HANDOFF6] = "esp6-encrypt-handoff", [ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT] = "interface-output", [ESP_ENCRYPT_NEXT_PENDING] = "esp-encrypt-pending", }, @@ -1093,17 +1104,10 @@ VLIB_REGISTER_NODE (esp6_encrypt_node) = { .vector_size = sizeof (u32), .format_trace = format_esp_encrypt_trace, .type = VLIB_NODE_TYPE_INTERNAL, + .sibling_of = "esp4-encrypt", .n_errors = ARRAY_LEN(esp_encrypt_error_strings), .error_strings = esp_encrypt_error_strings, - - .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] = "interface-output", - [ESP_ENCRYPT_NEXT_PENDING] = "esp-encrypt-pending", - }, }; /* *INDENT-ON* */ @@ -1120,7 +1124,7 @@ VLIB_REGISTER_NODE (esp6_encrypt_post_node) = { .vector_size = sizeof (u32), .format_trace = format_esp_post_encrypt_trace, .type = VLIB_NODE_TYPE_INTERNAL, - .sibling_of = "esp6-encrypt", + .sibling_of = "esp4-encrypt", .n_errors = ARRAY_LEN(esp_encrypt_error_strings), .error_strings = esp_encrypt_error_strings, @@ -1147,8 +1151,10 @@ VLIB_REGISTER_NODE (esp4_encrypt_tun_node) = { .n_next_nodes = ESP_ENCRYPT_N_NEXT, .next_nodes = { - [ESP_ENCRYPT_NEXT_DROP] = "ip4-drop", - [ESP_ENCRYPT_NEXT_HANDOFF] = "esp4-encrypt-tun-handoff", + [ESP_ENCRYPT_NEXT_DROP4] = "ip4-drop", + [ESP_ENCRYPT_NEXT_DROP6] = "ip6-drop", + [ESP_ENCRYPT_NEXT_HANDOFF4] = "esp4-encrypt-tun-handoff", + [ESP_ENCRYPT_NEXT_HANDOFF6] = "error-drop", [ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT] = "adj-midchain-tx", [ESP_ENCRYPT_NEXT_PENDING] = "esp-encrypt-pending", }, @@ -1194,8 +1200,10 @@ VLIB_REGISTER_NODE (esp6_encrypt_tun_node) = { .n_next_nodes = ESP_ENCRYPT_N_NEXT, .next_nodes = { - [ESP_ENCRYPT_NEXT_DROP] = "ip6-drop", - [ESP_ENCRYPT_NEXT_HANDOFF] = "esp6-encrypt-tun-handoff", + [ESP_ENCRYPT_NEXT_DROP4] = "ip4-drop", + [ESP_ENCRYPT_NEXT_DROP6] = "ip6-drop", + [ESP_ENCRYPT_NEXT_HANDOFF4] = "error-drop", + [ESP_ENCRYPT_NEXT_HANDOFF6] = "esp6-encrypt-tun-handoff", [ESP_ENCRYPT_NEXT_PENDING] = "esp-encrypt-pending", [ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT] = "adj-midchain-tx", }, diff --git a/src/vnet/ipsec/ipsec_cli.c b/src/vnet/ipsec/ipsec_cli.c index 695e5f01c74..4d452d53d22 100644 --- a/src/vnet/ipsec/ipsec_cli.c +++ b/src/vnet/ipsec/ipsec_cli.c @@ -234,13 +234,13 @@ ipsec_policy_add_del_command_fn (vlib_main_t * vm, unformat_input_t _line_input, *line_input = &_line_input; ipsec_policy_t p; int rv, is_add = 0; - u32 tmp, tmp2, stat_index; + u32 tmp, tmp2, stat_index, local_range_set, remote_range_set; clib_error_t *error = NULL; u32 is_outbound; clib_memset (&p, 0, sizeof (p)); p.lport.stop = p.rport.stop = ~0; - is_outbound = 0; + remote_range_set = local_range_set = is_outbound = 0; if (!unformat_user (input, unformat_line_input, line_input)) return 0; @@ -251,6 +251,8 @@ ipsec_policy_add_del_command_fn (vlib_main_t * vm, is_add = 1; else if (unformat (line_input, "del")) is_add = 0; + else if (unformat (line_input, "ip6")) + p.is_ipv6 = 1; else if (unformat (line_input, "spd %u", &p.id)) ; else if (unformat (line_input, "inbound")) @@ -277,22 +279,24 @@ ipsec_policy_add_del_command_fn (vlib_main_t * vm, else if (unformat (line_input, "local-ip-range %U - %U", unformat_ip4_address, &p.laddr.start.ip4, unformat_ip4_address, &p.laddr.stop.ip4)) - ; + local_range_set = 1; else if (unformat (line_input, "remote-ip-range %U - %U", unformat_ip4_address, &p.raddr.start.ip4, unformat_ip4_address, &p.raddr.stop.ip4)) - ; + remote_range_set = 1; else if (unformat (line_input, "local-ip-range %U - %U", unformat_ip6_address, &p.laddr.start.ip6, unformat_ip6_address, &p.laddr.stop.ip6)) { p.is_ipv6 = 1; + local_range_set = 1; } else if (unformat (line_input, "remote-ip-range %U - %U", unformat_ip6_address, &p.raddr.start.ip6, unformat_ip6_address, &p.raddr.stop.ip6)) { p.is_ipv6 = 1; + remote_range_set = 1; } else if (unformat (line_input, "local-port-range %u - %u", &tmp, &tmp2)) { @@ -313,6 +317,21 @@ ipsec_policy_add_del_command_fn (vlib_main_t * vm, } } + if (!remote_range_set) + { + if (p.is_ipv6) + clib_memset (&p.raddr.stop.ip6, 0xff, 16); + else + clib_memset (&p.raddr.stop.ip4, 0xff, 4); + } + if (!local_range_set) + { + if (p.is_ipv6) + clib_memset (&p.laddr.stop.ip6, 0xff, 16); + else + clib_memset (&p.laddr.stop.ip4, 0xff, 4); + } + rv = ipsec_policy_mk_type (is_outbound, p.is_ipv6, p.policy, &p.type); if (rv) |