From: Alan T. DeKok Date: Sun, 26 Feb 2023 23:13:14 +0000 (-0500) Subject: start of process_bfd state machine X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5cae4cad99e3c583e76d2ea5d6470325e04431e8;p=thirdparty%2Ffreeradius-server.git start of process_bfd state machine --- diff --git a/share/dictionary/bfd/dictionary b/share/dictionary/bfd/dictionary index 1c92670c7fc..69c61c74e8c 100644 --- a/share/dictionary/bfd/dictionary +++ b/share/dictionary/bfd/dictionary @@ -11,6 +11,7 @@ PROTOCOL BFD 13 BEGIN-PROTOCOL BFD +$INCLUDE dictionary.freeradius.internal $INCLUDE dictionary.rfc5880 END-PROTOCOL BFD diff --git a/share/dictionary/bfd/dictionary.freeradius.internal b/share/dictionary/bfd/dictionary.freeradius.internal new file mode 100644 index 00000000000..268fda12f1a --- /dev/null +++ b/share/dictionary/bfd/dictionary.freeradius.internal @@ -0,0 +1,31 @@ +# -*- text -*- +# Copyright (C) 2023 The FreeRADIUS Server project and contributors +# This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0 +# Version $Id$ +############################################################################## +# +# Internal FreeRADIUS BFD dictionary. +# +# $Id$ +# +############################################################################## + +# +# BFD States +# +FLAGS internal + +# +# These are the states that the other end sends us. +# +DEFINE Packet-Type uint32 +VALUE Packet-Type Admin-Down 0 +VALUE Packet-Type Down 1 +VALUE Packet-Type Init 2 +VALUE Packet-Type Up 3 + +# +# This is our version of our current link state, which is copied +# to the request packet. +# +DEFINE Link-State uint32 enum=Packet-Type diff --git a/src/process/bfd/all.mk b/src/process/bfd/all.mk new file mode 100644 index 00000000000..1d829dd541f --- /dev/null +++ b/src/process/bfd/all.mk @@ -0,0 +1,10 @@ +TARGETNAME := process_bfd + +ifneq "$(TARGETNAME)" "" +TARGET := $(TARGETNAME)$(L) +endif + +SOURCES := base.c + +TGT_PREREQS := libfreeradius-util$(L) + diff --git a/src/process/bfd/base.c b/src/process/bfd/base.c new file mode 100644 index 00000000000..2789c6c7b6c --- /dev/null +++ b/src/process/bfd/base.c @@ -0,0 +1,206 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * $Id$ + * @file src/process/bfd/base.c + * @brief BFD processing. + * + * @copyright 2023 Network RADIUS SAS (legal@networkradius.com) + */ +#include +#include + +static fr_dict_t const *dict_bfd; + +extern fr_dict_autoload_t process_bfd_dict[]; +fr_dict_autoload_t process_bfd_dict[] = { + { .out = &dict_bfd, .proto = "bfd" }, + { NULL } +}; + +static fr_dict_attr_t const *attr_packet_type; + +extern fr_dict_attr_autoload_t process_bfd_dict_attr[]; +fr_dict_attr_autoload_t process_bfd_dict_attr[] = { + { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_bfd}, + { NULL } +}; + +#define SECTION(_x) \ + CONF_SECTION *recv_ ## _x; \ + CONF_SECTION *send_ ## _x + +typedef struct { + uint64_t nothing; // so that the next field isn't at offset 0 + + SECTION(admin_down); + SECTION(down); + SECTION(init); + SECTION(up); +} process_bfd_sections_t; + +typedef struct { + bool unused; + + process_bfd_sections_t sections; +} process_bfd_t; + +typedef enum { + FR_BFD_ADMIN_DOWN, + FR_BFD_DOWN, + FR_BFD_INIT, + FR_BFD_UP, +} fr_bfd_packet_code_t; +#define FR_BFD_CODE_MAX (4) + +#define FR_BFD_PACKET_CODE_VALID(_code) (_code < FR_BFD_CODE_MAX) + +#define PROCESS_PACKET_TYPE fr_bfd_packet_code_t +#define PROCESS_CODE_MAX FR_BFD_CODE_MAX +#define PROCESS_PACKET_CODE_VALID FR_BFD_PACKET_CODE_VALID +#define PROCESS_INST process_bfd_t + +#define PROCESS_SEND_RECV (1) + +#include + +/* + * recv FOO + */ +static fr_process_state_t const process_state_packet[] = { + [ FR_BFD_ADMIN_DOWN ] = { + .default_reply = FR_BFD_DOWN, + .rcode = RLM_MODULE_NOOP, + .recv = recv_generic, + .resume = resume_recv_generic, + .section_offset = offsetof(process_bfd_sections_t, recv_admin_down), + }, + + [ FR_BFD_DOWN ] = { + .default_reply = FR_BFD_DOWN, + .rcode = RLM_MODULE_NOOP, + .recv = recv_generic, + .resume = resume_recv_generic, + .section_offset = offsetof(process_bfd_sections_t, recv_down), + }, + + [ FR_BFD_INIT ] = { + .default_reply = FR_BFD_UP, + .rcode = RLM_MODULE_NOOP, + .recv = recv_generic, + .resume = resume_recv_generic, + .section_offset = offsetof(process_bfd_sections_t, recv_init), + }, + + [ FR_BFD_UP ] = { + .default_reply = FR_BFD_UP, + .rcode = RLM_MODULE_NOOP, + .recv = recv_generic, + .resume = resume_recv_generic, + .section_offset = offsetof(process_bfd_sections_t, recv_up), + }, +}; + +/* + * send FOO + */ +static fr_process_state_t const process_state_reply[] = { + [ FR_BFD_ADMIN_DOWN ] = { + .rcode = RLM_MODULE_NOOP, + .send = send_generic, + .resume = resume_send_generic, + .section_offset = offsetof(process_bfd_sections_t, send_admin_down), + }, + + [ FR_BFD_DOWN ] = { + .rcode = RLM_MODULE_NOOP, + .send = send_generic, + .resume = resume_send_generic, + .section_offset = offsetof(process_bfd_sections_t, send_down), + }, + + [ FR_BFD_INIT ] = { + .rcode = RLM_MODULE_NOOP, + .send = send_generic, + .resume = resume_send_generic, + .section_offset = offsetof(process_bfd_sections_t, send_init), + }, + + [ FR_BFD_UP ] = { + .rcode = RLM_MODULE_NOOP, + .send = send_generic, + .resume = resume_send_generic, + .section_offset = offsetof(process_bfd_sections_t, send_up), + }, +}; + +static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request) +{ + fr_process_state_t const *state; + + PROCESS_TRACE; + + (void)talloc_get_type_abort_const(mctx->inst->data, process_bfd_t); + fr_assert(PROCESS_PACKET_CODE_VALID(request->packet->code)); + + request->component = "bfd"; + request->module = NULL; + fr_assert(request->dict == dict_bfd); + + UPDATE_STATE_RECV(packet); + + return state->recv(p_result, mctx, request); +} + +/* + * We send and receive the same packet types. + */ +#define SEND_RECV(_x, _y) \ + { \ + .name = "recv", \ + .name2 = _x, \ + .component = MOD_POST_AUTH, \ + .offset = PROCESS_CONF_OFFSET(recv_ ## _y), \ + }, \ + { \ + .name = "send", \ + .name2 = _x, \ + .component = MOD_POST_AUTH, \ + .offset = PROCESS_CONF_OFFSET(send_ ## _y), \ + } + +static const virtual_server_compile_t compile_list[] = { + SEND_RECV("Admin-Down", admin_down), + SEND_RECV("Down", down), + SEND_RECV("Init", init), + SEND_RECV("Up", up), + + COMPILE_TERMINATOR +}; + + +extern fr_process_module_t process_bfd; +fr_process_module_t process_bfd = { + .common = { + .magic = MODULE_MAGIC_INIT, + .name = "bfd", + .inst_size = sizeof(process_bfd_t), + }, + .process = mod_process, + .compile_list = compile_list, + .dict = &dict_bfd, +};