ikev2: add support for custom ipsec-over-udp port
[vpp.git] / src / vnet / ipsec / ipsec_input.c
index 970211e..61b10fb 100644 (file)
@@ -61,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;
 }
@@ -162,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,
@@ -195,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;
@@ -230,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.
@@ -242,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;
 
@@ -253,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;
                };
 
@@ -272,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;
                }
@@ -293,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;
 
@@ -304,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 */
@@ -321,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;
                }
@@ -353,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,
@@ -369,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,
@@ -450,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;
@@ -479,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;
                }
@@ -527,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,