|
FD.io VPP
v21.10.1-2-g0a485f517
Vector Packet Processing
|
Go to the documentation of this file.
37 #if defined(clib_crc32c_uses_intrinsics) && !defined (__i386__)
38 checksum = crc32_u64 (0, discriminator);
39 checksum = crc32_u64 (checksum, expire_time);
40 checksum = crc32_u64 (checksum, secret);
42 checksum =
clib_xxhash (discriminator ^ expire_time ^ secret);
76 s =
format (s,
"{auth-type=%u:%s, conf-key-id=%u, use-count=%u}, ",
78 key->conf_key_id,
key->use_count);
128 BFD_DBG (
"set local_diag, bs_idx=%d: '%d:%s'", bs->
bs_idx, code,
156 return "BFD_POLL_" #x;
168 BFD_DBG (
"Setting poll state=%s, bs_idx=%u",
179 BFD_DBG (
"Recalculated transmit interval " BFD_CLK_FMT,
188 BFD_DBG (
"Recalculated echo transmit interval " BFD_CLK_FMT,
207 BFD_DBG (
"Missed %lu transmit events (now is %lu, calc "
208 "tx_timeout is %lu)",
226 BFD_DBG (
"Missed %lu transmit events (now is %lu, calc "
227 "tx_timeout is %lu)",
235 BFD_DBG (
"Next transmit in %lu nsec/%.02fs@%lu",
250 BFD_DBG (
"Missed %lu echo transmit events (now is %lu, calc tx_timeout "
257 BFD_DBG (
"Next echo transmit in %lu nsec/%.02fs@%lu",
272 BFD_DBG (
"Recalculated detection time %lu nsec/%.3fs",
295 if (tx_timeout && rx_timeout)
311 BFD_DBG (
"bs_idx=%u, tx_timeout=%lu, echo_tx_timeout=%lu, rx_timeout=%lu, "
321 u32 wheel_time_ticks =
324 BFD_DBG (
"event_time_nsec %lu (%lu nsec/%.3fs in future) -> "
328 wheel_time_ticks = wheel_time_ticks ? wheel_time_ticks : 1;
333 BFD_DBG (
"tw_timer_update(%p, %u, %lu);", &bm->wheel, bs->
tw_id,
340 BFD_DBG (
"tw_timer_start(%p, %u, 0, %lu) == %u;", &bm->wheel,
341 bs->
bs_idx, wheel_time_ticks);
344 if (!handling_wakeup)
383 u64 desired_min_tx_nsec)
386 BFD_DBG (
"Set effective desired min tx to " BFD_CLK_FMT,
397 u64 required_min_rx_nsec)
400 BFD_DBG (
"Set effective required min rx to " BFD_CLK_FMT,
407 u64 now,
u32 remote_required_min_rx_usec)
413 BFD_DBG (
"Set remote min rx to " BFD_CLK_FMT,
423 u32 remote_required_min_echo_rx_usec)
430 BFD_DBG (
"Set remote min echo rx to " BFD_CLK_FMT,
493 const bfd_pkt_t *pkt = (bfd_pkt_t *) t->
data;
496 s =
format (s,
"BFD v%u, diag=%u(%s), state=%u(%s),\n"
497 " flags=(P:%u, F:%u, C:%u, A:%u, D:%u, M:%u), "
498 "detect_mult=%u, length=%u\n",
508 if (t->
len >= sizeof (bfd_pkt_t) &&
509 pkt->head.length >= sizeof (bfd_pkt_t))
511 s =
format (s,
" my discriminator: %u\n",
512 clib_net_to_host_u32 (pkt->my_disc));
513 s =
format (s,
" your discriminator: %u\n",
514 clib_net_to_host_u32 (pkt->your_disc));
515 s =
format (s,
" desired min tx interval: %u\n",
516 clib_net_to_host_u32 (pkt->des_min_tx));
517 s =
format (s,
" required min rx interval: %u\n",
518 clib_net_to_host_u32 (pkt->req_min_rx));
519 s =
format (s,
" required min echo rx interval: %u",
520 clib_net_to_host_u32 (pkt->req_min_echo_rx));
522 if (t->
len >= sizeof (bfd_pkt_with_common_auth_t) &&
523 pkt->head.length >= sizeof (bfd_pkt_with_common_auth_t) &&
526 const bfd_pkt_with_common_auth_t *with_auth = (
void *) pkt;
527 const bfd_auth_common_t *common = &with_auth->common_auth;
528 s =
format (s,
"\n auth len: %u\n", common->len);
529 s =
format (s,
" auth type: %u:%s\n", common->type,
531 if (t->
len >= sizeof (bfd_pkt_with_sha1_auth_t) &&
532 pkt->head.length >= sizeof (bfd_pkt_with_sha1_auth_t) &&
533 (BFD_AUTH_TYPE_keyed_sha1 == common->type ||
534 BFD_AUTH_TYPE_meticulous_keyed_sha1 == common->type))
536 const bfd_pkt_with_sha1_auth_t *with_sha1 = (
void *) pkt;
537 const bfd_auth_sha1_t *sha1 = &with_sha1->sha1_auth;
538 s =
format (s,
" seq num: %u\n",
539 clib_net_to_host_u32 (sha1->seq_num));
540 s =
format (s,
" key id: %u\n", sha1->key_id);
542 sizeof (sha1->hash));
563 u32 bs_idx =
a->bs_idx;
576 BFD_DBG (
"Ignoring event RPC for non-existent session index %u",
592 event->bs_idx = bs_idx;
605 u32 bs_idx =
a->bs_idx;
614 BFD_DBG (
"Ignoring notify RPC for non-existent session index %u",
648 case BFD_STATE_admin_down:
718 case BFD_TRANSPORT_UDP4:
722 case BFD_TRANSPORT_UDP6:
734 case BFD_TRANSPORT_UDP4:
738 case BFD_TRANSPORT_UDP6:
751 case BFD_TRANSPORT_UDP4:
752 BFD_DBG (
"Transport bfd echo via udp4, bs_idx=%u", bs->
bs_idx);
755 case BFD_TRANSPORT_UDP6:
756 BFD_DBG (
"Transport bfd echo via udp6, bs_idx=%u", bs->
bs_idx);
768 case BFD_TRANSPORT_UDP4:
769 BFD_DBG (
"Transport bfd echo via udp4, bs_idx=%u", bs->
bs_idx);
772 case BFD_TRANSPORT_UDP6:
773 BFD_DBG (
"Transport bfd echo via udp6, bs_idx=%u", bs->
bs_idx);
785 bfd_auth_sha1_t *
auth = &pkt->sha1_auth;
787 pkt->pkt.head.length +=
sizeof (*auth);
796 auth->type_len.len =
sizeof (bfd_auth_sha1_t);
805 unsigned char hash[
sizeof (
auth->hash)];
810 op.len =
sizeof (*pkt);
826 case BFD_AUTH_TYPE_reserved:
828 case BFD_AUTH_TYPE_simple_password:
830 case BFD_AUTH_TYPE_keyed_md5:
832 case BFD_AUTH_TYPE_meticulous_keyed_md5:
834 "internal error, unexpected BFD auth type '%d'",
837 case BFD_AUTH_TYPE_keyed_sha1:
839 case BFD_AUTH_TYPE_meticulous_keyed_sha1:
854 case BFD_TRANSPORT_UDP4:
856 case BFD_TRANSPORT_UDP6:
869 bfd_length =
sizeof (bfd_pkt_t);
875 pkt->head.length = bfd_length;
890 pkt->req_min_echo_rx = clib_host_to_net_u32 (1);
918 pkt->expire_time_nsec =
926 BFD_ERR (
"cannot send echo packet out, turning echo off");
933 BFD_ERR (
"cannot send echo packet out, turning echo off");
944 (
"No need to send echo packet now, now is %lu, tx_timeout is %lu",
955 BFD_DBG (
"Remote min rx interval is zero, not sending periodic control "
968 BFD_DBG (
"Remote demand is set, not sending periodic control frame");
986 case BFD_POLL_NEEDED:
987 if (now < bs->poll_state_start_or_timeout_nsec)
989 BFD_DBG (
"Cannot start a poll sequence yet, need to wait for "
998 case BFD_POLL_IN_PROGRESS:
999 case BFD_POLL_IN_PROGRESS_AND_QUEUED:
1001 BFD_DBG (
"Setting poll bit in packet, bs_idx=%u", bs->
bs_idx);
1003 case BFD_POLL_NOT_NEEDED:
1019 (
"No need to send control frame now, now is %lu, tx_timeout is %lu",
1029 BFD_DBG (
"Send final control frame for bs_idx=%lu", bs->
bs_idx);
1045 u64 now,
int handling_wakeup)
1049 BFD_DBG (
"Rx timeout, session goes down");
1078 BFD_DBG (
"Echo rx timeout, session goes down");
1091 case BFD_STATE_admin_down:
1094 case BFD_STATE_down:
1097 case BFD_STATE_init:
1107 BFD_DBG (
"Switching on echo function, bs_idx=%u", bs->
bs_idx);
1134 uword event_type, *event_data = 0;
1143 BFD_DBG (
"wakeup, now is %llunsec, vlib_time_now() is %.9f",
now,
1149 u32 first_expires_in_ticks =
1150 TW (tw_timer_first_expires_in_ticks) (&bm->wheel);
1151 if (!first_expires_in_ticks)
1154 (
"tw_timer_first_expires_in_ticks(%p) returns 0ticks",
1156 timeout = bm->wheel.next_run_time - vm_time;
1157 BFD_DBG (
"wheel.next_run_time is %.9f",
1158 bm->wheel.next_run_time);
1165 BFD_DBG (
"tw_timer_first_expires_in_ticks(%p) returns %luticks",
1166 &bm->wheel, first_expires_in_ticks);
1167 u64 next_expire_nsec =
1173 BFD_DBG (
"vlib_process_wait_for_event_or_clock(vm, %.09f)",
1184 uword *session_index;
1213 BFD_DBG (
"Ignoring event for non-existent session index %u",
1214 (
u32) * session_index);
1231 BFD_DBG (
"Ignoring event for non-existent session index %u",
1232 (
u32) * session_index);
1241 BFD_DBG (
"tw_timer_expire_timers_vec(%p, %.04f);", &bm->wheel, vm_time);
1249 const u32 bs_idx = *p;
1261 _vec_len (expired) = 0;
1265 _vec_len (event_data) = 0;
1279 .name =
"bfd-process",
1329 setbuf (stdout, NULL);
1341 BFD_DBG (
"tw_timer_wheel_init(%p, %p, %.04f, %u)", &bm->wheel, NULL,
1347 if (n_vlib_mains > 1)
1365 const unsigned limit = 1000;
1366 unsigned counter = 0;
1370 if (counter > limit)
1373 "couldn't allocate unused session discriminator even "
1374 "after %u tries!", limit);
1444 BFD_ERR (
"BFD verification failed - unexpected version: '%d'",
1448 if (pkt->head.length < sizeof (bfd_pkt_t) ||
1450 pkt->head.length < sizeof (bfd_pkt_with_common_auth_t)))
1452 BFD_ERR (
"BFD verification failed - unexpected length: '%d' (auth "
1457 if (!pkt->head.detect_mult)
1459 BFD_ERR (
"BFD verification failed - unexpected detect-mult: '%d'",
1460 pkt->head.detect_mult);
1465 BFD_ERR (
"BFD verification failed - unexpected multipoint: '%d'",
1471 BFD_ERR (
"BFD verification failed - unexpected my-disc: '%d'",
1475 if (!pkt->your_disc)
1478 if (pkt_state != BFD_STATE_down && pkt_state != BFD_STATE_admin_down)
1480 BFD_ERR (
"BFD verification failed - unexpected state: '%s' "
1491 BFD_DBG (
"Switching authentication key from %U to %U for bs_idx=%u",
1507 if (BFD_AUTH_TYPE_meticulous_keyed_md5 == auth_type ||
1508 BFD_AUTH_TYPE_meticulous_keyed_sha1 == auth_type)
1517 u32 received_seq_num,
int is_meticulous)
1528 BFD_DBG (
"BFD peer unresponsive for %lu nsec, which is > 2 * "
1529 "detection_time=%u nsec, resetting remote_seq_number_known "
1536 const u32 max_u32 = 0xffffffff;
1555 if (received_seq_num > x &&
1556 received_seq_num < bs->
auth.remote_seq_number + is_meticulous)
1559 (
"Recvd sequence number=%u out of ranges <0, %u>, <%u, %u>",
1560 received_seq_num, x,
1571 if (received_seq_num < min || received_seq_num > max)
1573 BFD_ERR (
"Recvd sequence number=%u out of range <%u, %u>",
1574 received_seq_num, min, max);
1588 auth_key->
auth_type == BFD_AUTH_TYPE_meticulous_keyed_sha1);
1590 bfd_pkt_with_common_auth_t *with_common = (
void *) pkt;
1591 if (pkt_size <
sizeof (*with_common))
1593 BFD_ERR (
"Packet size too small to hold authentication common header");
1596 if (with_common->common_auth.type != auth_key->
auth_type)
1598 BFD_ERR (
"BFD auth type mismatch, packet auth=%d:%s doesn't match "
1599 "in-use auth=%d:%s",
1600 with_common->common_auth.type,
1605 bfd_pkt_with_sha1_auth_t *with_sha1 = (
void *) pkt;
1606 if (pkt_size <
sizeof (*with_sha1) ||
1607 with_sha1->sha1_auth.type_len.len <
sizeof (with_sha1->sha1_auth))
1610 (
"BFD size mismatch, payload size=%u, expected=%u, auth_len=%u, "
1611 "expected=%u", pkt_size,
sizeof (*with_sha1),
1612 with_sha1->sha1_auth.type_len.len, sizeof (with_sha1->sha1_auth));
1615 if (with_sha1->sha1_auth.key_id != bfd_key_id)
1618 (
"BFD key ID mismatch, packet key ID=%u doesn't match key ID=%u%s",
1619 with_sha1->sha1_auth.key_id, bfd_key_id,
1621 auth.is_delayed ?
" (but a delayed auth change is scheduled)" :
"");
1627 clib_memcpy (hash_from_packet, with_sha1->sha1_auth.hash,
1628 sizeof (with_sha1->sha1_auth.hash));
1630 sizeof (auth_key->
key));
1633 op.
src = (
u8 *) with_sha1;
1634 op.
len =
sizeof (*with_sha1);
1635 op.
digest = calculated_hash;
1638 memcmp (calculated_hash, hash_from_packet,
sizeof (calculated_hash)))
1640 clib_memcpy (with_sha1->sha1_auth.hash, hash_from_packet,
1641 sizeof (hash_from_packet));
1644 BFD_ERR (
"SHA1 hash: %U doesn't match the expected value: %U",
1658 case BFD_AUTH_TYPE_reserved:
1660 "internal error, unexpected auth_type=%d:%s",
1664 case BFD_AUTH_TYPE_simple_password:
1666 "internal error, not implemented, unexpected auth_type=%d:%s",
1670 case BFD_AUTH_TYPE_keyed_md5:
1672 case BFD_AUTH_TYPE_meticulous_keyed_md5:
1675 "internal error, not implemented, unexpected auth_type=%d:%s",
1678 case BFD_AUTH_TYPE_keyed_sha1:
1680 case BFD_AUTH_TYPE_meticulous_keyed_sha1:
1683 const u32 seq_num = clib_net_to_host_u32 (((bfd_pkt_with_sha1_auth_t
1690 bfd_key_id, auth_key);
1758 if (pkt_size >
sizeof (*pkt))
1760 BFD_ERR (
"BFD verification failed - unexpected packet size '%d' "
1761 "(auth not present)", pkt_size);
1790 if (!bs || (pkt->your_disc && pkt->your_disc != bs->
local_discr))
1804 ((bfd_pkt_with_common_auth_t *) (pkt))->common_auth.type;
1807 case BFD_AUTH_TYPE_reserved:
1809 case BFD_AUTH_TYPE_simple_password:
1811 case BFD_AUTH_TYPE_keyed_md5:
1813 case BFD_AUTH_TYPE_meticulous_keyed_md5:
1815 "internal error, unexpected auth_type=%d:%s",
1818 case BFD_AUTH_TYPE_keyed_sha1:
1820 case BFD_AUTH_TYPE_meticulous_keyed_sha1:
1823 bfd_pkt_with_sha1_auth_t *with_sha1 =
1824 (bfd_pkt_with_sha1_auth_t *) pkt;
1826 clib_net_to_host_u32 (with_sha1->sha1_auth.seq_num);
1828 BFD_DBG (
"Received sequence number %u",
1838 clib_net_to_host_u32 (pkt->req_min_rx));
1840 clib_net_to_host_u32
1841 (pkt->req_min_echo_rx));
1846 BFD_DBG (
"Poll sequence terminated, bs_idx=%u", bs->
bs_idx);
1856 else if (BFD_POLL_IN_PROGRESS_AND_QUEUED == bs->
poll_state)
1862 BFD_DBG (
"Next poll sequence can commence in " BFD_CLK_FMT,
1867 (
"Poll sequence terminated, but another is needed, bs_idx=%u",
1876 BFD_DBG (
"Session is admin-down, ignoring packet, bs_idx=%u",
1920 bfd_echo_pkt_t *pkt = NULL;
1931 BFD_DBG (
"Scanning bfd echo packet, bs_idx=%d", bs->
bs_idx);
1935 if (checksum != pkt->checksum)
1937 BFD_DBG (
"Invalid echo packet, checksum mismatch");
1941 if (pkt->expire_time_nsec <
now)
1943 BFD_DBG (
"Stale packet received, expire time %lu < now %lu",
1944 pkt->expire_time_nsec,
now);
1957 s =
format (s,
"bs_idx=%u local-state=%s remote-state=%s\n"
1958 "local-discriminator=%u remote-discriminator=%u\n"
1959 "local-diag=%s echo-active=%s\n"
1960 "desired-min-tx=%u required-min-rx=%u\n"
1961 "required-min-echo-rx=%u detect-mult=%u\n"
1962 "remote-min-rx=%u remote-min-echo-rx=%u\n"
1963 "remote-demand=%s poll-state=%s\n"
1964 "auth: local-seq-num=%u remote-seq-num=%u\n"
1988 format (s,
"bs_idx=%u local-state=%s remote-state=%s", bs->
bs_idx,
1997 if (auth_type == BFD_AUTH_TYPE_keyed_sha1 ||
1998 auth_type == BFD_AUTH_TYPE_meticulous_keyed_sha1)
2007 u8 bfd_key_id,
u8 is_delayed)
2010 const uword *key_idx_p =
2015 "authentication key with config ID %u doesn't exist)",
2017 return VNET_API_ERROR_BFD_ENOENT;
2019 const uword key_idx = *key_idx_p;
2092 u32 desired_min_tx_usec,
2093 u32 required_min_rx_usec,
u8 detect_mult)
2102 case BFD_POLL_NOT_NEEDED:
2114 case BFD_POLL_NEEDED:
2115 case BFD_POLL_IN_PROGRESS_AND_QUEUED:
2121 case BFD_POLL_IN_PROGRESS:
2126 BFD_DBG (
"Poll in progress, queueing extra poll, bs_idx=%u",
2147 BFD_DBG (
"Ignore parameter change - no change, bs_idx=%u", bs->
bs_idx);
2154 const u8 * key_data)
2161 "invalid authentication key length for auth_type=%d:%s "
2162 "(key_len=%u, must be non-zero, expected max=%u)",
2165 return VNET_API_ERROR_INVALID_VALUE;
2171 return VNET_API_ERROR_BFD_NOTSUPP;
2177 const uword key_idx = *key_idx_p;
2182 "authentication key with conf ID %u in use by %u BFD "
2183 "session(s) - cannot modify", conf_key_id,
2185 return VNET_API_ERROR_BFD_EINUSE;
2211 const uword key_idx = *key_idx_p;
2216 "authentication key with conf ID %u in use by %u BFD "
2217 "session(s) - cannot delete", conf_key_id,
2219 return VNET_API_ERROR_BFD_EINUSE;
2229 "authentication key with conf ID %u does not exist",
2231 return VNET_API_ERROR_BFD_ENOENT;
static void vlib_process_signal_event_mt(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Signal event to process from any thread.
u64 remote_desired_min_tx_nsec
remote desired min tx interval (nsec)
static void clib_spinlock_init(clib_spinlock_t *p)
static uword bfd_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
void bfd_pkt_set_poll(bfd_pkt_t *pkt)
u8 bfd_pkt_get_final(const bfd_pkt_t *pkt)
u64 last_rx_nsec
timestamp of last packet received
void bfd_session_start(bfd_main_t *bm, bfd_session_t *bs)
u32 remote_discr
remote discriminator
bfd_diag_code_e remote_diag
remote diagnostics
static_always_inline void vnet_crypto_op_init(vnet_crypto_op_t *op, vnet_crypto_op_id_t type)
static void bfd_add_auth_section(vlib_main_t *vm, vlib_buffer_t *b, bfd_session_t *bs)
vlib_main_t * vlib_main
convenience variables
static clib_error_t * bfd_main_init(vlib_main_t *vm)
bfd_transport_e transport
transport type for this session
#define hash_set(h, key, value)
u8 bfd_pkt_get_diag_code(const bfd_pkt_t *pkt)
u64 effective_desired_min_tx_nsec
effective desired min tx interval (nsec)
static u64 bfd_usec_to_nsec(u64 us)
static int bfd_verify_pkt_auth_seq_num(vlib_main_t *vm, bfd_session_t *bs, u32 received_seq_num, int is_meticulous)
void(* bfd_notify_fn_t)(bfd_listen_event_e, const bfd_session_t *)
session nitification call back function type
u64 last_tx_nsec
timestamp of last packet transmitted
#define clib_memcpy(d, s, n)
static void bfd_set_effective_required_min_rx(bfd_main_t *bm, bfd_session_t *bs, u64 required_min_rx_nsec)
static void bfd_lock(bfd_main_t *bm)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
vnet_api_error_t bfd_auth_activate(bfd_session_t *bs, u32 conf_key_id, u8 bfd_key_id, u8 is_delayed)
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static void bfd_recalc_echo_tx_interval(bfd_main_t *bm, bfd_session_t *bs)
static void bfd_on_state_change(bfd_main_t *bm, bfd_session_t *bs, u64 now, int handling_wakeup)
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
u32 config_desired_min_tx_usec
configured desired min tx interval (microseconds)
vlib_main_t vlib_node_runtime_t * node
bfd_auth_key_t * next_key
set to next key to use if delayed switch is enabled - in that case the key is switched when first inc...
__clib_export u32 *TW() tw_timer_expire_timers_vec(TWT(tw_timer_wheel) *tw, f64 now, u32 *vec)
void bfd_pkt_set_version(bfd_pkt_t *pkt, int version)
bfd_hop_type_e hop_type
BFD hop type.
u64 detection_time_nsec
detection time
__clib_export void TW() tw_timer_update(TWT(tw_timer_wheel) *tw, u32 handle, u64 interval)
Update a tw timer.
u32 local_discr
local discriminator
u32 conf_key_id
global configuration key ID
@ VNET_SW_INTERFACE_FLAG_ADMIN_UP
#define pool_put(P, E)
Free an object E in pool P.
clib_spinlock_t lock
lock to protect data structures
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
static void bfd_notify_listeners(bfd_main_t *bm, bfd_listen_event_e event, const bfd_session_t *bs)
@ VNET_HW_INTERFACE_FLAG_LINK_UP
vl_api_dhcp_client_state_t state
const char * bfd_poll_state_string(bfd_poll_state_e state)
static vlib_node_registration_t bfd_process_node
(constructor) VLIB_REGISTER_NODE (bfd_process_node)
#define BFD_DEFAULT_DESIRED_MIN_TX_USEC
default, slow transmission interval for BFD packets, per spec at least 1s
u32 * session_by_disc
hashmap - bfd session by discriminator
u64 transmit_interval_nsec
transmit interval
@ BFD_EVENT_CONFIG_CHANGED
void bfd_register_listener(bfd_notify_fn_t fn)
Register a callback function to receive session notifications.
static void bfd_set_remote_required_min_rx(bfd_main_t *bm, bfd_session_t *bs, u64 now, u32 remote_required_min_rx_usec)
u64 effective_required_min_rx_nsec
effective required min rx interval (nsec)
u32 local_seq_number
sequence number incremented occasionally or always (if meticulous)
u8 bfd_pkt_get_auth_present(const bfd_pkt_t *pkt)
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)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
static void bfd_add_transport_layer(vlib_main_t *vm, u32 bi, bfd_session_t *bs)
static f64 random_f64(u32 *seed)
Generate f64 random number in the interval [0,1].
u64 event_time_nsec
next event time in nsec for this session (0 if no event)
#define vlib_log_info(...)
static u64 bfd_calc_echo_checksum(u32 discriminator, u64 expire_time, u32 secret)
static void bfd_set_defaults(bfd_main_t *bm, bfd_session_t *bs)
void bfd_put_session(bfd_main_t *bm, bfd_session_t *bs)
#define vlib_log_err(...)
static int bfd_verify_pkt_auth_key(vlib_main_t *vm, const bfd_pkt_t *pkt, u32 pkt_size, bfd_session_t *bs, u8 bfd_key_id, bfd_auth_key_t *auth_key)
#define hash_unset(h, key)
static void bfd_calc_next_tx(bfd_main_t *bm, bfd_session_t *bs, u64 now)
u8 next_bfd_key_id
key ID to use when switched to next_key
u64 config_required_min_rx_nsec
configured required min rx interval (nsec)
u64 config_desired_min_tx_nsec
configured desired min tx interval (nsec)
static void bfd_add_sha1_auth_section(vlib_main_t *vm, vlib_buffer_t *b, bfd_session_t *bs)
static u32 random_u32(u32 *seed)
32-bit random number generator
u32 bs_idx
index in bfd_main.sessions pool
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
static void bfd_set_state(vlib_main_t *vm, bfd_main_t *bm, bfd_session_t *bs, bfd_state_e new_state, int handling_wakeup)
static int bfd_transport_control_frame(vlib_main_t *vm, u32 bi, bfd_session_t *bs)
bfd_session_t * bfd_get_session(bfd_main_t *bm, bfd_transport_e t)
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type,...
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
static void bfd_set_diag(bfd_session_t *bs, bfd_diag_code_e code)
int bfd_add_udp6_transport(vlib_main_t *vm, u32 bi, const bfd_session_t *bs, int is_echo)
u64 bfd_process_next_wakeup_nsec
When the bfd process is supposed to wake up next.
u32 vnet_crypto_process_ops(vlib_main_t *vm, vnet_crypto_op_t ops[], u32 n_ops)
u8 remote_detect_mult
remote detect multiplier
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void bfd_pkt_set_state(bfd_pkt_t *pkt, int value)
u64 remote_min_echo_rx_usec
remote min echo rx interval (microseconds)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static __clib_warn_unused_result u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
u32 random_seed
for generating random numbers
u64 poll_state_start_or_timeout_nsec
helper for delayed poll sequence - marks either start of running poll sequence or timeout,...
static void bfd_rpc_notify_listeners_cb(const bfd_rpc_notify_listeners_t *a)
static void bfd_lock_check(bfd_main_t *bm)
vnet_main_t * vnet_get_main(void)
static void bfd_send_periodic(vlib_main_t *vm, vlib_node_runtime_t *rt, bfd_main_t *bm, bfd_session_t *bs, u64 now)
static void bfd_send_echo(vlib_main_t *vm, vlib_node_runtime_t *rt, bfd_main_t *bm, bfd_session_t *bs, u64 now)
static_always_inline uword vlib_get_thread_index(void)
static int bfd_auth_type_is_meticulous(bfd_auth_type_e auth_type)
bfd_state_e local_state
session state
static u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.
BFD protocol declarations.
static void bfd_session_switch_auth_to_next(bfd_session_t *bs)
u64 remote_min_rx_nsec
remote min rx interval (nsec)
u8 * format_bfd_auth_key(u8 *s, va_list *args)
static int bfd_echo_add_transport_layer(vlib_main_t *vm, u32 bi, bfd_session_t *bs)
u32 bfd_nsec_to_usec(u64 nsec)
int bfd_add_udp4_transport(vlib_main_t *vm, u32 bi, const bfd_session_t *bs, int is_echo)
u32 remote_seq_number
remote sequence number
const char * bfd_auth_type_str(bfd_auth_type_e auth_type)
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
vlib_thread_main_t vlib_thread_main
void bfd_pkt_set_diag_code(bfd_pkt_t *pkt, int value)
int bfd_transport_udp4(vlib_main_t *vm, u32 bi, const struct bfd_session_s *bs)
transport packet over udpv4
bfd_session_t * sessions
pool of bfd sessions context data
static void bfd_calc_next_echo_tx(bfd_main_t *bm, bfd_session_t *bs, u64 now)
void bfd_event(bfd_main_t *bm, bfd_session_t *bs)
static void bfd_recalc_tx_interval(bfd_main_t *bm, bfd_session_t *bs)
unsigned bfd_auth_type_supported(bfd_auth_type_e auth_type)
u32 bfd_process_node_index
background process node index
static void bfd_set_poll_state(bfd_session_t *bs, bfd_poll_state_e state)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
int bfd_process_wakeup_events_in_flight
Number of event wakeup RPCs in flight.
__clib_export void TW() tw_timer_wheel_init(TWT(tw_timer_wheel) *tw, void *expired_timer_callback, f64 timer_interval_in_seconds, u32 max_expirations)
Initialize a tw timer wheel template instance.
#define vlib_log_debug(...)
bfd_auth_key_t * curr_key
current key in use
static u64 clib_xxhash(u64 key)
u8 remote_seq_number_known
set to 1 if remote sequence number is known
static clib_error_t * bfd_sw_interface_up_down(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
#define vlib_log_crit(...)
static void bfd_recalc_detection_time(bfd_main_t *bm, bfd_session_t *bs)
struct _vlib_node_registration vlib_node_registration_t
u64 bfd_process_wakeup_event_start_nsec
The timestamp of last wakeup event being sent.
u8 * bfd_input_format_trace(u8 *s, va_list *args)
u16 current_length
Nbytes between current data and the end of this buffer.
void bfd_on_timeout(vlib_main_t *vm, vlib_node_runtime_t *rt, bfd_main_t *bm, bfd_session_t *bs, u64 now)
u64 tx_timeout_nsec
next time at which to transmit a packet
const char * bfd_diag_code_string(bfd_diag_code_e diag)
void bfd_pkt_set_final(bfd_pkt_t *pkt)
u32 * auth_key_by_conf_key_id
hashmap - index in pool auth_keys by conf_key_id
#define BFD_TW_TPS
timing wheel tick-rate, 1ms should be good enough
u32 use_count
keeps track of how many sessions reference this key
void bfd_pkt_set_auth_present(bfd_pkt_t *pkt)
bfd_session_t * bfd_find_session_by_disc(bfd_main_t *bm, u32 disc)
u64 bfd_process_wakeup_event_delay_nsec
The time it took the last wakeup event to make it to handling.
u8 curr_bfd_key_id
current key ID sent out in bfd packet
u8 bfd_pkt_get_state(const bfd_pkt_t *pkt)
__clib_export u32 TW() tw_timer_start(TWT(tw_timer_wheel) *tw, u32 user_id, u32 timer_id, u64 interval)
Start a Tw Timer.
#define BFD_REQUIRED_MIN_RX_USEC_WHILE_ECHO
minimum required min rx set locally when echo function is used, per spec should be set to at least 1s
int bfd_verify_pkt_common(const bfd_pkt_t *pkt)
verify bfd packet - common checks
static void bfd_on_config_change(vlib_main_t *vm, vlib_node_runtime_t *rt, bfd_main_t *bm, bfd_session_t *bs, u64 now)
u8 local_detect_mult
configured detect multiplier
u64 echo_tx_timeout_nsec
next time at which to transmit echo packet
int bfd_verify_pkt_auth(vlib_main_t *vm, const bfd_pkt_t *pkt, u16 pkt_size, bfd_session_t *bs)
verify bfd packet - authentication
u32 bfd_max_key_len_for_auth_type(bfd_auth_type_e auth_type)
get the maximum length of key data for given auth type
static int bfd_verify_pkt_auth_key_sha1(vlib_main_t *vm, const bfd_pkt_t *pkt, u32 pkt_size, bfd_session_t *bs, u8 bfd_key_id, bfd_auth_key_t *auth_key)
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
static void bfd_unlock(bfd_main_t *bm)
description fragment has unexpected format
bfd_diag_code_e local_diag
local diagnostics
static void bfd_init_control_frame(bfd_main_t *bm, bfd_session_t *bs, vlib_buffer_t *b)
u8 bfd_pkt_get_poll(const bfd_pkt_t *pkt)
u8 bfd_pkt_get_demand(const bfd_pkt_t *pkt)
#define VLIB_INIT_FUNCTION(x)
u8 bfd_pkt_get_version(const bfd_pkt_t *pkt)
bfd_session_t * bfd_find_session_by_idx(bfd_main_t *bm, uword bs_idx)
bfd_notify_fn_t * listeners
vector of callback notification functions
u8 remote_demand
1 if remote system sets demand mode, 0 otherwise
VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION(bfd_hw_interface_up_down)
#define vec_foreach(var, vec)
Vector iterator.
u32 tw_id
timing wheel internal id used to manipulate timer (if set)
void bfd_init_final_control_frame(vlib_main_t *vm, vlib_buffer_t *b, bfd_main_t *bm, bfd_session_t *bs, int is_local)
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
bfd_state_e remote_state
remote session state
static uword pool_elts(void *v)
Number of active elements in a pool.
vlib_log_class_t log_class
log class
void bfd_session_set_flags(vlib_main_t *vm, bfd_session_t *bs, u8 admin_up_down)
vnet_api_error_t bfd_auth_deactivate(bfd_session_t *bs, u8 is_delayed)
u64 nsec_per_tw_tick
how many nanoseconds is one timing wheel tick
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u8 bfd_pkt_get_control_plane_independent(const bfd_pkt_t *pkt)
u64 remote_min_echo_rx_nsec
remote min echo rx interval (nsec)
vnet_api_error_t bfd_auth_del_key(u32 conf_key_id)
delete existing authentication key
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
vnet_interface_output_runtime_t * rt
u8 is_delayed
set to 1 if delayed action is pending, which might be activation of authentication,...
u64 min_required_min_rx_while_echo_nsec
minimum required min rx while echo function is active - nsec
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
bfd_poll_state_e poll_state
state info regarding poll sequence
static void bfd_rpc_event_cb(const bfd_rpc_event_t *a)
u64 default_desired_min_tx_nsec
default desired min tx in nsec
static clib_error_t * bfd_hw_interface_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
int bfd_consume_echo_pkt(vlib_main_t *vm, bfd_main_t *bm, vlib_buffer_t *b)
int bfd_udp_is_echo_available(bfd_transport_e transport)
check if the bfd udp layer is echo-capable at this time
static u64 bfd_time_now_nsec(vlib_main_t *vm, f64 *vm_time)
static void bfd_set_timer(bfd_main_t *bm, bfd_session_t *bs, u64 now, int handling_wakeup)
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(bfd_sw_interface_up_down)
static void bfd_check_rx_timeout(vlib_main_t *vm, bfd_main_t *bm, bfd_session_t *bs, u64 now, int handling_wakeup)
static void vlib_buffer_free_one(vlib_main_t *vm, u32 buffer_index)
Free one buffer Shorthand to free a single buffer chain.
void bfd_consume_pkt(vlib_main_t *vm, bfd_main_t *bm, const bfd_pkt_t *pkt, u32 bs_idx)
const char * bfd_state_string(bfd_state_e state)
static f64 vlib_time_now(vlib_main_t *vm)
static void bfd_notify_listeners_rpc(u32 bs_idx)
bfd_auth_type_e auth_type
authentication type for this key
u8 bfd_pkt_get_multipoint(const bfd_pkt_t *pkt)
u64 remote_min_rx_usec
remote min rx interval (microseconds)
struct bfd_session_s::@149 auth
authentication information
u32 config_required_min_rx_usec
configured required min rx interval (microseconds)
static void bfd_set_remote_required_min_echo_rx(bfd_main_t *bm, bfd_session_t *bs, u64 now, u32 remote_required_min_echo_rx_usec)
vl_api_interface_index_t sw_if_index
u8 key[20]
key data directly usable for bfd purposes - already padded with zeroes (so we don't need the actual l...
static int bfd_transport_echo(vlib_main_t *vm, u32 bi, bfd_session_t *bs)
u8 * format_bfd_session(u8 *s, va_list *args)
bfd_auth_key_t * auth_keys
pool of authentication keys
u32 echo_secret
secret used for calculating/checking checksum of echo packets
#define STRUCT_SIZE_OF(t, f)
int bfd_transport_udp6(vlib_main_t *vm, u32 bi, const struct bfd_session_s *bs)
transport packet over udpv6
static void bfd_event_rpc(u32 bs_idx)
u64 echo_last_tx_nsec
timestamp of last echo packet transmitted
static int bfd_is_echo_possible(bfd_session_t *bs)
u64 echo_transmit_interval_nsec
transmit interval for echo packets
static void bfd_set_effective_desired_min_tx(bfd_main_t *bm, bfd_session_t *bs, u64 now, u64 desired_min_tx_nsec)
VLIB buffer representation.
u64 echo_last_rx_nsec
timestamp of last echo packet received
u8 echo
1 is echo function is active, 0 otherwise
#define VLIB_REGISTER_NODE(x,...)
u8 * format_bfd_session_brief(u8 *s, va_list *args)
static uword random_default_seed(void)
Default random seed (unix/linux user-mode)
vnet_api_error_t bfd_auth_set_key(u32 conf_key_id, u8 auth_type, u8 key_len, const u8 *key_data)
create or modify bfd authentication key
vl_api_wireguard_peer_flags_t flags