From be5a5dd904d4d25857c53a4b5dee7951f724e3e2 Mon Sep 17 00:00:00 2001 From: Klement Sekera Date: Tue, 9 Oct 2018 16:05:48 +0200 Subject: ipsec: split ipsec nodes into ip4/ip6 nodes Change-Id: Ic6b27659f1fe9e8df39e80a0441305e4e952195a Signed-off-by: Klement Sekera --- src/vnet/ipsec/ah_decrypt.c | 189 ++++++++++++++++++++++++------------------ src/vnet/ipsec/ah_encrypt.c | 119 +++++++++++++++++--------- src/vnet/ipsec/esp_decrypt.c | 148 ++++++++++++++++++++++----------- src/vnet/ipsec/esp_encrypt.c | 95 +++++++++++++++------ src/vnet/ipsec/ipsec.c | 53 ++++++++---- src/vnet/ipsec/ipsec.h | 58 ++++++++----- src/vnet/ipsec/ipsec_if.c | 8 +- src/vnet/ipsec/ipsec_if_in.c | 4 +- src/vnet/ipsec/ipsec_input.c | 71 ++++++++-------- src/vnet/ipsec/ipsec_output.c | 68 +++++++-------- 10 files changed, 502 insertions(+), 311 deletions(-) (limited to 'src/vnet/ipsec') diff --git a/src/vnet/ipsec/ah_decrypt.c b/src/vnet/ipsec/ah_decrypt.c index abe2e6f5f80..e3e0071a40f 100644 --- a/src/vnet/ipsec/ah_decrypt.c +++ b/src/vnet/ipsec/ah_decrypt.c @@ -23,11 +23,11 @@ #include #include -#define foreach_ah_decrypt_next \ -_(DROP, "error-drop") \ -_(IP4_INPUT, "ip4-input") \ -_(IP6_INPUT, "ip6-input") \ -_(IPSEC_GRE_INPUT, "ipsec-gre-input") +#define foreach_ah_decrypt_next \ + _ (DROP, "error-drop") \ + _ (IP4_INPUT, "ip4-input") \ + _ (IP6_INPUT, "ip6-input") \ + _ (IPSEC_GRE_INPUT, "ipsec-gre-input") #define _(v, s) AH_DECRYPT_NEXT_##v, typedef enum @@ -37,14 +37,11 @@ typedef enum AH_DECRYPT_N_NEXT, } ah_decrypt_next_t; - -#define foreach_ah_decrypt_error \ - _(RX_PKTS, "AH pkts received") \ - _(DECRYPTION_FAILED, "AH decryption failed") \ - _(INTEG_ERROR, "Integrity check failed") \ - _(REPLAY, "SA replayed packet") \ - _(NOT_IP, "Not IP packet (dropped)") - +#define foreach_ah_decrypt_error \ + _ (RX_PKTS, "AH pkts received") \ + _ (DECRYPTION_FAILED, "AH decryption failed") \ + _ (INTEG_ERROR, "Integrity check failed") \ + _ (REPLAY, "SA replayed packet") typedef enum { @@ -77,9 +74,10 @@ format_ah_decrypt_trace (u8 * s, va_list * args) return s; } -static uword -ah_decrypt_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * from_frame) +always_inline uword +ah_decrypt_inline (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame, + int is_ip6) { u32 n_left_from, *from, next_index, *to_next; ipsec_main_t *im = &ipsec_main; @@ -107,8 +105,6 @@ ah_decrypt_node_fn (vlib_main_t * vm, u32 seq; ip4_header_t *ih4 = 0, *oh4 = 0; ip6_header_t *ih6 = 0, *oh6 = 0; - u8 tunnel_mode = 1; - u8 transport_ip6 = 0; u8 ip_hdr_size = 0; u8 tos = 0; u8 ttl = 0; @@ -133,12 +129,7 @@ ah_decrypt_node_fn (vlib_main_t * vm, sa_index0 = vnet_buffer (i_b0)->ipsec.sad_index; sa0 = pool_elt_at_index (im->sad, sa_index0); - if ((ih4->ip_version_and_header_length & 0xF0) == 0x40) - { - ip_hdr_size = ip4_header_bytes (ih4); - ah0 = (ah_header_t *) ((u8 *) ih4 + ip_hdr_size); - } - else if ((ih4->ip_version_and_header_length & 0xF0) == 0x60) + if (is_ip6) { ip6_ext_header_t *prev = NULL; ip6_ext_header_find_t (ih6, prev, ah0, IP_PROTOCOL_IPSEC_AH); @@ -147,9 +138,8 @@ ah_decrypt_node_fn (vlib_main_t * vm, } else { - vlib_node_increment_counter (vm, ah_decrypt_node.index, - AH_DECRYPT_ERROR_NOT_IP, 1); - goto trace; + ip_hdr_size = ip4_header_bytes (ih4); + ah0 = (ah_header_t *) ((u8 *) ih4 + ip_hdr_size); } seq = clib_host_to_net_u32 (ah0->seq_no); @@ -167,8 +157,14 @@ ah_decrypt_node_fn (vlib_main_t * vm, if (PREDICT_FALSE (rv)) { clib_warning ("anti-replay SPI %u seq %u", sa0->spi, seq); - vlib_node_increment_counter (vm, ah_decrypt_node.index, - AH_DECRYPT_ERROR_REPLAY, 1); + if (is_ip6) + vlib_node_increment_counter (vm, + ah6_decrypt_node.index, + AH_DECRYPT_ERROR_REPLAY, 1); + else + vlib_node_increment_counter (vm, + ah6_decrypt_node.index, + AH_DECRYPT_ERROR_REPLAY, 1); to_next[0] = i_bi0; to_next += 1; goto trace; @@ -189,18 +185,7 @@ ah_decrypt_node_fn (vlib_main_t * vm, memcpy (digest, icv, icv_size); memset (icv, 0, icv_size); - if ((ih4->ip_version_and_header_length & 0xF0) == 0x40) - { - tos = ih4->tos; - ttl = ih4->ttl; - ih4->tos = 0; - ih4->ttl = 0; - ih4->checksum = 0; - ih4->flags_and_fragment_offset = 0; - icv_padding_len = - ah_calc_icv_padding_len (icv_size, 0 /* is_ipv6 */ ); - } - else + if (is_ip6) { ip_version_traffic_class_and_flow_label = ih6->ip_version_traffic_class_and_flow_label; @@ -211,15 +196,33 @@ ah_decrypt_node_fn (vlib_main_t * vm, icv_padding_len = ah_calc_icv_padding_len (icv_size, 1 /* is_ipv6 */ ); } + else + { + tos = ih4->tos; + ttl = ih4->ttl; + ih4->tos = 0; + ih4->ttl = 0; + ih4->checksum = 0; + ih4->flags_and_fragment_offset = 0; + icv_padding_len = + ah_calc_icv_padding_len (icv_size, 0 /* is_ipv6 */ ); + } hmac_calc (sa0->integ_alg, sa0->integ_key, sa0->integ_key_len, (u8 *) ih4, i_b0->current_length, sig, sa0->use_esn, sa0->seq_hi); if (PREDICT_FALSE (memcmp (digest, sig, icv_size))) { - vlib_node_increment_counter (vm, ah_decrypt_node.index, - AH_DECRYPT_ERROR_INTEG_ERROR, - 1); + if (is_ip6) + vlib_node_increment_counter (vm, + ah6_decrypt_node.index, + AH_DECRYPT_ERROR_INTEG_ERROR, + 1); + else + vlib_node_increment_counter (vm, + ah4_decrypt_node.index, + AH_DECRYPT_ERROR_INTEG_ERROR, + 1); to_next[0] = i_bi0; to_next += 1; goto trace; @@ -241,30 +244,8 @@ ah_decrypt_node_fn (vlib_main_t * vm, icv_padding_len); i_b0->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID; - /* transport mode */ - if (PREDICT_FALSE (!sa0->is_tunnel && !sa0->is_tunnel_ip6)) - { - tunnel_mode = 0; - - if (PREDICT_TRUE - ((ih4->ip_version_and_header_length & 0xF0) != 0x40)) - { - if (PREDICT_TRUE - ((ih4->ip_version_and_header_length & 0xF0) == 0x60)) - transport_ip6 = 1; - else - { - clib_warning ("next header: 0x%x", ah0->nexthdr); - vlib_node_increment_counter (vm, ah_decrypt_node.index, - AH_DECRYPT_ERROR_NOT_IP, - 1); - goto trace; - } - } - } - - if (PREDICT_TRUE (tunnel_mode)) - { + if (PREDICT_TRUE (sa0->is_tunnel)) + { /* tunnel mode */ if (PREDICT_TRUE (ah0->nexthdr == IP_PROTOCOL_IP_IN_IP)) next0 = AH_DECRYPT_NEXT_IP4_INPUT; else if (ah0->nexthdr == IP_PROTOCOL_IPV6) @@ -272,16 +253,22 @@ ah_decrypt_node_fn (vlib_main_t * vm, else { clib_warning ("next header: 0x%x", ah0->nexthdr); - vlib_node_increment_counter (vm, ah_decrypt_node.index, - AH_DECRYPT_ERROR_DECRYPTION_FAILED, - 1); + if (is_ip6) + vlib_node_increment_counter (vm, + ah6_decrypt_node.index, + AH_DECRYPT_ERROR_DECRYPTION_FAILED, + 1); + else + vlib_node_increment_counter (vm, + ah4_decrypt_node.index, + AH_DECRYPT_ERROR_DECRYPTION_FAILED, + 1); goto trace; } } - /* transport mode */ else - { - if (PREDICT_FALSE (transport_ip6)) + { /* transport mode */ + if (is_ip6) { vlib_buffer_advance (i_b0, -sizeof (ip6_header_t)); oh6 = vlib_buffer_get_current (i_b0); @@ -337,18 +324,58 @@ ah_decrypt_node_fn (vlib_main_t * vm, } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } - vlib_node_increment_counter (vm, ah_decrypt_node.index, - AH_DECRYPT_ERROR_RX_PKTS, - from_frame->n_vectors); + if (is_ip6) + vlib_node_increment_counter (vm, ah6_decrypt_node.index, + AH_DECRYPT_ERROR_RX_PKTS, + from_frame->n_vectors); + else + vlib_node_increment_counter (vm, ah4_decrypt_node.index, + AH_DECRYPT_ERROR_RX_PKTS, + from_frame->n_vectors); return from_frame->n_vectors; } +static uword +ah4_decrypt_node_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return ah_decrypt_inline (vm, node, from_frame, 0 /* is_ip6 */ ); +} + +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (ah4_decrypt_node) = { + .function = ah4_decrypt_node_fn, + .name = "ah4-decrypt", + .vector_size = sizeof (u32), + .format_trace = format_ah_decrypt_trace, + .type = VLIB_NODE_TYPE_INTERNAL, + + .n_errors = ARRAY_LEN(ah_decrypt_error_strings), + .error_strings = ah_decrypt_error_strings, + + .n_next_nodes = AH_DECRYPT_N_NEXT, + .next_nodes = { +#define _(s,n) [AH_DECRYPT_NEXT_##s] = n, + foreach_ah_decrypt_next +#undef _ + }, +}; +/* *INDENT-ON* */ + +VLIB_NODE_FUNCTION_MULTIARCH (ah4_decrypt_node, ah4_decrypt_node_fn); + +static uword +ah6_decrypt_node_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return ah_decrypt_inline (vm, node, from_frame, 1 /* is_ip6 */ ); +} /* *INDENT-OFF* */ -VLIB_REGISTER_NODE (ah_decrypt_node) = { - .function = ah_decrypt_node_fn, - .name = "ah-decrypt", +VLIB_REGISTER_NODE (ah6_decrypt_node) = { + .function = ah6_decrypt_node_fn, + .name = "ah6-decrypt", .vector_size = sizeof (u32), .format_trace = format_ah_decrypt_trace, .type = VLIB_NODE_TYPE_INTERNAL, @@ -365,7 +392,7 @@ VLIB_REGISTER_NODE (ah_decrypt_node) = { }; /* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (ah_decrypt_node, ah_decrypt_node_fn) +VLIB_NODE_FUNCTION_MULTIARCH (ah6_decrypt_node, ah6_decrypt_node_fn); /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/ipsec/ah_encrypt.c b/src/vnet/ipsec/ah_encrypt.c index 911dd333882..856eab62c91 100644 --- a/src/vnet/ipsec/ah_encrypt.c +++ b/src/vnet/ipsec/ah_encrypt.c @@ -23,11 +23,12 @@ #include #include -#define foreach_ah_encrypt_next \ -_(DROP, "error-drop") \ -_(IP4_LOOKUP, "ip4-lookup") \ -_(IP6_LOOKUP, "ip6-lookup") \ -_(INTERFACE_OUTPUT, "interface-output") +#define foreach_ah_encrypt_next \ + _ (DROP, "error-drop") \ + _ (IP4_LOOKUP, "ip4-lookup") \ + _ (IP6_LOOKUP, "ip6-lookup") \ + _ (INTERFACE_OUTPUT, "interface-output") + #define _(v, s) AH_ENCRYPT_NEXT_##v, typedef enum @@ -56,8 +57,6 @@ static char *ah_encrypt_error_strings[] = { #undef _ }; -vlib_node_registration_t ah_encrypt_node; - typedef struct { u32 spi; @@ -78,9 +77,10 @@ format_ah_encrypt_trace (u8 * s, va_list * args) return s; } -static uword -ah_encrypt_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * from_frame) +always_inline uword +ah_encrypt_inline (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame, + int is_ip6) { u32 n_left_from, *from, *to_next = 0, next_index; int icv_size = 0; @@ -104,10 +104,8 @@ ah_encrypt_node_fn (vlib_main_t * vm, ipsec_sa_t *sa0; ip4_and_ah_header_t *ih0, *oh0 = 0; ip6_and_ah_header_t *ih6_0, *oh6_0 = 0; - u8 is_ipv6; u8 ip_hdr_size; u8 next_hdr_type; - u8 transport_mode = 0; u8 tos = 0; u8 ttl = 0; u8 hop_limit = 0; @@ -129,8 +127,12 @@ ah_encrypt_node_fn (vlib_main_t * vm, { clib_warning ("sequence number counter has cycled SPI %u", sa0->spi); - vlib_node_increment_counter (vm, ah_encrypt_node.index, - AH_ENCRYPT_ERROR_SEQ_CYCLED, 1); + if (is_ip6) + vlib_node_increment_counter (vm, ah6_encrypt_node.index, + AH_ENCRYPT_ERROR_SEQ_CYCLED, 1); + else + vlib_node_increment_counter (vm, ah4_encrypt_node.index, + AH_ENCRYPT_ERROR_SEQ_CYCLED, 1); //TODO need to confirm if below is needed to_next[0] = i_bi0; to_next += 1; @@ -145,14 +147,12 @@ ah_encrypt_node_fn (vlib_main_t * vm, ttl = ih0->ip4.ttl; tos = ih0->ip4.tos; - is_ipv6 = (ih0->ip4.ip_version_and_header_length & 0xF0) == 0x60; - /* is ipv6 */ if (PREDICT_TRUE (sa0->is_tunnel)) { - if (PREDICT_TRUE (!is_ipv6)) - adv = -sizeof (ip4_and_ah_header_t); - else + if (is_ip6) adv = -sizeof (ip6_and_ah_header_t); + else + adv = -sizeof (ip4_and_ah_header_t); } else { @@ -161,9 +161,9 @@ ah_encrypt_node_fn (vlib_main_t * vm, icv_size = em->ipsec_proto_main_integ_algs[sa0->integ_alg].trunc_size; - const u8 padding_len = ah_calc_icv_padding_len (icv_size, is_ipv6); + const u8 padding_len = ah_calc_icv_padding_len (icv_size, is_ip6); adv -= padding_len; - /*transport mode save the eth header before it is overwritten */ + /* transport mode save the eth header before it is overwritten */ if (PREDICT_FALSE (!sa0->is_tunnel)) { ethernet_header_t *ieh0 = (ethernet_header_t *) @@ -176,8 +176,8 @@ ah_encrypt_node_fn (vlib_main_t * vm, vlib_buffer_advance (i_b0, adv - icv_size); - if (PREDICT_FALSE (is_ipv6)) - { /* is ipv6 */ + if (is_ip6) + { ih6_0 = (ip6_and_ah_header_t *) ih0; ip_hdr_size = sizeof (ip6_header_t); oh6_0 = vlib_buffer_get_current (i_b0); @@ -241,8 +241,7 @@ ah_encrypt_node_fn (vlib_main_t * vm, } - if (PREDICT_TRUE - (!is_ipv6 && sa0->is_tunnel && !sa0->is_tunnel_ip6)) + if (PREDICT_TRUE (!is_ip6 && sa0->is_tunnel && !sa0->is_tunnel_ip6)) { oh0->ip4.src_address.as_u32 = sa0->tunnel_src_addr.ip4.as_u32; oh0->ip4.dst_address.as_u32 = sa0->tunnel_dst_addr.ip4.as_u32; @@ -250,7 +249,7 @@ ah_encrypt_node_fn (vlib_main_t * vm, next0 = AH_ENCRYPT_NEXT_IP4_LOOKUP; vnet_buffer (i_b0)->sw_if_index[VLIB_TX] = (u32) ~ 0; } - else if (is_ipv6 && sa0->is_tunnel && sa0->is_tunnel_ip6) + else if (is_ip6 && sa0->is_tunnel && sa0->is_tunnel_ip6) { oh6_0->ip6.src_address.as_u64[0] = sa0->tunnel_src_addr.ip6.as_u64[0]; @@ -264,11 +263,6 @@ ah_encrypt_node_fn (vlib_main_t * vm, next0 = AH_ENCRYPT_NEXT_IP6_LOOKUP; vnet_buffer (i_b0)->sw_if_index[VLIB_TX] = (u32) ~ 0; } - else - { - transport_mode = 1; - next0 = AH_ENCRYPT_NEXT_INTERFACE_OUTPUT; - } u8 sig[64]; memset (sig, 0, sizeof (sig)); @@ -284,7 +278,7 @@ ah_encrypt_node_fn (vlib_main_t * vm, sa0->seq_hi); memcpy (digest, sig, size); - if (PREDICT_FALSE (is_ipv6)) + if (is_ip6) { oh6_0->ip6.hop_limit = hop_limit; oh6_0->ip6.ip_version_traffic_class_and_flow_label = @@ -297,8 +291,11 @@ ah_encrypt_node_fn (vlib_main_t * vm, oh0->ip4.checksum = ip4_header_checksum (&oh0->ip4); } - if (transport_mode) - vlib_buffer_advance (i_b0, -sizeof (ethernet_header_t)); + if (!sa0->is_tunnel) + { + next0 = AH_ENCRYPT_NEXT_INTERFACE_OUTPUT; + vlib_buffer_advance (i_b0, -sizeof (ethernet_header_t)); + } trace: if (PREDICT_FALSE (i_b0->flags & VLIB_BUFFER_IS_TRACED)) @@ -317,18 +314,58 @@ ah_encrypt_node_fn (vlib_main_t * vm, } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } - vlib_node_increment_counter (vm, ah_encrypt_node.index, - AH_ENCRYPT_ERROR_RX_PKTS, - from_frame->n_vectors); + if (is_ip6) + vlib_node_increment_counter (vm, ah6_encrypt_node.index, + AH_ENCRYPT_ERROR_RX_PKTS, + from_frame->n_vectors); + else + vlib_node_increment_counter (vm, ah4_encrypt_node.index, + AH_ENCRYPT_ERROR_RX_PKTS, + from_frame->n_vectors); return from_frame->n_vectors; } +static uword +ah4_encrypt_node_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return ah_encrypt_inline (vm, node, from_frame, 0 /* is_ip6 */ ); +} + +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (ah4_encrypt_node) = { + .function = ah4_encrypt_node_fn, + .name = "ah4-encrypt", + .vector_size = sizeof (u32), + .format_trace = format_ah_encrypt_trace, + .type = VLIB_NODE_TYPE_INTERNAL, + + .n_errors = ARRAY_LEN(ah_encrypt_error_strings), + .error_strings = ah_encrypt_error_strings, + + .n_next_nodes = AH_ENCRYPT_N_NEXT, + .next_nodes = { +#define _(s,n) [AH_ENCRYPT_NEXT_##s] = n, + foreach_ah_encrypt_next +#undef _ + }, +}; +/* *INDENT-ON* */ + +VLIB_NODE_FUNCTION_MULTIARCH (ah4_encrypt_node, ah4_encrypt_node_fn); + +static uword +ah6_encrypt_node_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return ah_encrypt_inline (vm, node, from_frame, 1 /* is_ip6 */ ); +} /* *INDENT-OFF* */ -VLIB_REGISTER_NODE (ah_encrypt_node) = { - .function = ah_encrypt_node_fn, - .name = "ah-encrypt", +VLIB_REGISTER_NODE (ah6_encrypt_node) = { + .function = ah6_encrypt_node_fn, + .name = "ah6-encrypt", .vector_size = sizeof (u32), .format_trace = format_ah_encrypt_trace, .type = VLIB_NODE_TYPE_INTERNAL, @@ -345,7 +382,7 @@ VLIB_REGISTER_NODE (ah_encrypt_node) = { }; /* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (ah_encrypt_node, ah_encrypt_node_fn) +VLIB_NODE_FUNCTION_MULTIARCH (ah6_encrypt_node, ah6_encrypt_node_fn); /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/ipsec/esp_decrypt.c b/src/vnet/ipsec/esp_decrypt.c index a0eeed464da..bfddb9ece8d 100644 --- a/src/vnet/ipsec/esp_decrypt.c +++ b/src/vnet/ipsec/esp_decrypt.c @@ -112,9 +112,10 @@ esp_decrypt_cbc (ipsec_crypto_alg_t alg, EVP_DecryptFinal_ex (ctx, out + out_len, &out_len); } -static uword -esp_decrypt_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * from_frame) +always_inline uword +esp_decrypt_inline (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame, + int is_ip6) { u32 n_left_from, *from, next_index, *to_next; ipsec_main_t *im = &ipsec_main; @@ -130,8 +131,14 @@ esp_decrypt_node_fn (vlib_main_t * vm, if (PREDICT_FALSE (vec_len (empty_buffers) < n_left_from)) { - vlib_node_increment_counter (vm, esp_decrypt_node.index, - ESP_DECRYPT_ERROR_NO_BUFFER, n_left_from); + if (is_ip6) + vlib_node_increment_counter (vm, esp6_decrypt_node.index, + ESP_DECRYPT_ERROR_NO_BUFFER, + n_left_from); + else + vlib_node_increment_counter (vm, esp4_decrypt_node.index, + ESP_DECRYPT_ERROR_NO_BUFFER, + n_left_from); goto free_buffers_and_exit; } @@ -155,8 +162,6 @@ esp_decrypt_node_fn (vlib_main_t * vm, ip4_header_t *ih4 = 0, *oh4 = 0; ip6_header_t *ih6 = 0, *oh6 = 0; u8 tunnel_mode = 1; - u8 transport_ip6 = 0; - i_bi0 = from[0]; from += 1; @@ -186,8 +191,14 @@ esp_decrypt_node_fn (vlib_main_t * vm, if (PREDICT_FALSE (rv)) { clib_warning ("anti-replay SPI %u seq %u", sa0->spi, seq); - vlib_node_increment_counter (vm, esp_decrypt_node.index, - ESP_DECRYPT_ERROR_REPLAY, 1); + if (is_ip6) + vlib_node_increment_counter (vm, + esp6_decrypt_node.index, + ESP_DECRYPT_ERROR_REPLAY, 1); + else + vlib_node_increment_counter (vm, + esp4_decrypt_node.index, + ESP_DECRYPT_ERROR_REPLAY, 1); o_bi0 = i_bi0; to_next[0] = o_bi0; to_next += 1; @@ -214,9 +225,16 @@ esp_decrypt_node_fn (vlib_main_t * vm, if (PREDICT_FALSE (memcmp (icv, sig, icv_size))) { - vlib_node_increment_counter (vm, esp_decrypt_node.index, - ESP_DECRYPT_ERROR_INTEG_ERROR, - 1); + if (is_ip6) + vlib_node_increment_counter (vm, + esp6_decrypt_node.index, + ESP_DECRYPT_ERROR_INTEG_ERROR, + 1); + else + vlib_node_increment_counter (vm, + esp4_decrypt_node.index, + ESP_DECRYPT_ERROR_INTEG_ERROR, + 1); o_bi0 = i_bi0; to_next[0] = o_bi0; to_next += 1; @@ -269,37 +287,19 @@ esp_decrypt_node_fn (vlib_main_t * vm, { tunnel_mode = 0; - if (i_b0->flags & VNET_BUFFER_F_IS_IP4) - ih4 = - (ip4_header_t *) ((u8 *) esp0 - sizeof (ip4_header_t)); - else - ih4 = - (ip4_header_t *) ((u8 *) esp0 - sizeof (ip6_header_t)); - - if (PREDICT_TRUE - ((ih4->ip_version_and_header_length & 0xF0) != 0x40)) + if (is_ip6) { - if (PREDICT_TRUE - ((ih4->ip_version_and_header_length & 0xF0) == - 0x60)) - { - transport_ip6 = 1; - ip_hdr_size = sizeof (ip6_header_t); - ih6 = (ip6_header_t *) ih4; - oh6 = vlib_buffer_get_current (o_b0); - } - else - { - vlib_node_increment_counter (vm, - esp_decrypt_node.index, - ESP_DECRYPT_ERROR_NOT_IP, - 1); - o_b0 = 0; - goto trace; - } + ih6 = + (ip6_header_t *) ((u8 *) esp0 - + sizeof (ip6_header_t)); + ip_hdr_size = sizeof (ip6_header_t); + oh6 = vlib_buffer_get_current (o_b0); } else { + ih4 = + (ip4_header_t *) ((u8 *) esp0 - + sizeof (ip4_header_t)); oh4 = vlib_buffer_get_current (o_b0); ip_hdr_size = sizeof (ip4_header_t); } @@ -331,9 +331,16 @@ esp_decrypt_node_fn (vlib_main_t * vm, else { clib_warning ("next header: 0x%x", f0->next_header); - vlib_node_increment_counter (vm, esp_decrypt_node.index, - ESP_DECRYPT_ERROR_DECRYPTION_FAILED, - 1); + if (is_ip6) + vlib_node_increment_counter (vm, + esp6_decrypt_node.index, + ESP_DECRYPT_ERROR_DECRYPTION_FAILED, + 1); + else + vlib_node_increment_counter (vm, + esp4_decrypt_node.index, + ESP_DECRYPT_ERROR_DECRYPTION_FAILED, + 1); o_b0 = 0; goto trace; } @@ -341,7 +348,7 @@ esp_decrypt_node_fn (vlib_main_t * vm, /* transport mode */ else { - if (PREDICT_FALSE (transport_ip6)) + if (is_ip6) { next0 = ESP_DECRYPT_NEXT_IP6_INPUT; oh6->ip_version_traffic_class_and_flow_label = @@ -405,9 +412,15 @@ esp_decrypt_node_fn (vlib_main_t * vm, } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } - vlib_node_increment_counter (vm, esp_decrypt_node.index, - ESP_DECRYPT_ERROR_RX_PKTS, - from_frame->n_vectors); + if (is_ip6) + vlib_node_increment_counter (vm, esp6_decrypt_node.index, + ESP_DECRYPT_ERROR_RX_PKTS, + from_frame->n_vectors); + else + vlib_node_increment_counter (vm, esp4_decrypt_node.index, + ESP_DECRYPT_ERROR_RX_PKTS, + from_frame->n_vectors); + free_buffers_and_exit: if (recycle) @@ -416,11 +429,46 @@ free_buffers_and_exit: return from_frame->n_vectors; } +static uword +esp4_decrypt_node_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return esp_decrypt_inline (vm, node, from_frame, 0 /* is_ip6 */ ); +} + +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (esp4_decrypt_node) = { + .function = esp4_decrypt_node_fn, + .name = "esp4-decrypt", + .vector_size = sizeof (u32), + .format_trace = format_esp_decrypt_trace, + .type = VLIB_NODE_TYPE_INTERNAL, + + .n_errors = ARRAY_LEN(esp_decrypt_error_strings), + .error_strings = esp_decrypt_error_strings, + + .n_next_nodes = ESP_DECRYPT_N_NEXT, + .next_nodes = { +#define _(s,n) [ESP_DECRYPT_NEXT_##s] = n, + foreach_esp_decrypt_next +#undef _ + }, +}; +/* *INDENT-ON* */ + +VLIB_NODE_FUNCTION_MULTIARCH (esp4_decrypt_node, esp4_decrypt_node_fn); + +static uword +esp6_decrypt_node_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return esp_decrypt_inline (vm, node, from_frame, 1 /* is_ip6 */ ); +} /* *INDENT-OFF* */ -VLIB_REGISTER_NODE (esp_decrypt_node) = { - .function = esp_decrypt_node_fn, - .name = "esp-decrypt", +VLIB_REGISTER_NODE (esp6_decrypt_node) = { + .function = esp6_decrypt_node_fn, + .name = "esp6-decrypt", .vector_size = sizeof (u32), .format_trace = format_esp_decrypt_trace, .type = VLIB_NODE_TYPE_INTERNAL, @@ -437,7 +485,7 @@ VLIB_REGISTER_NODE (esp_decrypt_node) = { }; /* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (esp_decrypt_node, esp_decrypt_node_fn) +VLIB_NODE_FUNCTION_MULTIARCH (esp6_decrypt_node, esp6_decrypt_node_fn); /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c index 4291e946b36..9c775ef1e47 100644 --- a/src/vnet/ipsec/esp_encrypt.c +++ b/src/vnet/ipsec/esp_encrypt.c @@ -60,8 +60,6 @@ static char *esp_encrypt_error_strings[] = { #undef _ }; -vlib_node_registration_t esp_encrypt_node; - typedef struct { u32 spi; @@ -120,9 +118,10 @@ esp_encrypt_cbc (vlib_main_t * vm, ipsec_crypto_alg_t alg, EVP_EncryptFinal_ex (ctx, out + out_len, &out_len); } -static uword -esp_encrypt_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * from_frame) +always_inline uword +esp_encrypt_inline (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame, + int is_ip6) { u32 n_left_from, *from, *to_next = 0, next_index; from = vlib_frame_vector_args (from_frame); @@ -138,8 +137,14 @@ esp_encrypt_node_fn (vlib_main_t * vm, if (PREDICT_FALSE (vec_len (empty_buffers) < n_left_from)) { - vlib_node_increment_counter (vm, esp_encrypt_node.index, - ESP_ENCRYPT_ERROR_NO_BUFFER, n_left_from); + if (is_ip6) + vlib_node_increment_counter (vm, esp6_encrypt_node.index, + ESP_ENCRYPT_ERROR_NO_BUFFER, + n_left_from); + else + vlib_node_increment_counter (vm, esp4_encrypt_node.index, + ESP_ENCRYPT_ERROR_NO_BUFFER, + n_left_from); clib_warning ("no enough empty buffers. discarding frame"); goto free_buffers_and_exit; } @@ -164,7 +169,6 @@ esp_encrypt_node_fn (vlib_main_t * vm, uword last_empty_buffer; esp_header_t *o_esp0; esp_footer_t *f0; - u8 is_ipv6; u8 ip_udp_hdr_size; u8 next_hdr_type; u32 ip_proto = 0; @@ -185,8 +189,12 @@ esp_encrypt_node_fn (vlib_main_t * vm, { clib_warning ("sequence number counter has cycled SPI %u", sa0->spi); - vlib_node_increment_counter (vm, esp_encrypt_node.index, - ESP_ENCRYPT_ERROR_SEQ_CYCLED, 1); + if (is_ip6) + vlib_node_increment_counter (vm, esp6_encrypt_node.index, + ESP_ENCRYPT_ERROR_SEQ_CYCLED, 1); + else + vlib_node_increment_counter (vm, esp4_encrypt_node.index, + ESP_ENCRYPT_ERROR_SEQ_CYCLED, 1); //TODO: rekey SA o_bi0 = i_bi0; to_next[0] = o_bi0; @@ -213,11 +221,8 @@ esp_encrypt_node_fn (vlib_main_t * vm, /* add old buffer to the recycle list */ vec_add1 (recycle, i_bi0); - /* is ipv6 */ - if (PREDICT_FALSE - ((iuh0->ip4.ip_version_and_header_length & 0xF0) == 0x60)) + if (is_ip6) { - is_ipv6 = 1; ih6_0 = vlib_buffer_get_current (i_b0); next_hdr_type = IP_PROTOCOL_IPV6; oh6_0 = vlib_buffer_get_current (o_b0); @@ -244,7 +249,6 @@ esp_encrypt_node_fn (vlib_main_t * vm, } else { - is_ipv6 = 0; next_hdr_type = IP_PROTOCOL_IP_IN_IP; oh0 = vlib_buffer_get_current (o_b0); ouh0 = vlib_buffer_get_current (o_b0); @@ -280,15 +284,14 @@ esp_encrypt_node_fn (vlib_main_t * vm, next0 = ESP_ENCRYPT_NEXT_IP4_LOOKUP; } - if (PREDICT_TRUE - (!is_ipv6 && sa0->is_tunnel && !sa0->is_tunnel_ip6)) + if (PREDICT_TRUE (!is_ip6 && sa0->is_tunnel && !sa0->is_tunnel_ip6)) { oh0->ip4.src_address.as_u32 = sa0->tunnel_src_addr.ip4.as_u32; oh0->ip4.dst_address.as_u32 = sa0->tunnel_dst_addr.ip4.as_u32; vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = (u32) ~ 0; } - else if (is_ipv6 && sa0->is_tunnel && sa0->is_tunnel_ip6) + else if (is_ip6 && sa0->is_tunnel && sa0->is_tunnel_ip6) { oh6_0->ip6.src_address.as_u64[0] = sa0->tunnel_src_addr.ip6.as_u64[0]; @@ -379,7 +382,7 @@ esp_encrypt_node_fn (vlib_main_t * vm, sa0->use_esn, sa0->seq_hi); - if (PREDICT_FALSE (is_ipv6)) + if (is_ip6) { oh6_0->ip6.payload_length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, o_b0) - @@ -425,9 +428,14 @@ esp_encrypt_node_fn (vlib_main_t * vm, } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } - vlib_node_increment_counter (vm, esp_encrypt_node.index, - ESP_ENCRYPT_ERROR_RX_PKTS, - from_frame->n_vectors); + if (is_ip6) + vlib_node_increment_counter (vm, esp6_encrypt_node.index, + ESP_ENCRYPT_ERROR_RX_PKTS, + from_frame->n_vectors); + else + vlib_node_increment_counter (vm, esp4_encrypt_node.index, + ESP_ENCRYPT_ERROR_RX_PKTS, + from_frame->n_vectors); free_buffers_and_exit: if (recycle) @@ -436,11 +444,46 @@ free_buffers_and_exit: return from_frame->n_vectors; } +static uword +esp4_encrypt_node_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return esp_encrypt_inline (vm, node, from_frame, 0 /* is_ip6 */ ); +} + +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (esp4_encrypt_node) = { + .function = esp4_encrypt_node_fn, + .name = "esp4-encrypt", + .vector_size = sizeof (u32), + .format_trace = format_esp_encrypt_trace, + .type = VLIB_NODE_TYPE_INTERNAL, + + .n_errors = ARRAY_LEN(esp_encrypt_error_strings), + .error_strings = esp_encrypt_error_strings, + + .n_next_nodes = ESP_ENCRYPT_N_NEXT, + .next_nodes = { +#define _(s,n) [ESP_ENCRYPT_NEXT_##s] = n, + foreach_esp_encrypt_next +#undef _ + }, +}; +/* *INDENT-ON* */ + +VLIB_NODE_FUNCTION_MULTIARCH (esp4_encrypt_node, esp4_encrypt_node_fn); + +static uword +esp6_encrypt_node_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame) +{ + return esp_encrypt_inline (vm, node, from_frame, 1 /* is_ip6 */ ); +} /* *INDENT-OFF* */ -VLIB_REGISTER_NODE (esp_encrypt_node) = { - .function = esp_encrypt_node_fn, - .name = "esp-encrypt", +VLIB_REGISTER_NODE (esp6_encrypt_node) = { + .function = esp6_encrypt_node_fn, + .name = "esp6-encrypt", .vector_size = sizeof (u32), .format_trace = format_esp_encrypt_trace, .type = VLIB_NODE_TYPE_INTERNAL, @@ -457,7 +500,7 @@ VLIB_REGISTER_NODE (esp_encrypt_node) = { }; /* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (esp_encrypt_node, esp_encrypt_node_fn) +VLIB_NODE_FUNCTION_MULTIARCH (esp6_encrypt_node, esp6_encrypt_node_fn); /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/ipsec/ipsec.c b/src/vnet/ipsec/ipsec.c index c882a628602..d1b82b51326 100644 --- a/src/vnet/ipsec/ipsec.c +++ b/src/vnet/ipsec/ipsec.c @@ -73,17 +73,17 @@ ipsec_set_interface_spd (vlib_main_t * vm, u32 sw_if_index, u32 spd_id, sw_if_index, spd_id, spd_index); /* enable IPsec on TX */ - vnet_feature_enable_disable ("ip4-output", "ipsec-output-ip4", sw_if_index, + vnet_feature_enable_disable ("ip4-output", "ipsec4-output", sw_if_index, is_add, 0, 0); - vnet_feature_enable_disable ("ip6-output", "ipsec-output-ip6", sw_if_index, + vnet_feature_enable_disable ("ip6-output", "ipsec6-output", sw_if_index, is_add, 0, 0); config.spd_index = spd_index; /* enable IPsec on RX */ - vnet_feature_enable_disable ("ip4-unicast", "ipsec-input-ip4", sw_if_index, + vnet_feature_enable_disable ("ip4-unicast", "ipsec4-input", sw_if_index, is_add, &config, sizeof (config)); - vnet_feature_enable_disable ("ip6-unicast", "ipsec-input-ip6", sw_if_index, + vnet_feature_enable_disable ("ip6-unicast", "ipsec6-input", sw_if_index, is_add, &config, sizeof (config)); return 0; @@ -562,26 +562,47 @@ ipsec_init (vlib_main_t * vm) ASSERT (node); im->error_drop_node_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "esp-encrypt"); + node = vlib_get_node_by_name (vm, (u8 *) "esp4-encrypt"); ASSERT (node); - im->esp_encrypt_node_index = node->index; + im->esp4_encrypt_node_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "esp-decrypt"); + node = vlib_get_node_by_name (vm, (u8 *) "esp4-decrypt"); ASSERT (node); - im->esp_decrypt_node_index = node->index; + im->esp4_decrypt_node_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "ah-encrypt"); + node = vlib_get_node_by_name (vm, (u8 *) "ah4-encrypt"); ASSERT (node); - im->ah_encrypt_node_index = node->index; + im->ah4_encrypt_node_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "ah-decrypt"); + node = vlib_get_node_by_name (vm, (u8 *) "ah4-decrypt"); ASSERT (node); - im->ah_decrypt_node_index = node->index; + im->ah4_decrypt_node_index = node->index; - im->esp_encrypt_next_index = IPSEC_OUTPUT_NEXT_ESP_ENCRYPT; - im->esp_decrypt_next_index = IPSEC_INPUT_NEXT_ESP_DECRYPT; - im->ah_encrypt_next_index = IPSEC_OUTPUT_NEXT_AH_ENCRYPT; - im->ah_decrypt_next_index = IPSEC_INPUT_NEXT_AH_DECRYPT; + im->esp4_encrypt_next_index = IPSEC_OUTPUT_NEXT_ESP4_ENCRYPT; + im->esp4_decrypt_next_index = IPSEC_INPUT_NEXT_ESP4_DECRYPT; + im->ah4_encrypt_next_index = IPSEC_OUTPUT_NEXT_AH4_ENCRYPT; + im->ah4_decrypt_next_index = IPSEC_INPUT_NEXT_AH4_DECRYPT; + + node = vlib_get_node_by_name (vm, (u8 *) "esp6-encrypt"); + ASSERT (node); + im->esp6_encrypt_node_index = node->index; + + node = vlib_get_node_by_name (vm, (u8 *) "esp6-decrypt"); + ASSERT (node); + im->esp6_decrypt_node_index = node->index; + + node = vlib_get_node_by_name (vm, (u8 *) "ah6-encrypt"); + ASSERT (node); + im->ah6_encrypt_node_index = node->index; + + node = vlib_get_node_by_name (vm, (u8 *) "ah6-decrypt"); + ASSERT (node); + im->ah6_decrypt_node_index = node->index; + + im->esp6_encrypt_next_index = IPSEC_OUTPUT_NEXT_ESP6_ENCRYPT; + im->esp6_decrypt_next_index = IPSEC_INPUT_NEXT_ESP6_DECRYPT; + im->ah6_encrypt_next_index = IPSEC_OUTPUT_NEXT_AH6_ENCRYPT; + im->ah6_decrypt_next_index = IPSEC_INPUT_NEXT_AH6_DECRYPT; im->cb.check_support_cb = ipsec_check_support; diff --git a/src/vnet/ipsec/ipsec.h b/src/vnet/ipsec/ipsec.h index f9ceae55a05..6a9c5b1c824 100644 --- a/src/vnet/ipsec/ipsec.h +++ b/src/vnet/ipsec/ipsec.h @@ -20,11 +20,12 @@ #define IPSEC_FLAG_IPSEC_GRE_TUNNEL (1 << 0) - -#define foreach_ipsec_output_next \ -_(DROP, "error-drop") \ -_(ESP_ENCRYPT, "esp-encrypt") \ -_(AH_ENCRYPT, "ah-encrypt") +#define foreach_ipsec_output_next \ + _ (DROP, "error-drop") \ + _ (ESP4_ENCRYPT, "esp4-encrypt") \ + _ (AH4_ENCRYPT, "ah4-encrypt") \ + _ (ESP6_ENCRYPT, "esp6-encrypt") \ + _ (AH6_ENCRYPT, "ah6-encrypt") #define _(v, s) IPSEC_OUTPUT_NEXT_##v, typedef enum @@ -34,11 +35,12 @@ typedef enum IPSEC_OUTPUT_N_NEXT, } ipsec_output_next_t; - -#define foreach_ipsec_input_next \ -_(DROP, "error-drop") \ -_(ESP_DECRYPT, "esp-decrypt") \ -_(AH_DECRYPT, "ah-decrypt") +#define foreach_ipsec_input_next \ + _ (DROP, "error-drop") \ + _ (ESP4_DECRYPT, "esp4-decrypt") \ + _ (AH4_DECRYPT, "ah4-decrypt") \ + _ (ESP6_DECRYPT, "esp6-decrypt") \ + _ (AH6_DECRYPT, "ah6-decrypt") #define _(v, s) IPSEC_INPUT_NEXT_##v, typedef enum @@ -288,15 +290,23 @@ typedef struct /* node indices */ u32 error_drop_node_index; - u32 esp_encrypt_node_index; - u32 esp_decrypt_node_index; - u32 ah_encrypt_node_index; - u32 ah_decrypt_node_index; + u32 esp4_encrypt_node_index; + u32 esp4_decrypt_node_index; + u32 ah4_encrypt_node_index; + u32 ah4_decrypt_node_index; + u32 esp6_encrypt_node_index; + u32 esp6_decrypt_node_index; + u32 ah6_encrypt_node_index; + u32 ah6_decrypt_node_index; /* next node indices */ - u32 esp_encrypt_next_index; - u32 esp_decrypt_next_index; - u32 ah_encrypt_next_index; - u32 ah_decrypt_next_index; + u32 esp4_encrypt_next_index; + u32 esp4_decrypt_next_index; + u32 ah4_encrypt_next_index; + u32 ah4_decrypt_next_index; + u32 esp6_encrypt_next_index; + u32 esp6_decrypt_next_index; + u32 ah6_encrypt_next_index; + u32 ah6_decrypt_next_index; /* callbacks */ ipsec_main_callbacks_t cb; @@ -307,10 +317,14 @@ typedef struct extern ipsec_main_t ipsec_main; -extern vlib_node_registration_t esp_encrypt_node; -extern vlib_node_registration_t esp_decrypt_node; -extern vlib_node_registration_t ah_encrypt_node; -extern vlib_node_registration_t ah_decrypt_node; +extern vlib_node_registration_t esp4_encrypt_node; +extern vlib_node_registration_t esp4_decrypt_node; +extern vlib_node_registration_t ah4_encrypt_node; +extern vlib_node_registration_t ah4_decrypt_node; +extern vlib_node_registration_t esp6_encrypt_node; +extern vlib_node_registration_t esp6_decrypt_node; +extern vlib_node_registration_t ah6_encrypt_node; +extern vlib_node_registration_t ah6_decrypt_node; extern vlib_node_registration_t ipsec_if_input_node; diff --git a/src/vnet/ipsec/ipsec_if.c b/src/vnet/ipsec/ipsec_if.c index cb7e89a68e6..2640f25c011 100644 --- a/src/vnet/ipsec/ipsec_if.c +++ b/src/vnet/ipsec/ipsec_if.c @@ -108,7 +108,7 @@ ipsec_if_tx_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, hi0 = vnet_get_sup_hw_interface (vnm, sw_if_index0); t0 = pool_elt_at_index (im->tunnel_interfaces, hi0->dev_instance); vnet_buffer (b0)->ipsec.sad_index = t0->output_sa_index; - next0 = IPSEC_OUTPUT_NEXT_ESP_ENCRYPT; + next0 = IPSEC_OUTPUT_NEXT_ESP4_ENCRYPT; len0 = vlib_buffer_length_in_chain (vm, b0); @@ -369,10 +369,10 @@ ipsec_add_del_tunnel_if_internal (vnet_main_t * vnm, hi = vnet_get_hw_interface (vnm, hw_if_index); slot = vlib_node_add_next_with_slot - (vnm->vlib_main, hi->tx_node_index, im->esp_encrypt_node_index, - IPSEC_OUTPUT_NEXT_ESP_ENCRYPT); + (vnm->vlib_main, hi->tx_node_index, im->esp4_encrypt_node_index, + IPSEC_OUTPUT_NEXT_ESP4_ENCRYPT); - ASSERT (slot == IPSEC_OUTPUT_NEXT_ESP_ENCRYPT); + ASSERT (slot == IPSEC_OUTPUT_NEXT_ESP4_ENCRYPT); t->hw_if_index = hw_if_index; diff --git a/src/vnet/ipsec/ipsec_if_in.c b/src/vnet/ipsec/ipsec_if_in.c index bc10f7f5f6c..a486bd98dbb 100644 --- a/src/vnet/ipsec/ipsec_if_in.c +++ b/src/vnet/ipsec/ipsec_if_in.c @@ -179,7 +179,7 @@ ipsec_if_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, } vlib_buffer_advance (b0, ip4_header_bytes (ip0)); - next0 = im->esp_decrypt_next_index; + next0 = im->esp4_decrypt_next_index; } trace: @@ -231,7 +231,7 @@ VLIB_REGISTER_NODE (ipsec_if_input_node) = { .n_errors = ARRAY_LEN(ipsec_if_input_error_strings), .error_strings = ipsec_if_input_error_strings, - .sibling_of = "ipsec-input-ip4", + .sibling_of = "ipsec4-input", }; /* *INDENT-ON* */ diff --git a/src/vnet/ipsec/ipsec_input.c b/src/vnet/ipsec/ipsec_input.c index ebfb909cbcf..6d5b2dcce69 100644 --- a/src/vnet/ipsec/ipsec_input.c +++ b/src/vnet/ipsec/ipsec_input.c @@ -129,9 +129,9 @@ ip6_addr_match_range (ip6_address_t * a, ip6_address_t * la, } always_inline ipsec_policy_t * -ipsec_input_ip6_protect_policy_match (ipsec_spd_t * spd, - ip6_address_t * sa, - ip6_address_t * da, u32 spi) +ipsec6_input_protect_policy_match (ipsec_spd_t * spd, + ip6_address_t * sa, + ip6_address_t * da, u32 spi) { ipsec_main_t *im = &ipsec_main; ipsec_policy_t *p; @@ -168,12 +168,11 @@ ipsec_input_ip6_protect_policy_match (ipsec_spd_t * spd, return 0; } -static vlib_node_registration_t ipsec_input_ip4_node; +static vlib_node_registration_t ipsec4_input_node; static uword -ipsec_input_ip4_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame) +ipsec4_input_node_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame) { u32 n_left_from, *from, next_index, *to_next; ipsec_main_t *im = &ipsec_main; @@ -252,7 +251,7 @@ ipsec_input_ip4_node_fn (vlib_main_t * vm, p0->counter.bytes += clib_net_to_host_u16 (ip0->length); vnet_buffer (b0)->ipsec.sad_index = p0->sa_index; vnet_buffer (b0)->ipsec.flags = 0; - next0 = im->esp_decrypt_next_index; + next0 = im->esp4_decrypt_next_index; vlib_buffer_advance (b0, ((u8 *) esp0 - (u8 *) ip0)); goto trace0; } @@ -295,7 +294,7 @@ ipsec_input_ip4_node_fn (vlib_main_t * vm, p0->counter.bytes += clib_net_to_host_u16 (ip0->length); vnet_buffer (b0)->ipsec.sad_index = p0->sa_index; vnet_buffer (b0)->ipsec.flags = 0; - next0 = im->ah_decrypt_next_index; + next0 = im->ah4_decrypt_next_index; goto trace1; } /* FIXME bypass and discard */ @@ -320,7 +319,7 @@ ipsec_input_ip4_node_fn (vlib_main_t * vm, } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } - vlib_node_increment_counter (vm, ipsec_input_ip4_node.index, + vlib_node_increment_counter (vm, ipsec4_input_node.index, IPSEC_INPUT_ERROR_RX_PKTS, from_frame->n_vectors); @@ -329,9 +328,9 @@ ipsec_input_ip4_node_fn (vlib_main_t * vm, /* *INDENT-OFF* */ -VLIB_REGISTER_NODE (ipsec_input_ip4_node,static) = { - .function = ipsec_input_ip4_node_fn, - .name = "ipsec-input-ip4", +VLIB_REGISTER_NODE (ipsec4_input_node,static) = { + .function = ipsec4_input_node_fn, + .name = "ipsec4-input", .vector_size = sizeof (u32), .format_trace = format_ipsec_input_trace, .type = VLIB_NODE_TYPE_INTERNAL, @@ -348,13 +347,13 @@ VLIB_REGISTER_NODE (ipsec_input_ip4_node,static) = { }; /* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn); -static vlib_node_registration_t ipsec_input_ip6_node; +VLIB_NODE_FUNCTION_MULTIARCH (ipsec4_input_node, ipsec4_input_node_fn); + +static vlib_node_registration_t ipsec6_input_node; static uword -ipsec_input_ip6_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * from_frame) +ipsec6_input_node_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * from_frame) { u32 n_left_from, *from, next_index, *to_next; ipsec_main_t *im = &ipsec_main; @@ -409,11 +408,11 @@ ipsec_input_ip6_node_fn (vlib_main_t * vm, clib_net_to_host_u16 (ip0->payload_length) + header_size, spd0->id); #endif - p0 = ipsec_input_ip6_protect_policy_match (spd0, - &ip0->src_address, - &ip0->dst_address, - clib_net_to_host_u32 - (esp0->spi)); + p0 = ipsec6_input_protect_policy_match (spd0, + &ip0->src_address, + &ip0->dst_address, + clib_net_to_host_u32 + (esp0->spi)); if (PREDICT_TRUE (p0 != 0)) { @@ -423,18 +422,18 @@ ipsec_input_ip6_node_fn (vlib_main_t * vm, p0->counter.bytes += header_size; vnet_buffer (b0)->ipsec.sad_index = p0->sa_index; vnet_buffer (b0)->ipsec.flags = 0; - next0 = im->esp_decrypt_next_index; + next0 = im->esp6_decrypt_next_index; vlib_buffer_advance (b0, header_size); goto trace0; } } else if (ip0->protocol == IP_PROTOCOL_IPSEC_AH) { - p0 = ipsec_input_ip6_protect_policy_match (spd0, - &ip0->src_address, - &ip0->dst_address, - clib_net_to_host_u32 - (ah0->spi)); + p0 = ipsec6_input_protect_policy_match (spd0, + &ip0->src_address, + &ip0->dst_address, + clib_net_to_host_u32 + (ah0->spi)); if (PREDICT_TRUE (p0 != 0)) { @@ -444,7 +443,7 @@ ipsec_input_ip6_node_fn (vlib_main_t * vm, p0->counter.bytes += header_size; vnet_buffer (b0)->ipsec.sad_index = p0->sa_index; vnet_buffer (b0)->ipsec.flags = 0; - next0 = im->ah_decrypt_next_index; + next0 = im->ah6_decrypt_next_index; goto trace0; } } @@ -468,7 +467,7 @@ ipsec_input_ip6_node_fn (vlib_main_t * vm, } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } - vlib_node_increment_counter (vm, ipsec_input_ip6_node.index, + vlib_node_increment_counter (vm, ipsec6_input_node.index, IPSEC_INPUT_ERROR_RX_PKTS, from_frame->n_vectors); @@ -477,9 +476,9 @@ ipsec_input_ip6_node_fn (vlib_main_t * vm, /* *INDENT-OFF* */ -VLIB_REGISTER_NODE (ipsec_input_ip6_node,static) = { - .function = ipsec_input_ip6_node_fn, - .name = "ipsec-input-ip6", +VLIB_REGISTER_NODE (ipsec6_input_node,static) = { + .function = ipsec6_input_node_fn, + .name = "ipsec6-input", .vector_size = sizeof (u32), .format_trace = format_ipsec_input_trace, .type = VLIB_NODE_TYPE_INTERNAL, @@ -487,11 +486,11 @@ VLIB_REGISTER_NODE (ipsec_input_ip6_node,static) = { .n_errors = ARRAY_LEN(ipsec_input_error_strings), .error_strings = ipsec_input_error_strings, - .sibling_of = "ipsec-input-ip4", + .sibling_of = "ipsec4-input", }; /* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip6_node, ipsec_input_ip6_node_fn) +VLIB_NODE_FUNCTION_MULTIARCH (ipsec6_input_node, ipsec6_input_node_fn); /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/ipsec/ipsec_output.c b/src/vnet/ipsec/ipsec_output.c index a62c0a53458..3a20d512f60 100644 --- a/src/vnet/ipsec/ipsec_output.c +++ b/src/vnet/ipsec/ipsec_output.c @@ -45,9 +45,6 @@ static char *ipsec_output_error_strings[] = { #undef _ }; -static vlib_node_registration_t ipsec_output_ip4_node; -static vlib_node_registration_t ipsec_output_ip6_node; - typedef struct { u32 spd_id; @@ -133,9 +130,9 @@ ip6_addr_match_range (ip6_address_t * a, ip6_address_t * la, } always_inline ipsec_policy_t * -ipsec_output_ip6_policy_match (ipsec_spd_t * spd, - ip6_address_t * la, - ip6_address_t * ra, u16 lp, u16 rp, u8 pr) +ipsec6_output_policy_match (ipsec_spd_t * spd, + ip6_address_t * la, + ip6_address_t * ra, u16 lp, u16 rp, u8 pr) { ipsec_policy_t *p; u32 *i; @@ -239,14 +236,13 @@ ipsec_output_inline (vlib_main_t * vm, vlib_node_runtime_t * node, spd0->id); #endif - p0 = ipsec_output_ip6_policy_match (spd0, - &ip6_0->src_address, - &ip6_0->dst_address, - clib_net_to_host_u16 - (udp0->src_port), - clib_net_to_host_u16 - (udp0->dst_port), - ip6_0->protocol); + p0 = ipsec6_output_policy_match (spd0, + &ip6_0->src_address, + &ip6_0->dst_address, + clib_net_to_host_u16 + (udp0->src_port), + clib_net_to_host_u16 + (udp0->dst_port), ip6_0->protocol); } else { @@ -281,9 +277,14 @@ ipsec_output_inline (vlib_main_t * vm, vlib_node_runtime_t * node, nc_protect++; sa = pool_elt_at_index (im->sad, p0->sa_index); if (sa->protocol == IPSEC_PROTOCOL_ESP) - next_node_index = im->esp_encrypt_node_index; + if (is_ipv6) + next_node_index = im->esp6_encrypt_node_index; + else + next_node_index = im->esp4_encrypt_node_index; + else if (is_ipv6) + next_node_index = im->ah6_encrypt_node_index; else - next_node_index = im->ah_encrypt_node_index; + next_node_index = im->ah4_encrypt_node_index; vnet_buffer (b0)->ipsec.sad_index = p0->sa_index; p0->counter.packets++; if (is_ipv6) @@ -414,16 +415,16 @@ ipsec_output_inline (vlib_main_t * vm, vlib_node_runtime_t * node, } static uword -ipsec_output_ip4_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * frame) +ipsec4_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, + vlib_frame_t * frame) { return ipsec_output_inline (vm, node, frame, 0); } /* *INDENT-OFF* */ -VLIB_REGISTER_NODE (ipsec_output_ip4_node,static) = { - .function = ipsec_output_ip4_node_fn, - .name = "ipsec-output-ip4", +VLIB_REGISTER_NODE (ipsec4_output_node,static) = { + .function = ipsec4_output_node_fn, + .name = "ipsec4-output", .vector_size = sizeof (u32), .format_trace = format_ipsec_output_trace, .type = VLIB_NODE_TYPE_INTERNAL, @@ -440,18 +441,19 @@ VLIB_REGISTER_NODE (ipsec_output_ip4_node,static) = { }; /* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (ipsec_output_ip4_node, ipsec_output_ip4_node_fn) - static uword - ipsec_output_ip6_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * frame) +VLIB_NODE_FUNCTION_MULTIARCH (ipsec4_output_node, ipsec4_output_node_fn); + +static uword +ipsec6_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, + vlib_frame_t * frame) { return ipsec_output_inline (vm, node, frame, 1); } /* *INDENT-OFF* */ -VLIB_REGISTER_NODE (ipsec_output_ip6_node,static) = { - .function = ipsec_output_ip6_node_fn, - .name = "ipsec-output-ip6", +VLIB_REGISTER_NODE (ipsec6_output_node,static) = { + .function = ipsec6_output_node_fn, + .name = "ipsec6-output", .vector_size = sizeof (u32), .format_trace = format_ipsec_output_trace, .type = VLIB_NODE_TYPE_INTERNAL, @@ -468,7 +470,7 @@ VLIB_REGISTER_NODE (ipsec_output_ip6_node,static) = { }; /* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (ipsec_output_ip6_node, ipsec_output_ip6_node_fn) +VLIB_NODE_FUNCTION_MULTIARCH (ipsec6_output_node, ipsec6_output_node_fn); #else /* IPSEC > 1 */ /* Dummy ipsec output node, in case when IPSec is disabled */ @@ -482,16 +484,16 @@ ipsec_output_node_fn (vlib_main_t * vm, } /* *INDENT-OFF* */ -VLIB_REGISTER_NODE (ipsec_output_node) = { +VLIB_REGISTER_NODE (ipsec4_output_node) = { .vector_size = sizeof (u32), .function = ipsec_output_node_fn, - .name = "ipsec-output-ip4", + .name = "ipsec4-output", }; -VLIB_REGISTER_NODE (ipsec_output_node) = { +VLIB_REGISTER_NODE (ipsec6_output_node) = { .vector_size = sizeof (u32), .function = ipsec_output_node_fn, - .name = "ipsec-output-ip6", + .name = "ipsec6-output", }; /* *INDENT-ON* */ #endif -- cgit 1.2.3-korg