3 * Copyright (C) 2018 Network Device Education Foundation, Inc. ("NetDEF")
5 * FRR is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2, or (at your option) any
10 * FRR is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with FRR; see the file COPYING. If not, write to the Free
17 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 #include "lib/version.h"
33 DEFINE_MGROUP(BFDD
, "Bidirectional Forwarding Detection Daemon")
34 DEFINE_MTYPE(BFDD
, BFDD_CONTROL
, "long-lived control socket memory")
35 DEFINE_MTYPE(BFDD
, BFDD_NOTIFICATION
, "short-lived control notification data")
37 /* Master of threads. */
38 struct thread_master
*master
;
41 static zebra_capabilities_t _caps_p
[] = {ZCAP_BIND
, ZCAP_SYS_ADMIN
, ZCAP_NET_RAW
};
43 /* BFD daemon information. */
44 static struct frr_daemon_info bfdd_di
;
46 void socket_close(int *s
)
52 log_error("%s: close(%d): (%d) %s", __func__
, *s
, errno
,
58 static void sigusr1_handler(void)
63 static void sigterm_handler(void)
65 /* Signalize shutdown. */
68 /* Stop receiving message from zebra. */
71 /* Shutdown controller to avoid receiving anymore commands. */
74 /* Shutdown and free all protocol related memory. */
79 /* Terminate and free() FRR related memory. */
85 static void sighup_handler(void)
87 zlog_info("SIGHUP received");
89 /* Reload config file. */
90 vty_read_config(NULL
, bfdd_di
.config_file
, config_default
);
93 static struct quagga_signal_t bfd_signals
[] = {
96 .handler
= &sigusr1_handler
,
100 .handler
= &sigterm_handler
,
104 .handler
= &sigterm_handler
,
108 .handler
= &sighup_handler
,
112 static const struct frr_yang_module_info
*bfdd_yang_modules
[] = {
117 FRR_DAEMON_INFO(bfdd
, BFD
, .vty_port
= 2617,
118 .proghelp
= "Implementation of the BFD protocol.",
119 .signals
= bfd_signals
, .n_signals
= array_size(bfd_signals
),
120 .privs
= &bglobal
.bfdd_privs
,
121 .yang_modules
= bfdd_yang_modules
,
122 .n_yang_modules
= array_size(bfdd_yang_modules
))
124 #define OPTION_CTLSOCK 1001
125 static struct option longopts
[] = {
126 {"bfdctl", required_argument
, NULL
, OPTION_CTLSOCK
},
132 * BFD daemon related code.
134 struct bfd_global bglobal
;
136 struct bfd_diag_str_list diag_list
[] = {
137 {.str
= "control-expired", .type
= BD_CONTROL_EXPIRED
},
138 {.str
= "echo-failed", .type
= BD_ECHO_FAILED
},
139 {.str
= "neighbor-down", .type
= BD_NEIGHBOR_DOWN
},
140 {.str
= "forwarding-reset", .type
= BD_FORWARDING_RESET
},
141 {.str
= "path-down", .type
= BD_PATH_DOWN
},
142 {.str
= "concatenated-path-down", .type
= BD_CONCATPATH_DOWN
},
143 {.str
= "administratively-down", .type
= BD_ADMIN_DOWN
},
144 {.str
= "reverse-concat-path-down", .type
= BD_REVCONCATPATH_DOWN
},
148 struct bfd_state_str_list state_list
[] = {
149 {.str
= "admin-down", .type
= PTM_BFD_ADM_DOWN
},
150 {.str
= "down", .type
= PTM_BFD_DOWN
},
151 {.str
= "init", .type
= PTM_BFD_INIT
},
152 {.str
= "up", .type
= PTM_BFD_UP
},
157 static void bg_init(void)
159 struct zebra_privs_t bfdd_privs
= {
160 #if defined(FRR_USER) && defined(FRR_GROUP)
164 #if defined(VTY_GROUP)
165 .vty_group
= VTY_GROUP
,
168 .cap_num_p
= array_size(_caps_p
),
172 TAILQ_INIT(&bglobal
.bg_bcslist
);
173 TAILQ_INIT(&bglobal
.bg_obslist
);
175 memcpy(&bglobal
.bfdd_privs
, &bfdd_privs
,
179 int main(int argc
, char *argv
[])
182 bool ctlsockused
= false;
185 /* Initialize system sockets. */
188 frr_preinit(&bfdd_di
, argc
, argv
);
189 frr_opt_add("", longopts
,
190 " --bfdctl Specify bfdd control socket\n");
192 snprintf(ctl_path
, sizeof(ctl_path
), BFDD_CONTROL_SOCKET
,
195 opt
= frr_getopt(argc
, argv
, NULL
);
201 strlcpy(ctl_path
, optarg
, sizeof(ctl_path
));
211 if (bfdd_di
.pathspace
&& !ctlsockused
)
212 snprintf(ctl_path
, sizeof(ctl_path
), BFDD_CONTROL_SOCKET
,
213 "/", bfdd_di
.pathspace
);
215 #if 0 /* TODO add support for JSON configuration files. */
219 /* Initialize logging API. */
220 log_init(1, BLOG_DEBUG
, &bfdd_di
);
222 /* Initialize control socket. */
223 control_init(ctl_path
);
225 /* Initialize FRR infrastructure. */
228 /* Initialize BFD data structures. */
235 /* Initialize zebra connection. */
236 bfdd_zclient_init(&bglobal
.bfdd_privs
);
238 thread_add_read(master
, control_accept
, NULL
, bglobal
.bg_csock
,
239 &bglobal
.bg_csockev
);
241 /* Install commands. */
244 /* read configuration file and daemonize */