summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/manpages/frr-fabricd.rst4
-rw-r--r--doc/user/fabricd.rst17
-rw-r--r--isisd/isis_circuit.c9
-rw-r--r--isisd/isis_main.c16
-rw-r--r--isisd/isisd.c19
-rw-r--r--isisd/isisd.h4
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);