From 9f231d4f147c7e3fdf562680488ec5dfe7655b5e Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Tue, 19 Mar 2019 10:06:00 +0000 Subject: [PATCH] IPSEC: tidy the policy types Change-Id: I5e981f12ff44243623cfd18d5e0ae06a7dfd1eb8 Signed-off-by: Neale Ranns --- src/vnet/ipsec/ipsec_api.c | 11 ++-- src/vnet/ipsec/ipsec_cli.c | 19 ++++++- src/vnet/ipsec/ipsec_format.c | 24 ++++++++- src/vnet/ipsec/ipsec_spd.h | 4 +- src/vnet/ipsec/ipsec_spd_policy.c | 111 +++++++++++++++----------------------- src/vnet/ipsec/ipsec_spd_policy.h | 11 +++- 6 files changed, 102 insertions(+), 78 deletions(-) diff --git a/src/vnet/ipsec/ipsec_api.c b/src/vnet/ipsec/ipsec_api.c index 906f4c4c16d..d0f543fe520 100644 --- a/src/vnet/ipsec/ipsec_api.c +++ b/src/vnet/ipsec/ipsec_api.c @@ -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; diff --git a/src/vnet/ipsec/ipsec_cli.c b/src/vnet/ipsec/ipsec_cli.c index 648455bbecf..8a4d068f9f7 100644 --- a/src/vnet/ipsec/ipsec_cli.c +++ b/src/vnet/ipsec/ipsec_cli.c @@ -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) diff --git a/src/vnet/ipsec/ipsec_format.c b/src/vnet/ipsec/ipsec_format.c index d65b2a7ee4f..aa5562caf63 100644 --- a/src/vnet/ipsec/ipsec_format.c +++ b/src/vnet/ipsec/ipsec_format.c @@ -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); diff --git a/src/vnet/ipsec/ipsec_spd.h b/src/vnet/ipsec/ipsec_spd.h index dd09041b046..1e6c2c3bc90 100644 --- a/src/vnet/ipsec/ipsec_spd.h +++ b/src/vnet/ipsec/ipsec_spd.h @@ -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 */ diff --git a/src/vnet/ipsec/ipsec_spd_policy.c b/src/vnet/ipsec/ipsec_spd_policy.c index 5ad147b934f..d4a32e38568 100644 --- a/src/vnet/ipsec/ipsec_spd_policy.c +++ b/src/vnet/ipsec/ipsec_spd_policy.c @@ -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) diff --git a/src/vnet/ipsec/ipsec_spd_policy.h b/src/vnet/ipsec/ipsec_spd_policy.h index 40fad342978..6d6b69592b0 100644 --- a/src/vnet/ipsec/ipsec_spd_policy.h +++ b/src/vnet/ipsec/ipsec_spd_policy.h @@ -15,7 +15,7 @@ #ifndef __IPSEC_SPD_POLICY_H__ #define __IPSEC_SPD_POLICY_H__ -#include +#include #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__ */ /* -- 2.16.6