ikev2: add support for custom ipsec-over-udp port
[vpp.git] / src / vnet / ipsec / ipsec_input.c
index 778570a..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;
 }
@@ -86,25 +86,25 @@ ipsec_input_protect_policy_match (ipsec_spd_t * spd, u32 sa, u32 da, u32 spi)
 
     if (ipsec_sa_is_set_IS_TUNNEL (s))
       {
-       if (da != s->tunnel_dst_addr.ip4.as_u32)
+       if (da != clib_net_to_host_u32 (s->tunnel_dst_addr.ip4.as_u32))
          continue;
 
-       if (sa != s->tunnel_src_addr.ip4.as_u32)
+       if (sa != clib_net_to_host_u32 (s->tunnel_src_addr.ip4.as_u32))
          continue;
 
        return p;
       }
 
-    if (da < p->laddr.start.ip4.as_u32)
+    if (da < clib_net_to_host_u32 (p->laddr.start.ip4.as_u32))
       continue;
 
-    if (da > p->laddr.stop.ip4.as_u32)
+    if (da > clib_net_to_host_u32 (p->laddr.stop.ip4.as_u32))
       continue;
 
-    if (sa < p->raddr.start.ip4.as_u32)
+    if (sa < clib_net_to_host_u32 (p->raddr.start.ip4.as_u32))
       continue;
 
-    if (sa > p->raddr.stop.ip4.as_u32)
+    if (sa > clib_net_to_host_u32 (p->raddr.stop.ip4.as_u32))
       continue;
 
     return p;
@@ -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,15 +231,23 @@ 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,
-                                                    ip0->src_address.as_u32,
-                                                    ip0->dst_address.as_u32,
+                                                    clib_net_to_host_u32
+                                                    (ip0->src_address.
+                                                     as_u32),
+                                                    clib_net_to_host_u32
+                                                    (ip0->dst_address.
+                                                     as_u32),
                                                     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;
 
@@ -255,6 +264,7 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
                }
              else
                {
+                 p0 = 0;
                  pi0 = ~0;
                };
 
@@ -267,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;
                }
@@ -279,12 +290,21 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
            {
              ah0 = (ah_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0));
              p0 = ipsec_input_protect_policy_match (spd0,
-                                                    ip0->src_address.as_u32,
-                                                    ip0->dst_address.as_u32,
+                                                    clib_net_to_host_u32
+                                                    (ip0->src_address.
+                                                     as_u32),
+                                                    clib_net_to_host_u32
+                                                    (ip0->dst_address.
+                                                     as_u32),
                                                     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;
 
@@ -300,6 +320,7 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
                }
              else
                {
+                 p0 = 0;
                  pi0 = ~0;
                }
              /* FIXME bypass and discard */
@@ -311,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;
                }
@@ -343,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,
@@ -359,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,
@@ -515,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,