aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilip Tehlar <ftehlar@cisco.com>2020-09-08 06:08:05 +0000
committerAndrew Yourtchenko <ayourtch@gmail.com>2020-11-26 15:02:41 +0000
commit469181845b735f01f94e2c25e1868570bcd55f0c (patch)
tree02006ca1dfc6732309a2e2b63d7e8437998f18c4
parent0b685565c18b3d16bfebae2dcee33d551395d387 (diff)
ikev2: support ipv6 traffic selectors & overlay
Ticket: VPP-1917 Type: feature Change-Id: Ie9f22e7336aa7807b1967c48de9843df10fb575c Signed-off-by: Filip Tehlar <ftehlar@cisco.com> (cherry picked from commit 84962d19ba76eafd5c7658aa86ec61c9b81f7702)
-rw-r--r--src/plugins/ikev2/ikev2.api2
-rw-r--r--src/plugins/ikev2/ikev2.c528
-rw-r--r--src/plugins/ikev2/ikev2.h12
-rw-r--r--src/plugins/ikev2/ikev2_api.c22
-rw-r--r--src/plugins/ikev2/ikev2_cli.c62
-rw-r--r--src/plugins/ikev2/ikev2_payload.c114
-rw-r--r--src/plugins/ikev2/ikev2_priv.h50
-rw-r--r--src/plugins/ikev2/ikev2_test.c78
-rw-r--r--src/plugins/ikev2/ikev2_types.api10
-rw-r--r--src/plugins/ikev2/test/test_ikev2.py184
-rw-r--r--src/plugins/ikev2/test/vpp_ikev2.py13
11 files changed, 695 insertions, 380 deletions
diff --git a/src/plugins/ikev2/ikev2.api b/src/plugins/ikev2/ikev2.api
index 1e1dbf9589d..a7aeff1fa44 100644
--- a/src/plugins/ikev2/ikev2.api
+++ b/src/plugins/ikev2/ikev2.api
@@ -264,7 +264,7 @@ autoreply define ikev2_profile_set_ts
string name[64];
vl_api_ikev2_ts_t ts;
- option vat_help = "name <profile_name> protocol <proto> start_port <port> end_port <port> start_addr <ip4> end_addr <ip4> (local|remote)";
+ option vat_help = "name <profile_name> protocol <proto> start_port <port> end_port <port> start_addr <ip> end_addr <ip> (local|remote)";
option status="in_progress";
};
diff --git a/src/plugins/ikev2/ikev2.c b/src/plugins/ikev2/ikev2.c
index bc37b7e0035..a266853760f 100644
--- a/src/plugins/ikev2/ikev2.c
+++ b/src/plugins/ikev2/ikev2.c
@@ -62,8 +62,6 @@ format_ikev2_trace (u8 * s, va_list * args)
return s;
}
-static vlib_node_registration_t ikev2_node;
-
#define foreach_ikev2_error \
_(PROCESSED, "IKEv2 packets processed") \
_(IKE_SA_INIT_RETRANSMIT, "IKE_SA_INIT retransmit ") \
@@ -92,9 +90,16 @@ static char *ikev2_error_strings[] = {
typedef enum
{
IKEV2_NEXT_IP4_LOOKUP,
- IKEV2_NEXT_ERROR_DROP,
- IKEV2_N_NEXT,
-} ikev2_next_t;
+ IKEV2_NEXT_IP4_ERROR_DROP,
+ IKEV2_IP4_N_NEXT,
+} ikev2_ip4_next_t;
+
+typedef enum
+{
+ IKEV2_NEXT_IP6_LOOKUP,
+ IKEV2_NEXT_IP6_ERROR_DROP,
+ IKEV2_IP6_N_NEXT,
+} ikev2_ip6_next_t;
typedef u32 ikev2_non_esp_marker;
@@ -263,7 +268,7 @@ ikev2_sa_free_proposal_vector (ikev2_sa_proposal_t ** v)
vec_free (p->transforms);
}
vec_free (*v);
-};
+}
static void
ikev2_sa_free_child_sa (ikev2_child_sa_t * c)
@@ -417,8 +422,8 @@ ikev2_complete_sa_data (ikev2_sa_t * sa, ikev2_sa_t * sai)
sa->i_nonce = _(sai->i_nonce);
sa->i_dh_data = _(sai->i_dh_data);
sa->dh_private_key = _(sai->dh_private_key);
- sa->iaddr.as_u32 = sai->iaddr.as_u32;
- sa->raddr.as_u32 = sai->raddr.as_u32;
+ ip_address_copy (&sa->iaddr, &sai->iaddr);
+ ip_address_copy (&sa->raddr, &sai->raddr);
sa->is_initiator = sai->is_initiator;
sa->i_id.type = sai->i_id.type;
sa->r_id.type = sai->r_id.type;
@@ -627,16 +632,17 @@ ikev2_calc_child_keys (ikev2_sa_t * sa, ikev2_child_sa_t * child)
}
static_always_inline u8 *
-ikev2_compute_nat_sha1 (u64 ispi, u64 rspi, u32 ip, u16 port)
+ikev2_compute_nat_sha1 (u64 ispi, u64 rspi, ip_address_t * ia, u16 port)
{
- /* ispi, rspi, ip, port */
- u8 buf[8 + 8 + 4 + 2];
+ const u32 max_buf_size =
+ sizeof (ispi) + sizeof (rspi) + sizeof (ip6_address_t) + sizeof (u16);
+ u8 buf[max_buf_size];
u8 *res = vec_new (u8, 20);
clib_memcpy_fast (&buf[0], &ispi, sizeof (ispi));
clib_memcpy_fast (&buf[8], &rspi, sizeof (rspi));
- clib_memcpy_fast (&buf[8 + 8], &ip, sizeof (ip));
- clib_memcpy_fast (&buf[8 + 8 + 4], &port, sizeof (port));
+ clib_memcpy_fast (&buf[8 + 8], ip_addr_bytes (ia), ip_address_size (ia));
+ clib_memcpy_fast (&buf[8 + 8 + ip_address_size (ia)], &port, sizeof (port));
SHA1 (buf, sizeof (buf), res);
return res;
}
@@ -691,9 +697,10 @@ ikev2_process_sa_init_req (vlib_main_t * vm,
u16 plen;
ikev2_elog_exchange ("ispi %lx rspi %lx IKE_INIT request received "
- "from %d.%d.%d.%d",
- clib_net_to_host_u64 (ike->ispi),
- clib_net_to_host_u64 (ike->rspi), sa->iaddr.as_u32);
+ "from ", clib_net_to_host_u64 (ike->ispi),
+ clib_net_to_host_u64 (ike->rspi),
+ ip_addr_v4 (&sa->iaddr).as_u32,
+ ip_addr_version (&sa->iaddr) == AF_IP4);
sa->ispi = clib_net_to_host_u64 (ike->ispi);
@@ -735,8 +742,7 @@ ikev2_process_sa_init_req (vlib_main_t * vm,
ikev2_parse_notify_payload (ikep, current_length);
if (n->msg_type == IKEV2_NOTIFY_MSG_NAT_DETECTION_SOURCE_IP)
{
- u8 *src_sha = ikev2_compute_nat_sha1 (ike->ispi, 0,
- sa->iaddr.as_u32,
+ u8 *src_sha = ikev2_compute_nat_sha1 (ike->ispi, 0, &sa->iaddr,
udp->src_port);
if (clib_memcmp (src_sha, n->data, vec_len (src_sha)))
{
@@ -749,8 +755,7 @@ ikev2_process_sa_init_req (vlib_main_t * vm,
else if (n->msg_type ==
IKEV2_NOTIFY_MSG_NAT_DETECTION_DESTINATION_IP)
{
- u8 *dst_sha = ikev2_compute_nat_sha1 (ike->ispi, 0,
- sa->raddr.as_u32,
+ u8 *dst_sha = ikev2_compute_nat_sha1 (ike->ispi, 0, &sa->raddr,
udp->dst_port);
if (clib_memcmp (dst_sha, n->data, vec_len (dst_sha)))
{
@@ -801,8 +806,9 @@ ikev2_process_sa_init_resp (vlib_main_t * vm,
sa->rspi = clib_net_to_host_u64 (ike->rspi);
ikev2_elog_exchange ("ispi %lx rspi %lx IKE_INIT response received "
- "from %d.%d.%d.%d", sa->ispi, sa->rspi,
- sa->raddr.as_u32);
+ "from ", sa->ispi, sa->rspi,
+ ip_addr_v4 (&sa->raddr).as_u32,
+ ip_addr_version (&sa->raddr) == AF_IP4);
/* store whole IKE payload - needed for PSK auth */
vec_reset_length (sa->last_sa_init_res_packet_data);
@@ -848,9 +854,8 @@ ikev2_process_sa_init_resp (vlib_main_t * vm,
ikev2_parse_notify_payload (ikep, current_length);
if (n->msg_type == IKEV2_NOTIFY_MSG_NAT_DETECTION_SOURCE_IP)
{
- u8 *src_sha = ikev2_compute_nat_sha1 (ike->ispi,
- ike->rspi,
- sa->raddr.as_u32,
+ u8 *src_sha = ikev2_compute_nat_sha1 (ike->ispi, ike->rspi,
+ &sa->raddr,
udp->src_port);
if (clib_memcmp (src_sha, n->data, vec_len (src_sha)))
{
@@ -862,9 +867,8 @@ ikev2_process_sa_init_resp (vlib_main_t * vm,
else if (n->msg_type ==
IKEV2_NOTIFY_MSG_NAT_DETECTION_DESTINATION_IP)
{
- u8 *dst_sha = ikev2_compute_nat_sha1 (ike->ispi,
- ike->rspi,
- sa->iaddr.as_u32,
+ u8 *dst_sha = ikev2_compute_nat_sha1 (ike->ispi, ike->rspi,
+ &sa->iaddr,
udp->dst_port);
if (clib_memcmp (dst_sha, n->data, vec_len (dst_sha)))
{
@@ -1100,10 +1104,12 @@ ikev2_process_auth_req (vlib_main_t * vm, ikev2_sa_t * sa,
u32 dlen = 0;
ikev2_elog_exchange ("ispi %lx rspi %lx EXCHANGE_IKE_AUTH received "
- "from %d.%d.%d.%d", clib_host_to_net_u64 (ike->ispi),
+ "from ", clib_host_to_net_u64 (ike->ispi),
clib_host_to_net_u64 (ike->rspi),
- sa->is_initiator ? sa->raddr.as_u32 : sa->
- iaddr.as_u32);
+ sa->is_initiator ?
+ ip_addr_v4 (&sa->raddr).as_u32 :
+ ip_addr_v4 (&sa->iaddr).as_u32,
+ ip_addr_version (&sa->raddr) == AF_IP4);
ikev2_calc_keys (sa);
@@ -1240,8 +1246,10 @@ ikev2_process_informational_req (vlib_main_t * vm,
sa->liveness_retries = 0;
ikev2_elog_exchange ("ispi %lx rspi %lx INFORMATIONAL received "
- "from %d.%d.%d.%d", clib_host_to_net_u64 (ike->ispi),
- clib_host_to_net_u64 (ike->rspi), sa->iaddr.as_u32);
+ "from ", clib_host_to_net_u64 (ike->ispi),
+ clib_host_to_net_u64 (ike->rspi),
+ ip_addr_v4 (&sa->iaddr).as_u32,
+ ip_addr_version (&sa->iaddr) == AF_IP4);
plaintext = ikev2_decrypt_sk_payload (sa, ike, &payload, len, &dlen);
@@ -1316,8 +1324,10 @@ ikev2_process_create_child_sa_req (vlib_main_t * vm,
u16 plen;
ikev2_elog_exchange ("ispi %lx rspi %lx CREATE_CHILD_SA received "
- "from %d.%d.%d.%d", clib_host_to_net_u64 (ike->ispi),
- clib_host_to_net_u64 (ike->rspi), sa->raddr.as_u32);
+ "from ", clib_host_to_net_u64 (ike->ispi),
+ clib_host_to_net_u64 (ike->rspi),
+ ip_addr_v4 (&sa->raddr).as_u32,
+ ip_addr_version (&sa->raddr) == AF_IP4);
plaintext = ikev2_decrypt_sk_payload (sa, ike, &payload, len, &dlen);
@@ -1479,8 +1489,8 @@ ikev2_ts_cmp (ikev2_ts_t * ts1, ikev2_ts_t * ts2)
{
if (ts1->ts_type == ts2->ts_type && ts1->protocol_id == ts2->protocol_id &&
ts1->start_port == ts2->start_port && ts1->end_port == ts2->end_port &&
- ts1->start_addr.as_u32 == ts2->start_addr.as_u32 &&
- ts1->end_addr.as_u32 == ts2->end_addr.as_u32)
+ !ip_address_cmp (&ts1->start_addr, &ts2->start_addr) &&
+ !ip_address_cmp (&ts1->end_addr, &ts2->end_addr))
return 1;
return 0;
@@ -1777,6 +1787,7 @@ ikev2_add_tunnel_from_main (ikev2_add_ipsec_tunnel_args_t * a)
ikev2_main_t *km = &ikev2_main;
u32 sw_if_index;
int rv = 0;
+ ip46_address_t zero_addr = ip46_address_initializer;
if (~0 == a->sw_if_index)
{
@@ -1802,9 +1813,9 @@ ikev2_add_tunnel_from_main (ikev2_add_ipsec_tunnel_args_t * a)
if (rv)
{
- ikev2_elog_peers (IKEV2_LOG_ERROR, "installing ipip tunnel failed! "
- "loc:%d.%d.%d.%d rem:%d.%d.%d.%d",
- a->local_ip.ip4.as_u32, a->remote_ip.ip4.as_u32);
+ ikev2_elog_uint (IKEV2_LOG_ERROR,
+ "installing ipip tunnel failed! local spi: %x",
+ a->local_spi);
return;
}
@@ -1825,14 +1836,14 @@ ikev2_add_tunnel_from_main (ikev2_add_ipsec_tunnel_args_t * a)
a->local_spi,
IPSEC_PROTOCOL_ESP, a->encr_type,
&a->loc_ckey, a->integ_type, &a->loc_ikey,
- a->flags, 0, a->salt_local, &a->local_ip,
- &a->remote_ip, NULL, a->src_port, a->dst_port);
+ a->flags, 0, a->salt_local, &zero_addr,
+ &zero_addr, NULL, a->src_port, a->dst_port);
rv |= ipsec_sa_add_and_lock (a->remote_sa_id, a->remote_spi,
IPSEC_PROTOCOL_ESP, a->encr_type, &a->rem_ckey,
a->integ_type, &a->rem_ikey,
(a->flags | IPSEC_SA_FLAG_IS_INBOUND), 0,
- a->salt_remote, &a->remote_ip,
- &a->local_ip, NULL, a->ipsec_over_udp_port,
+ a->salt_remote, &zero_addr,
+ &zero_addr, NULL, a->ipsec_over_udp_port,
a->ipsec_over_udp_port);
rv |= ipsec_tun_protect_update (sw_if_index, NULL, a->local_sa_id, sas_in);
@@ -1864,16 +1875,16 @@ ikev2_create_tunnel_interface (vlib_main_t * vm,
if (sa->is_initiator)
{
- ip46_address_set_ip4 (&a.local_ip, &sa->iaddr);
- ip46_address_set_ip4 (&a.remote_ip, &sa->raddr);
+ ip_address_to_46 (&sa->iaddr, &a.local_ip);
+ ip_address_to_46 (&sa->raddr, &a.remote_ip);
proposals = child->r_proposals;
a.local_spi = child->r_proposals[0].spi;
a.remote_spi = child->i_proposals[0].spi;
}
else
{
- ip46_address_set_ip4 (&a.local_ip, &sa->raddr);
- ip46_address_set_ip4 (&a.remote_ip, &sa->iaddr);
+ ip_address_to_46 (&sa->raddr, &a.local_ip);
+ ip_address_to_46 (&sa->iaddr, &a.remote_ip);
proposals = child->i_proposals;
a.local_spi = child->i_proposals[0].spi;
a.remote_spi = child->r_proposals[0].spi;
@@ -2153,13 +2164,13 @@ ikev2_delete_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa,
if (sa->is_initiator)
{
- ip46_address_set_ip4 (&a.local_ip, &sa->iaddr);
- ip46_address_set_ip4 (&a.remote_ip, &sa->raddr);
+ ip_address_to_46 (&sa->iaddr, &a.local_ip);
+ ip_address_to_46 (&sa->raddr, &a.remote_ip);
}
else
{
- ip46_address_set_ip4 (&a.local_ip, &sa->raddr);
- ip46_address_set_ip4 (&a.remote_ip, &sa->iaddr);
+ ip_address_to_46 (&sa->raddr, &a.local_ip);
+ ip_address_to_46 (&sa->iaddr, &a.remote_ip);
}
a.remote_sa_id = child->remote_sa_id;
@@ -2239,8 +2250,7 @@ ikev2_generate_message (vlib_buffer_t * b, ikev2_sa_t * sa,
u8 *nat_detection_sha1 =
ikev2_compute_nat_sha1 (clib_host_to_net_u64 (sa->ispi),
clib_host_to_net_u64 (sa->rspi),
- sa->raddr.as_u32,
- udp->dst_port);
+ &sa->raddr, udp->dst_port);
ikev2_payload_add_notify (chain,
IKEV2_NOTIFY_MSG_NAT_DETECTION_SOURCE_IP,
nat_detection_sha1);
@@ -2248,7 +2258,7 @@ ikev2_generate_message (vlib_buffer_t * b, ikev2_sa_t * sa,
nat_detection_sha1 =
ikev2_compute_nat_sha1 (clib_host_to_net_u64 (sa->ispi),
clib_host_to_net_u64 (sa->rspi),
- sa->iaddr.as_u32, udp->src_port);
+ &sa->iaddr, udp->src_port);
ikev2_payload_add_notify (chain,
IKEV2_NOTIFY_MSG_NAT_DETECTION_DESTINATION_IP,
nat_detection_sha1);
@@ -2518,18 +2528,17 @@ done:
}
static u32
-ikev2_retransmit_sa_init (ike_header_t * ike, ip4_address_t iaddr,
- ip4_address_t raddr, u32 rlen)
+ikev2_retransmit_sa_init (ike_header_t * ike, ip_address_t iaddr,
+ ip_address_t raddr, u32 rlen)
{
- ikev2_main_t *km = &ikev2_main;
ikev2_sa_t *sa;
- u32 thread_index = vlib_get_thread_index ();
+ ikev2_main_per_thread_data_t *ptd = ikev2_get_per_thread_data ();
/* *INDENT-OFF* */
- pool_foreach (sa, km->per_thread_data[thread_index].sas, ({
+ pool_foreach (sa, ptd->sas, ({
if (sa->ispi == clib_net_to_host_u64(ike->ispi) &&
- sa->iaddr.as_u32 == iaddr.as_u32 &&
- sa->raddr.as_u32 == raddr.as_u32)
+ !ip_address_cmp(&sa->iaddr, &iaddr) &&
+ !ip_address_cmp(&sa->raddr, &raddr))
{
int p = 0;
u8 payload = ike->nextpayload;
@@ -2566,7 +2575,8 @@ ikev2_retransmit_sa_init (ike_header_t * ike, ip4_address_t iaddr,
"ispi %lx IKE_SA_INIT retransmit "
"from %d.%d.%d.%d to %d.%d.%d.%d",
ike->ispi,
- raddr.as_u32, iaddr.as_u32);
+ ip_addr_v4(&raddr).as_u32,
+ ip_addr_v4 (&iaddr).as_u32);
return slen;
}
/* else ignore req */
@@ -2576,7 +2586,8 @@ ikev2_retransmit_sa_init (ike_header_t * ike, ip4_address_t iaddr,
"ispi %lx IKE_SA_INIT ignore "
"from %d.%d.%d.%d to %d.%d.%d.%d",
ike->ispi,
- raddr.as_u32, iaddr.as_u32);
+ ip_addr_v4(&raddr).as_u32,
+ ip_addr_v4(&iaddr).as_u32);
return ~0;
}
}
@@ -2619,13 +2630,15 @@ ikev2_retransmit_resp (ikev2_sa_t * sa, ike_header_t * ike)
ike->length = tmp->length;
clib_memcpy_fast (ike->payload, tmp->payload, slen - sizeof (*ike));
ikev2_elog_uint_peers (IKEV2_LOG_DEBUG, "IKE retransmit msgid %d",
- msg_id, sa->raddr.as_u32, sa->iaddr.as_u32);
+ msg_id, ip_addr_v4 (&sa->raddr).as_u32,
+ ip_addr_v4 (&sa->iaddr).as_u32);
return slen;
}
/* old req ignore */
ikev2_elog_uint_peers (IKEV2_LOG_DEBUG, "IKE req ignore msgid %d",
- msg_id, sa->raddr.as_u32, sa->iaddr.as_u32);
+ msg_id, ip_addr_v4 (&sa->raddr).as_u32,
+ ip_addr_v4 (&sa->iaddr).as_u32);
return ~0;
}
@@ -2658,9 +2671,50 @@ ikev2_del_sa_init (u64 ispi)
sizeof (ispi));
}
-static uword
-ikev2_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node, vlib_frame_t * frame)
+static_always_inline void
+ikev2_rewrite_v6_addrs (ikev2_sa_t * sa, ip6_header_t * ih)
+{
+ if (sa->is_initiator)
+ {
+ ip_address_copy_addr (&ih->dst_address, &sa->raddr);
+ ip_address_copy_addr (&ih->src_address, &sa->iaddr);
+ }
+ else
+ {
+ ip_address_copy_addr (&ih->dst_address, &sa->iaddr);
+ ip_address_copy_addr (&ih->src_address, &sa->raddr);
+ }
+}
+
+static_always_inline void
+ikev2_rewrite_v4_addrs (ikev2_sa_t * sa, ip4_header_t * ih)
+{
+ if (sa->is_initiator)
+ {
+ ip_address_copy_addr (&ih->dst_address, &sa->raddr);
+ ip_address_copy_addr (&ih->src_address, &sa->iaddr);
+ }
+ else
+ {
+ ip_address_copy_addr (&ih->dst_address, &sa->iaddr);
+ ip_address_copy_addr (&ih->src_address, &sa->raddr);
+ }
+}
+
+static_always_inline void
+ikev2_set_ip_address (ikev2_sa_t * sa, const void *src,
+ const void *dst, const int af, const int is_initiator)
+{
+ const void *raddr = is_initiator ? src : dst;
+ const void *iaddr = is_initiator ? dst : src;
+ ip_address_set (&sa->raddr, raddr, af);
+ ip_address_set (&sa->iaddr, iaddr, af);
+}
+
+static_always_inline uword
+ikev2_node_internal (vlib_main_t * vm,
+ vlib_node_runtime_t * node, vlib_frame_t * frame,
+ u8 is_ip4)
{
u32 n_left = frame->n_vectors, *from;
ikev2_main_t *km = &ikev2_main;
@@ -2676,13 +2730,16 @@ ikev2_node_fn (vlib_main_t * vm,
while (n_left > 0)
{
vlib_buffer_t *b0 = b[0];
- next[0] = IKEV2_NEXT_ERROR_DROP;
- ip4_header_t *ip40;
+ next[0] = is_ip4 ? IKEV2_NEXT_IP4_ERROR_DROP
+ : IKEV2_NEXT_IP6_ERROR_DROP;
+ ip4_header_t *ip40 = 0;
+ ip6_header_t *ip60 = 0;
udp_header_t *udp0;
ike_header_t *ike0;
ikev2_sa_t *sa0 = 0;
ikev2_sa_t sa; /* temporary store for SA */
u32 rlen, slen = 0;
+ int ip_hdr_sz = 0;
int is_req = 0, has_non_esp_marker = 0;
if (b0->punt_reason == ipsec_punt_reason[IPSEC_PUNT_IP4_SPI_UDP_0])
@@ -2693,17 +2750,29 @@ ikev2_node_fn (vlib_main_t * vm,
udp0 = (udp_header_t *) ptr;
ptr += sizeof (*udp0);
ike0 = (ike_header_t *) ptr;
+ ip_hdr_sz = sizeof (*ip40);
}
else
{
+ u8 *ipx_hdr = b0->data + vnet_buffer (b0)->l3_hdr_offset;
ike0 = vlib_buffer_get_current (b0);
vlib_buffer_advance (b0, -sizeof (*udp0));
udp0 = vlib_buffer_get_current (b0);
- vlib_buffer_advance (b0, -sizeof (*ip40));
- ip40 = vlib_buffer_get_current (b0);
+
+ if (is_ip4)
+ {
+ ip40 = (ip4_header_t *) ipx_hdr;
+ ip_hdr_sz = sizeof (*ip40);
+ }
+ else
+ {
+ ip60 = (ip6_header_t *) ipx_hdr;
+ ip_hdr_sz = sizeof (*ip60);
+ }
+ vlib_buffer_advance (b0, -ip_hdr_sz);
}
- rlen = b0->current_length - sizeof (*ip40) - sizeof (*udp0);
+ rlen = b0->current_length - ip_hdr_sz - sizeof (*udp0);
/* check for non-esp marker */
if (*((u32 *) ike0) == 0)
@@ -2716,14 +2785,14 @@ ikev2_node_fn (vlib_main_t * vm,
if (clib_net_to_host_u32 (ike0->length) != rlen)
{
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
IKEV2_ERROR_BAD_LENGTH, 1);
goto dispatch0;
}
if (ike0->version != IKE_VERSION_2)
{
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
IKEV2_ERROR_NOT_IKEV2, 1);
goto dispatch0;
}
@@ -2733,12 +2802,20 @@ ikev2_node_fn (vlib_main_t * vm,
sa0 = &sa;
clib_memset (sa0, 0, sizeof (*sa0));
- if (ike0->flags & IKEV2_HDR_FLAG_INITIATOR)
+ u8 is_initiator = ike0->flags & IKEV2_HDR_FLAG_INITIATOR;
+ if (is_initiator)
{
if (ike0->rspi == 0)
{
- sa0->raddr.as_u32 = ip40->dst_address.as_u32;
- sa0->iaddr.as_u32 = ip40->src_address.as_u32;
+ if (is_ip4)
+ ikev2_set_ip_address (sa0, &ip40->dst_address,
+ &ip40->src_address, AF_IP4,
+ is_initiator);
+ else
+ ikev2_set_ip_address (sa0, &ip60->dst_address,
+ &ip60->src_address, AF_IP6,
+ is_initiator);
+
sa0->dst_port = clib_net_to_host_u16 (udp0->src_port);
slen =
@@ -2746,7 +2823,7 @@ ikev2_node_fn (vlib_main_t * vm,
sa0->raddr, rlen);
if (slen)
{
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
~0 ==
slen ?
IKEV2_ERROR_IKE_SA_INIT_IGNORE
@@ -2758,7 +2835,7 @@ ikev2_node_fn (vlib_main_t * vm,
res = ikev2_process_sa_init_req (vm, sa0, ike0, udp0, rlen);
if (!res)
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
IKEV2_ERROR_MALFORMED_PACKET,
1);
@@ -2776,7 +2853,7 @@ ikev2_node_fn (vlib_main_t * vm,
{
slen = ikev2_generate_message (b0, sa0, ike0, 0, udp0);
if (~0 == slen)
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
IKEV2_ERROR_NO_BUFF_SPACE,
1);
}
@@ -2797,8 +2874,15 @@ ikev2_node_fn (vlib_main_t * vm,
}
else //received sa_init without initiator flag
{
- sa0->raddr.as_u32 = ip40->src_address.as_u32;
- sa0->iaddr.as_u32 = ip40->dst_address.as_u32;
+ if (is_ip4)
+ ikev2_set_ip_address (sa0, &ip40->src_address,
+ &ip40->dst_address, AF_IP4,
+ is_initiator);
+ else
+ ikev2_set_ip_address (sa0, &ip60->src_address,
+ &ip60->dst_address, AF_IP6,
+ is_initiator);
+
ikev2_process_sa_init_resp (vm, sa0, ike0, udp0, rlen);
if (sa0->state == IKEV2_STATE_SA_INIT)
@@ -2820,7 +2904,7 @@ ikev2_node_fn (vlib_main_t * vm,
ikev2_generate_message (b0, sa0, ike0, 0, udp0);
if (~0 == slen)
vlib_node_increment_counter (vm,
- ikev2_node.index,
+ node->node_index,
IKEV2_ERROR_NO_BUFF_SPACE,
1);
}
@@ -2855,7 +2939,7 @@ ikev2_node_fn (vlib_main_t * vm,
slen = ikev2_retransmit_resp (sa0, ike0);
if (slen)
{
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
~0 ==
slen ?
IKEV2_ERROR_IKE_REQ_IGNORE
@@ -2870,7 +2954,7 @@ ikev2_node_fn (vlib_main_t * vm,
if (res)
ikev2_sa_auth (sa0);
else
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
IKEV2_ERROR_MALFORMED_PACKET, 1);
if (sa0->state == IKEV2_STATE_AUTHENTICATED)
{
@@ -2890,7 +2974,7 @@ ikev2_node_fn (vlib_main_t * vm,
{
slen = ikev2_generate_message (b0, sa0, ike0, 0, udp0);
if (~0 == slen)
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
IKEV2_ERROR_NO_BUFF_SPACE,
1);
}
@@ -2906,7 +2990,7 @@ ikev2_node_fn (vlib_main_t * vm,
slen = ikev2_retransmit_resp (sa0, ike0);
if (slen)
{
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
~0 ==
slen ?
IKEV2_ERROR_IKE_REQ_IGNORE
@@ -2919,7 +3003,7 @@ ikev2_node_fn (vlib_main_t * vm,
res = ikev2_process_informational_req (vm, sa0, ike0, rlen);
if (!res)
{
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
IKEV2_ERROR_MALFORMED_PACKET,
1);
slen = ~0;
@@ -2962,7 +3046,7 @@ ikev2_node_fn (vlib_main_t * vm,
ike0->flags |= IKEV2_HDR_FLAG_RESPONSE;
slen = ikev2_generate_message (b0, sa0, ike0, 0, udp0);
if (~0 == slen)
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
IKEV2_ERROR_NO_BUFF_SPACE,
1);
}
@@ -2978,7 +3062,7 @@ ikev2_node_fn (vlib_main_t * vm,
slen = ikev2_retransmit_resp (sa0, ike0);
if (slen)
{
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
~0 ==
slen ?
IKEV2_ERROR_IKE_REQ_IGNORE
@@ -2991,7 +3075,7 @@ ikev2_node_fn (vlib_main_t * vm,
res = ikev2_process_create_child_sa_req (vm, sa0, ike0, rlen);
if (!res)
{
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
IKEV2_ERROR_MALFORMED_PACKET,
1);
slen = ~0;
@@ -3022,7 +3106,7 @@ ikev2_node_fn (vlib_main_t * vm,
{
slen = ikev2_generate_message (b0, sa0, ike0, 0, udp0);
if (~0 == slen)
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
IKEV2_ERROR_NO_BUFF_SPACE,
1);
}
@@ -3042,16 +3126,15 @@ ikev2_node_fn (vlib_main_t * vm,
/* if we are sending packet back, rewrite headers */
if (slen && ~0 != slen)
{
- next[0] = IKEV2_NEXT_IP4_LOOKUP;
- if (sa0->is_initiator)
+ if (is_ip4)
{
- ip40->dst_address.as_u32 = sa0->raddr.as_u32;
- ip40->src_address.as_u32 = sa0->iaddr.as_u32;
+ next[0] = IKEV2_NEXT_IP4_LOOKUP;
+ ikev2_rewrite_v4_addrs (sa0, ip40);
}
else
{
- ip40->dst_address.as_u32 = sa0->iaddr.as_u32;
- ip40->src_address.as_u32 = sa0->raddr.as_u32;
+ next[0] = IKEV2_NEXT_IP6_LOOKUP;
+ ikev2_rewrite_v6_addrs (sa0, ip60);
}
if (is_req)
@@ -3078,10 +3161,17 @@ ikev2_node_fn (vlib_main_t * vm,
udp0->length = clib_host_to_net_u16 (slen + sizeof (udp_header_t));
udp0->checksum = 0;
- b0->current_length =
- slen + sizeof (ip4_header_t) + sizeof (udp_header_t);
- ip40->length = clib_host_to_net_u16 (b0->current_length);
- ip40->checksum = ip4_header_checksum (ip40);
+ b0->current_length = slen + ip_hdr_sz + sizeof (udp_header_t);
+ if (is_ip4)
+ {
+ ip40->length = clib_host_to_net_u16 (b0->current_length);
+ ip40->checksum = ip4_header_checksum (ip40);
+ }
+ else
+ {
+ ip60->payload_length =
+ clib_host_to_net_u16 (b0->current_length - sizeof (*ip60));
+ }
}
/* delete sa */
if (sa0 && (sa0->state == IKEV2_STATE_DELETED ||
@@ -3107,16 +3197,28 @@ ikev2_node_fn (vlib_main_t * vm,
b += 1;
}
- vlib_node_increment_counter (vm, ikev2_node.index,
+ vlib_node_increment_counter (vm, node->node_index,
IKEV2_ERROR_PROCESSED, frame->n_vectors);
vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
return frame->n_vectors;
}
+static uword
+ikev2_ip4 (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
+{
+ return ikev2_node_internal (vm, node, frame, 1 /* is_ip4 */ );
+}
+
+static uword
+ikev2_ip6 (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
+{
+ return ikev2_node_internal (vm, node, frame, 0 /* is_ip4 */ );
+}
+
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (ikev2_node,static) = {
- .function = ikev2_node_fn,
- .name = "ikev2",
+VLIB_REGISTER_NODE (ikev2_node_ip4,static) = {
+ .function = ikev2_ip4,
+ .name = "ikev2-ip4",
.vector_size = sizeof (u32),
.format_trace = format_ikev2_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
@@ -3124,11 +3226,27 @@ VLIB_REGISTER_NODE (ikev2_node,static) = {
.n_errors = ARRAY_LEN(ikev2_error_strings),
.error_strings = ikev2_error_strings,
- .n_next_nodes = IKEV2_N_NEXT,
-
+ .n_next_nodes = IKEV2_IP4_N_NEXT,
.next_nodes = {
[IKEV2_NEXT_IP4_LOOKUP] = "ip4-lookup",
- [IKEV2_NEXT_ERROR_DROP] = "error-drop",
+ [IKEV2_NEXT_IP4_ERROR_DROP] = "error-drop",
+ },
+};
+
+VLIB_REGISTER_NODE (ikev2_node_ip6,static) = {
+ .function = ikev2_ip6,
+ .name = "ikev2-ip6",
+ .vector_size = sizeof (u32),
+ .format_trace = format_ikev2_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+
+ .n_errors = ARRAY_LEN(ikev2_error_strings),
+ .error_strings = ikev2_error_strings,
+
+ .n_next_nodes = IKEV2_IP6_N_NEXT,
+ .next_nodes = {
+ [IKEV2_NEXT_IP6_LOOKUP] = "ip6-lookup",
+ [IKEV2_NEXT_IP6_ERROR_DROP] = "error-drop",
},
};
/* *INDENT-ON* */
@@ -3276,10 +3394,11 @@ ikev2_profile_index_by_name (u8 * name)
static void
-ikev2_send_ike (vlib_main_t * vm, ip4_address_t * src, ip4_address_t * dst,
+ikev2_send_ike (vlib_main_t * vm, ip_address_t * src, ip_address_t * dst,
u32 bi0, u32 len, u16 src_port, u16 dst_port, u32 sw_if_index)
{
ip4_header_t *ip40;
+ ip6_header_t *ip60;
udp_header_t *udp0;
vlib_buffer_t *b0;
vlib_frame_t *f;
@@ -3288,35 +3407,59 @@ ikev2_send_ike (vlib_main_t * vm, ip4_address_t * src, ip4_address_t * dst,
b0 = vlib_get_buffer (vm, bi0);
vlib_buffer_advance (b0, -sizeof (udp_header_t));
udp0 = vlib_buffer_get_current (b0);
- vlib_buffer_advance (b0, -sizeof (ip4_header_t));
- ip40 = vlib_buffer_get_current (b0);
-
-
- ip40->ip_version_and_header_length = 0x45;
- ip40->tos = 0;
- ip40->fragment_id = 0;
- ip40->flags_and_fragment_offset = 0;
- ip40->ttl = 0xff;
- ip40->protocol = IP_PROTOCOL_UDP;
- ip40->dst_address.as_u32 = dst->as_u32;
- ip40->src_address.as_u32 = src->as_u32;
udp0->dst_port = clib_host_to_net_u16 (dst_port);
udp0->src_port = clib_host_to_net_u16 (src_port);
udp0->length = clib_host_to_net_u16 (len + sizeof (udp_header_t));
udp0->checksum = 0;
- b0->current_length = len + sizeof (ip4_header_t) + sizeof (udp_header_t);
- ip40->length = clib_host_to_net_u16 (b0->current_length);
- ip40->checksum = ip4_header_checksum (ip40);
+ if (ip_addr_version (dst) == AF_IP4)
+ {
+ vlib_buffer_advance (b0, -sizeof (ip4_header_t));
+ ip40 = vlib_buffer_get_current (b0);
+ ip40->ip_version_and_header_length = 0x45;
+ ip40->tos = 0;
+ ip40->fragment_id = 0;
+ ip40->flags_and_fragment_offset = 0;
+ ip40->ttl = 0xff;
+ ip40->protocol = IP_PROTOCOL_UDP;
+ ip40->dst_address.as_u32 = ip_addr_v4 (dst).as_u32;
+ ip40->src_address.as_u32 = ip_addr_v4 (src).as_u32;
+ b0->current_length =
+ len + sizeof (ip4_header_t) + sizeof (udp_header_t);
+ ip40->length = clib_host_to_net_u16 (b0->current_length);
+ ip40->checksum = ip4_header_checksum (ip40);
+ }
+ else
+ {
+ vlib_buffer_advance (b0, -sizeof (ip6_header_t));
+ ip60 = vlib_buffer_get_current (b0);
+
+ b0->current_length = len + sizeof (*ip60) + sizeof (udp_header_t);
+ ip60->ip_version_traffic_class_and_flow_label =
+ clib_host_to_net_u32 (0x6 << 28);
+ ip60->payload_length =
+ clib_host_to_net_u16 (b0->current_length - sizeof (*ip60));
+ ip60->protocol = IP_PROTOCOL_UDP;
+ ip60->hop_limit = 0xff;
+ clib_memcpy_fast (ip60->src_address.as_u8, ip_addr_v6 (src).as_u8,
+ sizeof (ip60->src_address));
+ clib_memcpy_fast (ip60->dst_address.as_u8, ip_addr_v6 (dst).as_u8,
+ sizeof (ip60->src_address));
+ }
+
+ b0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
vnet_buffer (b0)->sw_if_index[VLIB_RX] = sw_if_index;
vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
+ u32 next_index = (ip_addr_version (dst) == AF_IP4) ?
+ ip4_lookup_node.index : ip6_lookup_node.index;
+
/* send the request */
- f = vlib_get_frame_to_node (vm, ip4_lookup_node.index);
+ f = vlib_get_frame_to_node (vm, next_index);
to_next = vlib_frame_vector_args (f);
to_next[0] = bi0;
f->n_vectors = 1;
- vlib_put_frame_to_node (vm, ip4_lookup_node.index, f);
+ vlib_put_frame_to_node (vm, next_index, f);
}
@@ -3405,7 +3548,7 @@ ikev2_initiate_delete_ike_sa_internal (vlib_main_t * vm,
ikev2_sa_t * sa)
{
ikev2_main_t *km = &ikev2_main;
- ip4_address_t *src, *dst;
+ ip_address_t *src, *dst;
vlib_buffer_t *b0;
/* Create the Initiator notification for IKE SA removal */
@@ -3591,6 +3734,15 @@ ikev2_set_profile_auth (vlib_main_t * vm, u8 * name, u8 auth_method,
return 0;
}
+static int
+ikev2_is_id_supported (u8 id_type)
+{
+ return (id_type == IKEV2_ID_TYPE_ID_IPV4_ADDR ||
+ id_type == IKEV2_ID_TYPE_ID_IPV6_ADDR ||
+ id_type == IKEV2_ID_TYPE_ID_RFC822_ADDR ||
+ id_type == IKEV2_ID_TYPE_ID_FQDN);
+}
+
clib_error_t *
ikev2_set_profile_id (vlib_main_t * vm, u8 * name, u8 id_type, u8 * data,
int is_local)
@@ -3598,8 +3750,7 @@ ikev2_set_profile_id (vlib_main_t * vm, u8 * name, u8 id_type, u8 * data,
ikev2_profile_t *p;
clib_error_t *r;
- if (id_type > IKEV2_ID_TYPE_ID_RFC822_ADDR
- && id_type < IKEV2_ID_TYPE_ID_KEY_ID)
+ if (!ikev2_is_id_supported (id_type))
{
r = clib_error_return (0, "unsupported identity type %U",
format_ikev2_id_type, id_type);
@@ -3630,10 +3781,27 @@ ikev2_set_profile_id (vlib_main_t * vm, u8 * name, u8 id_type, u8 * data,
return 0;
}
+static_always_inline void
+ikev2_set_ts_type (ikev2_ts_t * ts, const ip_address_t * addr)
+{
+ if (ip_addr_version (addr) == AF_IP4)
+ ts->ts_type = TS_IPV4_ADDR_RANGE;
+ else
+ ts->ts_type = TS_IPV6_ADDR_RANGE;
+}
+
+static_always_inline void
+ikev2_set_ts_addrs (ikev2_ts_t * ts, const ip_address_t * start,
+ const ip_address_t * end)
+{
+ ip_address_copy (&ts->start_addr, start);
+ ip_address_copy (&ts->end_addr, end);
+}
+
clib_error_t *
ikev2_set_profile_ts (vlib_main_t * vm, u8 * name, u8 protocol_id,
- u16 start_port, u16 end_port, ip4_address_t start_addr,
- ip4_address_t end_addr, int is_local)
+ u16 start_port, u16 end_port, ip_address_t start_addr,
+ ip_address_t end_addr, int is_local)
{
ikev2_profile_t *p;
clib_error_t *r;
@@ -3646,23 +3814,24 @@ ikev2_set_profile_ts (vlib_main_t * vm, u8 * name, u8 protocol_id,
return r;
}
+ if (ip_addr_version (&start_addr) != ip_addr_version (&end_addr))
+ return clib_error_return (0, "IP address version mismatch!");
+
if (is_local)
{
- p->loc_ts.start_addr.as_u32 = start_addr.as_u32;
- p->loc_ts.end_addr.as_u32 = end_addr.as_u32;
+ ikev2_set_ts_addrs (&p->loc_ts, &start_addr, &end_addr);
p->loc_ts.start_port = start_port;
p->loc_ts.end_port = end_port;
p->loc_ts.protocol_id = protocol_id;
- p->loc_ts.ts_type = 7;
+ ikev2_set_ts_type (&p->loc_ts, &start_addr);
}
else
{
- p->rem_ts.start_addr.as_u32 = start_addr.as_u32;
- p->rem_ts.end_addr.as_u32 = end_addr.as_u32;
+ ikev2_set_ts_addrs (&p->rem_ts, &start_addr, &end_addr);
p->rem_ts.start_port = start_port;
p->rem_ts.end_port = end_port;
p->rem_ts.protocol_id = protocol_id;
- p->rem_ts.ts_type = 7;
+ ikev2_set_ts_type (&p->rem_ts, &start_addr);
}
return 0;
@@ -3671,7 +3840,7 @@ ikev2_set_profile_ts (vlib_main_t * vm, u8 * name, u8 protocol_id,
clib_error_t *
ikev2_set_profile_responder (vlib_main_t * vm, u8 * name,
- u32 sw_if_index, ip4_address_t ip4)
+ u32 sw_if_index, ip_address_t addr)
{
ikev2_profile_t *p;
clib_error_t *r;
@@ -3685,7 +3854,7 @@ ikev2_set_profile_responder (vlib_main_t * vm, u8 * name,
}
p->responder.sw_if_index = sw_if_index;
- p->responder.ip4 = ip4;
+ ip_address_copy (&p->responder.addr, &addr);
return 0;
}
@@ -3835,7 +4004,6 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
{
ikev2_profile_t *p;
clib_error_t *r;
- ip4_main_t *im = &ip4_main;
ikev2_main_t *km = &ikev2_main;
p = ikev2_profile_index_by_name (name);
@@ -3846,7 +4014,8 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
return r;
}
- if (p->responder.sw_if_index == ~0 || p->responder.ip4.data_u32 == 0)
+ if (p->responder.sw_if_index == ~0
+ || ip_address_is_zero (&p->responder.addr))
{
r = clib_error_return (0, "responder not set for profile %v", name);
return r;
@@ -3858,16 +4027,29 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
vlib_buffer_t *b0;
ike_header_t *ike0;
u32 bi0 = 0;
- ip_lookup_main_t *lm = &im->lookup_main;
- u32 if_add_index0;
int len = sizeof (ike_header_t);
+ ip4_address_t *if_ip4;
+ ip6_address_t *if_ip6;
+ ip_address_t if_ip = IP_ADDRESS_V4_ALL_0S;
- /* Get own iface IP */
- if_add_index0 =
- lm->if_address_pool_index_by_sw_if_index[p->responder.sw_if_index];
- ip_interface_address_t *if_add =
- pool_elt_at_index (lm->if_address_pool, if_add_index0);
- ip4_address_t *if_ip = ip_interface_address_get_address (lm, if_add);
+ if (ip_addr_version (&p->responder.addr) == AF_IP4)
+ {
+ if_ip4 = ip4_interface_first_address (&ip4_main,
+ p->responder.sw_if_index, 0);
+ if (if_ip4)
+ {
+ ip_address_set (&if_ip, if_ip4, AF_IP4);
+ }
+ }
+ else
+ {
+ if_ip6 = ip6_interface_first_address (&ip6_main,
+ p->responder.sw_if_index);
+ if (if_ip6)
+ {
+ ip_address_set (&if_ip, if_ip6, AF_IP6);
+ }
+ }
bi0 = ikev2_get_new_ike_header_buff (vm, &b0);
if (!bi0)
@@ -3920,8 +4102,7 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
u8 *nat_detection_sha1 =
ikev2_compute_nat_sha1 (clib_host_to_net_u64 (sa.ispi),
clib_host_to_net_u64 (sa.rspi),
- if_ip->as_u32,
- clib_host_to_net_u16 (IKEV2_PORT));
+ &if_ip, clib_host_to_net_u16 (IKEV2_PORT));
ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_NAT_DETECTION_SOURCE_IP,
nat_detection_sha1);
@@ -3929,7 +4110,7 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
nat_detection_sha1 =
ikev2_compute_nat_sha1 (clib_host_to_net_u64 (sa.ispi),
clib_host_to_net_u64 (sa.rspi),
- p->responder.ip4.as_u32,
+ &p->responder.addr,
clib_host_to_net_u16 (sa.dst_port));
ikev2_payload_add_notify (chain,
IKEV2_NOTIFY_MSG_NAT_DETECTION_DESTINATION_IP,
@@ -3964,8 +4145,8 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
vec_add (sa.last_sa_init_req_packet_data, ike0, len);
/* add data to the SA then add it to the pool */
- sa.iaddr.as_u32 = if_ip->as_u32;
- sa.raddr.as_u32 = p->responder.ip4.as_u32;
+ ip_address_copy (&sa.iaddr, &if_ip);
+ ip_address_copy (&sa.raddr, &p->responder.addr);
sa.i_id.type = p->loc_id.type;
sa.i_id.data = vec_dup (p->loc_id.data);
sa.r_id.type = p->rem_id.type;
@@ -3985,12 +4166,13 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
clib_memcpy_fast (sa0, &sa, sizeof (*sa0));
hash_set (km->sa_by_ispi, sa0->ispi, sa0 - km->sais);
- ikev2_send_ike (vm, if_ip, &p->responder.ip4, bi0, len,
+ ikev2_send_ike (vm, &if_ip, &p->responder.addr, bi0, len,
IKEV2_PORT, sa.dst_port, sa.sw_if_index);
- ikev2_elog_exchange ("ispi %lx rspi %lx IKEV2_EXCHANGE_SA_INIT sent to "
- "%d.%d.%d.%d", clib_host_to_net_u64 (sa0->ispi), 0,
- p->responder.ip4.as_u32);
+ ikev2_elog_exchange ("ispi %lx rspi %lx IKEV2_EXCHANGE_SA_INIT sent to ",
+ clib_host_to_net_u64 (sa0->ispi), 0,
+ ip_addr_v4 (&p->responder.addr).as_u32,
+ ip_addr_version (&p->responder.addr) == AF_IP4);
}
return 0;
@@ -4240,12 +4422,14 @@ ikev2_init (vlib_main_t * vm)
km->sw_if_indices = hash_create (0, 0);
km->udp_ports = hash_create (0, sizeof (uword));
- udp_register_dst_port (vm, IKEV2_PORT, ikev2_node.index, 1);
- udp_register_dst_port (vm, IKEV2_PORT_NATT, ikev2_node.index, 1);
+ udp_register_dst_port (vm, IKEV2_PORT, ikev2_node_ip4.index, 1);
+ udp_register_dst_port (vm, IKEV2_PORT, ikev2_node_ip6.index, 0);
+ udp_register_dst_port (vm, IKEV2_PORT_NATT, ikev2_node_ip4.index, 1);
+ udp_register_dst_port (vm, IKEV2_PORT_NATT, ikev2_node_ip6.index, 0);
- vlib_punt_hdl_t punt_hdl = vlib_punt_client_register ("ikev2");
+ vlib_punt_hdl_t punt_hdl = vlib_punt_client_register ("ikev2-ip4");
vlib_punt_register (punt_hdl, ipsec_punt_reason[IPSEC_PUNT_IP4_SPI_UDP_0],
- "ikev2");
+ "ikev2-ip4");
ikev2_cli_reference ();
km->log_level = IKEV2_LOG_ERROR;
@@ -4316,13 +4500,17 @@ ikev2_mngr_process_child_sa (ikev2_sa_t * sa, ikev2_child_sa_t * csa,
ip46_address_t remote_ip;
if (sa->is_initiator)
{
- ip46_address_set_ip4 (&local_ip, &sa->iaddr);
- ip46_address_set_ip4 (&remote_ip, &sa->raddr);
+ local_ip = to_ip46 (ip_addr_version (&sa->iaddr),
+ ip_addr_bytes (&sa->iaddr));
+ remote_ip = to_ip46 (ip_addr_version (&sa->raddr),
+ ip_addr_bytes (&sa->raddr));
}
else
{
- ip46_address_set_ip4 (&local_ip, &sa->raddr);
- ip46_address_set_ip4 (&remote_ip, &sa->iaddr);
+ local_ip = to_ip46 (ip_addr_version (&sa->raddr),
+ ip_addr_bytes (&sa->raddr));
+ remote_ip = to_ip46 (ip_addr_version (&sa->iaddr),
+ ip_addr_bytes (&sa->iaddr));
}
/* *INDENT-OFF* */
@@ -4460,7 +4648,7 @@ static void
ikev2_send_informational_request (ikev2_sa_t * sa)
{
ikev2_main_t *km = &ikev2_main;
- ip4_address_t *src, *dst;
+ ip_address_t *src, *dst;
ike_header_t *ike0;
vlib_buffer_t *b0;
u32 bi0 = 0;
diff --git a/src/plugins/ikev2/ikev2.h b/src/plugins/ikev2/ikev2.h
index 36ac85a39c5..47c301f33a1 100644
--- a/src/plugins/ikev2/ikev2.h
+++ b/src/plugins/ikev2/ikev2.h
@@ -369,6 +369,12 @@ typedef enum
#undef _
} ikev2_id_type_t;
+typedef enum
+{
+ TS_IPV4_ADDR_RANGE = 7,
+ TS_IPV6_ADDR_RANGE = 8,
+} ikev2_traffic_selector_type_t;
+
clib_error_t *ikev2_init (vlib_main_t * vm);
clib_error_t *ikev2_set_local_key (vlib_main_t * vm, u8 * file);
clib_error_t *ikev2_add_del_profile (vlib_main_t * vm, u8 * name, int is_add);
@@ -379,11 +385,11 @@ clib_error_t *ikev2_set_profile_id (vlib_main_t * vm, u8 * name,
u8 id_type, u8 * data, int is_local);
clib_error_t *ikev2_set_profile_ts (vlib_main_t * vm, u8 * name,
u8 protocol_id, u16 start_port,
- u16 end_port, ip4_address_t start_addr,
- ip4_address_t end_addr, int is_local);
+ u16 end_port, ip_address_t start_addr,
+ ip_address_t end_addr, int is_local);
clib_error_t *ikev2_set_profile_responder (vlib_main_t * vm, u8 * name,
u32 sw_if_index,
- ip4_address_t ip4);
+ ip_address_t addr);
clib_error_t *ikev2_set_profile_ike_transforms (vlib_main_t * vm, u8 * name,
ikev2_transform_encr_type_t
crypto_alg,
diff --git a/src/plugins/ikev2/ikev2_api.c b/src/plugins/ikev2/ikev2_api.c
index c73505b2421..33ff0853832 100644
--- a/src/plugins/ikev2/ikev2_api.c
+++ b/src/plugins/ikev2/ikev2_api.c
@@ -98,8 +98,8 @@ cp_ts (vl_api_ikev2_ts_t * vl_api_ts, ikev2_ts_t * ts, u8 is_local)
vl_api_ts->protocol_id = ts->protocol_id;
vl_api_ts->start_port = ts->start_port;
vl_api_ts->end_port = ts->end_port;
- ip4_address_encode (&ts->start_addr, vl_api_ts->start_addr);
- ip4_address_encode (&ts->end_addr, vl_api_ts->end_addr);
+ ip_address_encode2 (&ts->start_addr, &vl_api_ts->start_addr);
+ ip_address_encode2 (&ts->end_addr, &vl_api_ts->end_addr);
}
static void
@@ -116,7 +116,7 @@ cp_responder (vl_api_ikev2_responder_t * vl_api_responder,
ikev2_responder_t * responder)
{
vl_api_responder->sw_if_index = responder->sw_if_index;
- ip4_address_encode (&responder->ip4, vl_api_responder->ip4);
+ ip_address_encode2 (&responder->addr, &vl_api_responder->addr);
}
void
@@ -208,8 +208,8 @@ send_sa (ikev2_sa_t * sa, vl_api_ikev2_sa_dump_t * mp, u32 api_sa_index)
vl_api_ikev2_keys_t* k = &rsa->keys;
rsa->profile_index = rsa->profile_index;
rsa->sa_index = api_sa_index;
- ip4_address_encode (&sa->iaddr, rsa->iaddr);
- ip4_address_encode (&sa->raddr, rsa->raddr);
+ ip_address_encode2 (&sa->iaddr, &rsa->iaddr);
+ ip_address_encode2 (&sa->raddr, &rsa->raddr);
rsa->ispi = sa->ispi;
rsa->rspi = sa->rspi;
cp_id(&rsa->i_id, &sa->i_id);
@@ -593,9 +593,9 @@ vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp)
vlib_main_t *vm = vlib_get_main ();
clib_error_t *error;
u8 *tmp = format (0, "%s", mp->name);
- ip4_address_t start_addr, end_addr;
- ip4_address_decode (mp->ts.start_addr, &start_addr);
- ip4_address_decode (mp->ts.end_addr, &end_addr);
+ ip_address_t start_addr, end_addr;
+ ip_address_decode2 (&mp->ts.start_addr, &start_addr);
+ ip_address_decode2 (&mp->ts.end_addr, &end_addr);
error =
ikev2_set_profile_ts (vm, tmp, mp->ts.protocol_id,
clib_net_to_host_u16 (mp->ts.start_port),
@@ -642,11 +642,11 @@ vl_api_ikev2_set_responder_t_handler (vl_api_ikev2_set_responder_t * mp)
clib_error_t *error;
u8 *tmp = format (0, "%s", mp->name);
- ip4_address_t ip4;
- ip4_address_decode (mp->responder.ip4, &ip4);
+ ip_address_t ip;
+ ip_address_decode2 (&mp->responder.addr, &ip);
u32 sw_if_index = clib_net_to_host_u32 (mp->responder.sw_if_index);
- error = ikev2_set_profile_responder (vm, tmp, sw_if_index, ip4);
+ error = ikev2_set_profile_responder (vm, tmp, sw_if_index, ip);
vec_free (tmp);
if (error)
rv = VNET_API_ERROR_UNSPECIFIED;
diff --git a/src/plugins/ikev2/ikev2_cli.c b/src/plugins/ikev2/ikev2_cli.c
index 727e3473627..c948578eb23 100644
--- a/src/plugins/ikev2/ikev2_cli.c
+++ b/src/plugins/ikev2/ikev2_cli.c
@@ -55,8 +55,8 @@ format_ikev2_traffic_selector (u8 * s, va_list * va)
s = format (s, "%u type %u protocol_id %u addr "
"%U - %U port %u - %u\n",
index, ts->ts_type, ts->protocol_id,
- format_ip4_address, &ts->start_addr,
- format_ip4_address, &ts->end_addr,
+ format_ip_address, &ts->start_addr,
+ format_ip_address, &ts->end_addr,
clib_net_to_host_u16 (ts->start_port),
clib_net_to_host_u16 (ts->end_port));
return s;
@@ -127,8 +127,8 @@ format_ikev2_sa (u8 * s, va_list * va)
u32 indent = 1;
s = format (s, "iip %U ispi %lx rip %U rspi %lx",
- format_ip4_address, &sa->iaddr, sa->ispi,
- format_ip4_address, &sa->raddr, sa->rspi);
+ format_ip_address, &sa->iaddr, sa->ispi,
+ format_ip_address, &sa->raddr, sa->rspi);
if (!details)
return s;
@@ -279,11 +279,9 @@ ikev2_profile_add_del_command_fn (vlib_main_t * vm,
u8 *data = 0;
u32 tmp1, tmp2, tmp3;
u64 tmp4, tmp5;
- ip4_address_t ip4;
- ip4_address_t end_addr;
+ ip_address_t ip, end_addr;
u32 responder_sw_if_index = (u32) ~ 0;
u32 tun_sw_if_index = (u32) ~ 0;
- ip4_address_t responder_ip4;
ikev2_transform_encr_type_t crypto_alg;
ikev2_transform_integ_type_t integ_alg;
ikev2_transform_dh_type_t dh_type;
@@ -333,10 +331,10 @@ ikev2_profile_add_del_command_fn (vlib_main_t * vm,
else if (unformat (line_input, "set %U id local %U %U",
unformat_ikev2_token, &name,
unformat_ikev2_id_type, &id_type,
- unformat_ip4_address, &ip4))
+ unformat_ip_address, &ip))
{
- data = vec_new (u8, 4);
- clib_memcpy (data, ip4.as_u8, 4);
+ data = vec_new (u8, ip_address_size (&ip));
+ clib_memcpy (data, ip_addr_bytes (&ip), ip_address_size (&ip));
r =
ikev2_set_profile_id (vm, name, (u8) id_type, data, /*local */ 1);
goto done;
@@ -361,10 +359,10 @@ ikev2_profile_add_del_command_fn (vlib_main_t * vm,
else if (unformat (line_input, "set %U id remote %U %U",
unformat_ikev2_token, &name,
unformat_ikev2_id_type, &id_type,
- unformat_ip4_address, &ip4))
+ unformat_ip_address, &ip))
{
- data = vec_new (u8, 4);
- clib_memcpy (data, ip4.as_u8, 4);
+ data = vec_new (u8, ip_address_size (&ip));
+ clib_memcpy (data, ip_addr_bytes (&ip), ip_address_size (&ip));
r = ikev2_set_profile_id (vm, name, (u8) id_type, data, /*remote */
0);
goto done;
@@ -389,36 +387,32 @@ ikev2_profile_add_del_command_fn (vlib_main_t * vm,
else if (unformat (line_input, "set %U traffic-selector local "
"ip-range %U - %U port-range %u - %u protocol %u",
unformat_ikev2_token, &name,
- unformat_ip4_address, &ip4,
- unformat_ip4_address, &end_addr,
- &tmp1, &tmp2, &tmp3))
+ unformat_ip_address, &ip,
+ unformat_ip_address, &end_addr, &tmp1, &tmp2, &tmp3))
{
r =
ikev2_set_profile_ts (vm, name, (u8) tmp3, (u16) tmp1, (u16) tmp2,
- ip4, end_addr, /*local */ 1);
+ ip, end_addr, /*local */ 1);
goto done;
}
else if (unformat (line_input, "set %U traffic-selector remote "
"ip-range %U - %U port-range %u - %u protocol %u",
unformat_ikev2_token, &name,
- unformat_ip4_address, &ip4,
- unformat_ip4_address, &end_addr,
- &tmp1, &tmp2, &tmp3))
+ unformat_ip_address, &ip,
+ unformat_ip_address, &end_addr, &tmp1, &tmp2, &tmp3))
{
r =
ikev2_set_profile_ts (vm, name, (u8) tmp3, (u16) tmp1, (u16) tmp2,
- ip4, end_addr, /*remote */ 0);
+ ip, end_addr, /*remote */ 0);
goto done;
}
else if (unformat (line_input, "set %U responder %U %U",
unformat_ikev2_token, &name,
unformat_vnet_sw_interface, vnm,
- &responder_sw_if_index, unformat_ip4_address,
- &responder_ip4))
+ &responder_sw_if_index, unformat_ip_address, &ip))
{
r =
- ikev2_set_profile_responder (vm, name, responder_sw_if_index,
- responder_ip4);
+ ikev2_set_profile_responder (vm, name, responder_sw_if_index, ip);
goto done;
}
else if (unformat (line_input, "set %U tunnel %U",
@@ -565,7 +559,7 @@ show_ikev2_profile_command_fn (vlib_main_t * vm,
if (p->loc_id.type == IKEV2_ID_TYPE_ID_IPV4_ADDR)
vlib_cli_output(vm, " local id-type %U data %U",
format_ikev2_id_type, p->loc_id.type,
- format_ip4_address, p->loc_id.data);
+ format_ip_address, p->loc_id.data);
else if (p->loc_id.type == IKEV2_ID_TYPE_ID_KEY_ID)
vlib_cli_output(vm, " local id-type %U data 0x%U",
format_ikev2_id_type, p->loc_id.type,
@@ -581,7 +575,7 @@ show_ikev2_profile_command_fn (vlib_main_t * vm,
if (p->rem_id.type == IKEV2_ID_TYPE_ID_IPV4_ADDR)
vlib_cli_output(vm, " remote id-type %U data %U",
format_ikev2_id_type, p->rem_id.type,
- format_ip4_address, p->rem_id.data);
+ format_ip_address, p->rem_id.data);
else if (p->rem_id.type == IKEV2_ID_TYPE_ID_KEY_ID)
vlib_cli_output(vm, " remote id-type %U data 0x%U",
format_ikev2_id_type, p->rem_id.type,
@@ -592,19 +586,19 @@ show_ikev2_profile_command_fn (vlib_main_t * vm,
format_ikev2_id_type, p->rem_id.type, p->rem_id.data);
}
- if (p->loc_ts.end_addr.as_u32)
+ if (!ip_address_is_zero (&p->loc_ts.start_addr))
vlib_cli_output(vm, " local traffic-selector addr %U - %U port %u - %u"
" protocol %u",
- format_ip4_address, &p->loc_ts.start_addr,
- format_ip4_address, &p->loc_ts.end_addr,
+ format_ip_address, &p->loc_ts.start_addr,
+ format_ip_address, &p->loc_ts.end_addr,
p->loc_ts.start_port, p->loc_ts.end_port,
p->loc_ts.protocol_id);
- if (p->rem_ts.end_addr.as_u32)
+ if (!ip_address_is_zero (&p->rem_ts.start_addr))
vlib_cli_output(vm, " remote traffic-selector addr %U - %U port %u - %u"
" protocol %u",
- format_ip4_address, &p->rem_ts.start_addr,
- format_ip4_address, &p->rem_ts.end_addr,
+ format_ip_address, &p->rem_ts.start_addr,
+ format_ip_address, &p->rem_ts.end_addr,
p->rem_ts.start_port, p->rem_ts.end_port,
p->rem_ts.protocol_id);
if (~0 != p->tun_itf)
@@ -613,7 +607,7 @@ show_ikev2_profile_command_fn (vlib_main_t * vm,
if (~0 != p->responder.sw_if_index)
vlib_cli_output(vm, " responder %U %U",
format_vnet_sw_if_index_name, vnet_get_main(), p->responder.sw_if_index,
- format_ip4_address, &p->responder.ip4);
+ format_ip_address, &p->responder.addr);
if (p->udp_encap)
vlib_cli_output(vm, " udp-encap");
diff --git a/src/plugins/ikev2/ikev2_payload.c b/src/plugins/ikev2/ikev2_payload.c
index b7d7098605c..c03054aa9cd 100644
--- a/src/plugins/ikev2/ikev2_payload.c
+++ b/src/plugins/ikev2/ikev2_payload.c
@@ -38,13 +38,22 @@ typedef CLIB_PACKED (struct {
/* *INDENT-OFF* */
typedef CLIB_PACKED (struct {
+ ip4_address_t start_addr;
+ ip4_address_t end_addr;
+}) ikev2_ip4_addr_pair_t;
+
+typedef CLIB_PACKED (struct {
+ ip6_address_t start_addr;
+ ip6_address_t end_addr;
+}) ikev2_ip6_addr_pair_t;
+
+typedef CLIB_PACKED (struct {
u8 ts_type;
u8 protocol_id;
u16 selector_len;
u16 start_port;
u16 end_port;
- ip4_address_t start_addr;
- ip4_address_t end_addr;
+ u8 addr_pair[0];
}) ikev2_ts_payload_entry_t;
/* *INDENT-OFF* */
@@ -286,12 +295,46 @@ ikev2_payload_add_auth (ikev2_payload_chain_t * c, ikev2_auth_t * auth)
ikev2_payload_add_data (c, auth->data);
}
+static void
+ikev2_payload_add_ts_entry (u8 ** data, ikev2_ts_t * ts)
+{
+ u8 * tmp;
+ ikev2_ts_payload_entry_t *entry;
+ int len = sizeof (*entry);
+
+ if (ts->ts_type == TS_IPV4_ADDR_RANGE)
+ len += sizeof (ikev2_ip4_addr_pair_t);
+ else
+ len += sizeof (ikev2_ip6_addr_pair_t);
+
+ vec_add2 (data[0], tmp, len);
+ entry = (ikev2_ts_payload_entry_t *) tmp;
+ entry->ts_type = ts->ts_type;
+ entry->protocol_id = ts->protocol_id;
+ entry->selector_len = clib_host_to_net_u16 (len);
+ entry->start_port = clib_host_to_net_u16 (ts->start_port);
+ entry->end_port = clib_host_to_net_u16 (ts->end_port);
+
+ if (ts->ts_type == TS_IPV4_ADDR_RANGE)
+ {
+ ikev2_ip4_addr_pair_t *pair = (ikev2_ip4_addr_pair_t*) entry->addr_pair;
+ ip_address_copy_addr (&pair->start_addr, &ts->start_addr);
+ ip_address_copy_addr (&pair->end_addr, &ts->end_addr);
+ }
+ else
+ {
+ ikev2_ip6_addr_pair_t *pair = (ikev2_ip6_addr_pair_t*) entry->addr_pair;
+ ip_address_copy_addr (&pair->start_addr, &ts->start_addr);
+ ip_address_copy_addr (&pair->end_addr, &ts->end_addr);
+ }
+}
+
void
ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts, u8 type)
{
ike_ts_payload_header_t *tsh;
ikev2_ts_t *ts2;
- u8 *data = 0, *tmp;
+ u8 *data = 0;
tsh =
(ike_ts_payload_header_t *) ikev2_payload_add_hdr (c, type,
@@ -300,17 +343,9 @@ ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts, u8 type)
vec_foreach (ts2, ts)
{
- ASSERT (ts2->ts_type == 7); /*TS_IPV4_ADDR_RANGE */
- ikev2_ts_payload_entry_t *entry;
- vec_add2 (data, tmp, sizeof (*entry));
- entry = (ikev2_ts_payload_entry_t *) tmp;
- entry->ts_type = ts2->ts_type;
- entry->protocol_id = ts2->protocol_id;
- entry->selector_len = clib_host_to_net_u16 (16);
- entry->start_port = clib_host_to_net_u16 (ts2->start_port);
- entry->end_port = clib_host_to_net_u16 (ts2->end_port);
- entry->start_addr.as_u32 = ts2->start_addr.as_u32;
- entry->end_addr.as_u32 = ts2->end_addr.as_u32;
+ ASSERT (ts2->ts_type == TS_IPV4_ADDR_RANGE ||
+ ts2->ts_type == TS_IPV6_ADDR_RANGE);
+ ikev2_payload_add_ts_entry (&data, ts2);
}
ikev2_payload_add_data (c, data);
@@ -413,31 +448,56 @@ ikev2_parse_ts_payload (ike_payload_header_t * ikep, u32 rlen)
{
ike_ts_payload_header_t *tsp = (ike_ts_payload_header_t *) ikep;
ikev2_ts_t *r = 0, *ts;
- u8 i;
+ ikev2_ip4_addr_pair_t *pair4;
+ ikev2_ip6_addr_pair_t *pair6;
+ int p = 0, n_left;
+ ikev2_ts_payload_entry_t *pe;
if (sizeof (*tsp) > rlen)
return 0;
- if (sizeof (*tsp) + tsp->num_ts * sizeof (ikev2_ts_payload_entry_t) > rlen)
- return 0;
+ rlen -= sizeof (*tsp);
+ n_left = tsp->num_ts;
- for (i = 0; i < tsp->num_ts; i++)
+ while (n_left && p + sizeof (*pe) < rlen)
{
- if (tsp->ts[i].ts_type != 7) /* TS_IPV4_ADDR_RANGE */
+ pe = (ikev2_ts_payload_entry_t *) (((u8 *)tsp->ts) + p);
+ p += sizeof (*pe);
+
+ if (pe->ts_type != TS_IPV4_ADDR_RANGE &&
+ pe->ts_type != TS_IPV6_ADDR_RANGE)
{
ikev2_elog_uint (IKEV2_LOG_ERROR,
- "unsupported TS type received (%u)", tsp->ts[i].ts_type);
- continue;
+ "unsupported TS type received (%u)", pe->ts_type);
+ return 0;
}
vec_add2 (r, ts, 1);
- ts->ts_type = tsp->ts[i].ts_type;
- ts->protocol_id = tsp->ts[i].protocol_id;
- ts->start_port = tsp->ts[i].start_port;
- ts->end_port = tsp->ts[i].end_port;
- ts->start_addr.as_u32 = tsp->ts[i].start_addr.as_u32;
- ts->end_addr.as_u32 = tsp->ts[i].end_addr.as_u32;
+ ts->ts_type = pe->ts_type;
+ ts->protocol_id = pe->protocol_id;
+ ts->start_port = pe->start_port;
+ ts->end_port = pe->end_port;
+
+ if (pe->ts_type == TS_IPV4_ADDR_RANGE)
+ {
+ pair4 = (ikev2_ip4_addr_pair_t*) pe->addr_pair;
+ ip_address_set (&ts->start_addr, &pair4->start_addr, AF_IP4);
+ ip_address_set (&ts->end_addr, &pair4->end_addr, AF_IP4);
+ p += sizeof (*pair4);
+ }
+ else
+ {
+ pair6 = (ikev2_ip6_addr_pair_t*) pe->addr_pair;
+ ip_address_set (&ts->start_addr, &pair6->start_addr, AF_IP6);
+ ip_address_set (&ts->end_addr, &pair6->end_addr, AF_IP6);
+ p += sizeof (*pair6);
+ }
+ n_left--;
}
+
+ if (n_left)
+ return 0;
+
return r;
}
diff --git a/src/plugins/ikev2/ikev2_priv.h b/src/plugins/ikev2/ikev2_priv.h
index f6f9989e4b2..68a546a0f48 100644
--- a/src/plugins/ikev2/ikev2_priv.h
+++ b/src/plugins/ikev2/ikev2_priv.h
@@ -81,7 +81,7 @@ do { \
} \
} while (0) \
-#define ikev2_elog_exchange(_format, _ispi, _rspi, _addr) \
+#define ikev2_elog_exchange_internal(_format, _ispi, _rspi, _addr) \
do { \
ikev2_main_t *km = &ikev2_main; \
if (PREDICT_FALSE (km->log_level >= IKEV2_LOG_DEBUG)) \
@@ -110,6 +110,17 @@ do { \
} \
} while (0) \
+#define IKE_ELOG_IP4_FMT "%d.%d.%d.%d"
+#define IKE_ELOG_IP6_FMT "[v6]:%x%x:%x%x"
+
+#define ikev2_elog_exchange(_fmt, _ispi, _rspi, _addr, _v4) \
+do { \
+ if (_v4) \
+ ikev2_elog_exchange_internal (_fmt IKE_ELOG_IP4_FMT, _ispi, _rspi, _addr);\
+ else \
+ ikev2_elog_exchange_internal (_fmt IKE_ELOG_IP6_FMT, _ispi, _rspi, _addr);\
+} while (0)
+
#define ikev2_elog_uint(_level, _format, _val) \
do { \
ikev2_main_t *km = &ikev2_main; \
@@ -156,31 +167,6 @@ do { \
} \
} while (0)
-#define ikev2_elog_peers(_level, _format, _ip1, _ip2) \
-do { \
- ikev2_main_t *km = &ikev2_main; \
- if (PREDICT_FALSE (km->log_level >= _level)) \
- { \
- ELOG_TYPE_DECLARE (e) = \
- { \
- .format = "ikev2: " _format, \
- .format_args = "i1i1i1i1i1i1i1i1", \
- }; \
- CLIB_PACKED(struct { \
- u8 i11; u8 i12; u8 i13; u8 i14; \
- u8 i21; u8 i22; u8 i23; u8 i24; }) *ed; \
- ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
- ed->i14 = (_ip1) >> 24; \
- ed->i13 = (_ip1) >> 16; \
- ed->i12 = (_ip1) >> 8; \
- ed->i11 = (_ip1); \
- ed->i24 = (_ip2) >> 24; \
- ed->i23 = (_ip2) >> 16; \
- ed->i22 = (_ip2) >> 8; \
- ed->i21 = (_ip2); \
- } \
-} while (0)
-
#define ikev2_elog_error(_msg) \
_ikev2_elog(IKEV2_LOG_ERROR, "[error] " _msg)
#define ikev2_elog_warning(_msg) \
@@ -258,19 +244,19 @@ typedef struct
typedef struct
{
- u8 ts_type;
+ ikev2_traffic_selector_type_t ts_type;
u8 protocol_id;
u16 selector_len;
u16 start_port;
u16 end_port;
- ip4_address_t start_addr;
- ip4_address_t end_addr;
+ ip_address_t start_addr;
+ ip_address_t end_addr;
} ikev2_ts_t;
typedef struct
{
u32 sw_if_index;
- ip4_address_t ip4;
+ ip_address_t addr;
} ikev2_responder_t;
typedef struct
@@ -368,8 +354,8 @@ typedef struct
ikev2_state_t state;
u8 unsupported_cp;
u8 initial_contact;
- ip4_address_t iaddr;
- ip4_address_t raddr;
+ ip_address_t iaddr;
+ ip_address_t raddr;
u64 ispi;
u64 rspi;
u8 *i_nonce;
diff --git a/src/plugins/ikev2/ikev2_test.c b/src/plugins/ikev2/ikev2_test.c
index 222f01ad123..81a222c0971 100644
--- a/src/plugins/ikev2/ikev2_test.c
+++ b/src/plugins/ikev2/ikev2_test.c
@@ -135,7 +135,7 @@ MACRO_FORMAT (auth_method)
s = format (s, " %s", id->data);
break;
case IKEV2_ID_TYPE_ID_IPV4_ADDR:
- s = format (s, " %U", format_ip4_address, id->data);
+ s = format (s, " %U", format_ip_address, id->data);
break;
case IKEV2_ID_TYPE_ID_KEY_ID:
s = format (s, " 0x%U", format_hex_bytes, id->data, id->data_len);
@@ -225,7 +225,6 @@ static void vl_api_ikev2_profile_details_t_handler
{
vat_main_t *vam = ikev2_test_main.vat_main;
vl_api_ikev2_profile_t *p = &mp->profile;
- ip4_address_t start_addr, end_addr;
fformat (vam->ofp, "profile %s\n", p->name);
@@ -256,21 +255,17 @@ static void vl_api_ikev2_profile_details_t_handler
format_ikev2_id_type_and_data, &p->rem_id);
}
- ip4_address_decode (p->loc_ts.start_addr, &start_addr);
- ip4_address_decode (p->loc_ts.end_addr, &end_addr);
fformat (vam->ofp, " local traffic-selector addr %U - %U port %u - %u"
" protocol %u\n",
- format_ip4_address, &start_addr,
- format_ip4_address, &end_addr,
+ format_ip_address, &p->loc_ts.start_addr,
+ format_ip_address, &p->loc_ts.end_addr,
clib_net_to_host_u16 (p->loc_ts.start_port),
clib_net_to_host_u16 (p->loc_ts.end_port), p->loc_ts.protocol_id);
- ip4_address_decode (p->rem_ts.start_addr, &start_addr);
- ip4_address_decode (p->rem_ts.end_addr, &end_addr);
fformat (vam->ofp, " remote traffic-selector addr %U - %U port %u - %u"
" protocol %u\n",
- format_ip4_address, &start_addr,
- format_ip4_address, &end_addr,
+ format_ip_address, &p->rem_ts.start_addr,
+ format_ip_address, &p->rem_ts.end_addr,
clib_net_to_host_u16 (p->rem_ts.start_port),
clib_net_to_host_u16 (p->rem_ts.end_port), p->rem_ts.protocol_id);
u32 tun_itf = clib_net_to_host_u32 (p->tun_itf);
@@ -280,7 +275,7 @@ static void vl_api_ikev2_profile_details_t_handler
u32 sw_if_index = clib_net_to_host_u32 (p->responder.sw_if_index);
if (~0 != sw_if_index)
fformat (vam->ofp, " responder idx %d %U\n",
- sw_if_index, format_ip4_address, &p->responder.ip4);
+ sw_if_index, format_ip_address, &p->responder.addr);
if (p->udp_encap)
fformat (vam->ofp, " udp-encap\n");
@@ -348,18 +343,18 @@ vl_api_ikev2_sa_details_t_handler (vl_api_ikev2_sa_details_t * mp)
{
vat_main_t *vam = ikev2_test_main.vat_main;
vl_api_ikev2_sa_t *sa = &mp->sa;
- ip4_address_t iaddr;
- ip4_address_t raddr;
+ ip_address_t iaddr;
+ ip_address_t raddr;
vl_api_ikev2_keys_t *k = &sa->keys;
vl_api_ikev2_sa_t_endian (sa);
- ip4_address_decode (sa->iaddr, &iaddr);
- ip4_address_decode (sa->raddr, &raddr);
+ ip_address_decode2 (&sa->iaddr, &iaddr);
+ ip_address_decode2 (&sa->raddr, &raddr);
fformat (vam->ofp, "profile index %d sa index: %d\n",
mp->sa.profile_index, mp->sa.sa_index);
- fformat (vam->ofp, " iip %U ispi %lx rip %U rspi %lx\n", format_ip4_address,
- &iaddr, sa->ispi, format_ip4_address, &raddr, sa->rspi);
+ fformat (vam->ofp, " iip %U ispi %lx rip %U rspi %lx\n", format_ip_address,
+ &iaddr, sa->ispi, format_ip_address, &raddr, sa->rspi);
fformat (vam->ofp, " %U ", format_ikev2_sa_transform, &sa->encryption);
fformat (vam->ofp, "%U ", format_ikev2_sa_transform, &sa->prf);
fformat (vam->ofp, "%U ", format_ikev2_sa_transform, &sa->integrity);
@@ -526,18 +521,17 @@ static void
{
vat_main_t *vam = ikev2_test_main.vat_main;
vl_api_ikev2_ts_t *ts = &mp->ts;
- ip4_address_t start_addr;
- ip4_address_t end_addr;
+ ip_address_t start_addr, end_addr;
vl_api_ikev2_ts_t_endian (ts);
- ip4_address_decode (ts->start_addr, &start_addr);
- ip4_address_decode (ts->end_addr, &end_addr);
+ ip_address_decode2 (&ts->start_addr, &start_addr);
+ ip_address_decode2 (&ts->end_addr, &end_addr);
fformat (vam->ofp, " %s protocol_id %u addr "
"%U - %U port %u - %u\n",
ts->is_local, ts->protocol_id,
- format_ip4_address, &start_addr,
- format_ip4_address, &end_addr, ts->start_port, ts->end_port);
+ format_ip_address, &start_addr,
+ format_ip_address, &end_addr, ts->start_port, ts->end_port);
vam->result_ready = 1;
}
@@ -797,7 +791,7 @@ api_ikev2_profile_set_id (vat_main_t * vam)
u8 *data = 0;
u8 is_local = 0;
u32 id_type = 0;
- ip4_address_t ip4;
+ ip_address_t ip;
int ret;
const char *valid_chars = "a-zA-Z0-9_";
@@ -808,10 +802,10 @@ api_ikev2_profile_set_id (vat_main_t * vam)
vec_add1 (name, 0);
else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
;
- else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
+ else if (unformat (i, "id_data %U", unformat_ip_address, &ip))
{
- data = vec_new (u8, 4);
- clib_memcpy (data, ip4.as_u8, 4);
+ data = vec_new (u8, ip_address_size (&ip));
+ clib_memcpy (data, ip_addr_bytes (&ip), ip_address_size (&ip));
}
else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
;
@@ -875,14 +869,12 @@ api_ikev2_profile_set_ts (vat_main_t * vam)
u8 *name = 0;
u8 is_local = 0;
u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
- ip4_address_t start_addr, end_addr;
+ ip_address_t start_addr, end_addr;
+ u8 start_addr_set = 0, end_addr_set = 0;
const char *valid_chars = "a-zA-Z0-9_";
int ret;
- start_addr.as_u32 = 0;
- end_addr.as_u32 = (u32) ~ 0;
-
while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
{
if (unformat (i, "name %U", unformat_token, valid_chars, &name))
@@ -894,10 +886,10 @@ api_ikev2_profile_set_ts (vat_main_t * vam)
else if (unformat (i, "end_port %d", &end_port))
;
else
- if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
- ;
- else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
- ;
+ if (unformat (i, "start_addr %U", unformat_ip_address, &start_addr))
+ start_addr_set = 1;
+ else if (unformat (i, "end_addr %U", unformat_ip_address, &end_addr))
+ end_addr_set = 1;
else if (unformat (i, "local"))
is_local = 1;
else if (unformat (i, "remote"))
@@ -909,6 +901,12 @@ api_ikev2_profile_set_ts (vat_main_t * vam)
}
}
+ if (!start_addr_set || !end_addr_set)
+ {
+ errmsg ("missing start or end address");
+ return -99;
+ }
+
if (!vec_len (name))
{
errmsg ("profile name must be specified");
@@ -927,8 +925,8 @@ api_ikev2_profile_set_ts (vat_main_t * vam)
mp->ts.protocol_id = (u8) proto;
mp->ts.start_port = clib_host_to_net_u16 ((u16) start_port);
mp->ts.end_port = clib_host_to_net_u16 ((u16) end_port);
- ip4_address_encode (&start_addr, mp->ts.start_addr);
- ip4_address_encode (&end_addr, mp->ts.end_addr);
+ ip_address_encode2 (&start_addr, &mp->ts.start_addr);
+ ip_address_encode2 (&end_addr, &mp->ts.end_addr);
clib_memcpy (mp->name, name, vec_len (name));
vec_free (name);
@@ -1035,7 +1033,7 @@ api_ikev2_set_responder (vat_main_t * vam)
int ret;
u8 *name = 0;
u32 sw_if_index = ~0;
- ip4_address_t address;
+ ip_address_t address;
const char *valid_chars = "a-zA-Z0-9_";
@@ -1043,7 +1041,7 @@ api_ikev2_set_responder (vat_main_t * vam)
{
if (unformat
(i, "%U interface %d address %U", unformat_token, valid_chars,
- &name, &sw_if_index, unformat_ip4_address, &address))
+ &name, &sw_if_index, unformat_ip_address, &address))
vec_add1 (name, 0);
else
{
@@ -1070,7 +1068,7 @@ api_ikev2_set_responder (vat_main_t * vam)
vec_free (name);
mp->responder.sw_if_index = clib_host_to_net_u32 (sw_if_index);
- ip4_address_encode (&address, mp->responder.ip4);
+ ip_address_encode2 (&address, &mp->responder.addr);
S (mp);
W (ret);
diff --git a/src/plugins/ikev2/ikev2_types.api b/src/plugins/ikev2/ikev2_types.api
index 58297c05e9c..0f998b196c2 100644
--- a/src/plugins/ikev2/ikev2_types.api
+++ b/src/plugins/ikev2/ikev2_types.api
@@ -34,8 +34,8 @@ typedef ikev2_ts
u8 protocol_id;
u16 start_port;
u16 end_port;
- vl_api_ip4_address_t start_addr;
- vl_api_ip4_address_t end_addr;
+ vl_api_address_t start_addr;
+ vl_api_address_t end_addr;
};
typedef ikev2_auth
@@ -49,7 +49,7 @@ typedef ikev2_auth
typedef ikev2_responder
{
vl_api_interface_index_t sw_if_index;
- vl_api_ip4_address_t ip4;
+ vl_api_address_t addr;
};
typedef ikev2_ike_transforms
@@ -134,8 +134,8 @@ typedef ikev2_sa
u64 ispi;
u64 rspi;
- vl_api_ip4_address_t iaddr;
- vl_api_ip4_address_t raddr;
+ vl_api_address_t iaddr;
+ vl_api_address_t raddr;
vl_api_ikev2_keys_t keys;
diff --git a/src/plugins/ikev2/test/test_ikev2.py b/src/plugins/ikev2/test/test_ikev2.py
index 0bdc417fb2d..a47c59f578f 100644
--- a/src/plugins/ikev2/test/test_ikev2.py
+++ b/src/plugins/ikev2/test/test_ikev2.py
@@ -9,15 +9,20 @@ from cryptography.hazmat.primitives.ciphers import (
algorithms,
modes,
)
-from ipaddress import IPv4Address
+from ipaddress import IPv4Address, IPv6Address, ip_address
from scapy.layers.ipsec import ESP
from scapy.layers.inet import IP, UDP, Ether
+from scapy.layers.inet6 import IPv6
from scapy.packet import raw, Raw
from scapy.utils import long_converter
from framework import VppTestCase, VppTestRunner
from vpp_ikev2 import Profile, IDType, AuthMethod
from vpp_papi import VppEnum
+try:
+ text_type = unicode
+except NameError:
+ text_type = str
KEY_PAD = b"Key Pad for IKEv2"
SALT_SIZE = 4
@@ -156,9 +161,9 @@ class IKEv2ChildSA(object):
class IKEv2SA(object):
- def __init__(self, test, is_initiator=True, spi=b'\x04' * 8,
- i_id=None, r_id=None, id_type='fqdn', nonce=None,
- auth_data=None, local_ts=None, remote_ts=None,
+ def __init__(self, test, is_initiator=True, i_id=None, r_id=None,
+ spi=b'\x01\x02\x03\x04\x05\x06\x07\x08', id_type='fqdn',
+ nonce=None, auth_data=None, local_ts=None, remote_ts=None,
auth_method='shared-key', priv_key=None, natt=False):
self.natt = natt
if natt:
@@ -182,12 +187,12 @@ class IKEv2SA(object):
self.id_type = id_type
self.auth_method = auth_method
if self.is_initiator:
- self.rspi = None
+ self.rspi = 8 * b'\x00'
self.ispi = spi
self.i_nonce = nonce
else:
self.rspi = spi
- self.ispi = None
+ self.ispi = 8 * b'\x00'
self.r_nonce = None
self.child_sas = [IKEv2ChildSA(local_ts, remote_ts)]
@@ -416,18 +421,25 @@ class IKEv2SA(object):
ct = ep.load[:-integ_trunc]
return self.decrypt(ct)
- def generate_ts(self):
+ def build_ts_addr(self, ts, version):
+ return {'starting_address_v' + version: ts['start_addr'],
+ 'ending_address_v' + version: ts['end_addr']}
+
+ def generate_ts(self, is_ip4):
c = self.child_sas[0]
- ts1 = ikev2.IPv4TrafficSelector(
- IP_protocol_ID=0,
- start_port=0,
- end_port=0xffff,
- starting_address_v4=c.local_ts['start_addr'],
- ending_address_v4=c.local_ts['end_addr'])
- ts2 = ikev2.IPv4TrafficSelector(
- IP_protocol_ID=0,
- starting_address_v4=c.remote_ts['start_addr'],
- ending_address_v4=c.remote_ts['end_addr'])
+ ts_data = {'IP_protocol_ID': 0,
+ 'start_port': 0,
+ 'end_port': 0xffff}
+ if is_ip4:
+ ts_data.update(self.build_ts_addr(c.local_ts, '4'))
+ ts1 = ikev2.IPv4TrafficSelector(**ts_data)
+ ts_data.update(self.build_ts_addr(c.remote_ts, '4'))
+ ts2 = ikev2.IPv4TrafficSelector(**ts_data)
+ else:
+ ts_data.update(self.build_ts_addr(c.local_ts, '6'))
+ ts1 = ikev2.IPv6TrafficSelector(**ts_data)
+ ts_data.update(self.build_ts_addr(c.remote_ts, '6'))
+ ts2 = ikev2.IPv6TrafficSelector(**ts_data)
return ([ts1], [ts2])
def set_ike_props(self, crypto, crypto_key_len, integ, prf, dh):
@@ -474,7 +486,7 @@ class IKEv2SA(object):
return self.crypto_attr(self.esp_crypto_key_len)
def compute_nat_sha1(self, ip, port):
- data = self.ispi + b'\x00' * 8 + ip + (port).to_bytes(2, 'big')
+ data = self.ispi + self.rspi + ip + (port).to_bytes(2, 'big')
digest = hashes.Hash(hashes.SHA1(), backend=default_backend())
digest.update(data)
return digest.finalize()
@@ -493,6 +505,8 @@ class TemplateResponder(VppTestCase):
i.admin_up()
i.config_ip4()
i.resolve_arp()
+ i.config_ip6()
+ i.resolve_ndp()
@classmethod
def tearDownClass(cls):
@@ -504,6 +518,8 @@ class TemplateResponder(VppTestCase):
self.p.add_vpp_config()
self.assertIsNotNone(self.p.query_vpp_config())
self.sa.generate_dh_data()
+ self.vapi.cli('ikev2 set logging level 4')
+ self.vapi.cli('event-lo clear')
def tearDown(self):
super(TemplateResponder, self).tearDown()
@@ -528,16 +544,25 @@ class TemplateResponder(VppTestCase):
ike_msg = self.encrypt_ike_msg(header, del_sa, 'Delete')
packet = self.create_packet(self.pg0, ike_msg,
self.sa.sport, self.sa.dport,
- self.sa.natt)
+ self.sa.natt, self.ip6)
self.pg0.add_stream(packet)
self.pg0.enable_capture()
self.pg_start()
capture = self.pg0.get_capture(1)
self.verify_del_sa(capture[0])
- def create_packet(self, src_if, msg, sport=500, dport=500, natt=False):
+ def create_packet(self, src_if, msg, sport=500, dport=500, natt=False,
+ use_ip6=False):
+ if use_ip6:
+ src_ip = src_if.remote_ip6
+ dst_ip = src_if.local_ip6
+ ip_layer = IPv6
+ else:
+ src_ip = src_if.remote_ip4
+ dst_ip = src_if.local_ip4
+ ip_layer = IP
res = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
- IP(src=src_if.remote_ip4, dst=src_if.local_ip4) /
+ ip_layer(src=src_ip, dst=dst_ip) /
UDP(sport=sport, dport=dport))
if natt:
# insert non ESP marker
@@ -575,16 +600,24 @@ class TemplateResponder(VppTestCase):
load=self.sa.i_nonce))
if behind_nat:
- src_nat = self.sa.compute_nat_sha1(b'\x0a\x0a\x0a\x01',
- self.sa.sport)
- nat_detection = ikev2.IKEv2_payload_Notify(
- type='NAT_DETECTION_SOURCE_IP',
- load=src_nat)
- self.sa.init_req_packet = self.sa.init_req_packet / nat_detection
+ src_address = b'\x0a\x0a\x0a\x01'
+ else:
+ src_address = bytes(self.pg0.local_ip4, 'ascii')
+
+ src_nat = self.sa.compute_nat_sha1(src_address, self.sa.sport)
+ dst_nat = self.sa.compute_nat_sha1(bytes(self.pg0.remote_ip4, 'ascii'),
+ self.sa.sport)
+ nat_src_detection = ikev2.IKEv2_payload_Notify(
+ type='NAT_DETECTION_SOURCE_IP', load=src_nat)
+ nat_dst_detection = ikev2.IKEv2_payload_Notify(
+ type='NAT_DETECTION_DESTINATION_IP', load=dst_nat)
+ self.sa.init_req_packet = (self.sa.init_req_packet /
+ nat_src_detection /
+ nat_dst_detection)
ike_msg = self.create_packet(self.pg0, self.sa.init_req_packet,
self.sa.sport, self.sa.dport,
- self.sa.natt)
+ self.sa.natt, self.ip6)
self.pg0.add_stream(ike_msg)
self.pg0.enable_capture()
self.pg_start()
@@ -642,7 +675,7 @@ class TemplateResponder(VppTestCase):
props = (ikev2.IKEv2_payload_Proposal(proposal=1, proto='ESP',
SPIsize=4, SPI=os.urandom(4), trans_nb=4, trans=trans))
- tsi, tsr = self.sa.generate_ts()
+ tsi, tsr = self.sa.generate_ts(self.p.ts_is_ip4)
plain = (ikev2.IKEv2_payload_IDi(next_payload='IDr',
IDtype=self.sa.id_type, load=self.sa.i_id) /
ikev2.IKEv2_payload_IDr(next_payload='AUTH',
@@ -666,7 +699,7 @@ class TemplateResponder(VppTestCase):
ike_msg = self.encrypt_ike_msg(header, plain, 'IDi')
packet = self.create_packet(self.pg0, ike_msg, self.sa.sport,
- self.sa.dport, self.sa.natt)
+ self.sa.dport, self.sa.natt, self.ip6)
self.pg0.add_stream(packet)
self.pg0.enable_capture()
self.pg_start()
@@ -681,6 +714,8 @@ class TemplateResponder(VppTestCase):
# ipsec register for port 4500
esp = packet[ESP]
ih = self.verify_and_remove_non_esp_marker(esp)
+
+ self.assertEqual(ih.version, 0x20)
return ih
def verify_sa_init(self, packet):
@@ -776,10 +811,14 @@ class TemplateResponder(VppTestCase):
r = self.vapi.ikev2_sa_dump()
self.assertEqual(len(r), 1)
sa = r[0].sa
- self.assertEqual(self.sa.ispi, (sa.ispi).to_bytes(8, 'little'))
+ self.assertEqual(self.sa.ispi, (sa.ispi).to_bytes(8, 'big'))
self.assertEqual(self.sa.rspi, (sa.rspi).to_bytes(8, 'big'))
- self.assertEqual(sa.iaddr, IPv4Address(self.pg0.remote_ip4))
- self.assertEqual(sa.raddr, IPv4Address(self.pg0.local_ip4))
+ if self.ip6:
+ self.assertEqual(sa.iaddr, IPv6Address(self.pg0.remote_ip6))
+ self.assertEqual(sa.raddr, IPv6Address(self.pg0.local_ip6))
+ else:
+ self.assertEqual(sa.iaddr, IPv4Address(self.pg0.remote_ip4))
+ self.assertEqual(sa.raddr, IPv4Address(self.pg0.local_ip4))
self.verify_keymat(sa.keys, self.sa, 'sk_d')
self.verify_keymat(sa.keys, self.sa, 'sk_ai')
self.verify_keymat(sa.keys, self.sa, 'sk_ar')
@@ -806,7 +845,7 @@ class TemplateResponder(VppTestCase):
self.verify_keymat(csa.keys, c, 'sk_ei')
self.verify_keymat(csa.keys, c, 'sk_er')
- tsi, tsr = self.sa.generate_ts()
+ tsi, tsr = self.sa.generate_ts(self.p.ts_is_ip4)
tsi = tsi[0]
tsr = tsr[0]
r = self.vapi.ikev2_traffic_selector_dump(
@@ -838,10 +877,17 @@ class TemplateResponder(VppTestCase):
self.assertTrue(api_ts.is_local)
else:
self.assertFalse(api_ts.is_local)
- self.assertEqual(api_ts.start_addr,
- IPv4Address(ts.starting_address_v4))
- self.assertEqual(api_ts.end_addr,
- IPv4Address(ts.ending_address_v4))
+
+ if self.p.ts_is_ip4:
+ self.assertEqual(api_ts.start_addr,
+ IPv4Address(ts.starting_address_v4))
+ self.assertEqual(api_ts.end_addr,
+ IPv4Address(ts.ending_address_v4))
+ else:
+ self.assertEqual(api_ts.start_addr,
+ IPv6Address(ts.starting_address_v6))
+ self.assertEqual(api_ts.end_addr,
+ IPv6Address(ts.ending_address_v6))
self.assertEqual(api_ts.start_port, ts.start_port)
self.assertEqual(api_ts.end_port, ts.end_port)
self.assertEqual(api_ts.protocol_id, ts.IP_protocol_ID)
@@ -872,6 +918,7 @@ class Ikev2Params(object):
is_natt = 'natt' in params and params['natt'] or False
self.p = Profile(self, 'pr1')
+ self.ip6 = False if 'ip6' not in params else params['ip6']
if 'auth' in params and params['auth'] == 'rsa-sig':
auth_method = 'rsa-sig'
@@ -897,8 +944,12 @@ class Ikev2Params(object):
self.p.add_local_id(id_type='fqdn', data=b'vpp.home')
self.p.add_remote_id(id_type='fqdn', data=b'roadwarrior.example.com')
- self.p.add_local_ts(start_addr='10.10.10.0', end_addr='10.10.10.255')
- self.p.add_remote_ts(start_addr='10.0.0.0', end_addr='10.0.0.255')
+ loc_ts = {'start_addr': '10.10.10.0', 'end_addr': '10.10.10.255'} if\
+ 'loc_ts' not in params else params['loc_ts']
+ rem_ts = {'start_addr': '10.0.0.0', 'end_addr': '10.0.0.255'} if\
+ 'rem_ts' not in params else params['rem_ts']
+ self.p.add_local_ts(**loc_ts)
+ self.p.add_remote_ts(**rem_ts)
self.sa = IKEv2SA(self, i_id=self.p.remote_id['data'],
r_id=self.p.local_id['data'],
@@ -964,14 +1015,14 @@ class TestApi(VppTestCase):
def test_profile_api(self):
""" test profile dump API """
- loc_ts = {
+ loc_ts4 = {
'proto': 8,
'start_port': 1,
'end_port': 19,
'start_addr': '3.3.3.2',
'end_addr': '3.3.3.3',
}
- rem_ts = {
+ rem_ts4 = {
'proto': 9,
'start_port': 10,
'end_port': 119,
@@ -979,14 +1030,29 @@ class TestApi(VppTestCase):
'end_addr': '2.3.4.6',
}
+ loc_ts6 = {
+ 'proto': 8,
+ 'start_port': 1,
+ 'end_port': 19,
+ 'start_addr': 'ab::1',
+ 'end_addr': 'ab::4',
+ }
+ rem_ts6 = {
+ 'proto': 9,
+ 'start_port': 10,
+ 'end_port': 119,
+ 'start_addr': 'cd::12',
+ 'end_addr': 'cd::13',
+ }
+
conf = {
'p1': {
'name': 'p1',
'loc_id': ('fqdn', b'vpp.home'),
'rem_id': ('fqdn', b'roadwarrior.example.com'),
- 'loc_ts': loc_ts,
- 'rem_ts': rem_ts,
- 'responder': {'sw_if_index': 0, 'ip4': '5.6.7.8'},
+ 'loc_ts': loc_ts4,
+ 'rem_ts': rem_ts4,
+ 'responder': {'sw_if_index': 0, 'addr': '5.6.7.8'},
'ike_ts': {
'crypto_alg': 20,
'crypto_key_size': 32,
@@ -1008,10 +1074,10 @@ class TestApi(VppTestCase):
'p2': {
'name': 'p2',
'loc_id': ('ip4-addr', b'192.168.2.1'),
- 'rem_id': ('ip4-addr', b'192.168.2.2'),
- 'loc_ts': loc_ts,
- 'rem_ts': rem_ts,
- 'responder': {'sw_if_index': 4, 'ip4': '5.6.7.99'},
+ 'rem_id': ('ip6-addr', b'abcd::1'),
+ 'loc_ts': loc_ts6,
+ 'rem_ts': rem_ts6,
+ 'responder': {'sw_if_index': 4, 'addr': 'def::10'},
'ike_ts': {
'crypto_alg': 12,
'crypto_key_size': 16,
@@ -1042,12 +1108,14 @@ class TestApi(VppTestCase):
self.assertEqual(api_ts.protocol_id, cfg_ts['proto'])
self.assertEqual(api_ts.start_port, cfg_ts['start_port'])
self.assertEqual(api_ts.end_port, cfg_ts['end_port'])
- self.assertEqual(api_ts.start_addr, IPv4Address(cfg_ts['start_addr']))
- self.assertEqual(api_ts.end_addr, IPv4Address(cfg_ts['end_addr']))
+ self.assertEqual(api_ts.start_addr,
+ ip_address(text_type(cfg_ts['start_addr'])))
+ self.assertEqual(api_ts.end_addr,
+ ip_address(text_type(cfg_ts['end_addr'])))
def verify_responder(self, api_r, cfg_r):
self.assertEqual(api_r.sw_if_index, cfg_r['sw_if_index'])
- self.assertEqual(api_r.ip4, IPv4Address(cfg_r['ip4']))
+ self.assertEqual(api_r.addr, ip_address(cfg_r['addr']))
def verify_transforms(self, api_ts, cfg_ts):
self.assertEqual(api_ts.crypto_alg, cfg_ts['crypto_alg'])
@@ -1150,9 +1218,15 @@ class Test_IKE_AES_GCM_16_256(TemplateResponder, Ikev2Params):
"""
def config_tc(self):
self.config_params({
+ 'ip6': True,
+ 'natt': True,
'ike-crypto': ('AES-GCM-16ICV', 32),
'ike-integ': 'NULL',
- 'ike-dh': '2048MODPgr'})
+ 'ike-dh': '2048MODPgr',
+ 'loc_ts': {'start_addr': 'ab:cd::0',
+ 'end_addr': 'ab:cd::10'},
+ 'rem_ts': {'start_addr': '11::0',
+ 'end_addr': '11::100'}})
class TestMalformedMessages(TemplateResponder, Ikev2Params):
@@ -1164,8 +1238,8 @@ class TestMalformedMessages(TemplateResponder, Ikev2Params):
def config_tc(self):
self.config_params()
- def assert_counter(self, count, name):
- node_name = '/err/ikev2/' + name
+ def assert_counter(self, count, name, version='ip4'):
+ node_name = '/err/ikev2-%s/' % version + name
self.assertEqual(count, self.statistics.get_err_counter(node_name))
def create_ike_init_msg(self, length=None, payload=None):
diff --git a/src/plugins/ikev2/test/vpp_ikev2.py b/src/plugins/ikev2/test/vpp_ikev2.py
index b3339d0ea86..6ae30201450 100644
--- a/src/plugins/ikev2/test/vpp_ikev2.py
+++ b/src/plugins/ikev2/test/vpp_ikev2.py
@@ -1,3 +1,4 @@
+from ipaddress import IPv4Address, AddressValueError
from vpp_object import VppObject
from vpp_papi import VppEnum
@@ -12,7 +13,8 @@ class AuthMethod:
class IDType:
v = {'ip4-addr': 1,
- 'fqdn': 2}
+ 'fqdn': 2,
+ 'ip6-addr': 5}
@staticmethod
def value(key): return IDType.v[key]
@@ -52,7 +54,8 @@ class Profile(VppObject):
'is_local': False}
def add_local_ts(self, start_addr, end_addr, start_port=0, end_port=0xffff,
- proto=0):
+ proto=0, is_ip4=True):
+ self.ts_is_ip4 = is_ip4
self.local_ts = {'is_local': True,
'protocol_id': proto,
'start_port': start_port,
@@ -62,6 +65,12 @@ class Profile(VppObject):
def add_remote_ts(self, start_addr, end_addr, start_port=0,
end_port=0xffff, proto=0):
+ try:
+ IPv4Address(start_addr)
+ is_ip4 = True
+ except AddressValueError:
+ is_ip4 = False
+ self.ts_is_ip4 = is_ip4
self.remote_ts = {'is_local': False,
'protocol_id': proto,
'start_port': start_port,