IPSEC: tidy the policy types 74/18374/2
authorNeale Ranns <nranns@cisco.com>
Tue, 19 Mar 2019 10:06:00 +0000 (10:06 +0000)
committerDave Barach <openvpp@barachs.net>
Tue, 19 Mar 2019 11:26:14 +0000 (11:26 +0000)
Change-Id: I5e981f12ff44243623cfd18d5e0ae06a7dfd1eb8
Signed-off-by: Neale Ranns <nranns@cisco.com>
src/vnet/ipsec/ipsec_api.c
src/vnet/ipsec/ipsec_cli.c
src/vnet/ipsec/ipsec_format.c
src/vnet/ipsec/ipsec_spd.h
src/vnet/ipsec/ipsec_spd_policy.c
src/vnet/ipsec/ipsec_spd_policy.h

index 906f4c4..d0f543f 100644 (file)
@@ -141,7 +141,6 @@ static void vl_api_ipsec_spd_entry_add_del_t_handler
 
   p.id = ntohl (mp->entry.spd_id);
   p.priority = ntohl (mp->entry.priority);
-  p.is_outbound = mp->entry.is_outbound;
 
   itype = ip_address_decode (&mp->entry.remote_address_start, &p.raddr.start);
   ip_address_decode (&mp->entry.remote_address_stop, &p.raddr.stop);
@@ -169,6 +168,11 @@ static void vl_api_ipsec_spd_entry_add_del_t_handler
       goto out;
     }
   p.sa_id = ntohl (mp->entry.sa_id);
+  rv =
+    ipsec_policy_mk_type (mp->entry.is_outbound, p.is_ipv6, p.policy,
+                         &p.type);
+  if (rv)
+    goto out;
 
   rv = ipsec_add_del_policy (vm, &p, mp->is_add, &stat_index);
   if (rv)
@@ -466,7 +470,8 @@ send_ipsec_spd_details (ipsec_policy_t * p, vl_api_registration_t * reg,
 
   mp->entry.spd_id = htonl (p->id);
   mp->entry.priority = htonl (p->priority);
-  mp->entry.is_outbound = p->is_outbound;
+  mp->entry.is_outbound = ((p->type == IPSEC_SPD_POLICY_IP6_OUTBOUND) ||
+                          (p->type == IPSEC_SPD_POLICY_IP4_OUTBOUND));
 
   ip_address_encode (&p->laddr.start, IP46_TYPE_ANY,
                     &mp->entry.local_address_start);
@@ -492,7 +497,7 @@ vl_api_ipsec_spd_dump_t_handler (vl_api_ipsec_spd_dump_t * mp)
 {
   vl_api_registration_t *reg;
   ipsec_main_t *im = &ipsec_main;
-  ipsec_spd_policy_t ptype;
+  ipsec_spd_policy_type_t ptype;
   ipsec_policy_t *policy;
   ipsec_spd_t *spd;
   uword *p;
index 648455b..8a4d068 100644 (file)
@@ -226,12 +226,14 @@ ipsec_policy_add_del_command_fn (vlib_main_t * vm,
   int rv, is_add = 0;
   u32 tmp, tmp2, stat_index;
   clib_error_t *error = NULL;
+  u32 is_outbound;
 
   clib_memset (&p, 0, sizeof (p));
   p.lport.stop = p.rport.stop = ~0;
   p.laddr.stop.ip4.as_u32 = p.raddr.stop.ip4.as_u32 = (u32) ~ 0;
   p.laddr.stop.ip6.as_u64[0] = p.laddr.stop.ip6.as_u64[1] = (u64) ~ 0;
   p.raddr.stop.ip6.as_u64[0] = p.raddr.stop.ip6.as_u64[1] = (u64) ~ 0;
+  is_outbound = 0;
 
   if (!unformat_user (input, unformat_line_input, line_input))
     return 0;
@@ -245,9 +247,9 @@ ipsec_policy_add_del_command_fn (vlib_main_t * vm,
       else if (unformat (line_input, "spd %u", &p.id))
        ;
       else if (unformat (line_input, "inbound"))
-       p.is_outbound = 0;
+       is_outbound = 0;
       else if (unformat (line_input, "outbound"))
-       p.is_outbound = 1;
+       is_outbound = 1;
       else if (unformat (line_input, "priority %d", &p.priority))
        ;
       else if (unformat (line_input, "protocol %u", &tmp))
@@ -325,6 +327,19 @@ ipsec_policy_add_del_command_fn (vlib_main_t * vm,
          goto done;
        }
     }
+
+  rv = ipsec_policy_mk_type (is_outbound, p.is_ipv6, p.policy, &p.type);
+
+  if (rv)
+    {
+      error = clib_error_return (0, "unsupported policy type for:",
+                                " outboud:%s %s action:%U",
+                                (is_outbound ? "yes" : "no"),
+                                (p.is_ipv6 ? "IPv4" : "IPv6"),
+                                format_ipsec_policy_action, p.policy);
+      goto done;
+    }
+
   rv = ipsec_add_del_policy (vm, &p, is_add, &stat_index);
 
   if (!rv)
index d65b2a7..aa5562c 100644 (file)
@@ -41,6 +41,24 @@ format_ipsec_policy_action (u8 * s, va_list * args)
   return s;
 }
 
+u8 *
+format_ipsec_policy_type (u8 * s, va_list * args)
+{
+  u32 i = va_arg (*args, u32);
+  char *t = 0;
+
+  switch (i)
+    {
+#define _(f,str) case IPSEC_SPD_POLICY_##f: t = str; break;
+      foreach_ipsec_spd_policy_type
+#undef _
+    default:
+      s = format (s, "unknown");
+    }
+  s = format (s, "%s", t);
+  return s;
+}
+
 uword
 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
 {
@@ -143,8 +161,10 @@ format_ipsec_policy (u8 * s, va_list * args)
 
   p = pool_elt_at_index (im->policies, pi);
 
-  s = format (s, "  [%d] priority %d action %U protocol ",
-             pi, p->priority, format_ipsec_policy_action, p->policy);
+  s = format (s, "  [%d] priority %d action %U type %U protocol ",
+             pi, p->priority,
+             format_ipsec_policy_action, p->policy,
+             format_ipsec_policy_type, p->type);
   if (p->protocol)
     {
       s = format (s, "%U", format_ip_protocol, p->protocol);
index dd09041..1e6c2c3 100644 (file)
@@ -31,11 +31,13 @@ typedef enum ipsec_spd_policy_t_
   foreach_ipsec_spd_policy_type
 #undef _
     IPSEC_SPD_POLICY_N_TYPES,
-} ipsec_spd_policy_t;
+} ipsec_spd_policy_type_t;
 
 #define FOR_EACH_IPSEC_SPD_POLICY_TYPE(_t)      \
   for (_t = 0; _t < IPSEC_SPD_POLICY_N_TYPES; _t++)
 
+extern u8 *format_ipsec_policy_type (u8 * s, va_list * args);
+
 /**
  * @brief A Secruity Policy Database
  */
index 5ad147b..d4a32e3 100644 (file)
@@ -29,7 +29,7 @@ ipsec_policy_is_equal (ipsec_policy_t * p1, ipsec_policy_t * p2)
 {
   if (p1->priority != p2->priority)
     return 0;
-  if (p1->is_outbound != p2->is_outbound)
+  if (p1->type != p2->type)
     return (0);
   if (p1->policy != p2->policy)
     return (0);
@@ -96,6 +96,42 @@ ipsec_spd_entry_sort (void *a1, void *a2)
   return 0;
 }
 
+int
+ipsec_policy_mk_type (bool is_outbound,
+                     bool is_ipv6,
+                     ipsec_policy_action_t action,
+                     ipsec_spd_policy_type_t * type)
+{
+  if (is_outbound)
+    {
+      *type = (is_ipv6 ?
+              IPSEC_SPD_POLICY_IP6_OUTBOUND : IPSEC_SPD_POLICY_IP4_OUTBOUND);
+      return (0);
+    }
+  else
+    {
+      switch (action)
+       {
+       case IPSEC_POLICY_ACTION_PROTECT:
+         *type = (is_ipv6 ?
+                  IPSEC_SPD_POLICY_IP6_INBOUND_PROTECT :
+                  IPSEC_SPD_POLICY_IP4_INBOUND_PROTECT);
+         return (0);
+       case IPSEC_POLICY_ACTION_BYPASS:
+         *type = (is_ipv6 ?
+                  IPSEC_SPD_POLICY_IP6_INBOUND_BYPASS :
+                  IPSEC_SPD_POLICY_IP4_INBOUND_BYPASS);
+         return (0);
+       case IPSEC_POLICY_ACTION_DISCARD:
+       case IPSEC_POLICY_ACTION_RESOLVE:
+         break;
+       }
+    }
+
+  /* Unsupported type */
+  return (-1);
+}
+
 int
 ipsec_add_del_policy (vlib_main_t * vm,
                      ipsec_policy_t * policy, int is_add, u32 * stat_index)
@@ -106,8 +142,8 @@ ipsec_add_del_policy (vlib_main_t * vm,
   u32 spd_index;
   uword *p;
 
-  clib_warning ("policy-id %u priority %d is_outbound %u", policy->id,
-               policy->priority, policy->is_outbound);
+  clib_warning ("policy-id %u priority %d type %U", policy->id,
+               policy->priority, format_ipsec_policy_type, policy->type);
 
   if (policy->policy == IPSEC_POLICY_ACTION_PROTECT)
     {
@@ -139,75 +175,14 @@ ipsec_add_del_policy (vlib_main_t * vm,
                                      policy_index);
       vlib_zero_combined_counter (&ipsec_spd_policy_counters, policy_index);
 
-      if (policy->is_outbound)
-       {
-         if (policy->is_ipv6)
-           {
-             vec_add1 (spd->policies[IPSEC_SPD_POLICY_IP6_OUTBOUND],
-                       policy_index);
-             vec_sort_with_function (spd->policies
-                                     [IPSEC_SPD_POLICY_IP6_OUTBOUND],
-                                     ipsec_spd_entry_sort);
-           }
-         else
-           {
-             vec_add1 (spd->policies[IPSEC_SPD_POLICY_IP4_OUTBOUND],
-                       policy_index);
-             vec_sort_with_function (spd->policies
-                                     [IPSEC_SPD_POLICY_IP4_OUTBOUND],
-                                     ipsec_spd_entry_sort);
-           }
-       }
-      else
-       {
-         if (policy->is_ipv6)
-           {
-             if (policy->policy == IPSEC_POLICY_ACTION_PROTECT)
-               {
-                 vec_add1 (spd->policies
-                           [IPSEC_SPD_POLICY_IP6_INBOUND_PROTECT],
-                           policy_index);
-                 vec_sort_with_function (spd->policies
-                                         [IPSEC_SPD_POLICY_IP6_INBOUND_PROTECT],
-                                         ipsec_spd_entry_sort);
-               }
-             else
-               {
-                 vec_add1
-                   (spd->policies[IPSEC_SPD_POLICY_IP6_INBOUND_BYPASS],
-                    policy_index);
-                 vec_sort_with_function
-                   (spd->policies[IPSEC_SPD_POLICY_IP6_INBOUND_BYPASS],
-                    ipsec_spd_entry_sort);
-               }
-           }
-         else
-           {
-             if (policy->policy == IPSEC_POLICY_ACTION_PROTECT)
-               {
-                 vec_add1 (spd->policies
-                           [IPSEC_SPD_POLICY_IP4_INBOUND_PROTECT],
-                           policy_index);
-                 vec_sort_with_function (spd->policies
-                                         [IPSEC_SPD_POLICY_IP4_INBOUND_PROTECT],
-                                         ipsec_spd_entry_sort);
-               }
-             else
-               {
-                 vec_add1
-                   (spd->policies[IPSEC_SPD_POLICY_IP4_INBOUND_BYPASS],
-                    policy_index);
-                 vec_sort_with_function
-                   (spd->policies[IPSEC_SPD_POLICY_IP4_INBOUND_BYPASS],
-                    ipsec_spd_entry_sort);
-               }
-           }
-       }
+      vec_add1 (spd->policies[policy->type], policy_index);
+      vec_sort_with_function (spd->policies[policy->type],
+                             ipsec_spd_entry_sort);
       *stat_index = policy_index;
     }
   else
     {
-      ipsec_spd_policy_t ptype;
+      ipsec_spd_policy_type_t ptype;
       u32 ii;
 
       FOR_EACH_IPSEC_SPD_POLICY_TYPE (ptype)
index 40fad34..6d6b695 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef __IPSEC_SPD_POLICY_H__
 #define __IPSEC_SPD_POLICY_H__
 
-#include <vlib/vlib.h>
+#include <vnet/ipsec/ipsec_spd.h>
 
 #define foreach_ipsec_policy_action \
   _ (0, BYPASS, "bypass")           \
@@ -55,7 +55,9 @@ typedef struct ipsec_policy_t_
 {
   u32 id;
   i32 priority;
-  u8 is_outbound;
+
+  // the type of policy
+  ipsec_spd_policy_type_t type;
 
   // Selector
   u8 is_ipv6;
@@ -84,6 +86,11 @@ extern uword unformat_ipsec_policy_action (unformat_input_t * input,
                                           va_list * args);
 
 
+extern int ipsec_policy_mk_type (bool is_outbound,
+                                bool is_ipv6,
+                                ipsec_policy_action_t action,
+                                ipsec_spd_policy_type_t * type);
+
 #endif /* __IPSEC_SPD_POLICY_H__ */
 
 /*