BFD: echo function
Change-Id: Ib1e301d62b687d4e42434239e7cd412065c28da0 Signed-off-by: Klement Sekera <ksekera@cisco.com>
This commit is contained in:
Klement Sekera
committed by
Damjan Marion
parent
263440e789
commit
239790fd91
@ -13,29 +13,43 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** \brief Configure BFD feature
|
||||
/** \brief Set BFD echo source
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ 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
|
||||
@param sw_if_index - interface to use as echo source
|
||||
*/
|
||||
define bfd_set_config
|
||||
define bfd_udp_set_echo_source
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
u32 slow_timer;
|
||||
u32 min_tx;
|
||||
u32 min_rx;
|
||||
u8 detect_mult;
|
||||
u32 sw_if_index;
|
||||
};
|
||||
|
||||
/** \brief Configure BFD feature response
|
||||
/** \brief Set BFD feature response
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param retval - return code for the request
|
||||
*/
|
||||
define bfd_set_config_reply
|
||||
define bfd_udp_set_echo_source_reply
|
||||
{
|
||||
u32 context;
|
||||
i32 retval;
|
||||
};
|
||||
|
||||
/** \brief Delete BFD echo source
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
*/
|
||||
define bfd_udp_del_echo_source
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
};
|
||||
|
||||
/** \brief Delete BFD feature response
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param retval - return code for the request
|
||||
*/
|
||||
define bfd_udp_del_echo_source_reply
|
||||
{
|
||||
u32 context;
|
||||
i32 retval;
|
||||
|
@ -54,7 +54,9 @@
|
||||
_ (BFD_AUTH_DEL_KEY, bfd_auth_del_key) \
|
||||
_ (BFD_AUTH_KEYS_DUMP, bfd_auth_keys_dump) \
|
||||
_ (BFD_UDP_AUTH_ACTIVATE, bfd_udp_auth_activate) \
|
||||
_ (BFD_UDP_AUTH_DEACTIVATE, bfd_udp_auth_deactivate)
|
||||
_ (BFD_UDP_AUTH_DEACTIVATE, bfd_udp_auth_deactivate) \
|
||||
_ (BFD_UDP_SET_ECHO_SOURCE, bfd_udp_set_echo_source) \
|
||||
_ (BFD_UDP_DEL_ECHO_SOURCE, bfd_udp_del_echo_source)
|
||||
|
||||
pub_sub_handler (bfd_events, BFD_EVENTS);
|
||||
|
||||
@ -314,6 +316,33 @@ vl_api_bfd_udp_auth_deactivate_t_handler (vl_api_bfd_udp_auth_deactivate_t *
|
||||
REPLY_MACRO (VL_API_BFD_UDP_AUTH_DEACTIVATE_REPLY);
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_bfd_udp_set_echo_source_t_handler (vl_api_bfd_udp_set_echo_source_t *
|
||||
mp)
|
||||
{
|
||||
vl_api_bfd_udp_set_echo_source_reply_t *rmp;
|
||||
int rv;
|
||||
|
||||
VALIDATE_SW_IF_INDEX (mp);
|
||||
|
||||
rv = bfd_udp_set_echo_source (clib_net_to_host_u32 (mp->sw_if_index));
|
||||
|
||||
BAD_SW_IF_INDEX_LABEL;
|
||||
REPLY_MACRO (VL_API_BFD_UDP_SET_ECHO_SOURCE_REPLY);
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_bfd_udp_del_echo_source_t_handler (vl_api_bfd_udp_del_echo_source_t *
|
||||
mp)
|
||||
{
|
||||
vl_api_bfd_udp_del_echo_source_reply_t *rmp;
|
||||
int rv;
|
||||
|
||||
rv = bfd_udp_del_echo_source ();
|
||||
|
||||
REPLY_MACRO (VL_API_BFD_UDP_DEL_ECHO_SOURCE_REPLY);
|
||||
}
|
||||
|
||||
/*
|
||||
* bfd_api_hookup
|
||||
* Add vpe's API message handlers to the table.
|
||||
|
@ -24,6 +24,17 @@
|
||||
#include <vnet/ip/ip6_packet.h>
|
||||
#include <vnet/bfd/bfd_udp.h>
|
||||
|
||||
#define foreach_bfd_transport(F) \
|
||||
F (UDP4, "ip4-rewrite") \
|
||||
F (UDP6, "ip6-rewrite")
|
||||
|
||||
typedef enum
|
||||
{
|
||||
#define F(t, n) BFD_TRANSPORT_##t,
|
||||
foreach_bfd_transport (F)
|
||||
#undef F
|
||||
} bfd_transport_e;
|
||||
|
||||
vnet_api_error_t
|
||||
bfd_udp_add_session (u32 sw_if_index, const ip46_address_t * local_addr,
|
||||
const ip46_address_t * peer_addr,
|
||||
@ -31,12 +42,11 @@ bfd_udp_add_session (u32 sw_if_index, const ip46_address_t * local_addr,
|
||||
u8 detect_mult, u8 is_authenticated, u32 conf_key_id,
|
||||
u8 bfd_key_id);
|
||||
|
||||
vnet_api_error_t bfd_udp_mod_session (u32 sw_if_index,
|
||||
const ip46_address_t * local_addr,
|
||||
const ip46_address_t * peer_addr,
|
||||
u32 desired_min_tx_usec,
|
||||
u32 required_min_rx_usec,
|
||||
u8 detect_mult);
|
||||
vnet_api_error_t
|
||||
bfd_udp_mod_session (u32 sw_if_index, const ip46_address_t * local_addr,
|
||||
const ip46_address_t * peer_addr,
|
||||
u32 desired_min_tx_usec, u32 required_min_rx_usec,
|
||||
u8 detect_mult);
|
||||
|
||||
vnet_api_error_t bfd_udp_del_session (u32 sw_if_index,
|
||||
const ip46_address_t * local_addr,
|
||||
@ -63,6 +73,10 @@ vnet_api_error_t bfd_udp_auth_deactivate (u32 sw_if_index,
|
||||
const ip46_address_t * peer_addr,
|
||||
u8 is_delayed);
|
||||
|
||||
vnet_api_error_t bfd_udp_set_echo_source (u32 loopback_sw_if_index);
|
||||
|
||||
vnet_api_error_t bfd_udp_del_echo_source ();
|
||||
|
||||
#endif /* __included_bfd_api_h__ */
|
||||
|
||||
/*
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define __included_bfd_debug_h__
|
||||
|
||||
/* controls debug prints */
|
||||
#define BFD_DEBUG (0)
|
||||
#define BFD_DEBUG (1)
|
||||
|
||||
#if BFD_DEBUG
|
||||
#define BFD_DEBUG_FILE_DEF \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -24,17 +24,6 @@
|
||||
#include <vnet/bfd/bfd_protocol.h>
|
||||
#include <vnet/bfd/bfd_udp.h>
|
||||
|
||||
#define foreach_bfd_transport(F) \
|
||||
F (UDP4, "ip4-rewrite") \
|
||||
F (UDP6, "ip6-rewrite")
|
||||
|
||||
typedef enum
|
||||
{
|
||||
#define F(t, n) BFD_TRANSPORT_##t,
|
||||
foreach_bfd_transport (F)
|
||||
#undef F
|
||||
} bfd_transport_t;
|
||||
|
||||
#define foreach_bfd_mode(F) \
|
||||
F (asynchronous) \
|
||||
F (demand)
|
||||
@ -64,14 +53,15 @@ typedef struct
|
||||
bfd_auth_type_e auth_type;
|
||||
} bfd_auth_key_t;
|
||||
|
||||
#define foreach_bfd_poll_state(F)\
|
||||
F(NOT_NEEDED)\
|
||||
F(NEEDED)\
|
||||
F(IN_PROGRESS)
|
||||
#define foreach_bfd_poll_state(F) \
|
||||
F (NOT_NEEDED) \
|
||||
F (NEEDED) \
|
||||
F (IN_PROGRESS) \
|
||||
F (IN_PROGRESS_AND_QUEUED)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
#define F(x) POLL_##x,
|
||||
#define F(x) BFD_POLL_##x,
|
||||
foreach_bfd_poll_state (F)
|
||||
#undef F
|
||||
} bfd_poll_state_e;
|
||||
@ -120,21 +110,27 @@ typedef struct bfd_session_s
|
||||
/* remote min rx interval (clocks) */
|
||||
u64 remote_min_rx_clocks;
|
||||
|
||||
/* remote min echo rx interval (microseconds) */
|
||||
u64 remote_min_echo_rx_usec;
|
||||
|
||||
/* remote min echo rx interval (clocks) */
|
||||
u64 remote_min_echo_rx_clocks;
|
||||
|
||||
/* remote desired min tx interval (clocks) */
|
||||
u64 remote_desired_min_tx_clocks;
|
||||
|
||||
/* configured detect multiplier */
|
||||
u8 local_detect_mult;
|
||||
|
||||
/* 1 if in demand mode, 0 otherwise */
|
||||
u8 local_demand;
|
||||
|
||||
/* 1 if remote system sets demand mode, 0 otherwise */
|
||||
u8 remote_demand;
|
||||
|
||||
/* remote detect multiplier */
|
||||
u8 remote_detect_mult;
|
||||
|
||||
/* 1 is echo function is active, 0 otherwise */
|
||||
u8 echo;
|
||||
|
||||
/* set to value of timer in timing wheel, 0 if never set */
|
||||
u64 wheel_time_clocks;
|
||||
|
||||
@ -150,12 +146,33 @@ typedef struct bfd_session_s
|
||||
/* timestamp of last packet received */
|
||||
u64 last_rx_clocks;
|
||||
|
||||
/* transmit interval for echo packets */
|
||||
u64 echo_transmit_interval_clocks;
|
||||
|
||||
/* next time at which to transmit echo packet */
|
||||
u64 echo_tx_timeout_clocks;
|
||||
|
||||
/* timestamp of last echo packet transmitted */
|
||||
u64 echo_last_tx_clocks;
|
||||
|
||||
/* timestamp of last echo packet received */
|
||||
u64 echo_last_rx_clocks;
|
||||
|
||||
/* secret used for calculating/checking checksum of echo packets */
|
||||
u32 echo_secret;
|
||||
|
||||
/* detection time */
|
||||
u64 detection_time_clocks;
|
||||
|
||||
/* state info regarding poll sequence */
|
||||
bfd_poll_state_e poll_state;
|
||||
|
||||
/*
|
||||
* helper for delayed poll sequence - marks either start of running poll
|
||||
* sequence or timeout, after which we can start the next poll sequnce
|
||||
*/
|
||||
u64 poll_state_start_or_timeout_clocks;
|
||||
|
||||
/* authentication information */
|
||||
struct
|
||||
{
|
||||
@ -191,7 +208,7 @@ typedef struct bfd_session_s
|
||||
} auth;
|
||||
|
||||
/* transport type for this session */
|
||||
bfd_transport_t transport;
|
||||
bfd_transport_e transport;
|
||||
|
||||
/* union of transport-specific data */
|
||||
union
|
||||
@ -227,6 +244,9 @@ typedef struct
|
||||
/* default desired min tx in clocks */
|
||||
u64 default_desired_min_tx_clocks;
|
||||
|
||||
/* minimum required min rx while echo function is active - clocks */
|
||||
u64 min_required_min_rx_while_echo_clocks;
|
||||
|
||||
/* for generating random numbers */
|
||||
u32 random_seed;
|
||||
|
||||
@ -268,36 +288,54 @@ enum
|
||||
BFD_EVENT_CONFIG_CHANGED,
|
||||
} bfd_process_event_e;
|
||||
|
||||
u8 *bfd_input_format_trace (u8 * s, va_list * args);
|
||||
/* echo packet structure */
|
||||
/* *INDENT-OFF* */
|
||||
typedef CLIB_PACKED (struct {
|
||||
/* local discriminator */
|
||||
u32 discriminator;
|
||||
/* expire time of this packet - clocks */
|
||||
u64 expire_time_clocks;
|
||||
/* checksum - based on discriminator, local secret and expire time */
|
||||
u64 checksum;
|
||||
}) bfd_echo_pkt_t;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
bfd_session_t *bfd_get_session (bfd_main_t * bm, bfd_transport_t t);
|
||||
u8 *bfd_input_format_trace (u8 * s, va_list * args);
|
||||
bfd_session_t *bfd_get_session (bfd_main_t * bm, bfd_transport_e t);
|
||||
void bfd_put_session (bfd_main_t * bm, bfd_session_t * bs);
|
||||
bfd_session_t *bfd_find_session_by_idx (bfd_main_t * bm, uword bs_idx);
|
||||
bfd_session_t *bfd_find_session_by_disc (bfd_main_t * bm, u32 disc);
|
||||
void bfd_session_start (bfd_main_t * bm, bfd_session_t * bs);
|
||||
void bfd_consume_pkt (bfd_main_t * bm, const bfd_pkt_t * bfd, u32 bs_idx);
|
||||
int bfd_consume_echo_pkt (bfd_main_t * bm, vlib_buffer_t * b);
|
||||
int bfd_verify_pkt_common (const bfd_pkt_t * pkt);
|
||||
int bfd_verify_pkt_auth (const bfd_pkt_t * pkt, u16 pkt_size,
|
||||
bfd_session_t * bs);
|
||||
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_session_t * bs);
|
||||
bfd_main_t * bm, bfd_session_t * bs);
|
||||
u8 *format_bfd_session (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,
|
||||
u8 bfd_key_id, u8 is_delayed);
|
||||
vnet_api_error_t bfd_auth_deactivate (bfd_session_t * bs, u8 is_delayed);
|
||||
vnet_api_error_t
|
||||
bfd_session_set_params (bfd_main_t * bm, bfd_session_t * bs,
|
||||
u32 desired_min_tx_usec,
|
||||
u32 required_min_rx_usec, u8 detect_mult);
|
||||
vnet_api_error_t bfd_session_set_params (bfd_main_t * bm, bfd_session_t * bs,
|
||||
u32 desired_min_tx_usec,
|
||||
u32 required_min_rx_usec,
|
||||
u8 detect_mult);
|
||||
|
||||
#define USEC_PER_MS 1000LL
|
||||
#define USEC_PER_SECOND (1000 * USEC_PER_MS)
|
||||
|
||||
/* default, slow transmission interval for BFD packets, per spec at least 1s */
|
||||
#define BFD_DEFAULT_DESIRED_MIN_TX_US USEC_PER_SECOND
|
||||
#define BFD_DEFAULT_DESIRED_MIN_TX_USEC USEC_PER_SECOND
|
||||
|
||||
/*
|
||||
* minimum required min rx set locally when echo function is used, per spec
|
||||
* should be set to at least 1s
|
||||
*/
|
||||
#define BFD_REQUIRED_MIN_RX_USEC_WHILE_ECHO USEC_PER_SECOND
|
||||
|
||||
#endif /* __included_bfd_main_h__ */
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,7 @@
|
||||
#include <vppinfra/clib.h>
|
||||
#include <vnet/adj/adj_types.h>
|
||||
#include <vnet/ip/ip6_packet.h>
|
||||
#include <vnet/bfd/bfd_api.h>
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
typedef CLIB_PACKED (struct {
|
||||
@ -49,10 +50,17 @@ typedef struct
|
||||
|
||||
struct bfd_session_s;
|
||||
|
||||
void bfd_add_udp4_transport (vlib_main_t * vm, vlib_buffer_t * b,
|
||||
const struct bfd_session_s *bs);
|
||||
void bfd_add_udp6_transport (vlib_main_t * vm, vlib_buffer_t * b,
|
||||
const struct bfd_session_s *bs);
|
||||
int bfd_add_udp4_transport (vlib_main_t * vm, vlib_buffer_t * b,
|
||||
const struct bfd_session_s *bs, int is_echo);
|
||||
int bfd_add_udp6_transport (vlib_main_t * vm, vlib_buffer_t * b,
|
||||
const struct bfd_session_s *bs, int is_echo);
|
||||
|
||||
/**
|
||||
* @brief check if the bfd udp layer is echo-capable at this time
|
||||
*
|
||||
* @return 1 if available, 0 otherwise
|
||||
*/
|
||||
int bfd_udp_is_echo_available (bfd_transport_e transport);
|
||||
|
||||
#endif /* __included_bfd_udp_h__ */
|
||||
|
||||
|
21
test/bfd.py
21
test/bfd.py
@ -152,6 +152,27 @@ class BFD(Packet):
|
||||
bind_layers(UDP, BFD, dport=BFD.udp_dport)
|
||||
|
||||
|
||||
class BFD_vpp_echo(Packet):
|
||||
""" BFD echo packet as used by VPP (non-rfc, as rfc doesn't define one) """
|
||||
|
||||
udp_dport = 3785 #: BFD echo destination port per RFC 5881
|
||||
name = "BFD_VPP_ECHO"
|
||||
|
||||
fields_desc = [
|
||||
BitField("discriminator", 0, 32),
|
||||
BitField("expire_time_clocks", 0, 64),
|
||||
BitField("checksum", 0, 64)
|
||||
]
|
||||
|
||||
def mysummary(self):
|
||||
return self.sprintf(
|
||||
"BFD_VPP_ECHO(disc=%BFD_VPP_ECHO.discriminator%,"
|
||||
"expire_time_clocks=%BFD_VPP_ECHO.expire_time_clocks%)")
|
||||
|
||||
# glue the BFD echo packet class to scapy parser
|
||||
bind_layers(UDP, BFD_vpp_echo, dport=BFD_vpp_echo.udp_dport)
|
||||
|
||||
|
||||
class VppBFDAuthKey(VppObject):
|
||||
""" Represents BFD authentication key in VPP """
|
||||
|
||||
|
@ -574,7 +574,7 @@ class VppTestCase(unittest.TestCase):
|
||||
|
||||
def assert_equal(self, real_value, expected_value, name_or_class=None):
|
||||
if name_or_class is None:
|
||||
self.assertEqual(real_value, expected_value, msg)
|
||||
self.assertEqual(real_value, expected_value)
|
||||
return
|
||||
try:
|
||||
msg = "Invalid %s: %d('%s') does not match expected value %d('%s')"
|
||||
|
477
test/test_bfd.py
477
test/test_bfd.py
File diff suppressed because it is too large
Load Diff
@ -1117,6 +1117,10 @@ class VppPapiProvider(object):
|
||||
def bfd_auth_keys_dump(self):
|
||||
return self.api(self.papi.bfd_auth_keys_dump, {})
|
||||
|
||||
def bfd_udp_set_echo_source(self, sw_if_index):
|
||||
return self.api(self.papi.bfd_udp_set_echo_source,
|
||||
{'sw_if_index': sw_if_index})
|
||||
|
||||
def classify_add_del_table(
|
||||
self,
|
||||
is_add,
|
||||
|
Reference in New Issue
Block a user