aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec
diff options
context:
space:
mode:
authorNeale Ranns <neale@graphiant.com>2021-02-04 11:09:33 +0000
committerMatthew Smith <mgsmith@netgate.com>2021-02-08 19:37:28 +0000
commitc7eaa711f3e25580687df0618e9ca80d3dc85e5f (patch)
tree0871a2a166c46c3dc2a50bdc635de1a2a6cbc2b3 /src/vnet/ipsec
parent4c71d6c8f84d48754a8ead116f223088b85f587c (diff)
ipsec: Use the new tunnel API types to add flow label and TTL copy
support Type: feature Signed-off-by: Neale Ranns <neale@graphiant.com> Change-Id: I6d4a9b187daa725d4b2cbb66e11616802d44d2d3
Diffstat (limited to 'src/vnet/ipsec')
-rw-r--r--src/vnet/ipsec/ah_encrypt.c6
-rw-r--r--src/vnet/ipsec/esp_encrypt.c1
-rw-r--r--src/vnet/ipsec/ipsec.api37
-rw-r--r--src/vnet/ipsec/ipsec_api.c272
-rw-r--r--src/vnet/ipsec/ipsec_cli.c27
-rw-r--r--src/vnet/ipsec/ipsec_format.c22
-rw-r--r--src/vnet/ipsec/ipsec_input.c8
-rw-r--r--src/vnet/ipsec/ipsec_itf.c15
-rw-r--r--src/vnet/ipsec/ipsec_sa.c98
-rw-r--r--src/vnet/ipsec/ipsec_sa.h31
-rw-r--r--src/vnet/ipsec/ipsec_tun.c14
-rw-r--r--src/vnet/ipsec/ipsec_tun.h4
-rw-r--r--src/vnet/ipsec/ipsec_types.api24
13 files changed, 329 insertions, 230 deletions
diff --git a/src/vnet/ipsec/ah_encrypt.c b/src/vnet/ipsec/ah_encrypt.c
index a4c34917550..7213e473723 100644
--- a/src/vnet/ipsec/ah_encrypt.c
+++ b/src/vnet/ipsec/ah_encrypt.c
@@ -251,7 +251,7 @@ ah_encrypt_inline (vlib_main_t * vm,
oh6_0->ip6.ip_version_traffic_class_and_flow_label =
ih6_0->ip6.ip_version_traffic_class_and_flow_label;
- ip6_set_dscp_network_order (&oh6_0->ip6, sa0->dscp);
+ ip6_set_dscp_network_order (&oh6_0->ip6, sa0->tunnel.t_dscp);
tunnel_encap_fixup_6o6 (sa0->tunnel_flags,
&ih6_0->ip6, &oh6_0->ip6);
@@ -287,8 +287,8 @@ ah_encrypt_inline (vlib_main_t * vm,
oh0 = vlib_buffer_get_current (b[0]);
pd->ttl = ih0->ip4.ttl;
- if (sa0->dscp)
- pd->tos = sa0->dscp << 2;
+ if (sa0->tunnel.t_dscp)
+ pd->tos = sa0->tunnel.t_dscp << 2;
else
{
pd->tos = ih0->ip4.tos;
diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c
index 08f82db5d58..e64de26327f 100644
--- a/src/vnet/ipsec/esp_encrypt.c
+++ b/src/vnet/ipsec/esp_encrypt.c
@@ -829,6 +829,7 @@ esp_encrypt_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
}
else
next[0] = ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT;
+ b[0]->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
}
else /* transport mode */
{
diff --git a/src/vnet/ipsec/ipsec.api b/src/vnet/ipsec/ipsec.api
index c009d8dffaa..8d4580a2c28 100644
--- a/src/vnet/ipsec/ipsec.api
+++ b/src/vnet/ipsec/ipsec.api
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-option version = "5.0.0";
+option version = "5.0.1";
import "vnet/ipsec/ipsec_types.api";
import "vnet/interface_types.api";
@@ -191,6 +191,7 @@ define ipsec_spd_details {
*/
define ipsec_sad_entry_add_del
{
+ option deprecated;
u32 client_index;
u32 context;
bool is_add;
@@ -203,8 +204,17 @@ 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;
+ u32 context;
+ bool is_add;
+ vl_api_ipsec_sad_entry_v3_t entry;
+};
+
define ipsec_sad_entry_add_del_reply
{
+ option deprecated;
u32 context;
i32 retval;
u32 stat_index;
@@ -215,6 +225,12 @@ define ipsec_sad_entry_add_del_v2_reply
i32 retval;
u32 stat_index;
};
+define ipsec_sad_entry_add_del_v3_reply
+{
+ u32 context;
+ i32 retval;
+ u32 stat_index;
+};
/** \brief Add or Update Protection for a tunnel with IPSEC
@@ -378,6 +394,7 @@ define ipsec_itf_details
*/
define ipsec_sa_dump
{
+ option deprecated;
u32 client_index;
u32 context;
u32 sa_id;
@@ -388,6 +405,12 @@ define ipsec_sa_v2_dump
u32 context;
u32 sa_id;
};
+define ipsec_sa_v3_dump
+{
+ u32 client_index;
+ u32 context;
+ u32 sa_id;
+};
/** \brief IPsec security association database response
@param context - sender context which was passed in the request
@@ -402,6 +425,7 @@ define ipsec_sa_v2_dump
@param stat_index - index for the SA in the stats segment @ /net/ipsec/sa
*/
define ipsec_sa_details {
+ option deprecated;
u32 context;
vl_api_ipsec_sad_entry_t entry;
@@ -425,6 +449,17 @@ define ipsec_sa_v2_details {
u32 stat_index;
};
+define ipsec_sa_v3_details {
+ u32 context;
+ vl_api_ipsec_sad_entry_v3_t entry;
+
+ vl_api_interface_index_t sw_if_index;
+ u64 seq_outbound;
+ u64 last_seq_inbound;
+ u64 replay_window;
+
+ u32 stat_index;
+};
/** \brief Dump IPsec backends
@param client_index - opaque cookie to identify the sender
diff --git a/src/vnet/ipsec/ipsec_api.c b/src/vnet/ipsec/ipsec_api.c
index 1a419e5c21a..a3e0545c1b5 100644
--- a/src/vnet/ipsec/ipsec_api.c
+++ b/src/vnet/ipsec/ipsec_api.c
@@ -54,26 +54,28 @@
#include <vlibapi/api_helper_macros.h>
-#define foreach_vpe_api_msg \
-_(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
-_(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
-_(IPSEC_SPD_ENTRY_ADD_DEL, ipsec_spd_entry_add_del) \
-_(IPSEC_SAD_ENTRY_ADD_DEL, ipsec_sad_entry_add_del) \
-_(IPSEC_SAD_ENTRY_ADD_DEL_V2, ipsec_sad_entry_add_del_v2) \
-_(IPSEC_SA_DUMP, ipsec_sa_dump) \
-_(IPSEC_SA_V2_DUMP, ipsec_sa_v2_dump) \
-_(IPSEC_SPDS_DUMP, ipsec_spds_dump) \
-_(IPSEC_SPD_DUMP, ipsec_spd_dump) \
-_(IPSEC_SPD_INTERFACE_DUMP, ipsec_spd_interface_dump) \
-_(IPSEC_ITF_CREATE, ipsec_itf_create) \
-_(IPSEC_ITF_DELETE, ipsec_itf_delete) \
-_(IPSEC_ITF_DUMP, ipsec_itf_dump) \
-_(IPSEC_SELECT_BACKEND, ipsec_select_backend) \
-_(IPSEC_BACKEND_DUMP, ipsec_backend_dump) \
-_(IPSEC_TUNNEL_PROTECT_UPDATE, ipsec_tunnel_protect_update) \
-_(IPSEC_TUNNEL_PROTECT_DEL, ipsec_tunnel_protect_del) \
-_(IPSEC_TUNNEL_PROTECT_DUMP, ipsec_tunnel_protect_dump) \
-_(IPSEC_SET_ASYNC_MODE, ipsec_set_async_mode)
+#define foreach_vpe_api_msg \
+ _ (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del) \
+ _ (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd) \
+ _ (IPSEC_SPD_ENTRY_ADD_DEL, ipsec_spd_entry_add_del) \
+ _ (IPSEC_SAD_ENTRY_ADD_DEL, ipsec_sad_entry_add_del) \
+ _ (IPSEC_SAD_ENTRY_ADD_DEL_V2, ipsec_sad_entry_add_del_v2) \
+ _ (IPSEC_SAD_ENTRY_ADD_DEL_V3, ipsec_sad_entry_add_del_v3) \
+ _ (IPSEC_SA_DUMP, ipsec_sa_dump) \
+ _ (IPSEC_SA_V2_DUMP, ipsec_sa_v2_dump) \
+ _ (IPSEC_SA_V3_DUMP, ipsec_sa_v3_dump) \
+ _ (IPSEC_SPDS_DUMP, ipsec_spds_dump) \
+ _ (IPSEC_SPD_DUMP, ipsec_spd_dump) \
+ _ (IPSEC_SPD_INTERFACE_DUMP, ipsec_spd_interface_dump) \
+ _ (IPSEC_ITF_CREATE, ipsec_itf_create) \
+ _ (IPSEC_ITF_DELETE, ipsec_itf_delete) \
+ _ (IPSEC_ITF_DUMP, ipsec_itf_dump) \
+ _ (IPSEC_SELECT_BACKEND, ipsec_select_backend) \
+ _ (IPSEC_BACKEND_DUMP, ipsec_backend_dump) \
+ _ (IPSEC_TUNNEL_PROTECT_UPDATE, ipsec_tunnel_protect_update) \
+ _ (IPSEC_TUNNEL_PROTECT_DEL, ipsec_tunnel_protect_del) \
+ _ (IPSEC_TUNNEL_PROTECT_DUMP, ipsec_tunnel_protect_dump) \
+ _ (IPSEC_SET_ASYNC_MODE, ipsec_set_async_mode)
static void
vl_api_ipsec_spd_add_del_t_handler (vl_api_ipsec_spd_add_del_t * mp)
@@ -335,17 +337,21 @@ out:
static void vl_api_ipsec_sad_entry_add_del_t_handler
(vl_api_ipsec_sad_entry_add_del_t * mp)
{
- vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
vl_api_ipsec_sad_entry_add_del_reply_t *rmp;
- ip46_address_t tun_src = { }, tun_dst =
- {
- };
ipsec_key_t crypto_key, integ_key;
ipsec_crypto_alg_t crypto_alg;
ipsec_integ_alg_t integ_alg;
ipsec_protocol_t proto;
ipsec_sa_flags_t flags;
u32 id, spi, sa_index = ~0;
+ tunnel_t tun = {
+ .t_flags = TUNNEL_FLAG_NONE,
+ .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE,
+ .t_dscp = 0,
+ .t_mode = TUNNEL_MODE_P2P,
+ .t_table_id = 0,
+ .t_hop_limit = 255,
+ };
int rv;
#if WITH_LIBSSL > 0
@@ -373,19 +379,14 @@ static void vl_api_ipsec_sad_entry_add_del_t_handler
flags = ipsec_sa_flags_decode (mp->entry.flags);
- ip_address_decode (&mp->entry.tunnel_src, &tun_src);
- ip_address_decode (&mp->entry.tunnel_dst, &tun_dst);
+ ip_address_decode2 (&mp->entry.tunnel_src, &tun.t_src);
+ ip_address_decode2 (&mp->entry.tunnel_dst, &tun.t_dst);
if (mp->is_add)
- rv = ipsec_sa_add_and_lock (id, spi, proto,
- crypto_alg, &crypto_key,
- integ_alg, &integ_key, flags,
- 0, mp->entry.salt, &tun_src, &tun_dst,
- TUNNEL_ENCAP_DECAP_FLAG_NONE,
- IP_DSCP_CS0,
- &sa_index,
- htons (mp->entry.udp_src_port),
- htons (mp->entry.udp_dst_port));
+ rv = ipsec_sa_add_and_lock (
+ id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
+ mp->entry.salt, htons (mp->entry.udp_src_port),
+ htons (mp->entry.udp_dst_port), &tun, &sa_index);
else
rv = ipsec_sa_unlock_id (id);
@@ -407,10 +408,6 @@ static void vl_api_ipsec_sad_entry_add_del_v2_t_handler
{
vlib_main_t *vm __attribute__ ((unused)) = vlib_get_main ();
vl_api_ipsec_sad_entry_add_del_v2_reply_t *rmp;
- ip46_address_t tun_src = { }, tun_dst =
- {
- };
- tunnel_encap_decap_flags_t tunnel_flags;
ipsec_key_t crypto_key, integ_key;
ipsec_crypto_alg_t crypto_alg;
ipsec_integ_alg_t integ_alg;
@@ -418,6 +415,14 @@ static void vl_api_ipsec_sad_entry_add_del_v2_t_handler
ipsec_sa_flags_t flags;
u32 id, spi, sa_index = ~0;
int rv;
+ tunnel_t tun = {
+ .t_flags = TUNNEL_FLAG_NONE,
+ .t_encap_decap_flags = TUNNEL_ENCAP_DECAP_FLAG_NONE,
+ .t_dscp = 0,
+ .t_mode = TUNNEL_MODE_P2P,
+ .t_table_id = htonl (mp->entry.tx_table_id),
+ .t_hop_limit = 255,
+ };
#if WITH_LIBSSL > 0
@@ -439,8 +444,8 @@ static void vl_api_ipsec_sad_entry_add_del_v2_t_handler
if (rv)
goto out;
- rv =
- tunnel_encap_decap_flags_decode (mp->entry.tunnel_flags, &tunnel_flags);
+ rv = tunnel_encap_decap_flags_decode (mp->entry.tunnel_flags,
+ &tun.t_encap_decap_flags);
if (rv)
goto out;
@@ -449,16 +454,16 @@ static void vl_api_ipsec_sad_entry_add_del_v2_t_handler
ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
flags = ipsec_sa_flags_decode (mp->entry.flags);
+ tun.t_dscp = ip_dscp_decode (mp->entry.dscp);
- ip_address_decode (&mp->entry.tunnel_src, &tun_src);
- ip_address_decode (&mp->entry.tunnel_dst, &tun_dst);
+ ip_address_decode2 (&mp->entry.tunnel_src, &tun.t_src);
+ ip_address_decode2 (&mp->entry.tunnel_dst, &tun.t_dst);
if (mp->is_add)
rv = ipsec_sa_add_and_lock (
id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
- htonl (mp->entry.tx_table_id), mp->entry.salt, &tun_src, &tun_dst,
- tunnel_flags, ip_dscp_decode (mp->entry.dscp), &sa_index,
- htons (mp->entry.udp_src_port), htons (mp->entry.udp_dst_port));
+ mp->entry.salt, htons (mp->entry.udp_src_port),
+ htons (mp->entry.udp_dst_port), &tun, &sa_index);
else
rv = ipsec_sa_unlock_id (id);
@@ -476,6 +481,70 @@ out:
}
static void
+vl_api_ipsec_sad_entry_add_del_v3_t_handler (
+ vl_api_ipsec_sad_entry_add_del_v3_t *mp)
+{
+ vl_api_ipsec_sad_entry_add_del_v3_reply_t *rmp;
+ ipsec_key_t crypto_key, integ_key;
+ ipsec_crypto_alg_t crypto_alg;
+ ipsec_integ_alg_t integ_alg;
+ ipsec_protocol_t proto;
+ ipsec_sa_flags_t flags;
+ u32 id, spi, sa_index = ~0;
+ tunnel_t tun;
+ int rv;
+
+#if WITH_LIBSSL > 0
+
+ id = ntohl (mp->entry.sad_id);
+ spi = ntohl (mp->entry.spi);
+
+ rv = ipsec_proto_decode (mp->entry.protocol, &proto);
+
+ if (rv)
+ goto out;
+
+ rv = ipsec_crypto_algo_decode (mp->entry.crypto_algorithm, &crypto_alg);
+
+ if (rv)
+ goto out;
+
+ rv = ipsec_integ_algo_decode (mp->entry.integrity_algorithm, &integ_alg);
+
+ if (rv)
+ goto out;
+
+ flags = ipsec_sa_flags_decode (mp->entry.flags);
+
+ if (flags & IPSEC_SA_FLAG_IS_TUNNEL)
+ {
+ rv = tunnel_decode (&mp->entry.tunnel, &tun);
+
+ if (rv)
+ goto out;
+ }
+
+ ipsec_key_decode (&mp->entry.crypto_key, &crypto_key);
+ ipsec_key_decode (&mp->entry.integrity_key, &integ_key);
+
+ if (mp->is_add)
+ rv = ipsec_sa_add_and_lock (
+ id, spi, proto, crypto_alg, &crypto_key, integ_alg, &integ_key, flags,
+ mp->entry.salt, htons (mp->entry.udp_src_port),
+ htons (mp->entry.udp_dst_port), &tun, &sa_index);
+ else
+ rv = ipsec_sa_unlock_id (id);
+
+#else
+ rv = VNET_API_ERROR_UNIMPLEMENTED;
+#endif
+
+out:
+ REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_V3_REPLY,
+ { rmp->stat_index = htonl (sa_index); });
+}
+
+static void
send_ipsec_spds_details (ipsec_spd_t * spd, vl_api_registration_t * reg,
u32 context)
{
@@ -746,8 +815,7 @@ send_ipsec_sa_details (ipsec_sa_t * sa, void *arg)
mp->entry.sad_id = htonl (sa->id);
mp->entry.spi = htonl (sa->spi);
mp->entry.protocol = ipsec_proto_encode (sa->protocol);
- mp->entry.tx_table_id =
- htonl (fib_table_get_table_id (sa->tx_fib_index, FIB_PROTOCOL_IP4));
+ mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
@@ -773,10 +841,8 @@ send_ipsec_sa_details (ipsec_sa_t * sa, void *arg)
if (ipsec_sa_is_set_IS_TUNNEL (sa))
{
- ip_address_encode (&sa->tunnel_src_addr, IP46_TYPE_ANY,
- &mp->entry.tunnel_src);
- ip_address_encode (&sa->tunnel_dst_addr, IP46_TYPE_ANY,
- &mp->entry.tunnel_dst);
+ ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
+ ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
}
if (ipsec_sa_is_set_UDP_ENCAP (sa))
{
@@ -838,8 +904,7 @@ send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg)
mp->entry.sad_id = htonl (sa->id);
mp->entry.spi = htonl (sa->spi);
mp->entry.protocol = ipsec_proto_encode (sa->protocol);
- mp->entry.tx_table_id =
- htonl (fib_table_get_table_id (sa->tx_fib_index, FIB_PROTOCOL_IP4));
+ mp->entry.tx_table_id = htonl (sa->tunnel.t_table_id);
mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
@@ -865,10 +930,8 @@ send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg)
if (ipsec_sa_is_set_IS_TUNNEL (sa))
{
- ip_address_encode (&sa->tunnel_src_addr, IP46_TYPE_ANY,
- &mp->entry.tunnel_src);
- ip_address_encode (&sa->tunnel_dst_addr, IP46_TYPE_ANY,
- &mp->entry.tunnel_dst);
+ ip_address_encode2 (&sa->tunnel.t_src, &mp->entry.tunnel_src);
+ ip_address_encode2 (&sa->tunnel.t_dst, &mp->entry.tunnel_dst);
}
if (ipsec_sa_is_set_UDP_ENCAP (sa))
{
@@ -876,8 +939,9 @@ send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg)
mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
}
- mp->entry.tunnel_flags = tunnel_encap_decap_flags_encode (sa->tunnel_flags);
- mp->entry.dscp = ip_dscp_encode (sa->dscp);
+ mp->entry.tunnel_flags =
+ tunnel_encap_decap_flags_encode (sa->tunnel.t_encap_decap_flags);
+ mp->entry.dscp = ip_dscp_encode (sa->tunnel.t_dscp);
mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
@@ -897,7 +961,7 @@ send_ipsec_sa_v2_details (ipsec_sa_t * sa, void *arg)
}
static void
-vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
+vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_v2_dump_t *mp)
{
vl_api_registration_t *reg;
@@ -918,6 +982,92 @@ vl_api_ipsec_sa_v2_dump_t_handler (vl_api_ipsec_sa_dump_t * mp)
#endif
}
+static walk_rc_t
+send_ipsec_sa_v3_details (ipsec_sa_t *sa, void *arg)
+{
+ ipsec_dump_walk_ctx_t *ctx = arg;
+ vl_api_ipsec_sa_v3_details_t *mp;
+ ipsec_main_t *im = &ipsec_main;
+
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ clib_memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_IPSEC_SA_V3_DETAILS);
+ mp->context = ctx->context;
+
+ mp->entry.sad_id = htonl (sa->id);
+ mp->entry.spi = htonl (sa->spi);
+ mp->entry.protocol = ipsec_proto_encode (sa->protocol);
+
+ mp->entry.crypto_algorithm = ipsec_crypto_algo_encode (sa->crypto_alg);
+ ipsec_key_encode (&sa->crypto_key, &mp->entry.crypto_key);
+
+ mp->entry.integrity_algorithm = ipsec_integ_algo_encode (sa->integ_alg);
+ ipsec_key_encode (&sa->integ_key, &mp->entry.integrity_key);
+
+ mp->entry.flags = ipsec_sad_flags_encode (sa);
+ mp->entry.salt = clib_host_to_net_u32 (sa->salt);
+
+ if (ipsec_sa_is_set_IS_PROTECT (sa))
+ {
+ ipsec_sa_dump_match_ctx_t ctx = {
+ .sai = sa - im->sad,
+ .sw_if_index = ~0,
+ };
+ ipsec_tun_protect_walk (ipsec_sa_dump_match_sa, &ctx);
+
+ mp->sw_if_index = htonl (ctx.sw_if_index);
+ }
+ else
+ mp->sw_if_index = ~0;
+
+ if (ipsec_sa_is_set_IS_TUNNEL (sa))
+ tunnel_encode (&sa->tunnel, &mp->entry.tunnel);
+
+ if (ipsec_sa_is_set_UDP_ENCAP (sa))
+ {
+ mp->entry.udp_src_port = sa->udp_hdr.src_port;
+ mp->entry.udp_dst_port = sa->udp_hdr.dst_port;
+ }
+
+ mp->seq_outbound = clib_host_to_net_u64 (((u64) sa->seq));
+ mp->last_seq_inbound = clib_host_to_net_u64 (((u64) sa->last_seq));
+ if (ipsec_sa_is_set_USE_ESN (sa))
+ {
+ mp->seq_outbound |= (u64) (clib_host_to_net_u32 (sa->seq_hi));
+ mp->last_seq_inbound |= (u64) (clib_host_to_net_u32 (sa->last_seq_hi));
+ }
+ if (ipsec_sa_is_set_USE_ANTI_REPLAY (sa))
+ mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
+
+ mp->stat_index = clib_host_to_net_u32 (sa->stat_index);
+
+ vl_api_send_msg (ctx->reg, (u8 *) mp);
+
+ return (WALK_CONTINUE);
+}
+
+static void
+vl_api_ipsec_sa_v3_dump_t_handler (vl_api_ipsec_sa_v3_dump_t *mp)
+{
+ vl_api_registration_t *reg;
+
+#if WITH_LIBSSL > 0
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ ipsec_dump_walk_ctx_t ctx = {
+ .reg = reg,
+ .context = mp->context,
+ };
+
+ ipsec_sa_walk (send_ipsec_sa_v3_details, &ctx);
+
+#else
+ clib_warning ("unimplemented");
+#endif
+}
+
static void
vl_api_ipsec_backend_dump_t_handler (vl_api_ipsec_backend_dump_t * mp)
{
diff --git a/src/vnet/ipsec/ipsec_cli.c b/src/vnet/ipsec/ipsec_cli.c
index b708e50378c..eed910edb93 100644
--- a/src/vnet/ipsec/ipsec_cli.c
+++ b/src/vnet/ipsec/ipsec_cli.c
@@ -86,9 +86,6 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm,
vlib_cli_command_t * cmd)
{
unformat_input_t _line_input, *line_input = &_line_input;
- ip46_address_t tun_src = { }, tun_dst =
- {
- };
ipsec_crypto_alg_t crypto_alg;
ipsec_integ_alg_t integ_alg;
ipsec_protocol_t proto;
@@ -101,8 +98,7 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm,
u16 udp_src, udp_dst;
int is_add, rv;
u32 m_args = 0;
- ip_dscp_t dscp;
- u32 tx_table_id;
+ tunnel_t tun;
salt = 0;
error = NULL;
@@ -112,8 +108,6 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm,
integ_alg = IPSEC_INTEG_ALG_NONE;
crypto_alg = IPSEC_CRYPTO_ALG_NONE;
udp_src = udp_dst = IPSEC_UDP_PORT_NONE;
- dscp = IP_DSCP_CS0;
- tx_table_id = 0;
if (!unformat_user (input, unformat_line_input, line_input))
return 0;
@@ -149,22 +143,16 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm,
else if (unformat (line_input, "integ-alg %U",
unformat_ipsec_integ_alg, &integ_alg))
;
- else if (unformat (line_input, "tunnel-src %U",
- unformat_ip46_address, &tun_src, IP46_TYPE_ANY))
+ else if (unformat (line_input, " %U", unformat_tunnel, &tun))
{
flags |= IPSEC_SA_FLAG_IS_TUNNEL;
- if (!ip46_address_is_ip4 (&tun_src))
+ if (AF_IP6 == tunnel_get_af (&tun))
flags |= IPSEC_SA_FLAG_IS_TUNNEL_V6;
}
- else if (unformat (line_input, "tunnel-dst %U",
- unformat_ip46_address, &tun_dst, IP46_TYPE_ANY))
- ;
else if (unformat (line_input, "udp-src-port %d", &i))
udp_src = i;
else if (unformat (line_input, "udp-dst-port %d", &i))
udp_dst = i;
- else if (unformat (line_input, "tx-table-id %d", &tx_table_id))
- ;
else if (unformat (line_input, "inbound"))
flags |= IPSEC_SA_FLAG_IS_INBOUND;
else if (unformat (line_input, "use-anti-replay"))
@@ -200,12 +188,9 @@ ipsec_sa_add_del_command_fn (vlib_main_t * vm,
error = clib_error_return (0, "missing spi");
goto done;
}
- rv = ipsec_sa_add_and_lock (id, spi, proto, crypto_alg,
- &ck, integ_alg, &ik, flags,
- tx_table_id, clib_host_to_net_u32 (salt),
- &tun_src, &tun_dst,
- TUNNEL_ENCAP_DECAP_FLAG_NONE, dscp,
- &sai, udp_src, udp_dst);
+ rv = ipsec_sa_add_and_lock (id, spi, proto, crypto_alg, &ck, integ_alg,
+ &ik, flags, clib_host_to_net_u32 (salt),
+ udp_src, udp_dst, &tun, &sai);
}
else
{
diff --git a/src/vnet/ipsec/ipsec_format.c b/src/vnet/ipsec/ipsec_format.c
index 19321e7e347..001aa010364 100644
--- a/src/vnet/ipsec/ipsec_format.c
+++ b/src/vnet/ipsec/ipsec_format.c
@@ -273,7 +273,6 @@ format_ipsec_sa (u8 * s, va_list * args)
ipsec_format_flags_t flags = va_arg (*args, ipsec_format_flags_t);
ipsec_main_t *im = &ipsec_main;
vlib_counter_t counts;
- u32 tx_table_id;
ipsec_sa_t *sa;
if (pool_is_free_index (im->sad, sai))
@@ -318,26 +317,7 @@ format_ipsec_sa (u8 * s, va_list * args)
s = format (s, "\n packets %u bytes %u", counts.packets, counts.bytes);
if (ipsec_sa_is_set_IS_TUNNEL (sa))
- {
- tx_table_id = fib_table_get_table_id (
- sa->tx_fib_index,
- (ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ? FIB_PROTOCOL_IP6 :
- FIB_PROTOCOL_IP4));
- s = format (s, "\n table-ID %d tunnel %U src %U dst %U flags %U",
- tx_table_id,
- format_ip_dscp, sa->dscp,
- format_ip46_address, &sa->tunnel_src_addr, IP46_TYPE_ANY,
- format_ip46_address, &sa->tunnel_dst_addr, IP46_TYPE_ANY,
- format_tunnel_encap_decap_flags, sa->tunnel_flags);
- if (!ipsec_sa_is_set_IS_INBOUND (sa))
- {
- s =
- format (s, "\n resovle via fib-entry: %d",
- sa->fib_entry_index);
- s = format (s, "\n stacked on:");
- s = format (s, "\n %U", format_dpo_id, &sa->dpo, 6);
- }
- }
+ s = format (s, "\n%U", format_tunnel, &sa->tunnel, 3);
done:
return (s);
diff --git a/src/vnet/ipsec/ipsec_input.c b/src/vnet/ipsec/ipsec_input.c
index aa7627d9b4b..2ebc6c5a10c 100644
--- a/src/vnet/ipsec/ipsec_input.c
+++ b/src/vnet/ipsec/ipsec_input.c
@@ -118,10 +118,10 @@ 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 != clib_net_to_host_u32 (s->tunnel_dst_addr.ip4.as_u32))
+ if (da != clib_net_to_host_u32 (s->tunnel.t_dst.ip.ip4.as_u32))
continue;
- if (sa != clib_net_to_host_u32 (s->tunnel_src_addr.ip4.as_u32))
+ if (sa != clib_net_to_host_u32 (s->tunnel.t_src.ip.ip4.as_u32))
continue;
return p;
@@ -174,10 +174,10 @@ ipsec6_input_protect_policy_match (ipsec_spd_t * spd,
if (ipsec_sa_is_set_IS_TUNNEL (s))
{
- if (!ip6_address_is_equal (sa, &s->tunnel_src_addr.ip6))
+ if (!ip6_address_is_equal (sa, &s->tunnel.t_src.ip.ip6))
continue;
- if (!ip6_address_is_equal (da, &s->tunnel_dst_addr.ip6))
+ if (!ip6_address_is_equal (da, &s->tunnel.t_dst.ip.ip6))
continue;
return p;
diff --git a/src/vnet/ipsec/ipsec_itf.c b/src/vnet/ipsec/ipsec_itf.c
index 4a0f9e7bb6c..5f04fcf0a04 100644
--- a/src/vnet/ipsec/ipsec_itf.c
+++ b/src/vnet/ipsec/ipsec_itf.c
@@ -70,20 +70,11 @@ ipsec_itf_adj_stack (adj_index_t ai, u32 sai)
if (hw->flags & VNET_HW_INTERFACE_FLAG_LINK_UP)
{
const ipsec_sa_t *sa;
+ fib_prefix_t dst;
sa = ipsec_sa_get (sai);
-
- /* *INDENT-OFF* */
- const fib_prefix_t dst = {
- .fp_len = (ipsec_sa_is_set_IS_TUNNEL_V6(sa) ? 128 : 32),
- .fp_proto = (ipsec_sa_is_set_IS_TUNNEL_V6(sa)?
- FIB_PROTOCOL_IP6 :
- FIB_PROTOCOL_IP4),
- .fp_addr = sa->tunnel_dst_addr,
- };
- /* *INDENT-ON* */
-
- adj_midchain_delegate_stack (ai, sa->tx_fib_index, &dst);
+ ip_address_to_fib_prefix (&sa->tunnel.t_dst, &dst);
+ adj_midchain_delegate_stack (ai, sa->tunnel.t_fib_index, &dst);
}
else
adj_midchain_delegate_unstack (ai);
diff --git a/src/vnet/ipsec/ipsec_sa.c b/src/vnet/ipsec/ipsec_sa.c
index 515eb25d323..0a24aa2c8c0 100644
--- a/src/vnet/ipsec/ipsec_sa.c
+++ b/src/vnet/ipsec/ipsec_sa.c
@@ -72,15 +72,9 @@ static void
ipsec_sa_stack (ipsec_sa_t * sa)
{
ipsec_main_t *im = &ipsec_main;
- fib_forward_chain_type_t fct;
dpo_id_t tmp = DPO_INVALID;
- fct =
- fib_forw_chain_type_from_fib_proto ((ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ?
- FIB_PROTOCOL_IP6 :
- FIB_PROTOCOL_IP4));
-
- fib_entry_contribute_forwarding (sa->fib_entry_index, fct, &tmp);
+ tunnel_contribute_forwarding (&sa->tunnel, &tmp);
if (IPSEC_PROTOCOL_AH == sa->protocol)
dpo_stack_from_node ((ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ?
@@ -172,21 +166,11 @@ ipsec_sa_set_async_op_ids (ipsec_sa_t * sa)
}
int
-ipsec_sa_add_and_lock (u32 id,
- u32 spi,
- ipsec_protocol_t proto,
- ipsec_crypto_alg_t crypto_alg,
- const ipsec_key_t * ck,
- ipsec_integ_alg_t integ_alg,
- const ipsec_key_t * ik,
- ipsec_sa_flags_t flags,
- u32 tx_table_id,
- u32 salt,
- const ip46_address_t * tun_src,
- const ip46_address_t * tun_dst,
- tunnel_encap_decap_flags_t tunnel_flags,
- ip_dscp_t dscp,
- u32 * sa_out_index, u16 src_port, u16 dst_port)
+ipsec_sa_add_and_lock (u32 id, u32 spi, ipsec_protocol_t proto,
+ ipsec_crypto_alg_t crypto_alg, const ipsec_key_t *ck,
+ ipsec_integ_alg_t integ_alg, const ipsec_key_t *ik,
+ ipsec_sa_flags_t flags, u32 salt, u16 src_port,
+ u16 dst_port, const tunnel_t *tun, u32 *sa_out_index)
{
vlib_main_t *vm = vlib_get_main ();
ipsec_main_t *im = &ipsec_main;
@@ -194,6 +178,7 @@ ipsec_sa_add_and_lock (u32 id,
ipsec_sa_t *sa;
u32 sa_index;
uword *p;
+ int rv;
p = hash_get (im->sa_index_by_sa_id, id);
if (p)
@@ -208,13 +193,12 @@ ipsec_sa_add_and_lock (u32 id,
vlib_validate_combined_counter (&ipsec_sa_counters, sa_index);
vlib_zero_combined_counter (&ipsec_sa_counters, sa_index);
+ tunnel_copy (tun, &sa->tunnel);
sa->id = id;
sa->spi = spi;
sa->stat_index = sa_index;
sa->protocol = proto;
sa->flags = flags;
- sa->tunnel_flags = tunnel_flags;
- sa->dscp = dscp;
sa->salt = salt;
sa->thread_index = (vlib_num_workers ()) ? ~0 : 0;
if (integ_alg != IPSEC_INTEG_ALG_NONE)
@@ -226,8 +210,6 @@ ipsec_sa_add_and_lock (u32 id,
ipsec_sa_set_async_op_ids (sa);
clib_memcpy (&sa->crypto_key, ck, sizeof (sa->crypto_key));
- ip46_address_copy (&sa->tunnel_src_addr, tun_src);
- ip46_address_copy (&sa->tunnel_dst_addr, tun_dst);
sa->crypto_key_index = vnet_crypto_key_add (vm,
im->crypto_algs[crypto_alg].alg,
@@ -281,59 +263,33 @@ ipsec_sa_add_and_lock (u32 id,
if (ipsec_sa_is_set_IS_TUNNEL (sa) && !ipsec_sa_is_set_IS_INBOUND (sa))
{
- fib_protocol_t fproto = (ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ?
- FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
- fib_prefix_t pfx = {
- .fp_addr = sa->tunnel_dst_addr,
- .fp_len = (ipsec_sa_is_set_IS_TUNNEL_V6 (sa) ? 128 : 32),
- .fp_proto = fproto,
- };
- sa->tx_fib_index = fib_table_find (fproto, tx_table_id);
- if (sa->tx_fib_index == ~((u32) 0))
+ sa->tunnel_flags = sa->tunnel.t_encap_decap_flags;
+
+ rv = tunnel_resolve (&sa->tunnel, FIB_NODE_TYPE_IPSEC_SA, sa_index);
+
+ if (rv)
{
pool_put (im->sad, sa);
- return VNET_API_ERROR_NO_SUCH_FIB;
+ return rv;
}
-
- sa->fib_entry_index = fib_entry_track (sa->tx_fib_index,
- &pfx,
- FIB_NODE_TYPE_IPSEC_SA,
- sa_index, &sa->sibling);
ipsec_sa_stack (sa);
/* generate header templates */
if (ipsec_sa_is_set_IS_TUNNEL_V6 (sa))
{
- sa->ip6_hdr.ip_version_traffic_class_and_flow_label = 0x60;
- ip6_set_dscp_network_order (&sa->ip6_hdr, sa->dscp);
-
- sa->ip6_hdr.hop_limit = 254;
- sa->ip6_hdr.src_address.as_u64[0] =
- sa->tunnel_src_addr.ip6.as_u64[0];
- sa->ip6_hdr.src_address.as_u64[1] =
- sa->tunnel_src_addr.ip6.as_u64[1];
- sa->ip6_hdr.dst_address.as_u64[0] =
- sa->tunnel_dst_addr.ip6.as_u64[0];
- sa->ip6_hdr.dst_address.as_u64[1] =
- sa->tunnel_dst_addr.ip6.as_u64[1];
- if (ipsec_sa_is_set_UDP_ENCAP (sa))
- sa->ip6_hdr.protocol = IP_PROTOCOL_UDP;
- else
- sa->ip6_hdr.protocol = IP_PROTOCOL_IPSEC_ESP;
+ tunnel_build_v6_hdr (&sa->tunnel,
+ (ipsec_sa_is_set_UDP_ENCAP (sa) ?
+ IP_PROTOCOL_UDP :
+ IP_PROTOCOL_IPSEC_ESP),
+ &sa->ip6_hdr);
}
else
{
- sa->ip4_hdr.ip_version_and_header_length = 0x45;
- sa->ip4_hdr.ttl = 254;
- sa->ip4_hdr.src_address.as_u32 = sa->tunnel_src_addr.ip4.as_u32;
- sa->ip4_hdr.dst_address.as_u32 = sa->tunnel_dst_addr.ip4.as_u32;
- sa->ip4_hdr.tos = sa->dscp << 2;
-
- if (ipsec_sa_is_set_UDP_ENCAP (sa))
- sa->ip4_hdr.protocol = IP_PROTOCOL_UDP;
- else
- sa->ip4_hdr.protocol = IP_PROTOCOL_IPSEC_ESP;
- sa->ip4_hdr.checksum = ip4_header_checksum (&sa->ip4_hdr);
+ tunnel_build_v4_hdr (&sa->tunnel,
+ (ipsec_sa_is_set_UDP_ENCAP (sa) ?
+ IP_PROTOCOL_UDP :
+ IP_PROTOCOL_IPSEC_ESP),
+ &sa->ip4_hdr);
}
}
@@ -370,6 +326,7 @@ ipsec_sa_del (ipsec_sa_t * sa)
sa_index = sa - im->sad;
hash_unset (im->sa_index_by_sa_id, sa->id);
+ tunnel_unresolve (&sa->tunnel);
/* no recovery possible when deleting an SA */
(void) ipsec_call_add_del_callbacks (im, sa, sa_index, 0);
@@ -378,10 +335,7 @@ ipsec_sa_del (ipsec_sa_t * sa)
ipsec_unregister_udp_port (clib_net_to_host_u16 (sa->udp_hdr.dst_port));
if (ipsec_sa_is_set_IS_TUNNEL (sa) && !ipsec_sa_is_set_IS_INBOUND (sa))
- {
- fib_entry_untrack (sa->fib_entry_index, sa->sibling);
- dpo_reset (&sa->dpo);
- }
+ dpo_reset (&sa->dpo);
vnet_crypto_key_del (vm, sa->crypto_key_index);
if (sa->integ_alg != IPSEC_INTEG_ALG_NONE)
vnet_crypto_key_del (vm, sa->integ_key_index);
diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h
index 7a52e831c77..84abd6ef4b4 100644
--- a/src/vnet/ipsec/ipsec_sa.h
+++ b/src/vnet/ipsec/ipsec_sa.h
@@ -174,8 +174,7 @@ typedef struct
ipsec_protocol_t protocol;
tunnel_encap_decap_flags_t tunnel_flags;
- ip_dscp_t dscp;
- u8 __pad2[1];
+ u8 __pad[2];
/* data accessed by dataplane code should be above this comment */
CLIB_CACHE_LINE_ALIGN_MARK (cacheline2);
@@ -203,8 +202,7 @@ typedef struct
u64 data;
} async_op_data;
- ip46_address_t tunnel_src_addr;
- ip46_address_t tunnel_dst_addr;
+ tunnel_t tunnel;
fib_node_t node;
@@ -214,10 +212,6 @@ typedef struct
vnet_crypto_alg_t integ_calg;
vnet_crypto_alg_t crypto_calg;
- fib_node_index_t fib_entry_index;
- u32 sibling;
- u32 tx_fib_index;
-
/* else u8 packed */
ipsec_crypto_alg_t crypto_alg;
ipsec_integ_alg_t integ_alg;
@@ -258,21 +252,12 @@ extern vlib_combined_counter_main_t ipsec_sa_counters;
extern void ipsec_mk_key (ipsec_key_t * key, const u8 * data, u8 len);
-extern int ipsec_sa_add_and_lock (u32 id,
- u32 spi,
- ipsec_protocol_t proto,
- ipsec_crypto_alg_t crypto_alg,
- const ipsec_key_t * ck,
- ipsec_integ_alg_t integ_alg,
- const ipsec_key_t * ik,
- ipsec_sa_flags_t flags,
- u32 tx_table_id,
- u32 salt,
- const ip46_address_t * tunnel_src_addr,
- const ip46_address_t * tunnel_dst_addr,
- tunnel_encap_decap_flags_t tunnel_flags,
- ip_dscp_t dscp,
- u32 * sa_index, u16 src_port, u16 dst_port);
+extern int
+ipsec_sa_add_and_lock (u32 id, u32 spi, ipsec_protocol_t proto,
+ ipsec_crypto_alg_t crypto_alg, const ipsec_key_t *ck,
+ ipsec_integ_alg_t integ_alg, const ipsec_key_t *ik,
+ ipsec_sa_flags_t flags, u32 salt, u16 src_port,
+ u16 dst_port, const tunnel_t *tun, u32 *sa_out_index);
extern index_t ipsec_sa_find_and_lock (u32 id);
extern int ipsec_sa_unlock_id (u32 id);
extern void ipsec_sa_unlock (index_t sai);
diff --git a/src/vnet/ipsec/ipsec_tun.c b/src/vnet/ipsec/ipsec_tun.c
index 63e063fcee3..74340256f38 100644
--- a/src/vnet/ipsec/ipsec_tun.c
+++ b/src/vnet/ipsec/ipsec_tun.c
@@ -470,13 +470,13 @@ ipsec_tun_protect_set_crypto_addr (ipsec_tun_protect_t * itp)
({
if (ipsec_sa_is_set_IS_TUNNEL (sa))
{
- itp->itp_crypto.src = sa->tunnel_dst_addr;
- itp->itp_crypto.dst = sa->tunnel_src_addr;
- if (!(itp->itp_flags & IPSEC_PROTECT_ITF))
- {
- ipsec_sa_set_IS_PROTECT (sa);
- itp->itp_flags |= IPSEC_PROTECT_ENCAPED;
- }
+ itp->itp_crypto.src = ip_addr_46 (&sa->tunnel.t_dst);
+ itp->itp_crypto.dst = ip_addr_46 (&sa->tunnel.t_src);
+ if (!(itp->itp_flags & IPSEC_PROTECT_ITF))
+ {
+ ipsec_sa_set_IS_PROTECT (sa);
+ itp->itp_flags |= IPSEC_PROTECT_ENCAPED;
+ }
}
else
{
diff --git a/src/vnet/ipsec/ipsec_tun.h b/src/vnet/ipsec/ipsec_tun.h
index 7ae00992faa..070831fdca9 100644
--- a/src/vnet/ipsec/ipsec_tun.h
+++ b/src/vnet/ipsec/ipsec_tun.h
@@ -162,10 +162,6 @@ extern u8 *format_ipsec_tun_protect_index (u8 * s, va_list * args);
extern void ipsec_tun_register_nodes (ip_address_family_t af);
extern void ipsec_tun_unregister_nodes (ip_address_family_t af);
-// FIXME
-extern vlib_node_registration_t ipsec4_tun_input_node;
-extern vlib_node_registration_t ipsec6_tun_input_node;
-
/*
* DP API
*/
diff --git a/src/vnet/ipsec/ipsec_types.api b/src/vnet/ipsec/ipsec_types.api
index ca1b3788e64..b47355908e7 100644
--- a/src/vnet/ipsec/ipsec_types.api
+++ b/src/vnet/ipsec/ipsec_types.api
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-option version = "3.0.0";
+option version = "3.0.1";
import "vnet/ip/ip_types.api";
import "vnet/tunnel/tunnel_types.api";
@@ -162,6 +162,28 @@ typedef ipsec_sad_entry_v2
u16 udp_dst_port [default=4500];
};
+typedef ipsec_sad_entry_v3
+{
+ u32 sad_id;
+ u32 spi;
+
+ vl_api_ipsec_proto_t protocol;
+
+ vl_api_ipsec_crypto_alg_t crypto_algorithm;
+ vl_api_key_t crypto_key;
+
+ vl_api_ipsec_integ_alg_t integrity_algorithm;
+ vl_api_key_t integrity_key;
+
+ vl_api_ipsec_sad_flags_t flags;
+
+ vl_api_tunnel_t tunnel;
+
+ u32 salt;
+ u16 udp_src_port [default=4500];
+ u16 udp_dst_port [default=4500];
+};
+
/*
* Local Variables: