]>
Commit | Line | Data |
---|---|---|
e9e2c950 RZ |
1 | /* |
2 | * BFD daemon code | |
3 | * Copyright (C) 2018 Network Device Education Foundation, Inc. ("NetDEF") | |
4 | * | |
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 | |
8 | * later version. | |
9 | * | |
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. | |
14 | * | |
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 | |
18 | * 02111-1307, USA. | |
19 | */ | |
20 | ||
21 | #include <zebra.h> | |
22 | ||
9f95a33a DS |
23 | #include "filter.h" |
24 | ||
e9e2c950 | 25 | #include "bfd.h" |
6c574029 | 26 | #include "bfdd_nb.h" |
e9e2c950 | 27 | #include "lib/version.h" |
0bdeb5e5 | 28 | #include "lib/command.h" |
6ed84949 | 29 | |
e9e2c950 RZ |
30 | |
31 | /* | |
32 | * FRR related code. | |
33 | */ | |
1b88c3cb DL |
34 | DEFINE_MGROUP(BFDD, "Bidirectional Forwarding Detection Daemon") |
35 | DEFINE_MTYPE(BFDD, BFDD_CONTROL, "long-lived control socket memory") | |
36 | DEFINE_MTYPE(BFDD, BFDD_NOTIFICATION, "short-lived control notification data") | |
e9e2c950 RZ |
37 | |
38 | /* Master of threads. */ | |
39 | struct thread_master *master; | |
40 | ||
41 | /* BFDd privileges */ | |
4e6b48d3 | 42 | static zebra_capabilities_t _caps_p[] = {ZCAP_BIND, ZCAP_SYS_ADMIN, ZCAP_NET_RAW}; |
e9e2c950 | 43 | |
49cc9e7b RZ |
44 | /* BFD daemon information. */ |
45 | static struct frr_daemon_info bfdd_di; | |
46 | ||
e9e2c950 RZ |
47 | void socket_close(int *s) |
48 | { | |
49 | if (*s <= 0) | |
50 | return; | |
51 | ||
52 | if (close(*s) != 0) | |
259b64eb RZ |
53 | zlog_err("%s: close(%d): (%d) %s", __func__, *s, errno, |
54 | strerror(errno)); | |
e9e2c950 RZ |
55 | |
56 | *s = -1; | |
57 | } | |
58 | ||
59 | static void sigusr1_handler(void) | |
60 | { | |
61 | zlog_rotate(); | |
62 | } | |
63 | ||
64 | static void sigterm_handler(void) | |
65 | { | |
66 | /* Signalize shutdown. */ | |
67 | frr_early_fini(); | |
68 | ||
d3af6147 RZ |
69 | /* Stop receiving message from zebra. */ |
70 | bfdd_zclient_stop(); | |
71 | ||
e9e2c950 RZ |
72 | /* Shutdown controller to avoid receiving anymore commands. */ |
73 | control_shutdown(); | |
74 | ||
75 | /* Shutdown and free all protocol related memory. */ | |
76 | bfd_shutdown(); | |
77 | ||
7bcadbae | 78 | bfd_vrf_terminate(); |
e9e2c950 RZ |
79 | |
80 | /* Terminate and free() FRR related memory. */ | |
81 | frr_fini(); | |
82 | ||
83 | exit(0); | |
84 | } | |
85 | ||
49cc9e7b RZ |
86 | static void sighup_handler(void) |
87 | { | |
88 | zlog_info("SIGHUP received"); | |
89 | ||
90 | /* Reload config file. */ | |
91 | vty_read_config(NULL, bfdd_di.config_file, config_default); | |
92 | } | |
93 | ||
e9e2c950 RZ |
94 | static struct quagga_signal_t bfd_signals[] = { |
95 | { | |
96 | .signal = SIGUSR1, | |
97 | .handler = &sigusr1_handler, | |
98 | }, | |
99 | { | |
100 | .signal = SIGTERM, | |
101 | .handler = &sigterm_handler, | |
102 | }, | |
103 | { | |
104 | .signal = SIGINT, | |
105 | .handler = &sigterm_handler, | |
106 | }, | |
49cc9e7b RZ |
107 | { |
108 | .signal = SIGHUP, | |
109 | .handler = &sighup_handler, | |
110 | }, | |
e9e2c950 RZ |
111 | }; |
112 | ||
0d8c7a26 | 113 | static const struct frr_yang_module_info *const bfdd_yang_modules[] = { |
adc26455 RZ |
114 | &frr_interface_info, |
115 | &frr_bfdd_info, | |
6fd8972a | 116 | &frr_vrf_info, |
adc26455 RZ |
117 | }; |
118 | ||
e9e2c950 RZ |
119 | FRR_DAEMON_INFO(bfdd, BFD, .vty_port = 2617, |
120 | .proghelp = "Implementation of the BFD protocol.", | |
121 | .signals = bfd_signals, .n_signals = array_size(bfd_signals), | |
adc26455 RZ |
122 | .privs = &bglobal.bfdd_privs, |
123 | .yang_modules = bfdd_yang_modules, | |
124 | .n_yang_modules = array_size(bfdd_yang_modules)) | |
e9e2c950 RZ |
125 | |
126 | #define OPTION_CTLSOCK 1001 | |
2b64873d | 127 | static const struct option longopts[] = { |
e9e2c950 RZ |
128 | {"bfdctl", required_argument, NULL, OPTION_CTLSOCK}, |
129 | {0} | |
130 | }; | |
131 | ||
132 | ||
133 | /* | |
134 | * BFD daemon related code. | |
135 | */ | |
136 | struct bfd_global bglobal; | |
137 | ||
2b64873d | 138 | const struct bfd_diag_str_list diag_list[] = { |
40675ea9 RZ |
139 | {.str = "control-expired", .type = BD_CONTROL_EXPIRED}, |
140 | {.str = "echo-failed", .type = BD_ECHO_FAILED}, | |
141 | {.str = "neighbor-down", .type = BD_NEIGHBOR_DOWN}, | |
142 | {.str = "forwarding-reset", .type = BD_FORWARDING_RESET}, | |
143 | {.str = "path-down", .type = BD_PATH_DOWN}, | |
144 | {.str = "concatenated-path-down", .type = BD_CONCATPATH_DOWN}, | |
145 | {.str = "administratively-down", .type = BD_ADMIN_DOWN}, | |
146 | {.str = "reverse-concat-path-down", .type = BD_REVCONCATPATH_DOWN}, | |
e9e2c950 RZ |
147 | {.str = NULL}, |
148 | }; | |
149 | ||
2b64873d | 150 | const struct bfd_state_str_list state_list[] = { |
40675ea9 RZ |
151 | {.str = "admin-down", .type = PTM_BFD_ADM_DOWN}, |
152 | {.str = "down", .type = PTM_BFD_DOWN}, | |
153 | {.str = "init", .type = PTM_BFD_INIT}, | |
154 | {.str = "up", .type = PTM_BFD_UP}, | |
e9e2c950 RZ |
155 | {.str = NULL}, |
156 | }; | |
157 | ||
158 | ||
159 | static void bg_init(void) | |
160 | { | |
f21536d2 PG |
161 | struct zebra_privs_t bfdd_privs = { |
162 | #if defined(FRR_USER) && defined(FRR_GROUP) | |
163 | .user = FRR_USER, | |
164 | .group = FRR_GROUP, | |
165 | #endif | |
166 | #if defined(VTY_GROUP) | |
167 | .vty_group = VTY_GROUP, | |
168 | #endif | |
169 | .caps_p = _caps_p, | |
170 | .cap_num_p = array_size(_caps_p), | |
171 | .cap_num_i = 0, | |
172 | }; | |
173 | ||
e9e2c950 | 174 | TAILQ_INIT(&bglobal.bg_bcslist); |
d245e522 | 175 | TAILQ_INIT(&bglobal.bg_obslist); |
f21536d2 PG |
176 | |
177 | memcpy(&bglobal.bfdd_privs, &bfdd_privs, | |
178 | sizeof(bfdd_privs)); | |
e9e2c950 RZ |
179 | } |
180 | ||
181 | int main(int argc, char *argv[]) | |
182 | { | |
89277ebf DS |
183 | char ctl_path[512]; |
184 | bool ctlsockused = false; | |
e9e2c950 RZ |
185 | int opt; |
186 | ||
f21536d2 PG |
187 | /* Initialize system sockets. */ |
188 | bg_init(); | |
189 | ||
e9e2c950 RZ |
190 | frr_preinit(&bfdd_di, argc, argv); |
191 | frr_opt_add("", longopts, | |
192 | " --bfdctl Specify bfdd control socket\n"); | |
193 | ||
89277ebf DS |
194 | snprintf(ctl_path, sizeof(ctl_path), BFDD_CONTROL_SOCKET, |
195 | "", ""); | |
e9e2c950 RZ |
196 | while (true) { |
197 | opt = frr_getopt(argc, argv, NULL); | |
198 | if (opt == EOF) | |
199 | break; | |
200 | ||
201 | switch (opt) { | |
202 | case OPTION_CTLSOCK: | |
89277ebf DS |
203 | strlcpy(ctl_path, optarg, sizeof(ctl_path)); |
204 | ctlsockused = true; | |
e9e2c950 RZ |
205 | break; |
206 | ||
207 | default: | |
208 | frr_help_exit(1); | |
209 | break; | |
210 | } | |
211 | } | |
212 | ||
89277ebf DS |
213 | if (bfdd_di.pathspace && !ctlsockused) |
214 | snprintf(ctl_path, sizeof(ctl_path), BFDD_CONTROL_SOCKET, | |
215 | "/", bfdd_di.pathspace); | |
216 | ||
e9e2c950 RZ |
217 | #if 0 /* TODO add support for JSON configuration files. */ |
218 | parse_config(conf); | |
219 | #endif | |
220 | ||
d85b048d DL |
221 | /* Initialize FRR infrastructure. */ |
222 | master = frr_init(); | |
e9e2c950 | 223 | |
e9e2c950 RZ |
224 | /* Initialize control socket. */ |
225 | control_init(ctl_path); | |
226 | ||
e9e2c950 RZ |
227 | /* Initialize BFD data structures. */ |
228 | bfd_initialize(); | |
229 | ||
9fc0bc5c PG |
230 | bfd_vrf_init(); |
231 | ||
9f95a33a DS |
232 | access_list_init(); |
233 | ||
d3af6147 | 234 | /* Initialize zebra connection. */ |
f21536d2 | 235 | bfdd_zclient_init(&bglobal.bfdd_privs); |
d3af6147 | 236 | |
e9e2c950 RZ |
237 | thread_add_read(master, control_accept, NULL, bglobal.bg_csock, |
238 | &bglobal.bg_csockev); | |
239 | ||
c2f29cf3 RZ |
240 | /* Install commands. */ |
241 | bfdd_vty_init(); | |
242 | ||
e9e2c950 RZ |
243 | /* read configuration file and daemonize */ |
244 | frr_config_fork(); | |
245 | ||
246 | frr_run(master); | |
247 | /* NOTREACHED */ | |
248 | ||
249 | return 0; | |
250 | } |