BFD: command line interface
Implement command line interface to the BFD binary APIs. Add corresponding unit tests. Change-Id: Ia0542d0bc4c8d78e6f7b777a08fd94ebfe4d524f Signed-off-by: Klement Sekera <ksekera@cisco.com>
This commit is contained in:

committed by
Damjan Marion

parent
c3a814be9d
commit
7388448712
@ -369,6 +369,7 @@ libvnet_la_SOURCES += \
|
||||
vnet/bfd/bfd_udp.c \
|
||||
vnet/bfd/bfd_main.c \
|
||||
vnet/bfd/bfd_protocol.c \
|
||||
vnet/bfd/bfd_cli.c \
|
||||
vnet/bfd/bfd_api.c
|
||||
|
||||
API_FILES += vnet/bfd/bfd.api
|
||||
|
@ -51,7 +51,6 @@ _(ADDRESS_LENGTH_MISMATCH, -59, "Address length mismatch") \
|
||||
_(ADDRESS_NOT_FOUND_FOR_INTERFACE, -60, "Address not found for interface") \
|
||||
_(ADDRESS_NOT_LINK_LOCAL, -61, "Address not link-local") \
|
||||
_(IP6_NOT_ENABLED, -62, "ip6 not enabled") \
|
||||
_(ADDRESS_MATCHES_INTERFACE_ADDRESS, -63, "Address matches interface address") \
|
||||
_(IN_PROGRESS, 10, "Operation in progress") \
|
||||
_(NO_SUCH_NODE, -63, "No such graph node") \
|
||||
_(NO_SUCH_NODE2, -64, "No such graph node #2") \
|
||||
|
@ -45,7 +45,7 @@ define bfd_udp_del_echo_source
|
||||
u32 context;
|
||||
};
|
||||
|
||||
/** \brief Delete BFD feature response
|
||||
/** \brief Delete BFD echo source response
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param retval - return code for the request
|
||||
*/
|
||||
@ -55,32 +55,6 @@ define bfd_udp_del_echo_source_reply
|
||||
i32 retval;
|
||||
};
|
||||
|
||||
/** \brief Get BFD configuration
|
||||
*/
|
||||
define bfd_get_config
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
};
|
||||
|
||||
/** \brief Get BFD configuration response
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param retval - return code for the request
|
||||
@param slow_timer - slow timer (seconds)
|
||||
@param min_tx - desired min tx interval
|
||||
@param min_rx - desired min rx interval
|
||||
@param detect_mult - desired detection multiplier
|
||||
*/
|
||||
define bfd_get_config_reply
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
u32 slow_timer;
|
||||
u32 min_tx;
|
||||
u32 min_rx;
|
||||
u8 detect_mult;
|
||||
};
|
||||
|
||||
/** \brief Add UDP BFD session on interface
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
|
@ -154,6 +154,21 @@ send_bfd_udp_session_details (unix_shared_memory_queue_t * q, u32 context,
|
||||
bfd_udp_key_t *key = &bus->key;
|
||||
mp->sw_if_index = clib_host_to_net_u32 (key->sw_if_index);
|
||||
mp->is_ipv6 = !(ip46_address_is_ip4 (&key->local_addr));
|
||||
if ((!bs->auth.is_delayed && bs->auth.curr_key) ||
|
||||
(bs->auth.is_delayed && bs->auth.next_key))
|
||||
{
|
||||
mp->is_authenticated = 1;
|
||||
}
|
||||
if (bs->auth.is_delayed && bs->auth.next_key)
|
||||
{
|
||||
mp->bfd_key_id = bs->auth.next_bfd_key_id;
|
||||
mp->conf_key_id = clib_host_to_net_u32 (bs->auth.next_key->conf_key_id);
|
||||
}
|
||||
else if (!bs->auth.is_delayed && bs->auth.curr_key)
|
||||
{
|
||||
mp->bfd_key_id = bs->auth.curr_bfd_key_id;
|
||||
mp->conf_key_id = clib_host_to_net_u32 (bs->auth.curr_key->conf_key_id);
|
||||
}
|
||||
if (mp->is_ipv6)
|
||||
{
|
||||
clib_memcpy (mp->local_addr, &key->local_addr,
|
||||
@ -289,10 +304,9 @@ vl_api_bfd_udp_auth_activate_t_handler (vl_api_bfd_udp_auth_activate_t * mp)
|
||||
|
||||
BFD_UDP_API_PARAM_COMMON_CODE;
|
||||
|
||||
rv =
|
||||
bfd_udp_auth_activate (BFD_UDP_API_PARAM_FROM_MP (mp),
|
||||
clib_net_to_host_u32 (mp->conf_key_id),
|
||||
mp->bfd_key_id, mp->is_delayed);
|
||||
rv = bfd_udp_auth_activate (BFD_UDP_API_PARAM_FROM_MP (mp),
|
||||
clib_net_to_host_u32 (mp->conf_key_id),
|
||||
mp->bfd_key_id, mp->is_delayed);
|
||||
|
||||
BAD_SW_IF_INDEX_LABEL;
|
||||
REPLY_MACRO (VL_API_BFD_UDP_AUTH_ACTIVATE_REPLY);
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <vnet/api_errno.h>
|
||||
#include <vnet/vnet.h>
|
||||
#include <vnet/ip/ip6_packet.h>
|
||||
#include <vnet/bfd/bfd_udp.h>
|
||||
|
||||
#define foreach_bfd_transport(F) \
|
||||
F (UDP4, "ip4-rewrite") \
|
||||
|
900
src/vnet/bfd/bfd_cli.c
Normal file
900
src/vnet/bfd/bfd_cli.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -55,7 +55,7 @@ bfd_usec_to_clocks (const bfd_main_t * bm, u64 us)
|
||||
return bm->cpu_cps * ((f64) us / USEC_PER_SECOND);
|
||||
}
|
||||
|
||||
static u32
|
||||
u32
|
||||
bfd_clocks_to_usec (const bfd_main_t * bm, u64 clocks)
|
||||
{
|
||||
return (clocks / bm->cpu_cps) * USEC_PER_SECOND;
|
||||
@ -70,7 +70,7 @@ static u32 bfd_node_index_by_transport[] = {
|
||||
#undef F
|
||||
};
|
||||
|
||||
static u8 *
|
||||
u8 *
|
||||
format_bfd_auth_key (u8 * s, va_list * args)
|
||||
{
|
||||
const bfd_auth_key_t *key = va_arg (*args, bfd_auth_key_t *);
|
||||
@ -147,7 +147,7 @@ bfd_set_state (bfd_main_t * bm, bfd_session_t * bs,
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
const char *
|
||||
bfd_poll_state_string (bfd_poll_state_e state)
|
||||
{
|
||||
switch (state)
|
||||
@ -265,12 +265,16 @@ bfd_calc_next_echo_tx (bfd_main_t * bm, bfd_session_t * bs, u64 now)
|
||||
static void
|
||||
bfd_recalc_detection_time (bfd_main_t * bm, bfd_session_t * bs)
|
||||
{
|
||||
bs->detection_time_clocks =
|
||||
bs->remote_detect_mult * clib_max (bs->effective_required_min_rx_clocks,
|
||||
bs->remote_desired_min_tx_clocks);
|
||||
BFD_DBG ("Recalculated detection time %lu clocks/%.2fs",
|
||||
bs->detection_time_clocks,
|
||||
bs->detection_time_clocks / bm->cpu_cps);
|
||||
if (bs->local_state == BFD_STATE_init || bs->local_state == BFD_STATE_up)
|
||||
{
|
||||
bs->detection_time_clocks =
|
||||
bs->remote_detect_mult *
|
||||
clib_max (bs->effective_required_min_rx_clocks,
|
||||
bs->remote_desired_min_tx_clocks);
|
||||
BFD_DBG ("Recalculated detection time %lu clocks/%.2fs",
|
||||
bs->detection_time_clocks,
|
||||
bs->detection_time_clocks / bm->cpu_cps);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -284,7 +288,8 @@ bfd_set_timer (bfd_main_t * bm, bfd_session_t * bs, u64 now,
|
||||
{
|
||||
rx_timeout = bs->last_rx_clocks + bs->detection_time_clocks;
|
||||
}
|
||||
if (BFD_STATE_up != bs->local_state || !bs->remote_demand ||
|
||||
if (BFD_STATE_up != bs->local_state ||
|
||||
(!bs->remote_demand && bs->remote_min_rx_usec) ||
|
||||
BFD_POLL_NOT_NEEDED != bs->poll_state)
|
||||
{
|
||||
tx_timeout = bs->tx_timeout_clocks;
|
||||
@ -348,7 +353,7 @@ bfd_set_effective_desired_min_tx (bfd_main_t * bm,
|
||||
|
||||
static void
|
||||
bfd_set_effective_required_min_rx (bfd_main_t * bm,
|
||||
bfd_session_t * bs, u64 now,
|
||||
bfd_session_t * bs,
|
||||
u64 required_min_rx_clocks)
|
||||
{
|
||||
bs->effective_required_min_rx_clocks = required_min_rx_clocks;
|
||||
@ -393,44 +398,33 @@ void
|
||||
bfd_session_start (bfd_main_t * bm, bfd_session_t * bs)
|
||||
{
|
||||
BFD_DBG ("\nStarting session: %U", format_bfd_session, bs);
|
||||
bfd_set_effective_required_min_rx (bm, bs,
|
||||
bs->config_required_min_rx_clocks);
|
||||
bfd_recalc_tx_interval (bm, bs);
|
||||
vlib_process_signal_event (bm->vlib_main, bm->bfd_process_node_index,
|
||||
BFD_EVENT_NEW_SESSION, bs->bs_idx);
|
||||
}
|
||||
|
||||
vnet_api_error_t
|
||||
bfd_del_session (uword bs_idx)
|
||||
{
|
||||
const bfd_main_t *bm = &bfd_main;
|
||||
if (!pool_is_free_index (bm->sessions, bs_idx))
|
||||
{
|
||||
bfd_session_t *bs = pool_elt_at_index (bm->sessions, bs_idx);
|
||||
pool_put (bm->sessions, bs);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
BFD_ERR ("no such session");
|
||||
return VNET_API_ERROR_BFD_ENOENT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bfd_session_set_flags (bfd_session_t * bs, u8 admin_up_down)
|
||||
{
|
||||
bfd_main_t *bm = &bfd_main;
|
||||
u64 now = clib_cpu_time_now ();
|
||||
if (admin_up_down)
|
||||
{
|
||||
BFD_DBG ("Session set admin-up, bs-idx=%u", bs->bs_idx);
|
||||
bfd_set_state (bm, bs, BFD_STATE_down, 0);
|
||||
bfd_set_diag (bs, BFD_DIAG_CODE_no_diag);
|
||||
bfd_calc_next_tx (bm, bs, now);
|
||||
bfd_set_timer (bm, bs, now, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
BFD_DBG ("Session set admin-down, bs-idx=%u", bs->bs_idx);
|
||||
bfd_set_diag (bs, BFD_DIAG_CODE_admin_down);
|
||||
bfd_set_state (bm, bs, BFD_STATE_admin_down, 0);
|
||||
bfd_calc_next_tx (bm, bs, now);
|
||||
bfd_set_timer (bm, bs, now, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -515,7 +509,7 @@ bfd_on_state_change (bfd_main_t * bm, bfd_session_t * bs, u64 now,
|
||||
clib_max
|
||||
(bs->config_desired_min_tx_clocks,
|
||||
bm->default_desired_min_tx_clocks));
|
||||
bfd_set_effective_required_min_rx (bm, bs, now,
|
||||
bfd_set_effective_required_min_rx (bm, bs,
|
||||
bs->config_required_min_rx_clocks);
|
||||
bfd_set_timer (bm, bs, now, handling_wakeup);
|
||||
break;
|
||||
@ -525,7 +519,7 @@ bfd_on_state_change (bfd_main_t * bm, bfd_session_t * bs, u64 now,
|
||||
clib_max
|
||||
(bs->config_desired_min_tx_clocks,
|
||||
bm->default_desired_min_tx_clocks));
|
||||
bfd_set_effective_required_min_rx (bm, bs, now,
|
||||
bfd_set_effective_required_min_rx (bm, bs,
|
||||
bs->config_required_min_rx_clocks);
|
||||
bfd_set_timer (bm, bs, now, handling_wakeup);
|
||||
break;
|
||||
@ -540,7 +534,7 @@ bfd_on_state_change (bfd_main_t * bm, bfd_session_t * bs, u64 now,
|
||||
bs->config_desired_min_tx_clocks);
|
||||
if (BFD_POLL_NOT_NEEDED == bs->poll_state)
|
||||
{
|
||||
bfd_set_effective_required_min_rx (bm, bs, now,
|
||||
bfd_set_effective_required_min_rx (bm, bs,
|
||||
bs->config_required_min_rx_clocks);
|
||||
}
|
||||
bfd_set_timer (bm, bs, now, handling_wakeup);
|
||||
@ -932,7 +926,7 @@ bfd_on_timeout (vlib_main_t * vm, vlib_node_runtime_t * rt, bfd_main_t * bm,
|
||||
bs->echo = 1;
|
||||
bs->echo_last_rx_clocks = now;
|
||||
bs->echo_tx_timeout_clocks = now;
|
||||
bfd_set_effective_required_min_rx (bm, bs, now,
|
||||
bfd_set_effective_required_min_rx (bm, bs,
|
||||
clib_max
|
||||
(bm->min_required_min_rx_while_echo_clocks,
|
||||
bs->config_required_min_rx_clocks));
|
||||
@ -1569,6 +1563,7 @@ bfd_consume_pkt (bfd_main_t * bm, const bfd_pkt_t * pkt, u32 bs_idx)
|
||||
bs->remote_discr = pkt->my_disc;
|
||||
bs->remote_state = bfd_pkt_get_state (pkt);
|
||||
bs->remote_demand = bfd_pkt_get_demand (pkt);
|
||||
bs->remote_diag = bfd_pkt_get_diag_code (pkt);
|
||||
u64 now = clib_cpu_time_now ();
|
||||
bs->last_rx_clocks = now;
|
||||
if (bfd_pkt_get_auth_present (pkt))
|
||||
@ -1621,7 +1616,7 @@ bfd_consume_pkt (bfd_main_t * bm, const bfd_pkt_t * pkt, u32 bs_idx)
|
||||
bfd_set_poll_state (bs, BFD_POLL_NOT_NEEDED);
|
||||
if (BFD_STATE_up == bs->local_state)
|
||||
{
|
||||
bfd_set_effective_required_min_rx (bm, bs, now,
|
||||
bfd_set_effective_required_min_rx (bm, bs,
|
||||
clib_max (bs->echo *
|
||||
bm->min_required_min_rx_while_echo_clocks,
|
||||
bs->config_required_min_rx_clocks));
|
||||
@ -1914,6 +1909,97 @@ bfd_session_set_params (bfd_main_t * bm, bfd_session_t * bs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
vnet_api_error_t
|
||||
bfd_auth_set_key (u32 conf_key_id, u8 auth_type, u8 key_len,
|
||||
const u8 * key_data)
|
||||
{
|
||||
#if WITH_LIBSSL > 0
|
||||
bfd_auth_key_t *auth_key = NULL;
|
||||
if (!key_len || key_len > bfd_max_len_for_auth_type (auth_type))
|
||||
{
|
||||
clib_warning ("Invalid authentication key length for auth_type=%d:%s "
|
||||
"(key_len=%u, must be "
|
||||
"non-zero, expected max=%u)",
|
||||
auth_type, bfd_auth_type_str (auth_type), key_len,
|
||||
(u32) bfd_max_len_for_auth_type (auth_type));
|
||||
return VNET_API_ERROR_INVALID_VALUE;
|
||||
}
|
||||
if (!bfd_auth_type_supported (auth_type))
|
||||
{
|
||||
clib_warning ("Unsupported auth type=%d:%s", auth_type,
|
||||
bfd_auth_type_str (auth_type));
|
||||
return VNET_API_ERROR_BFD_NOTSUPP;
|
||||
}
|
||||
bfd_main_t *bm = &bfd_main;
|
||||
uword *key_idx_p = hash_get (bm->auth_key_by_conf_key_id, conf_key_id);
|
||||
if (key_idx_p)
|
||||
{
|
||||
/* modifying existing key - must not be used */
|
||||
const uword key_idx = *key_idx_p;
|
||||
auth_key = pool_elt_at_index (bm->auth_keys, key_idx);
|
||||
if (auth_key->use_count > 0)
|
||||
{
|
||||
clib_warning ("Authentication key with conf ID %u in use by %u BFD "
|
||||
"session(s) - cannot modify",
|
||||
conf_key_id, auth_key->use_count);
|
||||
return VNET_API_ERROR_BFD_EINUSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* adding new key */
|
||||
pool_get (bm->auth_keys, auth_key);
|
||||
auth_key->conf_key_id = conf_key_id;
|
||||
hash_set (bm->auth_key_by_conf_key_id, conf_key_id,
|
||||
auth_key - bm->auth_keys);
|
||||
}
|
||||
auth_key->auth_type = auth_type;
|
||||
memset (auth_key->key, 0, sizeof (auth_key->key));
|
||||
clib_memcpy (auth_key->key, key_data, key_len);
|
||||
return 0;
|
||||
#else
|
||||
clib_warning ("SSL missing, cannot manipulate authentication keys");
|
||||
return VNET_API_ERROR_BFD_NOTSUPP;
|
||||
#endif
|
||||
}
|
||||
|
||||
vnet_api_error_t
|
||||
bfd_auth_del_key (u32 conf_key_id)
|
||||
{
|
||||
#if WITH_LIBSSL > 0
|
||||
bfd_auth_key_t *auth_key = NULL;
|
||||
bfd_main_t *bm = &bfd_main;
|
||||
uword *key_idx_p = hash_get (bm->auth_key_by_conf_key_id, conf_key_id);
|
||||
if (key_idx_p)
|
||||
{
|
||||
/* deleting existing key - must not be used */
|
||||
const uword key_idx = *key_idx_p;
|
||||
auth_key = pool_elt_at_index (bm->auth_keys, key_idx);
|
||||
if (auth_key->use_count > 0)
|
||||
{
|
||||
clib_warning ("Authentication key with conf ID %u in use by %u BFD "
|
||||
"session(s) - cannot delete",
|
||||
conf_key_id, auth_key->use_count);
|
||||
return VNET_API_ERROR_BFD_EINUSE;
|
||||
}
|
||||
hash_unset (bm->auth_key_by_conf_key_id, conf_key_id);
|
||||
memset (auth_key, 0, sizeof (*auth_key));
|
||||
pool_put (bm->auth_keys, auth_key);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no such key */
|
||||
clib_warning ("Authentication key with conf ID %u does not exist",
|
||||
conf_key_id);
|
||||
return VNET_API_ERROR_BFD_ENOENT;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
clib_warning ("SSL missing, cannot manipulate authentication keys");
|
||||
return VNET_API_ERROR_BFD_NOTSUPP;
|
||||
#endif
|
||||
}
|
||||
|
||||
bfd_main_t bfd_main;
|
||||
|
||||
/*
|
||||
|
@ -74,11 +74,14 @@ typedef struct bfd_session_s
|
||||
/* session state */
|
||||
bfd_state_e local_state;
|
||||
|
||||
/* remote session state */
|
||||
bfd_state_e remote_state;
|
||||
|
||||
/* local diagnostics */
|
||||
bfd_diag_code_e local_diag;
|
||||
|
||||
/* remote session state */
|
||||
bfd_state_e remote_state;
|
||||
/* remote diagnostics */
|
||||
bfd_diag_code_e remote_diag;
|
||||
|
||||
/* local discriminator */
|
||||
u32 local_discr;
|
||||
@ -315,6 +318,7 @@ void bfd_event (bfd_main_t * bm, bfd_session_t * bs);
|
||||
void bfd_init_final_control_frame (vlib_main_t * vm, vlib_buffer_t * b,
|
||||
bfd_main_t * bm, bfd_session_t * bs);
|
||||
u8 *format_bfd_session (u8 * s, va_list * args);
|
||||
u8 *format_bfd_auth_key (u8 * s, va_list * args);
|
||||
void bfd_session_set_flags (bfd_session_t * bs, u8 admin_up_down);
|
||||
unsigned bfd_auth_type_supported (bfd_auth_type_e auth_type);
|
||||
vnet_api_error_t bfd_auth_activate (bfd_session_t * bs, u32 conf_key_id,
|
||||
@ -325,6 +329,9 @@ vnet_api_error_t bfd_session_set_params (bfd_main_t * bm, bfd_session_t * bs,
|
||||
u32 required_min_rx_usec,
|
||||
u8 detect_mult);
|
||||
|
||||
u32 bfd_clocks_to_usec (const bfd_main_t * bm, u64 clocks);
|
||||
const char *bfd_poll_state_string (bfd_poll_state_e state);
|
||||
|
||||
#define USEC_PER_MS 1000LL
|
||||
#define USEC_PER_SECOND (1000 * USEC_PER_MS)
|
||||
|
||||
|
@ -82,11 +82,13 @@ bfd_pkt_get_control_plane_independent (const bfd_pkt_t * pkt)
|
||||
return (pkt->head.sta_flags >> 3) & 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
bfd_pkt_set_control_plane_independent (bfd_pkt_t * pkt)
|
||||
{
|
||||
pkt->head.sta_flags |= 1 << 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
u8
|
||||
bfd_pkt_get_auth_present (const bfd_pkt_t * pkt)
|
||||
@ -106,11 +108,13 @@ bfd_pkt_get_demand (const bfd_pkt_t * pkt)
|
||||
return (pkt->head.sta_flags >> 1) & 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
bfd_pkt_set_demand (bfd_pkt_t * pkt)
|
||||
{
|
||||
pkt->head.sta_flags |= 1 << 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
u8
|
||||
bfd_pkt_get_multipoint (const bfd_pkt_t * pkt)
|
||||
@ -118,11 +122,13 @@ bfd_pkt_get_multipoint (const bfd_pkt_t * pkt)
|
||||
return (pkt->head.sta_flags >> 0) & 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
bfd_pkt_set_multipoint (bfd_pkt_t * pkt)
|
||||
{
|
||||
pkt->head.sta_flags |= 1 << 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
u32
|
||||
bfd_max_len_for_auth_type (bfd_auth_type_e auth_type)
|
||||
|
@ -60,8 +60,7 @@ vnet_api_error_t
|
||||
bfd_udp_set_echo_source (u32 sw_if_index)
|
||||
{
|
||||
vnet_sw_interface_t *sw_if =
|
||||
vnet_get_sw_interface_safe (bfd_udp_main.vnet_main,
|
||||
bfd_udp_main.echo_source_sw_if_index);
|
||||
vnet_get_sw_interface_safe (bfd_udp_main.vnet_main, sw_if_index);
|
||||
if (sw_if)
|
||||
{
|
||||
bfd_udp_main.echo_source_sw_if_index = sw_if_index;
|
||||
@ -84,6 +83,7 @@ bfd_udp_is_echo_available (bfd_transport_e transport)
|
||||
{
|
||||
if (!bfd_udp_main.echo_source_is_set)
|
||||
{
|
||||
BFD_DBG ("UDP echo source not set - echo not available");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
@ -127,6 +127,7 @@ bfd_udp_is_echo_available (bfd_transport_e transport)
|
||||
/* *INDENT-ON* */
|
||||
}
|
||||
}
|
||||
BFD_DBG ("No usable IP address for UDP echo - echo not available");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -144,11 +145,6 @@ bfd_udp_bs_idx_to_sport (u32 bs_idx)
|
||||
return 49152 + bs_idx % (65535 - 49152 + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
lol ()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
bfd_udp_get_echo_src_ip4 (ip4_address_t * addr)
|
||||
{
|
||||
@ -204,7 +200,6 @@ bfd_udp_get_echo_src_ip6 (ip6_address_t * addr)
|
||||
{
|
||||
*addr = *x;
|
||||
addr->as_u8[15] ^= 1; /* flip the last bit of the address */
|
||||
lol ();
|
||||
return 1;
|
||||
}
|
||||
}));
|
||||
@ -213,6 +208,24 @@ bfd_udp_get_echo_src_ip6 (ip6_address_t * addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bfd_udp_get_echo_source (int *is_set, u32 * sw_if_index, int *have_usable_ip4,
|
||||
ip4_address_t * ip4, int *have_usable_ip6,
|
||||
ip6_address_t * ip6)
|
||||
{
|
||||
if (bfd_udp_main.echo_source_is_set)
|
||||
{
|
||||
*is_set = 1;
|
||||
*sw_if_index = bfd_udp_main.echo_source_sw_if_index;
|
||||
*have_usable_ip4 = bfd_udp_get_echo_src_ip4 (ip4);
|
||||
*have_usable_ip6 = bfd_udp_get_echo_src_ip6 (ip6);
|
||||
}
|
||||
else
|
||||
{
|
||||
*is_set = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
bfd_add_udp4_transport (vlib_main_t * vm, vlib_buffer_t * b,
|
||||
const bfd_session_t * bs, int is_echo)
|
||||
@ -660,97 +673,6 @@ bfd_udp_session_set_flags (u32 sw_if_index,
|
||||
return 0;
|
||||
}
|
||||
|
||||
vnet_api_error_t
|
||||
bfd_auth_set_key (u32 conf_key_id, u8 auth_type, u8 key_len,
|
||||
const u8 * key_data)
|
||||
{
|
||||
#if WITH_LIBSSL > 0
|
||||
bfd_auth_key_t *auth_key = NULL;
|
||||
if (!key_len || key_len > bfd_max_len_for_auth_type (auth_type))
|
||||
{
|
||||
clib_warning ("Invalid authentication key length for auth_type=%d:%s "
|
||||
"(key_len=%u, must be "
|
||||
"non-zero, expected max=%u)",
|
||||
auth_type, bfd_auth_type_str (auth_type), key_len,
|
||||
(u32) bfd_max_len_for_auth_type (auth_type));
|
||||
return VNET_API_ERROR_INVALID_VALUE;
|
||||
}
|
||||
if (!bfd_auth_type_supported (auth_type))
|
||||
{
|
||||
clib_warning ("Unsupported auth type=%d:%s", auth_type,
|
||||
bfd_auth_type_str (auth_type));
|
||||
return VNET_API_ERROR_BFD_NOTSUPP;
|
||||
}
|
||||
bfd_main_t *bm = bfd_udp_main.bfd_main;
|
||||
uword *key_idx_p = hash_get (bm->auth_key_by_conf_key_id, conf_key_id);
|
||||
if (key_idx_p)
|
||||
{
|
||||
/* modifying existing key - must not be used */
|
||||
const uword key_idx = *key_idx_p;
|
||||
auth_key = pool_elt_at_index (bm->auth_keys, key_idx);
|
||||
if (auth_key->use_count > 0)
|
||||
{
|
||||
clib_warning ("Authentication key with conf ID %u in use by %u BFD "
|
||||
"sessions - cannot modify",
|
||||
conf_key_id, auth_key->use_count);
|
||||
return VNET_API_ERROR_BFD_EINUSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* adding new key */
|
||||
pool_get (bm->auth_keys, auth_key);
|
||||
auth_key->conf_key_id = conf_key_id;
|
||||
hash_set (bm->auth_key_by_conf_key_id, conf_key_id,
|
||||
auth_key - bm->auth_keys);
|
||||
}
|
||||
auth_key->auth_type = auth_type;
|
||||
memset (auth_key->key, 0, sizeof (auth_key->key));
|
||||
clib_memcpy (auth_key->key, key_data, key_len);
|
||||
return 0;
|
||||
#else
|
||||
clib_warning ("SSL missing, cannot manipulate authentication keys");
|
||||
return VNET_API_ERROR_BFD_NOTSUPP;
|
||||
#endif
|
||||
}
|
||||
|
||||
vnet_api_error_t
|
||||
bfd_auth_del_key (u32 conf_key_id)
|
||||
{
|
||||
#if WITH_LIBSSL > 0
|
||||
bfd_auth_key_t *auth_key = NULL;
|
||||
bfd_main_t *bm = bfd_udp_main.bfd_main;
|
||||
uword *key_idx_p = hash_get (bm->auth_key_by_conf_key_id, conf_key_id);
|
||||
if (key_idx_p)
|
||||
{
|
||||
/* deleting existing key - must not be used */
|
||||
const uword key_idx = *key_idx_p;
|
||||
auth_key = pool_elt_at_index (bm->auth_keys, key_idx);
|
||||
if (auth_key->use_count > 0)
|
||||
{
|
||||
clib_warning ("Authentication key with conf ID %u in use by %u BFD "
|
||||
"sessions - cannot delete",
|
||||
conf_key_id, auth_key->use_count);
|
||||
return VNET_API_ERROR_BFD_EINUSE;
|
||||
}
|
||||
hash_unset (bm->auth_key_by_conf_key_id, conf_key_id);
|
||||
memset (auth_key, 0, sizeof (*auth_key));
|
||||
pool_put (bm->auth_keys, auth_key);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no such key */
|
||||
clib_warning ("Authentication key with conf ID %u does not exist",
|
||||
conf_key_id);
|
||||
return VNET_API_ERROR_BFD_ENOENT;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
clib_warning ("SSL missing, cannot manipulate authentication keys");
|
||||
return VNET_API_ERROR_BFD_NOTSUPP;
|
||||
#endif
|
||||
}
|
||||
|
||||
vnet_api_error_t
|
||||
bfd_udp_auth_activate (u32 sw_if_index,
|
||||
const ip46_address_t * local_addr,
|
||||
|
@ -62,6 +62,11 @@ int bfd_add_udp6_transport (vlib_main_t * vm, vlib_buffer_t * b,
|
||||
*/
|
||||
int bfd_udp_is_echo_available (bfd_transport_e transport);
|
||||
|
||||
void
|
||||
bfd_udp_get_echo_source (int *is_set, u32 * sw_if_index, int *have_usable_ip4,
|
||||
ip4_address_t * ip4, int *have_usable_ip6,
|
||||
ip6_address_t * ip6);
|
||||
|
||||
#endif /* __included_bfd_udp_h__ */
|
||||
|
||||
/*
|
||||
|
@ -198,6 +198,10 @@ class VppBFDAuthKey(VppObject):
|
||||
""" key data """
|
||||
return self._key
|
||||
|
||||
@key.setter
|
||||
def key(self, value):
|
||||
self._key = value
|
||||
|
||||
@property
|
||||
def conf_key_id(self):
|
||||
""" configuration key ID """
|
||||
@ -249,7 +253,10 @@ class VppBFDUDPSession(VppObject):
|
||||
self._required_min_rx = required_min_rx
|
||||
self._detect_mult = detect_mult
|
||||
self._sha1_key = sha1_key
|
||||
self._bfd_key_id = bfd_key_id if bfd_key_id else randint(0, 255)
|
||||
if bfd_key_id is not None:
|
||||
self._bfd_key_id = bfd_key_id
|
||||
else:
|
||||
self._bfd_key_id = randint(0, 255)
|
||||
|
||||
@property
|
||||
def test(self):
|
||||
|
579
test/test_bfd.py
579
test/test_bfd.py
File diff suppressed because it is too large
Load Diff
@ -46,6 +46,7 @@ class VppObjectRegistry(object):
|
||||
if obj.object_id() not in self._object_dict:
|
||||
self._object_registry.append(obj)
|
||||
self._object_dict[obj.object_id()] = obj
|
||||
logger.debug("REG: registering %s" % obj)
|
||||
else:
|
||||
logger.debug("REG: duplicate add, ignoring (%s)" % obj)
|
||||
|
||||
|
@ -29,6 +29,11 @@ class L2_VTR_OP:
|
||||
L2_POP_1 = 3
|
||||
|
||||
|
||||
class UnexpectedApiReturnValueError(Exception):
|
||||
""" exception raised when the API return value is unexpected """
|
||||
pass
|
||||
|
||||
|
||||
class VppPapiProvider(object):
|
||||
"""VPP-api provider using vpp-papi
|
||||
|
||||
@ -144,13 +149,13 @@ class VppPapiProvider(object):
|
||||
"return value instead of %d in %s" % \
|
||||
(reply.retval, repr(reply))
|
||||
self.test_class.logger.info(msg)
|
||||
raise Exception(msg)
|
||||
raise UnexpectedApiReturnValueError(msg)
|
||||
elif self._expect_api_retval == self._zero:
|
||||
if hasattr(reply, 'retval') and reply.retval != expected_retval:
|
||||
msg = "API call failed, expected zero return value instead "\
|
||||
"of %d in %s" % (expected_retval, repr(reply))
|
||||
self.test_class.logger.info(msg)
|
||||
raise Exception(msg)
|
||||
raise UnexpectedApiReturnValueError(msg)
|
||||
else:
|
||||
raise Exception("Internal error, unexpected value for "
|
||||
"self._expect_api_retval %s" %
|
||||
@ -1188,6 +1193,9 @@ class VppPapiProvider(object):
|
||||
return self.api(self.papi.bfd_udp_set_echo_source,
|
||||
{'sw_if_index': sw_if_index})
|
||||
|
||||
def bfd_udp_del_echo_source(self):
|
||||
return self.api(self.papi.bfd_udp_del_echo_source, {})
|
||||
|
||||
def classify_add_del_table(
|
||||
self,
|
||||
is_add,
|
||||
|
Reference in New Issue
Block a user