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";
};
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 ") \
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;
vec_free (p->transforms);
}
vec_free (*v);
-};
+}
static void
ikev2_sa_free_child_sa (ikev2_child_sa_t * c)
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;
}
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;
}
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);
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)))
{
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)))
{
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);
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)))
{
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)))
{
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);
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);
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);
{
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;
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)
{
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;
}
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);
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;
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;
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);
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);
}
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;
"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 */
"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;
}
}
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;
}
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;
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])
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)
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;
}
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 =
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
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);
{
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);
}
}
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)
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);
}
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
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)
{
{
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);
}
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
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;
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);
}
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
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;
{
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);
}
/* 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)
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 ||
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,
.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* */
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;
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);
}
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 */
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)
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);
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;
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;
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;
}
p->responder.sw_if_index = sw_if_index;
- p->responder.ip4 = ip4;
+ ip_address_copy (&p->responder.addr, &addr);
return 0;
}
{
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);
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;
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)
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);
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,
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;
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;
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;
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* */
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;
#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);
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,
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
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
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);
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),
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;
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;
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;
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;
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;
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;
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",
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,
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,
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)
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");
/* *INDENT-ON* */
/* *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* */
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,
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);
{
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;
}
} \
} 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)) \
} \
} 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; \
} \
} 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) \
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
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;
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);
{
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);
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);
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");
{
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);
{
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;
}
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_";
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))
;
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))
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"))
}
}
+ 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");
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);
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_";
{
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
{
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);
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
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
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;
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
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:
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)]
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):
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()
i.admin_up()
i.config_ip4()
i.resolve_arp()
+ i.config_ip6()
+ i.resolve_ndp()
@classmethod
def tearDownClass(cls):
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()
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
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()
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',
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()
# 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):
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')
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(
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)
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'
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'],
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,
'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,
'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,
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'])
"""
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):
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):
+from ipaddress import IPv4Address, AddressValueError
from vpp_object import VppObject
from vpp_papi import VppEnum
class IDType:
v = {'ip4-addr': 1,
- 'fqdn': 2}
+ 'fqdn': 2,
+ 'ip6-addr': 5}
@staticmethod
def value(key): return IDType.v[key]
'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,
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,