ikev2: add support for custom ipsec-over-udp port
[vpp.git] / src / vnet / ipsec / ipsec_input.c
index 193b03f..61b10fb 100644 (file)
@@ -23,6 +23,7 @@
 #include <vnet/ipsec/ipsec.h>
 #include <vnet/ipsec/esp.h>
 #include <vnet/ipsec/ah.h>
+#include <vnet/ipsec/ipsec_io.h>
 
 #define foreach_ipsec_input_error               \
 _(RX_PKTS, "IPSEC pkts received")              \
@@ -60,9 +61,9 @@ format_ipsec_input_trace (u8 * s, va_list * args)
   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
   ipsec_input_trace_t *t = va_arg (*args, ipsec_input_trace_t *);
 
-  s = format (s, "%U: sa_id %u spd %u policy %d spi %u seq %u",
+  s = format (s, "%U: sa_id %u spd %u policy %d spi %u (0x%08x) seq %u",
              format_ip_protocol, t->proto, t->sa_id,
-             t->spd, t->policy_index, t->spi, t->seq);
+             t->spd, t->policy_index, t->spi, t->spi, t->seq);
 
   return s;
 }
@@ -83,7 +84,7 @@ ipsec_input_protect_policy_match (ipsec_spd_t * spd, u32 sa, u32 da, u32 spi)
     if (spi != s->spi)
       continue;
 
-    if (s->is_tunnel)
+    if (ipsec_sa_is_set_IS_TUNNEL (s))
       {
        if (da != clib_net_to_host_u32 (s->tunnel_dst_addr.ip4.as_u32))
          continue;
@@ -139,7 +140,7 @@ ipsec6_input_protect_policy_match (ipsec_spd_t * spd,
     if (spi != s->spi)
       continue;
 
-    if (s->is_tunnel)
+    if (ipsec_sa_is_set_IS_TUNNEL (s))
       {
        if (!ip6_address_is_equal (sa, &s->tunnel_src_addr.ip6))
          continue;
@@ -161,7 +162,7 @@ ipsec6_input_protect_policy_match (ipsec_spd_t * spd,
   return 0;
 }
 
-static vlib_node_registration_t ipsec4_input_node;
+extern vlib_node_registration_t ipsec4_input_node;
 
 VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
                                  vlib_node_runtime_t * node,
@@ -194,6 +195,7 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
          ip4_ipsec_config_t *c0;
          ipsec_spd_t *spd0;
          ipsec_policy_t *p0 = 0;
+         u8 has_space0;
 
          bi0 = to_next[0] = from[0];
          from += 1;
@@ -229,8 +231,7 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
                  esp0 =
                    (esp_header_t *) ((u8 *) esp0 + sizeof (udp_header_t));
                }
-             /* FIXME TODO missing check whether there is enough data inside
-              * IP/UDP to contain ESP header & stuff ? */
+
              p0 = ipsec_input_protect_policy_match (spd0,
                                                     clib_net_to_host_u32
                                                     (ip0->src_address.
@@ -241,7 +242,12 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
                                                     clib_net_to_host_u32
                                                     (esp0->spi));
 
-             if (PREDICT_TRUE (p0 != NULL))
+             has_space0 =
+               vlib_buffer_has_space (b0,
+                                      (clib_address_t) (esp0 + 1) -
+                                      (clib_address_t) ip0);
+
+             if (PREDICT_TRUE ((p0 != NULL) & (has_space0)))
                {
                  ipsec_matched += 1;
 
@@ -252,13 +258,13 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
                     clib_net_to_host_u16 (ip0->length));
 
                  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
-                 vnet_buffer (b0)->ipsec.flags = 0;
                  next0 = im->esp4_decrypt_next_index;
                  vlib_buffer_advance (b0, ((u8 *) esp0 - (u8 *) ip0));
                  goto trace0;
                }
              else
                {
+                 p0 = 0;
                  pi0 = ~0;
                };
 
@@ -271,10 +277,11 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
                    vlib_add_trace (vm, node, b0, sizeof (*tr));
 
                  tr->proto = ip0->protocol;
-                 if (p0)
-                   tr->sa_id = p0->sa_id;
-                 tr->spi = clib_net_to_host_u32 (esp0->spi);
-                 tr->seq = clib_net_to_host_u32 (esp0->seq);
+                 tr->sa_id = p0 ? p0->sa_id : ~0;
+                 tr->spi =
+                   has_space0 ? clib_net_to_host_u32 (esp0->spi) : ~0;
+                 tr->seq =
+                   has_space0 ? clib_net_to_host_u32 (esp0->seq) : ~0;
                  tr->spd = spd0->id;
                  tr->policy_index = pi0;
                }
@@ -292,7 +299,12 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
                                                     clib_net_to_host_u32
                                                     (ah0->spi));
 
-             if (PREDICT_TRUE (p0 != 0))
+             has_space0 =
+               vlib_buffer_has_space (b0,
+                                      (clib_address_t) (ah0 + 1) -
+                                      (clib_address_t) ip0);
+
+             if (PREDICT_TRUE ((p0 != NULL) & (has_space0)))
                {
                  ipsec_matched += 1;
 
@@ -303,12 +315,12 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
                     clib_net_to_host_u16 (ip0->length));
 
                  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
-                 vnet_buffer (b0)->ipsec.flags = 0;
                  next0 = im->ah4_decrypt_next_index;
                  goto trace1;
                }
              else
                {
+                 p0 = 0;
                  pi0 = ~0;
                }
              /* FIXME bypass and discard */
@@ -320,10 +332,10 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
                    vlib_add_trace (vm, node, b0, sizeof (*tr));
 
                  tr->proto = ip0->protocol;
-                 if (p0)
-                   tr->sa_id = p0->sa_id;
-                 tr->spi = clib_net_to_host_u32 (ah0->spi);
-                 tr->seq = clib_net_to_host_u32 (ah0->seq_no);
+                 tr->sa_id = p0 ? p0->sa_id : ~0;
+                 tr->spi = has_space0 ? clib_net_to_host_u32 (ah0->spi) : ~0;
+                 tr->seq =
+                   has_space0 ? clib_net_to_host_u32 (ah0->seq_no) : ~0;
                  tr->spd = spd0->id;
                  tr->policy_index = pi0;
                }
@@ -352,7 +364,7 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
 
 
 /* *INDENT-OFF* */
-VLIB_REGISTER_NODE (ipsec4_input_node,static) = {
+VLIB_REGISTER_NODE (ipsec4_input_node) = {
   .name = "ipsec4-input-feature",
   .vector_size = sizeof (u32),
   .format_trace = format_ipsec_input_trace,
@@ -368,7 +380,7 @@ VLIB_REGISTER_NODE (ipsec4_input_node,static) = {
 };
 /* *INDENT-ON* */
 
-static vlib_node_registration_t ipsec6_input_node;
+extern vlib_node_registration_t ipsec6_input_node;
 
 
 VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
@@ -449,7 +461,6 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
                     header_size);
 
                  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
-                 vnet_buffer (b0)->ipsec.flags = 0;
                  next0 = im->esp6_decrypt_next_index;
                  vlib_buffer_advance (b0, header_size);
                  goto trace0;
@@ -478,7 +489,6 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
                     header_size);
 
                  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
-                 vnet_buffer (b0)->ipsec.flags = 0;
                  next0 = im->ah6_decrypt_next_index;
                  goto trace0;
                }
@@ -526,7 +536,7 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
 
 
 /* *INDENT-OFF* */
-VLIB_REGISTER_NODE (ipsec6_input_node,static) = {
+VLIB_REGISTER_NODE (ipsec6_input_node) = {
   .name = "ipsec6-input-feature",
   .vector_size = sizeof (u32),
   .format_trace = format_ipsec_input_trace,