aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/ipsec/esp_encrypt.c131
-rw-r--r--src/vnet/ipsec/ipsec.c2
-rw-r--r--src/vnet/ipsec/ipsec.h7
-rw-r--r--src/vnet/ipsec/ipsec_if.c27
4 files changed, 162 insertions, 5 deletions
diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c
index c879a404b54..041b268975d 100644
--- a/src/vnet/ipsec/esp_encrypt.c
+++ b/src/vnet/ipsec/esp_encrypt.c
@@ -666,6 +666,137 @@ VNET_FEATURE_INIT (esp6_encrypt_tun_feat_node, static) =
};
/* *INDENT-ON* */
+typedef struct
+{
+ u32 sa_index;
+} esp_no_crypto_trace_t;
+
+static u8 *
+format_esp_no_crypto_trace (u8 * s, va_list * args)
+{
+ CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+ CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+ esp_no_crypto_trace_t *t = va_arg (*args, esp_no_crypto_trace_t *);
+
+ s = format (s, "esp-no-crypto: sa-index %u", t->sa_index);
+
+ return s;
+}
+
+enum
+{
+ ESP_NO_CRYPTO_NEXT_DROP,
+ ESP_NO_CRYPTO_N_NEXT,
+};
+
+enum
+{
+ ESP_NO_CRYPTO_ERROR_RX_PKTS,
+};
+
+static char *esp_no_crypto_error_strings[] = {
+ "Outbound ESP packets received",
+};
+
+always_inline uword
+esp_no_crypto_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
+ u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
+ u32 *from = vlib_frame_vector_args (frame);
+ u32 n_left = frame->n_vectors;
+
+ vlib_get_buffers (vm, from, b, n_left);
+
+ while (n_left > 0)
+ {
+ u32 next0;
+ u32 sa_index0;
+
+ /* packets are always going to be dropped, but get the sa_index */
+ sa_index0 = *(u32 *) vnet_feature_next_with_data (&next0, b[0],
+ sizeof (sa_index0));
+
+ next[0] = ESP_NO_CRYPTO_NEXT_DROP;
+
+ if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ esp_no_crypto_trace_t *tr = vlib_add_trace (vm, node, b[0],
+ sizeof (*tr));
+ tr->sa_index = sa_index0;
+ }
+
+ n_left -= 1;
+ next += 1;
+ b += 1;
+ }
+
+ vlib_node_increment_counter (vm, node->node_index,
+ ESP_NO_CRYPTO_ERROR_RX_PKTS, frame->n_vectors);
+
+ vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
+
+ return frame->n_vectors;
+}
+
+VLIB_NODE_FN (esp4_no_crypto_tun_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * from_frame)
+{
+ return esp_no_crypto_inline (vm, node, from_frame);
+}
+
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE (esp4_no_crypto_tun_node) =
+{
+ .name = "esp4-no-crypto",
+ .vector_size = sizeof (u32),
+ .format_trace = format_esp_no_crypto_trace,
+ .n_errors = ARRAY_LEN(esp_no_crypto_error_strings),
+ .error_strings = esp_no_crypto_error_strings,
+ .n_next_nodes = ESP_NO_CRYPTO_N_NEXT,
+ .next_nodes = {
+ [ESP_NO_CRYPTO_NEXT_DROP] = "ip4-drop",
+ },
+};
+
+VNET_FEATURE_INIT (esp4_no_crypto_tun_feat_node, static) =
+{
+ .arc_name = "ip4-output",
+ .node_name = "esp4-no-crypto",
+ .runs_before = VNET_FEATURES ("adj-midchain-tx"),
+};
+
+VLIB_NODE_FN (esp6_no_crypto_tun_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * from_frame)
+{
+ return esp_no_crypto_inline (vm, node, from_frame);
+}
+
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE (esp6_no_crypto_tun_node) =
+{
+ .name = "esp6-no-crypto",
+ .vector_size = sizeof (u32),
+ .format_trace = format_esp_no_crypto_trace,
+ .n_errors = ARRAY_LEN(esp_no_crypto_error_strings),
+ .error_strings = esp_no_crypto_error_strings,
+ .n_next_nodes = ESP_NO_CRYPTO_N_NEXT,
+ .next_nodes = {
+ [ESP_NO_CRYPTO_NEXT_DROP] = "ip6-drop",
+ },
+};
+
+VNET_FEATURE_INIT (esp6_no_crypto_tun_feat_node, static) =
+{
+ .arc_name = "ip6-output",
+ .node_name = "esp6-no-crypto",
+ .runs_before = VNET_FEATURES ("adj-midchain-tx"),
+};
+/* *INDENT-ON* */
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/vnet/ipsec/ipsec.c b/src/vnet/ipsec/ipsec.c
index 4caae4840fb..21e1d5ec43f 100644
--- a/src/vnet/ipsec/ipsec.c
+++ b/src/vnet/ipsec/ipsec.c
@@ -122,7 +122,7 @@ ipsec_add_node (vlib_main_t * vm, const char *node_name,
*out_next_index = vlib_node_add_next (vm, prev_node->index, node->index);
}
-static void
+void
ipsec_add_feature (const char *arc_name,
const char *node_name, u32 * out_feature_index)
{
diff --git a/src/vnet/ipsec/ipsec.h b/src/vnet/ipsec/ipsec.h
index c77d0fe7dd8..ccbe7d7aa5c 100644
--- a/src/vnet/ipsec/ipsec.h
+++ b/src/vnet/ipsec/ipsec.h
@@ -142,6 +142,10 @@ typedef struct
u32 esp4_encrypt_tun_feature_index;
u32 esp6_encrypt_tun_feature_index;
+ /* tun nodes to drop packets when no crypto alg set on outbound SA */
+ u32 esp4_no_crypto_tun_feature_index;
+ u32 esp6_no_crypto_tun_feature_index;
+
/* pool of ah backends */
ipsec_ah_backend_t *ah_backends;
/* pool of esp backends */
@@ -241,6 +245,9 @@ ipsec_sa_get (u32 sa_index)
return (pool_elt_at_index (ipsec_main.sad, sa_index));
}
+void ipsec_add_feature (const char *arc_name, const char *node_name,
+ u32 * out_feature_index);
+
#endif /* __IPSEC_H__ */
/*
diff --git a/src/vnet/ipsec/ipsec_if.c b/src/vnet/ipsec/ipsec_if.c
index 5fc49e1af4e..562f40ec9ab 100644
--- a/src/vnet/ipsec/ipsec_if.c
+++ b/src/vnet/ipsec/ipsec_if.c
@@ -234,19 +234,31 @@ static void
ipsec_tunnel_feature_set (ipsec_main_t * im, ipsec_tunnel_if_t * t, u8 enable)
{
u8 arc;
+ u32 esp4_feature_index, esp6_feature_index;
+ ipsec_sa_t *sa;
+
+ sa = ipsec_sa_get (t->output_sa_index);
+ if (sa->crypto_alg == IPSEC_CRYPTO_ALG_NONE)
+ {
+ esp4_feature_index = im->esp4_no_crypto_tun_feature_index;
+ esp6_feature_index = im->esp6_no_crypto_tun_feature_index;
+ }
+ else
+ {
+ esp4_feature_index = im->esp4_encrypt_tun_feature_index;
+ esp6_feature_index = im->esp6_encrypt_tun_feature_index;
+ }
arc = vnet_get_feature_arc_index ("ip4-output");
- vnet_feature_enable_disable_with_index (arc,
- im->esp4_encrypt_tun_feature_index,
+ vnet_feature_enable_disable_with_index (arc, esp4_feature_index,
t->sw_if_index, enable,
&t->output_sa_index,
sizeof (t->output_sa_index));
arc = vnet_get_feature_arc_index ("ip6-output");
- vnet_feature_enable_disable_with_index (arc,
- im->esp6_encrypt_tun_feature_index,
+ vnet_feature_enable_disable_with_index (arc, esp6_feature_index,
t->sw_if_index, enable,
&t->output_sa_index,
sizeof (t->output_sa_index));
@@ -562,6 +574,13 @@ ipsec_tunnel_if_init (vlib_main_t * vm)
udp_register_dst_port (vm, UDP_DST_PORT_ipsec, ipsec4_if_input_node.index,
1);
+
+ /* set up feature nodes to drop outbound packets with no crypto alg set */
+ ipsec_add_feature ("ip4-output", "esp4-no-crypto",
+ &im->esp4_no_crypto_tun_feature_index);
+ ipsec_add_feature ("ip6-output", "esp6-no-crypto",
+ &im->esp6_no_crypto_tun_feature_index);
+
return 0;
}