From 84d99ad8a6ba975f881fe272646aca18f0e4ffc7 Mon Sep 17 00:00:00 2001 From: Gabriel Goller Date: Tue, 25 Feb 2025 10:24:58 +0100 Subject: [PATCH] fabricd: add option to treat dummy interfaces as loopback interfaces Enable dummy-interfaces to be used as router-id interfaces in openfabric networks. This allows multiple openfabric routers with different router-ids on a single node when using IP unnumbered setup (interfaces without IPs configured). Previously we were limited by having a single loopback interface, allowing only one openfabric router per node. Signed-off-by: Gabriel Goller --- doc/manpages/frr-fabricd.rst | 4 ++++ doc/user/fabricd.rst | 17 ++++++++++++----- isisd/isis_circuit.c | 9 +++++---- isisd/isis_main.c | 16 +++++++++++++--- isisd/isisd.c | 19 +++++++++++++++++++ isisd/isisd.h | 4 ++++ 6 files changed, 57 insertions(+), 12 deletions(-) diff --git a/doc/manpages/frr-fabricd.rst b/doc/manpages/frr-fabricd.rst index c14c07661e..7e6d253887 100644 --- a/doc/manpages/frr-fabricd.rst +++ b/doc/manpages/frr-fabricd.rst @@ -21,6 +21,10 @@ OPTIONS available for the |DAEMON| command: .. include:: common-options.rst +.. option:: --dummy_as_loopback + + Treat dummy interfaces as loopback interfaces. + FILES ===== diff --git a/doc/user/fabricd.rst b/doc/user/fabricd.rst index 48d264f30e..23de6731e2 100644 --- a/doc/user/fabricd.rst +++ b/doc/user/fabricd.rst @@ -15,11 +15,18 @@ FRR implements OpenFabric in a daemon called *fabricd* Configuring fabricd =================== -There are no *fabricd* specific options. Common options can be specified -(:ref:`common-invocation-options`) to *fabricd*. *fabricd* needs to acquire -interface information from *zebra* in order to function. Therefore *zebra* must -be running before invoking *fabricd*. Also, if *zebra* is restarted then *fabricd* -must be too. +*fabricd* accepts all common invocations (:ref:`common-invocation-options`) and +the following specific options. + +.. program:: fabricd + +.. option:: --dummy_as_loopback + + Treat dummy interfaces as loopback interfaces. + +*fabricd* needs to acquire interface information from *zebra* in order to +function. Therefore *zebra* must be running before invoking *fabricd*. Also, if +*zebra* is restarted then *fabricd* must be too. Like other daemons, *fabricd* configuration is done in an OpenFabric specific configuration file :file:`fabricd.conf`. diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index 5b62d3c518..eed2c52552 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -491,16 +491,17 @@ void isis_circuit_if_add(struct isis_circuit *circuit, struct interface *ifp) { struct connected *conn; - if (if_is_broadcast(ifp)) { + if (if_is_loopback(ifp) || (isis_option_check(ISIS_OPT_DUMMY_AS_LOOPBACK) && + CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_DUMMY))) { + circuit->circ_type = CIRCUIT_T_LOOPBACK; + circuit->is_passive = 1; + } else if (if_is_broadcast(ifp)) { if (fabricd || circuit->circ_type_config == CIRCUIT_T_P2P) circuit->circ_type = CIRCUIT_T_P2P; else circuit->circ_type = CIRCUIT_T_BROADCAST; } else if (if_is_pointopoint(ifp)) { circuit->circ_type = CIRCUIT_T_P2P; - } else if (if_is_loopback(ifp)) { - circuit->circ_type = CIRCUIT_T_LOOPBACK; - circuit->is_passive = 1; } else { /* It's normal in case of loopback etc. */ if (IS_DEBUG_EVENTS) diff --git a/isisd/isis_main.c b/isisd/isis_main.c index b7ed8f7605..0d9b3df39c 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -80,9 +80,12 @@ struct zebra_privs_t isisd_privs = { .cap_num_p = array_size(_caps_p), .cap_num_i = 0}; +#define OPTION_DUMMY_AS_LOOPBACK 2000 + /* isisd options */ static const struct option longopts[] = { {"int_num", required_argument, NULL, 'I'}, + {"dummy_as_loopback", no_argument, NULL, OPTION_DUMMY_AS_LOOPBACK}, {0}}; /* Master of threads. */ @@ -269,15 +272,16 @@ int main(int argc, char **argv, char **envp) { int opt; int instance = 1; + bool dummy_as_loopback = false; #ifdef FABRICD frr_preinit(&fabricd_di, argc, argv); #else frr_preinit(&isisd_di, argc, argv); #endif - frr_opt_add( - "I:", longopts, - " -I, --int_num Set instance number (label-manager)\n"); + frr_opt_add("I:", longopts, + " -I, --int_num Set instance number (label-manager).\n" + " --dummy_as_loopback Treat dummy interfaces like loopback interfaces.\n"); /* Command line argument treatment. */ while (1) { @@ -295,6 +299,9 @@ int main(int argc, char **argv, char **envp) zlog_err("Instance %i out of range (1..%u)", instance, (unsigned short)-1); break; + case OPTION_DUMMY_AS_LOOPBACK: + dummy_as_loopback = true; + break; default: frr_help_exit(1); } @@ -311,6 +318,9 @@ int main(int argc, char **argv, char **envp) /* thread master */ isis_master_init(frr_init()); master = im->master; + if (dummy_as_loopback) + isis_option_set(ISIS_OPT_DUMMY_AS_LOOPBACK); + /* * initializations */ diff --git a/isisd/isisd.c b/isisd/isisd.c index fed6d3c6dc..a0faf31221 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -116,6 +116,25 @@ int show_isis_neighbor_common(struct vty *, struct json_object *json, int clear_isis_neighbor_common(struct vty *, const char *id, const char *vrf_name, bool all_vrf); + +/* ISIS global flag manipulation. */ +int isis_option_set(int flag) +{ + switch (flag) { + case ISIS_OPT_DUMMY_AS_LOOPBACK: + SET_FLAG(im->options, flag); + break; + default: + return -1; + } + return 0; +} + +int isis_option_check(int flag) +{ + return CHECK_FLAG(im->options, flag); +} + /* Link ISIS instance to VRF. */ void isis_vrf_link(struct isis *isis, struct vrf *vrf) { diff --git a/isisd/isisd.h b/isisd/isisd.h index 1ae39f0ae9..ae39502023 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -74,7 +74,9 @@ struct isis_master { struct list *isis; /* ISIS thread master. */ struct event_loop *master; + /* Various global options */ uint8_t options; +#define ISIS_OPT_DUMMY_AS_LOOPBACK (1 << 0) }; #define F_ISIS_UNIT_TEST 0x01 @@ -269,6 +271,8 @@ DECLARE_HOOK(isis_area_overload_bit_update, (struct isis_area * area), (area)); void isis_terminate(void); void isis_master_init(struct event_loop *master); void isis_master_terminate(void); +int isis_option_set(int flag); +int isis_option_check(int flag); void isis_vrf_link(struct isis *isis, struct vrf *vrf); void isis_vrf_unlink(struct isis *isis, struct vrf *vrf); struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id); -- 2.39.5