From: Alan T. DeKok Date: Thu, 2 Mar 2023 22:37:08 +0000 (-0500) Subject: add "event list set" function fort BFD X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5defe28a70c97b8b32fbefcf7fdc9129f8f842e;p=thirdparty%2Ffreeradius-server.git add "event list set" function fort BFD and use it to bootstrap the state machine. --- diff --git a/src/listen/bfd/proto_bfd_udp.c b/src/listen/bfd/proto_bfd_udp.c index 7fb0704f7de..3c86e66abdd 100644 --- a/src/listen/bfd/proto_bfd_udp.c +++ b/src/listen/bfd/proto_bfd_udp.c @@ -439,6 +439,34 @@ static fr_client_t *mod_client_find(fr_listen_t *li, fr_ipaddr_t const *ipaddr, return fr_rb_find(inst->peers, &(fr_client_t) { .ipaddr = *ipaddr, .proto = IPPROTO_UDP }); } +/** Set the event list for a new socket + * + * @param[in] li the listener + * @param[in] el the event list + * @param[in] nr context from the network side + */ +static void mod_event_list_set(fr_listen_t *li, fr_event_list_t *el, UNUSED void *nr) +{ + proto_bfd_udp_t *inst = talloc_get_type_abort(li->app_io_instance, proto_bfd_udp_t); + proto_bfd_udp_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_bfd_udp_thread_t); + fr_rb_iter_inorder_t iter; + proto_bfd_peer_t *peer; + + inst->el = el; + + /* + * Walk over the list of peers, associating them with this listener. + */ + for (peer = fr_rb_iter_init_inorder(&iter, inst->peers); + peer != NULL; + peer = fr_rb_iter_next_inorder(&iter)) { + if (peer->inst != inst) continue; + + bfd_session_start(peer, el, thread->sockfd); + } +} + + fr_app_io_t proto_bfd_udp = { .common = { .magic = MODULE_MAGIC_INIT, @@ -456,6 +484,7 @@ fr_app_io_t proto_bfd_udp = { .write = mod_write, .fd_set = mod_fd_set, .network_get = mod_network_get, + .event_list_set = mod_event_list_set, .client_find = mod_client_find, .get_name = mod_name, }; diff --git a/src/listen/bfd/session.c b/src/listen/bfd/session.c index 27ed565b256..4972c3fed0b 100644 --- a/src/listen/bfd/session.c +++ b/src/listen/bfd/session.c @@ -904,14 +904,12 @@ static int bfd_socket_parse(CONF_SECTION *cs, rad_listen_t *this) } #endif -//static int bfd_start_packets(proto_bfd_peer_t *session); -static int bfd_start_control(proto_bfd_peer_t *session); +static void bfd_start_packets(proto_bfd_peer_t *session); +static void bfd_start_control(proto_bfd_peer_t *session); static int bfd_stop_control(proto_bfd_peer_t *session); //static int bfd_process(proto_bfd_peer_t *session, bfd_packet_t *bfd); static void bfd_set_timeout(proto_bfd_peer_t *session, fr_time_t when); -static int bfd_start_packets(proto_bfd_peer_t *session); - static const char *bfd_state[] = { "admin-down", "down", @@ -997,7 +995,7 @@ static void bfd_send_packet(UNUSED fr_event_list_t *el, UNUSED fr_time_t now, vo /* * Start sending packets. */ -static int bfd_start_packets(proto_bfd_peer_t *session) +static void bfd_start_packets(proto_bfd_peer_t *session) { uint64_t interval, base; uint64_t jitter; @@ -1035,17 +1033,15 @@ static int bfd_start_packets(proto_bfd_peer_t *session) bfd_send_packet, session) < 0) { fr_assert("Failed to insert event" == NULL); } - - return 0; } /* * Start polling for the peer. */ -static int bfd_start_poll(proto_bfd_peer_t *session) +static void bfd_start_poll(proto_bfd_peer_t *session) { - if (session->doing_poll) return 0; + if (session->doing_poll) return; /* * Already sending packets. Reset the timers and set the @@ -1061,7 +1057,7 @@ static int bfd_start_poll(proto_bfd_peer_t *session) * Send POLL packets, even if we're not sending CONTROL * packets. */ - return bfd_start_packets(session); + bfd_start_packets(session); } /* @@ -1214,7 +1210,7 @@ static int bfd_stop_control(proto_bfd_peer_t *session) return 1; } -static int bfd_start_control(proto_bfd_peer_t *session) +static void bfd_start_control(proto_bfd_peer_t *session) { /* * @todo - change our discriminator? @@ -1223,9 +1219,20 @@ static int bfd_start_control(proto_bfd_peer_t *session) /* * We don't expect to see remote packets, so don't do anything. */ - if (fr_time_delta_unwrap(session->remote_min_rx_interval) == 0) return 0; + if (fr_time_delta_unwrap(session->remote_min_rx_interval) == 0) return; - if ((session->remote_disc == 0) && session->passive) return 0; + /* + * @todo - support passive. From 6.1: + * + * A system may take either an Active role or a Passive role in session + * initialization. A system taking the Active role MUST send BFD + * Control packets for a particular session, regardless of whether it + * has received any BFD packets for that session. A system taking the + * Passive role MUST NOT begin sending BFD packets for a particular + * session until it has received a BFD packet for that session, and thus + * has learned the remote system's discriminator value. + */ + if ((session->remote_disc == 0) && session->passive) return; /* * We were asked to go "up" when we were alread "up" @@ -1238,17 +1245,18 @@ static int bfd_start_control(proto_bfd_peer_t *session) session->client.shortname); fr_assert(0 == 1); bfd_stop_control(session); - return 0; + return; } bfd_set_timeout(session, session->last_recv); - if (session->ev_packet) return 0; + if (session->ev_packet) return; + /* * Start sending packets. */ - return bfd_start_packets(session); + bfd_start_packets(session); } @@ -1258,7 +1266,7 @@ int bfd_session_init(proto_bfd_peer_t *session) session->local_disc = fr_rand(); session->remote_disc = 0; session->local_diag = BFD_DIAG_NONE; - session->remote_min_rx_interval = fr_time_delta_wrap(0); + session->remote_min_rx_interval = fr_time_delta_wrap(1); session->remote_demand_mode = false; session->recv_auth_seq = 0; session->xmit_auth_seq = fr_rand(); @@ -1278,3 +1286,15 @@ int bfd_session_init(proto_bfd_peer_t *session) return 0; } + +void bfd_session_start(proto_bfd_peer_t *session, fr_event_list_t *el, int sockfd) +{ + DEBUG("Starting BFD for %s", session->client.shortname); + + fr_assert(!session->el); + + session->el = el; + session->sockfd = sockfd; + + bfd_start_control(session); +} diff --git a/src/listen/bfd/session.h b/src/listen/bfd/session.h index e783254c3ef..b934f84fef9 100644 --- a/src/listen/bfd/session.h +++ b/src/listen/bfd/session.h @@ -26,3 +26,5 @@ #include "proto_bfd.h" int bfd_session_init(proto_bfd_peer_t *session); + +void bfd_session_start(proto_bfd_peer_t *session, fr_event_list_t *el, int sockfd);