ipsec: Dedicated IPSec interface type
Type: feature Signed-off-by: Neale Ranns <nranns@cisco.com> Change-Id: Ie8bd50df163aea2798e9f9d35a13dcadc4a4a4b2
This commit is contained in:
@@ -581,6 +581,7 @@ list(APPEND VNET_SOURCES
|
||||
ipsec/ipsec_format.c
|
||||
ipsec/ipsec_handoff.c
|
||||
ipsec/ipsec_input.c
|
||||
ipsec/ipsec_itf.c
|
||||
ipsec/ipsec_punt.c
|
||||
ipsec/ipsec_sa.c
|
||||
ipsec/ipsec_spd.c
|
||||
|
||||
@@ -20,6 +20,7 @@ import "vnet/ipsec/ipsec_types.api";
|
||||
import "vnet/interface_types.api";
|
||||
import "vnet/ip/ip_types.api";
|
||||
import "vnet/interface_types.api";
|
||||
import "vnet/tunnel/tunnel_types.api";
|
||||
|
||||
/** \brief IPsec: Add/delete Security Policy Database
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@@ -379,12 +380,60 @@ define ipsec_tunnel_if_add_del_reply {
|
||||
vl_api_interface_index_t sw_if_index;
|
||||
};
|
||||
|
||||
typedef ipsec_itf
|
||||
{
|
||||
u32 user_instance [default=0xffffffff];
|
||||
vl_api_tunnel_mode_t mode;
|
||||
vl_api_interface_index_t sw_if_index;
|
||||
};
|
||||
|
||||
/** \brief Create an IPSec interface
|
||||
*/
|
||||
define ipsec_itf_create {
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
vl_api_ipsec_itf_t itf;
|
||||
};
|
||||
|
||||
/** \brief Add IPsec interface interface response
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param retval - return status
|
||||
@param sw_if_index - sw_if_index of new interface (for successful add)
|
||||
*/
|
||||
define ipsec_itf_create_reply
|
||||
{
|
||||
u32 context;
|
||||
i32 retval;
|
||||
vl_api_interface_index_t sw_if_index;
|
||||
};
|
||||
|
||||
autoreply define ipsec_itf_delete
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
vl_api_interface_index_t sw_if_index;
|
||||
};
|
||||
|
||||
define ipsec_itf_dump
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
vl_api_interface_index_t sw_if_index;
|
||||
};
|
||||
|
||||
define ipsec_itf_details
|
||||
{
|
||||
u32 context;
|
||||
vl_api_ipsec_itf_t itf;
|
||||
};
|
||||
|
||||
/** \brief Dump IPsec security association
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param sa_id - optional ID of an SA to dump, if ~0 dump all SAs in SAD
|
||||
*/
|
||||
define ipsec_sa_dump {
|
||||
define ipsec_sa_dump
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
u32 sa_id;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <vnet/ip/ip.h>
|
||||
#include <vnet/ip/ip_types_api.h>
|
||||
#include <vnet/ipsec/ipsec_types_api.h>
|
||||
#include <vnet/tunnel/tunnel_types_api.h>
|
||||
#include <vnet/fib/fib.h>
|
||||
#include <vnet/ipip/ipip.h>
|
||||
|
||||
@@ -33,6 +34,7 @@
|
||||
#if WITH_LIBSSL > 0
|
||||
#include <vnet/ipsec/ipsec.h>
|
||||
#include <vnet/ipsec/ipsec_tun.h>
|
||||
#include <vnet/ipsec/ipsec_itf.h>
|
||||
#endif /* IPSEC */
|
||||
|
||||
#define vl_typedefs /* define message structures */
|
||||
@@ -60,6 +62,9 @@ _(IPSEC_SA_DUMP, ipsec_sa_dump) \
|
||||
_(IPSEC_SPDS_DUMP, ipsec_spds_dump) \
|
||||
_(IPSEC_SPD_DUMP, ipsec_spd_dump) \
|
||||
_(IPSEC_SPD_INTERFACE_DUMP, ipsec_spd_interface_dump) \
|
||||
_(IPSEC_ITF_CREATE, ipsec_itf_create) \
|
||||
_(IPSEC_ITF_DELETE, ipsec_itf_delete) \
|
||||
_(IPSEC_ITF_DUMP, ipsec_itf_dump) \
|
||||
_(IPSEC_TUNNEL_IF_ADD_DEL, ipsec_tunnel_if_add_del) \
|
||||
_(IPSEC_TUNNEL_IF_SET_SA, ipsec_tunnel_if_set_sa) \
|
||||
_(IPSEC_SELECT_BACKEND, ipsec_select_backend) \
|
||||
@@ -736,6 +741,43 @@ done:
|
||||
/* *INDENT-ON* */
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_ipsec_itf_create_t_handler (vl_api_ipsec_itf_create_t * mp)
|
||||
{
|
||||
vl_api_ipsec_itf_create_reply_t *rmp;
|
||||
tunnel_mode_t mode;
|
||||
u32 sw_if_index = ~0;
|
||||
int rv;
|
||||
|
||||
rv = tunnel_mode_decode (mp->itf.mode, &mode);
|
||||
|
||||
if (!rv)
|
||||
rv = ipsec_itf_create (ntohl (mp->itf.user_instance), mode, &sw_if_index);
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
REPLY_MACRO2 (VL_API_IPSEC_ITF_CREATE_REPLY,
|
||||
({
|
||||
rmp->sw_if_index = htonl (sw_if_index);
|
||||
}));
|
||||
/* *INDENT-ON* */
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_ipsec_itf_delete_t_handler (vl_api_ipsec_itf_delete_t * mp)
|
||||
{
|
||||
vl_api_ipsec_itf_delete_reply_t *rmp;
|
||||
int rv;
|
||||
|
||||
rv = ipsec_itf_delete (ntohl (mp->sw_if_index));
|
||||
|
||||
REPLY_MACRO (VL_API_IPSEC_ITF_DELETE_REPLY);
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_ipsec_itf_dump_t_handler (vl_api_ipsec_itf_dump_t * mp)
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct ipsec_sa_dump_match_ctx_t_
|
||||
{
|
||||
index_t sai;
|
||||
|
||||
@@ -353,6 +353,21 @@ format_ipsec_tun_protect_index (u8 * s, va_list * args)
|
||||
return (format (s, "%U", format_ipsec_tun_protect, itp));
|
||||
}
|
||||
|
||||
u8 *
|
||||
format_ipsec_tun_protect_flags (u8 * s, va_list * args)
|
||||
{
|
||||
ipsec_protect_flags_t flags = va_arg (*args, int);
|
||||
|
||||
if (IPSEC_PROTECT_NONE == flags)
|
||||
s = format (s, "none");
|
||||
#define _(a,b,c) \
|
||||
else if (flags & IPSEC_PROTECT_##a) \
|
||||
s = format (s, "%s", c); \
|
||||
foreach_ipsec_protect_flags
|
||||
#undef _
|
||||
|
||||
return (s);
|
||||
}
|
||||
|
||||
u8 *
|
||||
format_ipsec_tun_protect (u8 * s, va_list * args)
|
||||
@@ -360,8 +375,9 @@ format_ipsec_tun_protect (u8 * s, va_list * args)
|
||||
ipsec_tun_protect_t *itp = va_arg (*args, ipsec_tun_protect_t *);
|
||||
u32 sai;
|
||||
|
||||
s = format (s, "%U", format_vnet_sw_if_index_name,
|
||||
vnet_get_main (), itp->itp_sw_if_index);
|
||||
s = format (s, "%U flags:[%U]", format_vnet_sw_if_index_name,
|
||||
vnet_get_main (), itp->itp_sw_if_index,
|
||||
format_ipsec_tun_protect_flags, itp->itp_flags);
|
||||
if (!ip_address_is_zero (itp->itp_key))
|
||||
s = format (s, ": %U", format_ip_address, itp->itp_key);
|
||||
s = format (s, "\n output-sa:");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* ipsec_itf.c: IPSec dedicated interface type
|
||||
*
|
||||
* Copyright (c) 2020 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __IPSEC_ITF_H__
|
||||
#define __IPSEC_ITF_H__
|
||||
|
||||
#include <vnet/tunnel/tunnel.h>
|
||||
#include <vnet/ipsec/ipsec_sa.h>
|
||||
|
||||
/**
|
||||
* @brief A dedicated IPSec interface type
|
||||
*
|
||||
* In order to support route based VPNs one needs 3 elements: an interface,
|
||||
* for routing to resolve routes through, an SA from the peer to describe
|
||||
* security, and encap, to describe how to reach the peer. There are two
|
||||
* ways one could model this:
|
||||
*
|
||||
* interface + encap + SA = (interface + encap) + SA =
|
||||
* ipip-interface + SA transport mode
|
||||
*
|
||||
* or
|
||||
*
|
||||
* interface + encap + SA = interface + (encap + SA) =
|
||||
* IPSec-interface + SA tunnel mode
|
||||
*
|
||||
* It's a question of where you add the parenthesis, from the perspective
|
||||
* of the external user the effect is identical.
|
||||
*
|
||||
* The IPsec interface serves as the encap-free interface to be used
|
||||
* in conjunction with an encap-describing tunnel mode SA.
|
||||
*
|
||||
* VPP supports both models, which modelshould you pick?
|
||||
* A route based VPN could impose 0, 1 or 2 encaps. the support matrix for
|
||||
* these use cases is:
|
||||
*
|
||||
* | 0 | 1 | 2 |
|
||||
* --------------------------
|
||||
* ipip | N | Y | Y |
|
||||
* ipsec | P | Y | P |
|
||||
*
|
||||
* Where P = potentially.
|
||||
* ipsec could potnetially support 0 encap (i.e. transport mode) since neither
|
||||
* the interface nor the SA *requires* encap. However, for a route beased VPN
|
||||
* to use transport mode is probably wrong since one shouldn't use thransport
|
||||
* mode for transit traffic, since without encap it is not guaranteed to return.
|
||||
* ipsec could potnetially support 2 encaps, but that would require the SA to
|
||||
* describe both, something it does not do at this time.
|
||||
*
|
||||
* ipsec currently does not support:
|
||||
* - multipoint interfaces
|
||||
* but this is only because it is not yet implemented, rather than it cannot
|
||||
* be done.
|
||||
*
|
||||
* Internally the difference is that the midchain adjacency for the IPSec
|
||||
* interface has no associated encap (whereas for an ipip tunnel it describes
|
||||
* the peer). Consequently, features on the output arc see packets without
|
||||
* any encap. Since the protecting SAs are in tunnel mode,
|
||||
* they apply the encap. The midchain adj is stacked only once the proctecting
|
||||
* SA is known, since only then is the peer known. Otherwise the VLIB graph
|
||||
* nodes used are the same:
|
||||
* (routing) --> ipX-michain --> espX-encrypt --> adj-midchain-tx --> (routing)
|
||||
* where X = 4 or 6.
|
||||
*
|
||||
* Some benefits to the ipsec interface:
|
||||
* - it is slightly more efficient since the encapsulating IP header has
|
||||
* its checksum updated only once.
|
||||
* - even when the interface is admin up traffic cannot be sent to a peer
|
||||
* unless the SA is available (since it's the SA that determines the
|
||||
* encap). With ipip interfaces a client must use the admin state to
|
||||
* prevent sending until the SA is available.
|
||||
*
|
||||
* The best recommendations i can make are:
|
||||
* - pick a model that supports your use case
|
||||
* - make sure any other features you wish to use are supported by the model
|
||||
* - choose the model that best fits your control plane's model.
|
||||
*
|
||||
*
|
||||
* gun reloaded, fire away.
|
||||
*/
|
||||
typedef struct ipsec_itf_t_
|
||||
{
|
||||
tunnel_mode_t ii_mode;
|
||||
int ii_user_instance;
|
||||
u32 ii_sw_if_index;
|
||||
} __clib_packed ipsec_itf_t;
|
||||
|
||||
|
||||
extern int ipsec_itf_create (u32 user_instance,
|
||||
tunnel_mode_t mode, u32 * sw_if_indexp);
|
||||
extern int ipsec_itf_delete (u32 sw_if_index);
|
||||
|
||||
extern void ipsec_itf_adj_stack (adj_index_t ai, u32 sai);
|
||||
extern void ipsec_itf_adj_unstack (adj_index_t ai);
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
||||
|
||||
#endif
|
||||
+47
-14
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include <vnet/ipsec/ipsec_tun.h>
|
||||
#include <vnet/ipsec/ipsec_itf.h>
|
||||
#include <vnet/ipsec/esp.h>
|
||||
#include <vnet/udp/udp.h>
|
||||
#include <vnet/adj/adj_delegate.h>
|
||||
@@ -126,14 +127,20 @@ ipsec_tun_protect_from_const_base (const adj_delegate_t * ad)
|
||||
}
|
||||
|
||||
static u32
|
||||
ipsec_tun_protect_get_adj_next (const ipsec_tun_protect_t * itp)
|
||||
ipsec_tun_protect_get_adj_next (vnet_link_t linkt,
|
||||
const ipsec_tun_protect_t * itp)
|
||||
{
|
||||
ipsec_main_t *im;
|
||||
ipsec_sa_t *sa;
|
||||
bool is_ip4;
|
||||
u32 next;
|
||||
|
||||
is_ip4 = ip46_address_is_ip4 (&itp->itp_tun.src);
|
||||
|
||||
if (itp->itp_flags & IPSEC_PROTECT_ITF)
|
||||
is_ip4 = linkt == VNET_LINK_IP4;
|
||||
else
|
||||
is_ip4 = ip46_address_is_ip4 (&itp->itp_tun.src);
|
||||
|
||||
sa = ipsec_sa_get (itp->itp_out_sa);
|
||||
im = &ipsec_main;
|
||||
|
||||
@@ -169,7 +176,7 @@ ipsec_tun_protect_add_adj (adj_index_t ai, const ipsec_tun_protect_t * itp)
|
||||
{
|
||||
ipsec_tun_protect_sa_by_adj_index[ai] = itp->itp_out_sa;
|
||||
adj_nbr_midchain_update_next_node
|
||||
(ai, ipsec_tun_protect_get_adj_next (itp));
|
||||
(ai, ipsec_tun_protect_get_adj_next (adj_get_link_type (ai), itp));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,6 +256,9 @@ ipsec_tun_protect_adj_add (adj_index_t ai, void *arg)
|
||||
itp - ipsec_tun_protect_pool);
|
||||
ipsec_tun_protect_add_adj (ai, itp);
|
||||
|
||||
if (itp->itp_flags & IPSEC_PROTECT_ITF)
|
||||
ipsec_itf_adj_stack (ai, itp->itp_out_sa);
|
||||
|
||||
return (ADJ_WALK_RC_CONTINUE);
|
||||
}
|
||||
|
||||
@@ -349,9 +359,14 @@ ipsec_tun_protect_rx_db_remove (ipsec_main_t * im,
|
||||
static adj_walk_rc_t
|
||||
ipsec_tun_protect_adj_remove (adj_index_t ai, void *arg)
|
||||
{
|
||||
ipsec_tun_protect_t *itp = arg;
|
||||
|
||||
adj_delegate_remove (ai, ipsec_tun_adj_delegate_type);
|
||||
ipsec_tun_protect_add_adj (ai, NULL);
|
||||
|
||||
if (itp->itp_flags & IPSEC_PROTECT_ITF)
|
||||
ipsec_itf_adj_unstack (ai);
|
||||
|
||||
return (ADJ_WALK_RC_CONTINUE);
|
||||
}
|
||||
|
||||
@@ -404,8 +419,11 @@ ipsec_tun_protect_set_crypto_addr (ipsec_tun_protect_t * itp)
|
||||
{
|
||||
itp->itp_crypto.src = sa->tunnel_dst_addr;
|
||||
itp->itp_crypto.dst = sa->tunnel_src_addr;
|
||||
ipsec_sa_set_IS_PROTECT (sa);
|
||||
itp->itp_flags |= IPSEC_PROTECT_ENCAPED;
|
||||
if (!(itp->itp_flags & IPSEC_PROTECT_ITF))
|
||||
{
|
||||
ipsec_sa_set_IS_PROTECT (sa);
|
||||
itp->itp_flags |= IPSEC_PROTECT_ENCAPED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -657,6 +675,7 @@ ipsec_tun_protect_update (u32 sw_if_index,
|
||||
pool_get_zero (ipsec_tun_protect_pool, itp);
|
||||
|
||||
itp->itp_sw_if_index = sw_if_index;
|
||||
itp->itp_ai = ADJ_INDEX_INVALID;
|
||||
|
||||
itp->itp_n_sa_in = vec_len (sas_in);
|
||||
for (ii = 0; ii < itp->itp_n_sa_in; ii++)
|
||||
@@ -673,7 +692,24 @@ ipsec_tun_protect_update (u32 sw_if_index,
|
||||
if (rv)
|
||||
goto out;
|
||||
|
||||
if (ip46_address_is_zero (&itp->itp_tun.dst))
|
||||
if (ip46_address_is_zero (&itp->itp_tun.src))
|
||||
{
|
||||
/* must be one of thos pesky ipsec interfaces that has no encap.
|
||||
* the encap then MUST comefrom the tunnel mode SA.
|
||||
*/
|
||||
ipsec_sa_t *sa;
|
||||
|
||||
sa = ipsec_sa_get (itp->itp_out_sa);
|
||||
|
||||
if (!ipsec_sa_is_set_IS_TUNNEL (sa))
|
||||
{
|
||||
rv = VNET_API_ERROR_INVALID_DST_ADDRESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
itp->itp_flags |= IPSEC_PROTECT_ITF;
|
||||
}
|
||||
else if (ip46_address_is_zero (&itp->itp_tun.dst))
|
||||
{
|
||||
/* tunnel has no destination address, presumably because it's p2mp
|
||||
in which case we use the nh that this is protection for */
|
||||
@@ -690,7 +726,7 @@ ipsec_tun_protect_update (u32 sw_if_index,
|
||||
|
||||
/*
|
||||
* add to the tunnel DB for ingress
|
||||
* - if the SA is in trasnport mode, then the packates will arrivw
|
||||
* - if the SA is in trasnport mode, then the packates will arrive
|
||||
* with the IP src,dst of the protected tunnel, in which case we can
|
||||
* simply strip the IP header and hand the payload to the protocol
|
||||
* appropriate input handler
|
||||
@@ -752,6 +788,9 @@ ipsec_tun_protect_del (u32 sw_if_index, const ip_address_t * nh)
|
||||
itp = ipsec_tun_protect_get (itpi);
|
||||
ipsec_tun_protect_unconfig (im, itp);
|
||||
|
||||
if (ADJ_INDEX_INVALID != itp->itp_ai)
|
||||
adj_unlock (itp->itp_ai);
|
||||
|
||||
clib_mem_free (itp->itp_key);
|
||||
pool_put (ipsec_tun_protect_pool, itp);
|
||||
|
||||
@@ -828,13 +867,7 @@ ipsec_tun_protect_adj_delegate_adj_created (adj_index_t ai)
|
||||
itpi = ipsec_tun_protect_find (adj->rewrite_header.sw_if_index, &ip);
|
||||
|
||||
if (INDEX_INVALID != itpi)
|
||||
{
|
||||
const ipsec_tun_protect_t *itp;
|
||||
|
||||
itp = ipsec_tun_protect_get (itpi);
|
||||
adj_delegate_add (adj_get (ai), ipsec_tun_adj_delegate_type, itpi);
|
||||
ipsec_tun_protect_add_adj (ai, itp);
|
||||
}
|
||||
ipsec_tun_protect_adj_add (ai, ipsec_tun_protect_get (itpi));
|
||||
}
|
||||
|
||||
static u8 *
|
||||
|
||||
@@ -47,12 +47,21 @@ typedef CLIB_PACKED(struct {
|
||||
extern u8 *format_ipsec4_tunnel_key (u8 * s, va_list * args);
|
||||
extern u8 *format_ipsec6_tunnel_key (u8 * s, va_list * args);
|
||||
|
||||
#define foreach_ipsec_protect_flags \
|
||||
_(L2, 1, "l2") \
|
||||
_(ENCAPED, 2, "encapped") \
|
||||
_(ITF, 4, "itf") \
|
||||
|
||||
typedef enum ipsec_protect_flags_t_
|
||||
{
|
||||
IPSEC_PROTECT_L2 = (1 << 0),
|
||||
IPSEC_PROTECT_ENCAPED = (1 << 1),
|
||||
IPSEC_PROTECT_NONE = 0,
|
||||
#define _(a,b,c) IPSEC_PROTECT_##a = b,
|
||||
foreach_ipsec_protect_flags
|
||||
#undef _
|
||||
} __clib_packed ipsec_protect_flags_t;
|
||||
|
||||
extern u8 *format_ipsec_tun_protect_flags (u8 * s, va_list * args);
|
||||
|
||||
typedef struct ipsec_ep_t_
|
||||
{
|
||||
ip46_address_t src;
|
||||
@@ -76,6 +85,7 @@ typedef struct ipsec_tun_protect_t_
|
||||
ipsec_ep_t itp_crypto;
|
||||
|
||||
ipsec_protect_flags_t itp_flags;
|
||||
adj_index_t itp_ai;
|
||||
|
||||
ipsec_ep_t itp_tun;
|
||||
|
||||
|
||||
@@ -914,6 +914,7 @@ class IpsecTun4(object):
|
||||
|
||||
def verify_tun_64(self, p, count=1):
|
||||
self.vapi.cli("clear errors")
|
||||
self.vapi.cli("clear ipsec sa")
|
||||
try:
|
||||
send_pkts = self.gen_encrypt_pkts6(p, p.scapy_tun_sa, self.tun_if,
|
||||
src=p.remote_tun_if_host6,
|
||||
@@ -1104,6 +1105,7 @@ class IpsecTun6(object):
|
||||
def verify_tun_46(self, p, count=1):
|
||||
""" ipsec 4o6 tunnel basic test """
|
||||
self.vapi.cli("clear errors")
|
||||
self.vapi.cli("clear ipsec sa")
|
||||
try:
|
||||
send_pkts = self.gen_encrypt_pkts(p, p.scapy_tun_sa, self.tun_if,
|
||||
src=p.remote_tun_if_host4,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
from vpp_object import VppObject
|
||||
from ipaddress import ip_address
|
||||
from vpp_papi import VppEnum
|
||||
from vpp_interface import VppInterface
|
||||
|
||||
try:
|
||||
text_type = unicode
|
||||
@@ -368,3 +369,41 @@ class VppIpsecTunProtect(VppObject):
|
||||
self.nh == str(b.tun.nh):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class VppIpsecInterface(VppInterface):
|
||||
"""
|
||||
VPP IPSec interface
|
||||
"""
|
||||
|
||||
def __init__(self, test, mode=None):
|
||||
super(VppIpsecInterface, self).__init__(test)
|
||||
|
||||
# only p2p mode is supported currently
|
||||
self.mode = (VppEnum.vl_api_tunnel_mode_t.
|
||||
TUNNEL_API_MODE_P2P)
|
||||
|
||||
def add_vpp_config(self):
|
||||
r = self.test.vapi.ipsec_itf_create(itf={
|
||||
'user_instance': 0xffffffff,
|
||||
'mode': self.mode,
|
||||
})
|
||||
self.set_sw_if_index(r.sw_if_index)
|
||||
self.test.registry.register(self, self.test.logger)
|
||||
return self
|
||||
|
||||
def remove_vpp_config(self):
|
||||
self.test.vapi.ipsec_itf_delete(sw_if_index=self._sw_if_index)
|
||||
|
||||
def query_vpp_config(self):
|
||||
ts = self.test.vapi.ipsec_itf_dump(sw_if_index=0xffffffff)
|
||||
for t in ts:
|
||||
if t.tunnel.sw_if_index == self._sw_if_index:
|
||||
return True
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
return self.object_id()
|
||||
|
||||
def object_id(self):
|
||||
return "ipsec-%d" % self._sw_if_index
|
||||
|
||||
Reference in New Issue
Block a user