2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2002-12-13 21:15:29 +01:00
|
|
|
/*
|
|
|
|
* OSPFd main routine.
|
|
|
|
* Copyright (C) 1998, 99 Kunihiro Ishiguro, Toshiaki Takada
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
2004-03-16 15:38:36 +01:00
|
|
|
#include <lib/version.h>
|
2021-03-03 21:22:47 +01:00
|
|
|
#include "bfd.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "getopt.h"
|
2023-03-07 20:22:48 +01:00
|
|
|
#include "frrevent.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "prefix.h"
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "if.h"
|
|
|
|
#include "vector.h"
|
|
|
|
#include "vty.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "filter.h"
|
|
|
|
#include "plist.h"
|
|
|
|
#include "stream.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "memory.h"
|
2003-06-04 15:59:38 +02:00
|
|
|
#include "privs.h"
|
2004-01-19 22:31:15 +01:00
|
|
|
#include "sigevent.h"
|
2011-11-25 15:51:48 +01:00
|
|
|
#include "zclient.h"
|
2015-05-22 11:39:58 +02:00
|
|
|
#include "vrf.h"
|
2016-11-13 08:02:23 +01:00
|
|
|
#include "libfrr.h"
|
2019-10-01 22:56:41 +02:00
|
|
|
#include "routemap.h"
|
2023-09-12 13:39:44 +02:00
|
|
|
#include "keychain.h"
|
2024-05-09 13:47:29 +02:00
|
|
|
#include "libagentx.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#include "ospfd/ospfd.h"
|
|
|
|
#include "ospfd/ospf_interface.h"
|
|
|
|
#include "ospfd/ospf_asbr.h"
|
|
|
|
#include "ospfd/ospf_lsa.h"
|
|
|
|
#include "ospfd/ospf_lsdb.h"
|
|
|
|
#include "ospfd/ospf_neighbor.h"
|
|
|
|
#include "ospfd/ospf_dump.h"
|
2018-08-21 14:40:51 +02:00
|
|
|
#include "ospfd/ospf_route.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "ospfd/ospf_zebra.h"
|
|
|
|
#include "ospfd/ospf_vty.h"
|
2015-07-22 21:35:37 +02:00
|
|
|
#include "ospfd/ospf_bfd.h"
|
2021-05-31 15:27:51 +02:00
|
|
|
#include "ospfd/ospf_gr.h"
|
2018-06-19 22:41:28 +02:00
|
|
|
#include "ospfd/ospf_errors.h"
|
2020-07-22 19:31:14 +02:00
|
|
|
#include "ospfd/ospf_ldp_sync.h"
|
2020-10-30 08:44:04 +01:00
|
|
|
#include "ospfd/ospf_routemap_nb.h"
|
2024-04-19 17:33:20 +02:00
|
|
|
#include "ospfd/ospf_apiserver.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2024-01-25 18:10:08 +01:00
|
|
|
#define OSPFD_STATE_NAME "%s/ospfd.json", frr_libstatedir
|
2024-07-10 09:49:51 +02:00
|
|
|
#define OSPFD_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_libstatedir, i
|
2024-01-25 18:10:08 +01:00
|
|
|
|
|
|
|
/* this one includes the path... because the instance number was in the path
|
|
|
|
* before :( ... which totally didn't have a mkdir anywhere.
|
2024-07-10 09:49:51 +02:00
|
|
|
*
|
|
|
|
* ... and libstatedir & runstatedir got switched around while changing this;
|
|
|
|
* for non-instance it read the wrong path, for instance it wrote the wrong
|
|
|
|
* path. (There is no COMPAT2 for non-instance because it was writing to the
|
|
|
|
* right place, i.e. no extra path to check exists from reading a wrong path.)
|
2024-01-25 18:10:08 +01:00
|
|
|
*/
|
2024-07-10 09:49:51 +02:00
|
|
|
#define OSPFD_COMPAT_STATE_NAME "%s/ospfd-gr.json", frr_runstatedir
|
|
|
|
#define OSPFD_COMPAT1_INST_STATE_NAME(i) \
|
2024-01-25 18:10:08 +01:00
|
|
|
"%s-%d/ospfd-gr.json", frr_runstatedir, i
|
2024-07-10 09:49:51 +02:00
|
|
|
#define OSPFD_COMPAT2_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_runstatedir, i
|
2024-01-25 18:10:08 +01:00
|
|
|
|
2003-06-04 15:59:38 +02:00
|
|
|
/* ospfd privileges */
|
2018-03-02 15:20:43 +01:00
|
|
|
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_NET_ADMIN,
|
|
|
|
ZCAP_SYS_ADMIN};
|
2003-06-04 15:59:38 +02:00
|
|
|
|
|
|
|
struct zebra_privs_t ospfd_privs = {
|
2016-12-14 19:30:44 +01:00
|
|
|
#if defined(FRR_USER) && defined(FRR_GROUP)
|
|
|
|
.user = FRR_USER,
|
|
|
|
.group = FRR_GROUP,
|
2003-06-04 15:59:38 +02:00
|
|
|
#endif
|
|
|
|
#if defined(VTY_GROUP)
|
|
|
|
.vty_group = VTY_GROUP,
|
|
|
|
#endif
|
|
|
|
.caps_p = _caps_p,
|
2012-09-26 10:39:10 +02:00
|
|
|
.cap_num_p = array_size(_caps_p),
|
2003-06-04 15:59:38 +02:00
|
|
|
.cap_num_i = 0};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* OSPFd options. */
|
2019-11-20 17:26:59 +01:00
|
|
|
const struct option longopts[] = {
|
|
|
|
{"instance", required_argument, NULL, 'n'},
|
|
|
|
{"apiserver", no_argument, NULL, 'a'},
|
2024-04-19 17:33:20 +02:00
|
|
|
{"apiserver_addr", required_argument, NULL, 'l'},
|
2019-11-20 17:26:59 +01:00
|
|
|
{0}
|
|
|
|
};
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* OSPFd program name */
|
|
|
|
|
|
|
|
/* Master of threads. */
|
2023-03-07 20:14:41 +01:00
|
|
|
struct event_loop *master;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* SIGHUP handler. */
|
2004-01-19 22:31:15 +01:00
|
|
|
static void sighup(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
*: get rid of zlog(*, LOG_LEVEL, ...)
Result of running the following Coccinelle patch + fixups:
<<EOF
/* long-forms: zlog(NULL, <level>, ...)
* => zlog_level(...)
*/
@@
expression list args;
@@
- zlog(NULL, LOG_DEBUG, args)
+ zlog_debug(args)
@@
expression list args;
@@
- zlog(NULL, LOG_NOTICE, args)
+ zlog_notice(args)
@@
expression list args;
@@
- zlog(NULL, LOG_INFO, args)
+ zlog_info(args)
@@
expression list args;
@@
- zlog(NULL, LOG_WARNING, args)
+ zlog_warn(args)
@@
expression list args;
@@
- zlog(NULL, LOG_ERR, args)
+ zlog_err(args)
/* long-forms: zlog(base->log, <level>, ...)
* => zlog_level(...)
*/
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_DEBUG, args)
+ zlog_debug(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_NOTICE, args)
+ zlog_notice(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_INFO, args)
+ zlog_info(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_WARNING, args)
+ zlog_warn(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_ERR, args)
+ zlog_err(args)
EOF
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2016-11-13 04:19:14 +01:00
|
|
|
zlog_info("SIGHUP received");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
/* SIGINT / SIGTERM handler. */
|
2004-01-19 22:31:15 +01:00
|
|
|
static void sigint(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-12-03 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* bgp_main.c: (sigint) Use zlog_notice for termination message.
(main) Use zlog_notice for startup announcement.
* isis_main.c: (sigint,sigterm) Use zlog_notice for termination message.
(terminate) This function should be static, not global.
(main) Use zlog_notice for startup announcement, and remove
ifdef ZEBRA_VERSION.
* version.h.in: Remove declaration for pid_output_lock, this function
is now static, not global.
* pid_output.c: (pid_output_lock) This function should be static, not
global. And remove "old umask" error message, since it was really
an unimportant debug message, not an error.
(pid_output) Need to declare static function pid_output_lock.
* ospf6_main.c: (sigint,sigterm) Use zlog_notice for termination
message.
(main) Remove commented-out call to pid_output_lock (which should
never be called other than from inside pid_output). And use
zlog_notice to print the startup message, which now includes
the vty port.
* ospf_main.c: (sigint) Use zlog_notice for termination message.
(main) Issue a startup announcement using zlog_notice.
* rip_main.c: (sigint) Use zlog_notice for termination message.
(main) Add a startup announcement using zlog_notice.
* ripng_main.c: (sighup) Remove spurious terminating message.
(sigint) Use zlog_notice for termination message.
(main) Issue a startup announcement using zlog_notice.
* main.c: (sigint) Use zlog_notice for termination message.
(main) Add a startup announcement using zlog_notice.
2004-12-03 17:36:46 +01:00
|
|
|
zlog_notice("Terminating on signal");
|
2021-03-03 21:22:47 +01:00
|
|
|
bfd_protocol_integration_set_shutdown(true);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_terminate();
|
2023-11-12 04:57:24 +01:00
|
|
|
|
2020-06-11 17:16:02 +02:00
|
|
|
exit(0);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* SIGUSR1 handler. */
|
2004-01-19 22:31:15 +01:00
|
|
|
static void sigusr1(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-02-23 12:49:45 +01:00
|
|
|
zlog_rotate();
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2021-11-11 20:28:54 +01:00
|
|
|
struct frr_signal_t ospf_signals[] = {
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-01-19 22:31:15 +01:00
|
|
|
.signal = SIGHUP,
|
|
|
|
.handler = &sighup,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.signal = SIGUSR1,
|
|
|
|
.handler = &sigusr1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.signal = SIGINT,
|
|
|
|
.handler = &sigint,
|
|
|
|
},
|
2004-03-22 09:55:25 +01:00
|
|
|
{
|
|
|
|
.signal = SIGTERM,
|
|
|
|
.handler = &sigint,
|
|
|
|
},
|
2004-01-19 22:31:15 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2019-11-20 17:23:04 +01:00
|
|
|
static const struct frr_yang_module_info *const ospfd_yang_modules[] = {
|
2019-11-08 18:41:46 +01:00
|
|
|
&frr_filter_info,
|
2018-07-08 03:04:33 +02:00
|
|
|
&frr_interface_info,
|
2019-10-01 22:56:41 +02:00
|
|
|
&frr_route_map_info,
|
2020-03-11 21:14:08 +01:00
|
|
|
&frr_vrf_info,
|
2020-10-30 08:44:04 +01:00
|
|
|
&frr_ospf_route_map_info,
|
2024-02-24 11:48:40 +01:00
|
|
|
&ietf_key_chain_info,
|
|
|
|
&ietf_key_chain_deviation_info,
|
2018-05-24 01:29:50 +02:00
|
|
|
};
|
|
|
|
|
2024-01-25 18:10:08 +01:00
|
|
|
/* actual paths filled in main() */
|
|
|
|
static char state_path[512];
|
2024-07-10 09:49:51 +02:00
|
|
|
static char state_compat1_path[512];
|
|
|
|
static char state_compat2_path[512];
|
2024-01-25 18:10:08 +01:00
|
|
|
static char *state_paths[] = {
|
|
|
|
state_path,
|
2024-07-10 09:49:51 +02:00
|
|
|
state_compat1_path,
|
|
|
|
state_compat2_path, /* NULLed out if not needed */
|
2024-01-25 18:10:08 +01:00
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
2024-01-25 18:30:10 +01:00
|
|
|
/* clang-format off */
|
|
|
|
FRR_DAEMON_INFO(ospfd, OSPF,
|
|
|
|
.vty_port = OSPF_VTY_PORT,
|
|
|
|
.proghelp = "Implementation of the OSPFv2 routing protocol.",
|
2016-11-13 08:02:23 +01:00
|
|
|
|
2024-01-25 18:30:10 +01:00
|
|
|
.signals = ospf_signals,
|
|
|
|
.n_signals = array_size(ospf_signals),
|
2016-11-13 08:02:23 +01:00
|
|
|
|
2024-01-25 18:30:10 +01:00
|
|
|
.privs = &ospfd_privs,
|
2016-11-13 08:02:23 +01:00
|
|
|
|
2024-01-25 18:30:10 +01:00
|
|
|
.yang_modules = ospfd_yang_modules,
|
|
|
|
.n_yang_modules = array_size(ospfd_yang_modules),
|
2024-01-25 18:10:08 +01:00
|
|
|
|
|
|
|
.state_paths = state_paths,
|
2018-05-24 01:29:50 +02:00
|
|
|
);
|
2024-01-25 18:30:10 +01:00
|
|
|
/* clang-format on */
|
2016-11-13 08:02:23 +01:00
|
|
|
|
2023-06-15 23:50:24 +02:00
|
|
|
/** Max wait time for config to load before accepting hellos */
|
|
|
|
#define OSPF_PRE_CONFIG_MAX_WAIT_SECONDS 600
|
|
|
|
|
|
|
|
static void ospf_config_finish(struct event *t)
|
|
|
|
{
|
|
|
|
zlog_err("OSPF configuration end timer expired after %d seconds.",
|
|
|
|
OSPF_PRE_CONFIG_MAX_WAIT_SECONDS);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ospf_config_start(void)
|
|
|
|
{
|
|
|
|
EVENT_OFF(t_ospf_cfg);
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug("ospfd config start callback received.");
|
|
|
|
event_add_timer(master, ospf_config_finish, NULL,
|
|
|
|
OSPF_PRE_CONFIG_MAX_WAIT_SECONDS, &t_ospf_cfg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ospf_config_end(void)
|
|
|
|
{
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug("ospfd config end callback received.");
|
|
|
|
|
|
|
|
EVENT_OFF(t_ospf_cfg);
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* OSPFd main routine. */
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
2016-11-13 08:02:23 +01:00
|
|
|
frr_preinit(&ospfd_di, argc, argv);
|
2024-04-19 17:33:20 +02:00
|
|
|
frr_opt_add("n:al:", longopts,
|
2016-11-13 08:02:23 +01:00
|
|
|
" -n, --instance Set the instance id\n"
|
2024-04-19 17:33:20 +02:00
|
|
|
" -a, --apiserver Enable OSPF apiserver\n"
|
|
|
|
" -l, --apiserver_addr Set OSPF apiserver bind address\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
int opt;
|
|
|
|
|
2016-11-13 08:02:23 +01:00
|
|
|
opt = frr_getopt(argc, argv, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (opt == EOF)
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
switch (opt) {
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
case 'n':
|
2021-01-28 00:41:07 +01:00
|
|
|
ospfd_di.instance = ospf_instance = atoi(optarg);
|
|
|
|
if (ospf_instance < 1)
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
exit(0);
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
case 0:
|
|
|
|
break;
|
2004-10-13 11:32:48 +02:00
|
|
|
#ifdef SUPPORT_OSPF_API
|
2004-10-11 18:27:03 +02:00
|
|
|
case 'a':
|
|
|
|
ospf_apiserver_enable = 1;
|
|
|
|
break;
|
2024-04-19 17:33:20 +02:00
|
|
|
case 'l':
|
|
|
|
if (inet_pton(AF_INET, optarg, &ospf_apiserver_addr) <=
|
|
|
|
0) {
|
|
|
|
zlog_err("OSPF: Invalid API Server IPv4 address %s specified",
|
|
|
|
optarg);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
break;
|
2004-10-13 11:32:48 +02:00
|
|
|
#endif /* SUPPORT_OSPF_API */
|
2002-12-13 21:15:29 +01:00
|
|
|
default:
|
2016-11-13 08:02:23 +01:00
|
|
|
frr_help_exit(1);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2011-11-25 15:51:48 +01:00
|
|
|
/* Invoked by a priviledged user? -- endo. */
|
|
|
|
if (geteuid() != 0) {
|
|
|
|
errno = EPERM;
|
2016-11-13 08:02:23 +01:00
|
|
|
perror(ospfd_di.progname);
|
2017-07-17 14:03:14 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2024-01-25 18:10:08 +01:00
|
|
|
if (ospf_instance) {
|
|
|
|
snprintf(state_path, sizeof(state_path),
|
|
|
|
OSPFD_INST_STATE_NAME(ospf_instance));
|
2024-07-10 09:49:51 +02:00
|
|
|
snprintf(state_compat1_path, sizeof(state_compat1_path),
|
|
|
|
OSPFD_COMPAT1_INST_STATE_NAME(ospf_instance));
|
|
|
|
snprintf(state_compat2_path, sizeof(state_compat2_path),
|
|
|
|
OSPFD_COMPAT2_INST_STATE_NAME(ospf_instance));
|
2024-01-25 18:10:08 +01:00
|
|
|
} else {
|
|
|
|
snprintf(state_path, sizeof(state_path), OSPFD_STATE_NAME);
|
2024-07-10 09:49:51 +02:00
|
|
|
snprintf(state_compat1_path, sizeof(state_compat1_path),
|
2024-01-25 18:10:08 +01:00
|
|
|
OSPFD_COMPAT_STATE_NAME);
|
2024-07-10 09:49:51 +02:00
|
|
|
/* no COMPAT2 here since it was reading that was broken,
|
|
|
|
* there is no additional path that would've been written
|
|
|
|
*/
|
|
|
|
state_paths[2] = NULL;
|
2024-01-25 18:10:08 +01:00
|
|
|
}
|
|
|
|
|
2011-11-25 15:51:48 +01:00
|
|
|
/* OSPF master init. */
|
2016-11-13 08:02:23 +01:00
|
|
|
ospf_master_init(frr_init());
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Initializations. */
|
2003-04-04 04:44:16 +02:00
|
|
|
master = om->master;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Library inits. */
|
2024-05-09 13:47:29 +02:00
|
|
|
libagentx_init();
|
2018-10-01 14:55:06 +02:00
|
|
|
ospf_debug_init();
|
2017-08-25 22:51:12 +02:00
|
|
|
ospf_vrf_init();
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
access_list_init();
|
|
|
|
prefix_list_init();
|
2023-09-12 13:39:44 +02:00
|
|
|
keychain_init();
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2023-06-15 23:50:24 +02:00
|
|
|
/* Configuration processing callback initialization. */
|
|
|
|
cmd_init_config_callbacks(ospf_config_start, ospf_config_end);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* OSPFd inits. */
|
|
|
|
ospf_if_init();
|
2021-01-28 00:41:07 +01:00
|
|
|
ospf_zebra_init(master, ospf_instance);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* OSPF vty inits. */
|
|
|
|
ospf_vty_init();
|
|
|
|
ospf_vty_show_init();
|
2015-05-20 02:58:13 +02:00
|
|
|
ospf_vty_clear_init();
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-07-22 21:35:37 +02:00
|
|
|
/* OSPF BFD init */
|
2021-03-03 21:22:47 +01:00
|
|
|
ospf_bfd_init(master);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-07-22 19:31:14 +02:00
|
|
|
/* OSPF LDP IGP Sync init */
|
|
|
|
ospf_ldp_sync_init();
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_route_map_init();
|
|
|
|
ospf_opaque_init();
|
2021-05-31 15:27:51 +02:00
|
|
|
ospf_gr_init();
|
2021-05-31 15:27:51 +02:00
|
|
|
ospf_gr_helper_init();
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-06-20 20:48:35 +02:00
|
|
|
/* OSPF errors init */
|
|
|
|
ospf_error_init();
|
|
|
|
|
2016-11-14 01:56:02 +01:00
|
|
|
frr_config_fork();
|
|
|
|
frr_run(master);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Not reached. */
|
2020-02-09 13:21:56 +01:00
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|