diff options
| -rw-r--r-- | lib/libfrr.c | 48 | ||||
| -rw-r--r-- | lib/libfrr.h | 16 | ||||
| -rwxr-xr-x | tools/frr.in | 15 | ||||
| -rw-r--r-- | watchfrr/watchfrr.c | 165 | ||||
| -rw-r--r-- | watchfrr/watchfrr.h | 4 | ||||
| -rw-r--r-- | zebra/zebra_netns_id.c | 60 | ||||
| -rw-r--r-- | zebra/zebra_vxlan_null.c | 213 |
7 files changed, 142 insertions, 379 deletions
diff --git a/lib/libfrr.c b/lib/libfrr.c index 94cd0ab623..35a6da577f 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -54,6 +54,7 @@ static char pidfile_default[512]; static char vtypath_default[256]; bool debug_memstats_at_exit = 0; +static bool nodetach_term, nodetach_daemon; static char comb_optstr[256]; static struct option comb_lo[64]; @@ -281,6 +282,8 @@ void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv) opt_extend(&os_zclient); if (!(di->flags & FRR_NO_TCPVTY)) opt_extend(&os_vty); + if (di->flags & FRR_DETACH_LATER) + nodetach_daemon = true; snprintf(config_default, sizeof(config_default), "%s/%s.conf", frr_sysconfdir, di->name); @@ -767,13 +770,16 @@ void frr_config_fork(void) { hook_call(frr_late_init, master); - /* Don't start execution if we are in dry-run mode */ - if (di->dryrun) { - frr_config_read_in(NULL); - exit(0); - } + if (!(di->flags & FRR_NO_CFG_PID_DRY)) { + /* Don't start execution if we are in dry-run mode */ + if (di->dryrun) { + frr_config_read_in(NULL); + exit(0); + } - thread_add_event(master, frr_config_read_in, NULL, 0, &di->read_in); + thread_add_event(master, frr_config_read_in, NULL, 0, + &di->read_in); + } if (di->daemon_mode || di->terminal) frr_daemonize(); @@ -783,7 +789,7 @@ void frr_config_fork(void) pid_output(di->pid_file); } -void frr_vty_serv(void) +static void frr_vty_serv(void) { /* allow explicit override of vty_path in the future * (not currently set anywhere) */ @@ -810,14 +816,22 @@ void frr_vty_serv(void) vty_serv_sock(di->vty_addr, di->vty_port, di->vty_path); } +static void frr_check_detach(void) +{ + if (nodetach_term || nodetach_daemon) + return; + + if (daemon_ctl_sock != -1) + close(daemon_ctl_sock); + daemon_ctl_sock = -1; +} + static void frr_terminal_close(int isexit) { int nullfd; - if (daemon_ctl_sock != -1) { - close(daemon_ctl_sock); - daemon_ctl_sock = -1; - } + nodetach_term = false; + frr_check_detach(); if (!di->daemon_mode || isexit) { printf("\n%s exiting\n", di->name); @@ -881,6 +895,12 @@ out: return 0; } +void frr_detach(void) +{ + nodetach_daemon = false; + frr_check_detach(); +} + void frr_run(struct thread_master *master) { char instanceinfo[64] = ""; @@ -895,6 +915,8 @@ void frr_run(struct thread_master *master) instanceinfo, di->vty_port, di->startinfo); if (di->terminal) { + nodetach_term = true; + vty_stdio(frr_terminal_close); if (daemon_ctl_sock != -1) { set_nonblocking(daemon_ctl_sock); @@ -914,9 +936,7 @@ void frr_run(struct thread_master *master) close(nullfd); } - if (daemon_ctl_sock != -1) - close(daemon_ctl_sock); - daemon_ctl_sock = -1; + frr_check_detach(); } /* end fixed stderr startup logging */ diff --git a/lib/libfrr.h b/lib/libfrr.h index d255279906..db58ff92be 100644 --- a/lib/libfrr.h +++ b/lib/libfrr.h @@ -29,11 +29,21 @@ #include "module.h" #include "hook.h" +/* The following options disable specific command line options that + * are not applicable for a particular daemon. + */ #define FRR_NO_PRIVSEP (1 << 0) #define FRR_NO_TCPVTY (1 << 1) #define FRR_LIMITED_CLI (1 << 2) -#define FRR_NO_CFG_PID_DRY (1 << 3) +#define FRR_NO_CFG_PID_DRY (1 << 3) #define FRR_NO_ZCLIENT (1 << 4) +/* If FRR_DETACH_LATER is used, the daemon will keep its parent running + * until frr_detach() is called. Normally "somedaemon -d" returns once the + * main event loop is reached in the daemon; use this for extra startup bits. + * + * Does nothing if -d isn't used. + */ +#define FRR_DETACH_LATER (1 << 5) struct frr_daemon_info { unsigned flags; @@ -102,10 +112,8 @@ extern struct thread_master *frr_init(void); DECLARE_HOOK(frr_late_init, (struct thread_master * tm), (tm)) extern void frr_config_fork(void); -extern void frr_vty_serv(void); - -/* note: contains call to frr_vty_serv() */ extern void frr_run(struct thread_master *master); +extern void frr_detach(void); extern bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len, const char *path); diff --git a/tools/frr.in b/tools/frr.in index dd34b08876..4ff080909d 100755 --- a/tools/frr.in +++ b/tools/frr.in @@ -28,7 +28,6 @@ FRR_VTY_GROUP="@enable_vty_group@" # frrvty DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd" MAX_INSTANCES=5 RELOAD_SCRIPT="$D_PATH/frr-reload.py" -WATCHFRR_STARTED="$V_PATH/watchfrr.started" if [ -e /lib/lsb/init-functions ]; then . /lib/lsb/init-functions @@ -128,23 +127,13 @@ start() echo -n " $1" fi - if [ -e $WATCHFRR_STARTED ] ; then - rm $WATCHFRR_STARTED - fi - ${SSD} \ + ${SSD} \ --start \ --pidfile=`pidfile $1` \ --exec "$D_PATH/$1" \ -- \ "${watchfrr_options[@]}" - for i in `seq 1 10`; - do - if [ -e $WATCHFRR_STARTED ] ; then - break - else - sleep 1 - fi - done + elif [ -n "$2" ]; then echo -n " $1-$2" if ! check_daemon $1 $2 ; then diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c index ec922490e2..e32bf3359b 100644 --- a/watchfrr/watchfrr.c +++ b/watchfrr/watchfrr.c @@ -55,9 +55,11 @@ #define PING_TOKEN "PING" +DEFINE_MGROUP(WATCHFRR, "watchfrr") +DEFINE_MTYPE_STATIC(WATCHFRR, WATCHFRR_DAEMON, "watchfrr daemon entry") + /* Needs to be global, referenced somewhere inside libfrr. */ struct thread_master *master; -static char pidfile_default[256]; static bool watch_only = false; @@ -230,7 +232,7 @@ Otherwise, the interval is doubled (but capped at the -M value).\n\n", name of the daemon should be substituted.\n\ --dry Do not start or restart anything, just log.\n\ -p, --pid-file Set process identifier file name\n\ - (default is %s).\n\ + (default is %s/watchfrr.pid).\n\ -b, --blank-string\n\ When the supplied argument string is found in any of the\n\ various shell command arguments (-r, -s, or -k), replace\n\ @@ -240,7 +242,7 @@ Otherwise, the interval is doubled (but capped at the -M value).\n\n", -h, --help Display this help and exit\n", frr_vtydir, DEFAULT_LOGLEVEL, LOG_EMERG, LOG_DEBUG, LOG_DEBUG, DEFAULT_MIN_RESTART, DEFAULT_MAX_RESTART, DEFAULT_PERIOD, - DEFAULT_TIMEOUT, DEFAULT_RESTART_TIMEOUT, pidfile_default); + DEFAULT_TIMEOUT, DEFAULT_RESTART_TIMEOUT, frr_vtydir); } static pid_t run_background(char *shell_cmd) @@ -609,12 +611,13 @@ static void daemon_send_ready(void) if (!sent && gs.numdown == 0) { FILE *fp; + zlog_notice("all daemons up, doing startup-complete notify"); + frr_detach(); + fp = fopen(DAEMON_VTY_DIR "/watchfrr.started", "w"); if (fp) fclose(fp); #if defined HAVE_SYSTEMD - zlog_notice( - "Watchfrr: Notifying Systemd we are up and running"); systemd_send_started(master, 0); #endif sent = 1; @@ -961,6 +964,53 @@ static char *translate_blanks(const char *cmd, const char *blankstr) return res; } +static void watchfrr_init(int argc, char **argv) +{ + const char *special = "zebra"; + int i; + struct daemon *dmn, **add = &gs.daemons; + char alldaemons[512] = "", *p = alldaemons; + + for (i = optind; i < argc; i++) { + dmn = XCALLOC(MTYPE_WATCHFRR_DAEMON, sizeof(*dmn)); + + dmn->name = dmn->restart.name = argv[i]; + dmn->state = DAEMON_INIT; + gs.numdaemons++; + gs.numdown++; + dmn->fd = -1; + dmn->t_wakeup = NULL; + thread_add_timer_msec(master, wakeup_init, dmn, + 100 + (random() % 900), + &dmn->t_wakeup); + dmn->restart.interval = gs.min_restart_interval; + *add = dmn; + add = &dmn->next; + + if (!strcmp(dmn->name, special)) + gs.special = dmn; + } + + if (!gs.daemons) { + fprintf(stderr, + "Must specify one or more daemons to monitor.\n\n"); + frr_help_exit(1); + } + if (!watch_only && !gs.special) { + fprintf(stderr, "\"%s\" daemon must be in daemon lists\n\n", + special); + frr_help_exit(1); + } + + for (dmn = gs.daemons; dmn; dmn = dmn->next) { + snprintf(p, alldaemons + sizeof(alldaemons) - p, "%s%s", + (p == alldaemons) ? "" : " ", dmn->name); + p += strlen(p); + } + zlog_notice("%s %s watching [%s]%s", progname, FRR_VERSION, alldaemons, + watch_only ? ", monitor mode" : ""); +} + struct zebra_privs_t watchfrr_privs = { #ifdef VTY_GROUP .vty_group = VTY_GROUP, @@ -984,7 +1034,8 @@ static struct quagga_signal_t watchfrr_signals[] = { FRR_DAEMON_INFO(watchfrr, WATCHFRR, .flags = FRR_NO_PRIVSEP | FRR_NO_TCPVTY | FRR_LIMITED_CLI - | FRR_NO_CFG_PID_DRY | FRR_NO_ZCLIENT, + | FRR_NO_CFG_PID_DRY | FRR_NO_ZCLIENT + | FRR_DETACH_LATER, .printhelp = printhelp, .copyright = "Copyright 2004 Andrew J. Schorr", @@ -999,13 +1050,8 @@ FRR_DAEMON_INFO(watchfrr, WATCHFRR, int main(int argc, char **argv) { int opt; - const char *pidfile = pidfile_default; - const char *special = "zebra"; const char *blankstr = NULL; - snprintf(pidfile_default, sizeof(pidfile_default), "%s/watchfrr.pid", - frr_vtydir); - frr_preinit(&watchfrr_di, argc, argv); progname = watchfrr_di.progname; @@ -1087,7 +1133,7 @@ int main(int argc, char **argv) gs.period = 1000 * period; } break; case 'p': - pidfile = optarg; + watchfrr_di.pid_file = optarg; break; case 'r': if (!valid_command(optarg)) { @@ -1167,99 +1213,18 @@ int main(int argc, char **argv) master = frr_init(); watchfrr_error_init(); + watchfrr_init(argc, argv); + watchfrr_vty_init(); + + frr_config_fork(); zlog_set_level(ZLOG_DEST_MONITOR, ZLOG_DISABLED); - if (watchfrr_di.daemon_mode) { + if (watchfrr_di.daemon_mode) zlog_set_level(ZLOG_DEST_SYSLOG, MIN(gs.loglevel, LOG_DEBUG)); - if (daemon(0, 0) < 0) { - fprintf(stderr, "Watchfrr daemon failed: %s", - strerror(errno)); - exit(1); - } - } else + else zlog_set_level(ZLOG_DEST_STDOUT, MIN(gs.loglevel, LOG_DEBUG)); - watchfrr_vty_init(); - - frr_vty_serv(); - - { - int i; - struct daemon *tail = NULL; - - for (i = optind; i < argc; i++) { - struct daemon *dmn; - - if (!(dmn = (struct daemon *)calloc(1, sizeof(*dmn)))) { - fprintf(stderr, "calloc(1,%u) failed: %s\n", - (unsigned int)sizeof(*dmn), - safe_strerror(errno)); - return 1; - } - dmn->name = dmn->restart.name = argv[i]; - dmn->state = DAEMON_INIT; - gs.numdaemons++; - gs.numdown++; - dmn->fd = -1; - dmn->t_wakeup = NULL; - thread_add_timer_msec(master, wakeup_init, dmn, - 100 + (random() % 900), - &dmn->t_wakeup); - dmn->restart.interval = gs.min_restart_interval; - if (tail) - tail->next = dmn; - else - gs.daemons = dmn; - tail = dmn; - - if (!strcmp(dmn->name, special)) - gs.special = dmn; - } - } - if (!gs.daemons) { - flog_err(EC_WATCHFRR_UNEXPECTED_DAEMONS, - "Must specify one or more daemons to monitor."); - frr_help_exit(1); - } - if (!watch_only && !gs.special) { - flog_err(EC_WATCHFRR_UNEXPECTED_DAEMONS, - "\"%s\" daemon must be in daemon lists", special); - frr_help_exit(1); - } - - /* Make sure we're not already running. */ - pid_output(pidfile); - - /* Announce which daemons are being monitored. */ - { - struct daemon *dmn; - size_t len = 0; - - for (dmn = gs.daemons; dmn; dmn = dmn->next) - len += strlen(dmn->name) + 1; - - { - char buf[len + 1]; - char *p = buf; - - for (dmn = gs.daemons; dmn; dmn = dmn->next) { - if (p != buf) - *p++ = ' '; - strcpy(p, dmn->name); - p += strlen(p); - } - zlog_notice("%s %s watching [%s]%s", progname, - FRR_VERSION, buf, - watch_only ? ", monitor mode" : ""); - } - } - - { - struct thread thread; - - while (thread_fetch(master, &thread)) - thread_call(&thread); - } + frr_run(master); systemd_send_stopping(); /* Not reached. */ diff --git a/watchfrr/watchfrr.h b/watchfrr/watchfrr.h index 1a1c19056f..ee16846a1d 100644 --- a/watchfrr/watchfrr.h +++ b/watchfrr/watchfrr.h @@ -21,6 +21,10 @@ #ifndef FRR_WATCHFRR_H #define FRR_WATCHFRR_H +#include "lib/memory.h" + +DECLARE_MGROUP(WATCHFRR) + extern void watchfrr_vty_init(void); extern pid_t integrated_write_pid; diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c index 600d1d55c6..ea4b07a87d 100644 --- a/zebra/zebra_netns_id.c +++ b/zebra/zebra_netns_id.c @@ -220,46 +220,36 @@ ns_id_t zebra_ns_id_get(const char *netnspath) nlh = (struct nlmsghdr *)buf; /* message to analyse : NEWNSID response */ - len = ret; ret = 0; - do { - if (nlh->nlmsg_type >= NLMSG_MIN_TYPE) { - return_nsid = extract_nsid(nlh, buf); - if (return_nsid != NS_UNKNOWN) - break; - } else { - if (nlh->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = - (struct nlmsgerr - *)((char *)nlh - + NETLINK_ALIGN(sizeof( - struct - nlmsghdr))); - - ret = -1; - if (err->error < 0) - errno = -err->error; - else - errno = err->error; - if (errno == 0) { - /* request NEWNSID was successfull - * return EEXIST error to get GETNSID - */ - errno = EEXIST; - } - } else { - /* other errors ignored - * attempt to get nsid + if (nlh->nlmsg_type >= NLMSG_MIN_TYPE) { + return_nsid = extract_nsid(nlh, buf); + } else { + if (nlh->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err = + (struct nlmsgerr + *)((char *)nlh + + NETLINK_ALIGN( + sizeof(struct nlmsghdr))); + + ret = -1; + if (err->error < 0) + errno = -err->error; + else + errno = err->error; + if (errno == 0) { + /* request NEWNSID was successfull + * return EEXIST error to get GETNSID */ - ret = -1; errno = EEXIST; - break; } + } else { + /* other errors ignored + * attempt to get nsid + */ + ret = -1; + errno = EEXIST; } - len = len - NETLINK_ALIGN(nlh->nlmsg_len); - nlh = (struct nlmsghdr *)((char *)nlh - + NETLINK_ALIGN(nlh->nlmsg_len)); - } while (len != 0 && return_nsid != NS_UNKNOWN && ret == 0); + } if (ret <= 0) { if (errno != EEXIST && ret != 0) { diff --git a/zebra/zebra_vxlan_null.c b/zebra/zebra_vxlan_null.c deleted file mode 100644 index 00c849a3d0..0000000000 --- a/zebra/zebra_vxlan_null.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Zebra VxLAN (EVPN) - * Copyright (C) 2016, 2017 Cumulus Networks, Inc. - * - * This file is part of FRR. - * - * FRR 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, or (at your option) any - * later version. - * - * FRR 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 FRR; see the file COPYING. If not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#include <zebra.h> - -#include "if.h" -#include "zebra/debug.h" -#include "zebra/zserv.h" -#include "zebra/rib.h" -#include "zebra/zebra_vrf.h" -#include "zebra/zebra_l2.h" -#include "zebra/zebra_vxlan.h" - -void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni) -{ -} - -void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf) -{ -} - -void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty, - struct zebra_vrf *zvrf, - struct in_addr vtep_ip) -{ -} - -void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni, struct ethaddr *mac) -{ -} - -void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni, struct in_addr vtep_ip) -{ -} - -void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni) -{ -} - -void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf) -{ -} - -void zebra_vxlan_print_specific_neigh_vni(struct vty *vty, - struct zebra_vrf *zvrf, vni_t vni, - struct ipaddr *ip) -{ -} - -void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf, - vni_t vni, struct in_addr vtep_ip) -{ -} - -void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni) -{ -} - -void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf) -{ -} - -void zebra_vxlan_print_evpn(struct vty *vty, bool uj) -{ -} - -void zebra_vxlan_print_rmacs_l3vni(struct vty *, vni_t, uint8_t) -{ -} - -void zebra_vxlan_print_rmacs_all_l3vni(struct vty *, uint8_t) -{ -} - -void zebra_vxlan_print_nh_l3vni(struct vty *, vni_t, uint8_t) -{ -} - -void zebra_vxlan_print_nh_all_l3vni(struct vty *, uint8_t) -{ -} - -void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni) -{ -} - -int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if) -{ - return 0; -} - -int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if) -{ - return 0; -} - -int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, - unsigned short length, struct zebra_vrf *zvrf) -{ - return 0; -} - -int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, - unsigned short length, struct zebra_vrf *zvrf) -{ - return 0; -} - -int zebra_vxlan_local_mac_add_update(struct interface *ifp, - struct interface *br_if, - struct ethaddr *mac, vlanid_t vid, - uint8_t sticky) -{ - return 0; -} - -int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, - struct ethaddr *mac, vlanid_t vid) -{ - return 0; -} - -int zebra_vxlan_check_readd_remote_mac(struct interface *ifp, - struct interface *br_if, - struct ethaddr *mac, vlanid_t vid) -{ - return 0; -} - -int zebra_vxlan_check_del_local_mac(struct interface *ifp, - struct interface *br_if, - struct ethaddr *mac, vlanid_t vid) -{ - return 0; -} - -int zebra_vxlan_if_up(struct interface *ifp) -{ - return 0; -} - -int zebra_vxlan_if_down(struct interface *ifp) -{ - return 0; -} - -int zebra_vxlan_if_add(struct interface *ifp) -{ - return 0; -} - -int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags) -{ - return 0; -} - -int zebra_vxlan_if_del(struct interface *ifp) -{ - return 0; -} - -int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, - unsigned short length, struct zebra_vrf *zvrf) -{ - return 0; -} - -int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, - unsigned short length, struct zebra_vrf *zvrf) -{ - return 0; -} - -int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock, - unsigned short length, struct zebra_vrf *zvrf) -{ - return 0; -} - -void zebra_vxlan_init_tables(struct zebra_vrf *zvrf) -{ -} - -void zebra_vxlan_close_tables(struct zebra_vrf *zvrf) -{ -} - -void zebra_vxlan_cleanup_tables(struct zebra_vrf *zvrf) -{ -} |
