diff options
author | Piotr Bronowski <piotrx.bronowski@intel.com> | 2022-06-09 09:09:28 +0000 |
---|---|---|
committer | Fan Zhang <roy.fan.zhang@intel.com> | 2022-06-28 14:53:07 +0000 |
commit | 815c6a4fbcbb636ce3b4dc98446ad205a30670a6 (patch) | |
tree | 36e3b6aec51cdd5603dce1c9dd701da869c11c39 /src/vnet/ipsec | |
parent | 5b4b4c05ff06b866b90b0df9b2be2ed28e606f16 (diff) |
ipsec: change wildcard value for any protocol of spd policy
Currently 0 has been used as the wildcard representing ANY type of
protocol. However 0 is valid value of ip protocol (HOPOPT) and therefore
it should not be used as a wildcard. Instead 255 is used which is
guaranteed by IANA to be reserved and not used as a protocol id.
Type: improvement
Signed-off-by: Piotr Bronowski <piotrx.bronowski@intel.com>
Change-Id: I2320bae6fe380cb999dc5a9187beb68fda2d31eb
Diffstat (limited to 'src/vnet/ipsec')
-rw-r--r-- | src/vnet/ipsec/ipsec.api | 84 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_api.c | 62 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_cli.c | 1 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_format.c | 2 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_output.c | 6 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_spd_policy.h | 2 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_test.c | 104 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_types.api | 97 |
8 files changed, 300 insertions, 58 deletions
diff --git a/src/vnet/ipsec/ipsec.api b/src/vnet/ipsec/ipsec.api index be45c3e2401..18df893c0d4 100644 --- a/src/vnet/ipsec/ipsec.api +++ b/src/vnet/ipsec/ipsec.api @@ -57,74 +57,35 @@ autoreply define ipsec_interface_add_del_spd u32 spd_id; }; +/** \brief IPsec: Add/delete Security Policy Database entry -enum ipsec_spd_action -{ - /* bypass - no IPsec processing */ - IPSEC_API_SPD_ACTION_BYPASS = 0, - /* discard - discard packet with ICMP processing */ - IPSEC_API_SPD_ACTION_DISCARD, - /* resolve - send request to control plane for SA resolving */ - IPSEC_API_SPD_ACTION_RESOLVE, - /* protect - apply IPsec policy using following parameters */ - IPSEC_API_SPD_ACTION_PROTECT, -}; - -/** \brief IPsec: Security Policy Database entry - - See RFC 4301, 4.4.1.1 on how to match packet to selectors - - @param spd_id - SPD instance id (control plane allocated) - @param priority - priority of SPD entry (non-unique value). Used to order SPD matching - higher priorities match before lower - @param is_outbound - entry applies to outbound traffic if non-zero, otherwise applies to inbound traffic - @param remote_address_start - start of remote address range to match - @param remote_address_stop - end of remote address range to match - @param local_address_start - start of local address range to match - @param local_address_stop - end of local address range to match - @param protocol - protocol type to match [0 means any] otherwise IANA value - @param remote_port_start - start of remote port range to match ... - @param remote_port_stop - end of remote port range to match [0 to 65535 means ANY, 65535 to 0 means OPAQUE] - @param local_port_start - start of local port range to match ... - @param local_port_stop - end of remote port range to match [0 to 65535 means ANY, 65535 to 0 means OPAQUE] - @param policy - action to perform on match - @param sa_id - SAD instance id (control plane allocated) + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - add SPD if non-zero, else delete + @param entry - Description of the entry to add/dell */ -typedef ipsec_spd_entry +define ipsec_spd_entry_add_del { - u32 spd_id; - i32 priority; - bool is_outbound; - - u32 sa_id; - vl_api_ipsec_spd_action_t policy; - /* Which protocol?? */ - u8 protocol; - - // Selector - vl_api_address_t remote_address_start; - vl_api_address_t remote_address_stop; - vl_api_address_t local_address_start; - vl_api_address_t local_address_stop; - - u16 remote_port_start; - u16 remote_port_stop; - u16 local_port_start; - u16 local_port_stop; + option deprecated; + u32 client_index; + u32 context; + bool is_add; + vl_api_ipsec_spd_entry_t entry; }; -/** \brief IPsec: Add/delete Security Policy Database entry +/** \brief IPsec: Add/delete Security Policy Database entry v2 @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @param is_add - add SPD if non-zero, else delete @param entry - Description of the entry to add/dell */ -define ipsec_spd_entry_add_del +define ipsec_spd_entry_add_del_v2 { u32 client_index; u32 context; bool is_add; - vl_api_ipsec_spd_entry_t entry; + vl_api_ipsec_spd_entry_v2_t entry; }; /** \brief IPsec: Reply Add/delete Security Policy Database entry @@ -140,6 +101,19 @@ define ipsec_spd_entry_add_del_reply u32 stat_index; }; +/** \brief IPsec: Reply Add/delete Security Policy Database entry v2 + + @param context - sender context, to match reply w/ request + @param retval - success/fail rutrun code + @param stat_index - An index for the policy in the stats segment @ /net/ipec/policy +*/ +define ipsec_spd_entry_add_del_v2_reply +{ + u32 context; + i32 retval; + u32 stat_index; +}; + /** \brief Dump IPsec all SPD IDs @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @@ -197,6 +171,7 @@ define ipsec_sad_entry_add_del bool is_add; vl_api_ipsec_sad_entry_t entry; }; + define ipsec_sad_entry_add_del_v2 { u32 client_index; @@ -204,6 +179,7 @@ define ipsec_sad_entry_add_del_v2 bool is_add; vl_api_ipsec_sad_entry_v2_t entry; }; + define ipsec_sad_entry_add_del_v3 { u32 client_index; @@ -231,12 +207,14 @@ define ipsec_sad_entry_add_del_reply i32 retval; u32 stat_index; }; + define ipsec_sad_entry_add_del_v2_reply { u32 context; i32 retval; u32 stat_index; }; + define ipsec_sad_entry_add_del_v3_reply { u32 context; diff --git a/src/vnet/ipsec/ipsec_api.c b/src/vnet/ipsec/ipsec_api.c index 72231f656ff..15f7bfafad3 100644 --- a/src/vnet/ipsec/ipsec_api.c +++ b/src/vnet/ipsec/ipsec_api.c @@ -233,7 +233,8 @@ static void vl_api_ipsec_spd_entry_add_del_t_handler p.is_ipv6 = (itype == IP46_TYPE_IP6); - p.protocol = mp->entry.protocol; + p.protocol = + mp->entry.protocol ? mp->entry.protocol : IPSEC_POLICY_PROTOCOL_ANY; p.rport.start = ntohs (mp->entry.remote_port_start); p.rport.stop = ntohs (mp->entry.remote_port_stop); p.lport.start = ntohs (mp->entry.local_port_start); @@ -271,6 +272,65 @@ out: /* *INDENT-ON* */ } +static void +vl_api_ipsec_spd_entry_add_del_v2_t_handler ( + vl_api_ipsec_spd_entry_add_del_v2_t *mp) +{ + vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main (); + vl_api_ipsec_spd_entry_add_del_reply_t *rmp; + ip46_type_t itype; + u32 stat_index; + int rv; + + stat_index = ~0; + + ipsec_policy_t p; + + clib_memset (&p, 0, sizeof (p)); + + p.id = ntohl (mp->entry.spd_id); + p.priority = ntohl (mp->entry.priority); + + itype = ip_address_decode (&mp->entry.remote_address_start, &p.raddr.start); + ip_address_decode (&mp->entry.remote_address_stop, &p.raddr.stop); + ip_address_decode (&mp->entry.local_address_start, &p.laddr.start); + ip_address_decode (&mp->entry.local_address_stop, &p.laddr.stop); + + p.is_ipv6 = (itype == IP46_TYPE_IP6); + + p.protocol = mp->entry.protocol; + p.rport.start = ntohs (mp->entry.remote_port_start); + p.rport.stop = ntohs (mp->entry.remote_port_stop); + p.lport.start = ntohs (mp->entry.local_port_start); + p.lport.stop = ntohs (mp->entry.local_port_stop); + + rv = ipsec_spd_action_decode (mp->entry.policy, &p.policy); + + if (rv) + goto out; + + /* policy action resolve unsupported */ + if (p.policy == IPSEC_POLICY_ACTION_RESOLVE) + { + clib_warning ("unsupported action: 'resolve'"); + rv = VNET_API_ERROR_UNIMPLEMENTED; + 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) + goto out; + +out: + REPLY_MACRO2 (VL_API_IPSEC_SPD_ENTRY_ADD_DEL_REPLY, + ({ rmp->stat_index = ntohl (stat_index); })); +} + static void vl_api_ipsec_sad_entry_add_del_t_handler (vl_api_ipsec_sad_entry_add_del_t * mp) { diff --git a/src/vnet/ipsec/ipsec_cli.c b/src/vnet/ipsec/ipsec_cli.c index df8f9378111..8b436b6b805 100644 --- a/src/vnet/ipsec/ipsec_cli.c +++ b/src/vnet/ipsec/ipsec_cli.c @@ -279,6 +279,7 @@ ipsec_policy_add_del_command_fn (vlib_main_t * vm, clib_memset (&p, 0, sizeof (p)); p.lport.stop = p.rport.stop = ~0; remote_range_set = local_range_set = is_outbound = 0; + p.protocol = IPSEC_POLICY_PROTOCOL_ANY; if (!unformat_user (input, unformat_line_input, line_input)) return 0; diff --git a/src/vnet/ipsec/ipsec_format.c b/src/vnet/ipsec/ipsec_format.c index c8c0170efe7..24c9bee2878 100644 --- a/src/vnet/ipsec/ipsec_format.c +++ b/src/vnet/ipsec/ipsec_format.c @@ -168,7 +168,7 @@ format_ipsec_policy (u8 * s, va_list * args) pi, p->priority, format_ipsec_policy_action, p->policy, format_ipsec_policy_type, p->type); - if (p->protocol) + if (p->protocol != IPSEC_POLICY_PROTOCOL_ANY) { s = format (s, "%U", format_ip_protocol, p->protocol); } diff --git a/src/vnet/ipsec/ipsec_output.c b/src/vnet/ipsec/ipsec_output.c index 6d6608d7a32..760d0921f67 100644 --- a/src/vnet/ipsec/ipsec_output.c +++ b/src/vnet/ipsec/ipsec_output.c @@ -158,7 +158,8 @@ ipsec_output_policy_match (ipsec_spd_t *spd, u8 pr, u32 la, u32 ra, u16 lp, vec_foreach (i, spd->policies[IPSEC_SPD_POLICY_IP4_OUTBOUND]) { p = pool_elt_at_index (im->policies, *i); - if (PREDICT_FALSE (p->protocol && (p->protocol != pr))) + if (PREDICT_FALSE ((p->protocol != IPSEC_POLICY_PROTOCOL_ANY) && + (p->protocol != pr))) continue; if (ra < clib_net_to_host_u32 (p->raddr.start.ip4.as_u32)) @@ -232,7 +233,8 @@ ipsec6_output_policy_match (ipsec_spd_t * spd, vec_foreach (i, spd->policies[IPSEC_SPD_POLICY_IP6_OUTBOUND]) { p = pool_elt_at_index (im->policies, *i); - if (PREDICT_FALSE (p->protocol && (p->protocol != pr))) + if (PREDICT_FALSE ((p->protocol != IPSEC_POLICY_PROTOCOL_ANY) && + (p->protocol != pr))) continue; if (!ip6_addr_match_range (ra, &p->raddr.start.ip6, &p->raddr.stop.ip6)) diff --git a/src/vnet/ipsec/ipsec_spd_policy.h b/src/vnet/ipsec/ipsec_spd_policy.h index 6d6b69592b0..fc9c23a4c62 100644 --- a/src/vnet/ipsec/ipsec_spd_policy.h +++ b/src/vnet/ipsec/ipsec_spd_policy.h @@ -17,6 +17,8 @@ #include <vnet/ipsec/ipsec_spd.h> +#define IPSEC_POLICY_PROTOCOL_ANY IP_PROTOCOL_RESERVED + #define foreach_ipsec_policy_action \ _ (0, BYPASS, "bypass") \ _ (1, DISCARD, "discard") \ diff --git a/src/vnet/ipsec/ipsec_test.c b/src/vnet/ipsec/ipsec_test.c index f3a9992e916..f1436193636 100644 --- a/src/vnet/ipsec/ipsec_test.c +++ b/src/vnet/ipsec/ipsec_test.c @@ -73,7 +73,103 @@ api_ipsec_spd_entry_add_del (vat_main_t *vam) unformat_input_t *i = vam->input; vl_api_ipsec_spd_entry_add_del_t *mp; u8 is_add = 1, is_outbound = 0; - u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0; + u32 spd_id = 0, sa_id = 0, protocol = IPSEC_POLICY_PROTOCOL_ANY, policy = 0; + i32 priority = 0; + u32 rport_start = 0, rport_stop = (u32) ~0; + u32 lport_start = 0, lport_stop = (u32) ~0; + vl_api_address_t laddr_start = {}, laddr_stop = {}, raddr_start = {}, + raddr_stop = {}; + int ret; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "del")) + is_add = 0; + if (unformat (i, "outbound")) + is_outbound = 1; + if (unformat (i, "inbound")) + is_outbound = 0; + else if (unformat (i, "spd_id %d", &spd_id)) + ; + else if (unformat (i, "sa_id %d", &sa_id)) + ; + else if (unformat (i, "priority %d", &priority)) + ; + else if (unformat (i, "protocol %d", &protocol)) + ; + else if (unformat (i, "lport_start %d", &lport_start)) + ; + else if (unformat (i, "lport_stop %d", &lport_stop)) + ; + else if (unformat (i, "rport_start %d", &rport_start)) + ; + else if (unformat (i, "rport_stop %d", &rport_stop)) + ; + else if (unformat (i, "laddr_start %U", unformat_vl_api_address, + &laddr_start)) + ; + else if (unformat (i, "laddr_stop %U", unformat_vl_api_address, + &laddr_stop)) + ; + else if (unformat (i, "raddr_start %U", unformat_vl_api_address, + &raddr_start)) + ; + else if (unformat (i, "raddr_stop %U", unformat_vl_api_address, + &raddr_stop)) + ; + else if (unformat (i, "action %U", unformat_ipsec_policy_action, + &policy)) + { + if (policy == IPSEC_POLICY_ACTION_RESOLVE) + { + clib_warning ("unsupported action: 'resolve'"); + return -99; + } + } + else + { + clib_warning ("parse error '%U'", format_unformat_error, i); + return -99; + } + } + + M (IPSEC_SPD_ENTRY_ADD_DEL, mp); + + mp->is_add = is_add; + + mp->entry.spd_id = ntohl (spd_id); + mp->entry.priority = ntohl (priority); + mp->entry.is_outbound = is_outbound; + + clib_memcpy (&mp->entry.remote_address_start, &raddr_start, + sizeof (vl_api_address_t)); + clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop, + sizeof (vl_api_address_t)); + clib_memcpy (&mp->entry.local_address_start, &laddr_start, + sizeof (vl_api_address_t)); + clib_memcpy (&mp->entry.local_address_stop, &laddr_stop, + sizeof (vl_api_address_t)); + + mp->entry.protocol = protocol ? (u8) protocol : IPSEC_POLICY_PROTOCOL_ANY; + mp->entry.local_port_start = ntohs ((u16) lport_start); + mp->entry.local_port_stop = ntohs ((u16) lport_stop); + mp->entry.remote_port_start = ntohs ((u16) rport_start); + mp->entry.remote_port_stop = ntohs ((u16) rport_stop); + mp->entry.policy = (u8) policy; + mp->entry.sa_id = ntohl (sa_id); + + S (mp); + W (ret); + return ret; +} + +static int +api_ipsec_spd_entry_add_del_v2 (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_ipsec_spd_entry_add_del_t *mp; + u8 is_add = 1, is_outbound = 0; + u32 spd_id = 0, sa_id = 0, protocol = IPSEC_POLICY_PROTOCOL_ANY, policy = 0; i32 priority = 0; u32 rport_start = 0, rport_stop = (u32) ~0; u32 lport_start = 0, lport_stop = (u32) ~0; @@ -257,6 +353,12 @@ vl_api_ipsec_spd_entry_add_del_reply_t_handler ( { } +static void +vl_api_ipsec_spd_entry_add_del_v2_reply_t_handler ( + vl_api_ipsec_spd_entry_add_del_v2_reply_t *mp) +{ +} + static int api_ipsec_spds_dump (vat_main_t *vam) { diff --git a/src/vnet/ipsec/ipsec_types.api b/src/vnet/ipsec/ipsec_types.api index ed04f470fd2..fd7068e926e 100644 --- a/src/vnet/ipsec/ipsec_types.api +++ b/src/vnet/ipsec/ipsec_types.api @@ -95,6 +95,102 @@ typedef key u8 data[128]; }; +enum ipsec_spd_action +{ + /* bypass - no IPsec processing */ + IPSEC_API_SPD_ACTION_BYPASS = 0, + /* discard - discard packet with ICMP processing */ + IPSEC_API_SPD_ACTION_DISCARD, + /* resolve - send request to control plane for SA resolving */ + IPSEC_API_SPD_ACTION_RESOLVE, + /* protect - apply IPsec policy using following parameters */ + IPSEC_API_SPD_ACTION_PROTECT, +}; + +/** \brief IPsec: Security Policy Database entry + + See RFC 4301, 4.4.1.1 on how to match packet to selectors + + @param spd_id - SPD instance id (control plane allocated) + @param priority - priority of SPD entry (non-unique value). Used to order SPD matching - higher priorities match before lower + @param is_outbound - entry applies to outbound traffic if non-zero, otherwise applies to inbound traffic + @param remote_address_start - start of remote address range to match + @param remote_address_stop - end of remote address range to match + @param local_address_start - start of local address range to match + @param local_address_stop - end of local address range to match + @param protocol - protocol type to match [0 means any] otherwise IANA value + @param remote_port_start - start of remote port range to match ... + @param remote_port_stop - end of remote port range to match [0 to 65535 means ANY, 65535 to 0 means OPAQUE] + @param local_port_start - start of local port range to match ... + @param local_port_stop - end of remote port range to match [0 to 65535 means ANY, 65535 to 0 means OPAQUE] + @param policy - action to perform on match + @param sa_id - SAD instance id (control plane allocated) +*/ +typedef ipsec_spd_entry +{ + u32 spd_id; + i32 priority; + bool is_outbound; + + u32 sa_id; + vl_api_ipsec_spd_action_t policy; + /* Which protocol?? */ + u8 protocol; + + // Selector + vl_api_address_t remote_address_start; + vl_api_address_t remote_address_stop; + vl_api_address_t local_address_start; + vl_api_address_t local_address_stop; + + u16 remote_port_start; + u16 remote_port_stop; + u16 local_port_start; + u16 local_port_stop; +}; + +/** \brief IPsec: Security Policy Database entry v2 + + See RFC 4301, 4.4.1.1 on how to match packet to selectors + + @param spd_id - SPD instance id (control plane allocated) + @param priority - priority of SPD entry (non-unique value). Used to order SPD matching - higher priorities match before lower + @param is_outbound - entry applies to outbound traffic if non-zero, otherwise applies to inbound traffic + @param remote_address_start - start of remote address range to match + @param remote_address_stop - end of remote address range to match + @param local_address_start - start of local address range to match + @param local_address_stop - end of local address range to match + @param protocol - protocol type to match [255 means any] otherwise IANA value + @param remote_port_start - start of remote port range to match ... + @param remote_port_stop - end of remote port range to match [0 to 65535 means ANY, 65535 to 0 means OPAQUE] + @param local_port_start - start of local port range to match ... + @param local_port_stop - end of remote port range to match [0 to 65535 means ANY, 65535 to 0 means OPAQUE] + @param policy - action to perform on match + @param sa_id - SAD instance id (control plane allocated) +*/ +typedef ipsec_spd_entry_v2 +{ + u32 spd_id; + i32 priority; + bool is_outbound; + + u32 sa_id; + vl_api_ipsec_spd_action_t policy; + u8 protocol; + + // Selector + vl_api_address_t remote_address_start; + vl_api_address_t remote_address_stop; + vl_api_address_t local_address_start; + vl_api_address_t local_address_stop; + + u16 remote_port_start; + u16 remote_port_stop; + u16 local_port_start; + u16 local_port_stop; +}; + + /** \brief IPsec: Security Association Database entry @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @@ -117,6 +213,7 @@ typedef key @param tunnel_flags - Flags controlling the copying of encap/decap value @param dscp - Fixed DSCP vaule for tunnel encap */ + typedef ipsec_sad_entry { u32 sad_id; |