]> git.proxmox.com Git - mirror_frr.git/blob - bfdd/bfdd.c
Merge pull request #4230 from sworleys/Route-Info-Check
[mirror_frr.git] / bfdd / bfdd.c
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
23 #include "bfd.h"
24 #include "lib/version.h"
25
26
27 /*
28 * FRR related code.
29 */
30 DEFINE_MGROUP(BFDD, "Bidirectional Forwarding Detection Daemon");
31 DEFINE_MTYPE(BFDD, BFDD_TMP, "short-lived temporary memory");
32 DEFINE_MTYPE(BFDD, BFDD_CONFIG, "long-lived configuration memory");
33 DEFINE_MTYPE(BFDD, BFDD_LABEL, "long-lived label memory");
34 DEFINE_MTYPE(BFDD, BFDD_CONTROL, "long-lived control socket memory");
35 DEFINE_MTYPE(BFDD, BFDD_SESSION_OBSERVER, "Session observer");
36 DEFINE_MTYPE(BFDD, BFDD_NOTIFICATION, "short-lived control notification data");
37
38 /* Master of threads. */
39 struct thread_master *master;
40
41 /* BFDd privileges */
42 static zebra_capabilities_t _caps_p[] = {ZCAP_BIND};
43
44 struct zebra_privs_t bfdd_privs = {
45 #if defined(FRR_USER) && defined(FRR_GROUP)
46 .user = FRR_USER,
47 .group = FRR_GROUP,
48 #endif
49 #if defined(VTY_GROUP)
50 .vty_group = VTY_GROUP,
51 #endif
52 .caps_p = _caps_p,
53 .cap_num_p = array_size(_caps_p),
54 .cap_num_i = 0,
55 };
56
57 void socket_close(int *s)
58 {
59 if (*s <= 0)
60 return;
61
62 if (close(*s) != 0)
63 log_error("%s: close(%d): (%d) %s", __func__, *s, errno,
64 strerror(errno));
65
66 *s = -1;
67 }
68
69 static void sigusr1_handler(void)
70 {
71 zlog_rotate();
72 }
73
74 static void sigterm_handler(void)
75 {
76 /* Signalize shutdown. */
77 frr_early_fini();
78
79 /* Stop receiving message from zebra. */
80 bfdd_zclient_stop();
81
82 /* Shutdown controller to avoid receiving anymore commands. */
83 control_shutdown();
84
85 /* Shutdown and free all protocol related memory. */
86 bfd_shutdown();
87
88 /* Close all descriptors. */
89 socket_close(&bglobal.bg_echo);
90 socket_close(&bglobal.bg_shop);
91 socket_close(&bglobal.bg_mhop);
92 socket_close(&bglobal.bg_shop6);
93 socket_close(&bglobal.bg_mhop6);
94
95 /* Terminate and free() FRR related memory. */
96 frr_fini();
97
98 exit(0);
99 }
100
101 static struct quagga_signal_t bfd_signals[] = {
102 {
103 .signal = SIGUSR1,
104 .handler = &sigusr1_handler,
105 },
106 {
107 .signal = SIGTERM,
108 .handler = &sigterm_handler,
109 },
110 {
111 .signal = SIGINT,
112 .handler = &sigterm_handler,
113 },
114 };
115
116 FRR_DAEMON_INFO(bfdd, BFD, .vty_port = 2617,
117 .proghelp = "Implementation of the BFD protocol.",
118 .signals = bfd_signals, .n_signals = array_size(bfd_signals),
119 .privs = &bfdd_privs)
120
121 #define OPTION_CTLSOCK 1001
122 static struct option longopts[] = {
123 {"bfdctl", required_argument, NULL, OPTION_CTLSOCK},
124 {0}
125 };
126
127
128 /*
129 * BFD daemon related code.
130 */
131 struct bfd_global bglobal;
132
133 struct bfd_diag_str_list diag_list[] = {
134 {.str = "control-expired", .type = BD_CONTROL_EXPIRED},
135 {.str = "echo-failed", .type = BD_ECHO_FAILED},
136 {.str = "neighbor-down", .type = BD_NEIGHBOR_DOWN},
137 {.str = "forwarding-reset", .type = BD_FORWARDING_RESET},
138 {.str = "path-down", .type = BD_PATH_DOWN},
139 {.str = "concatenated-path-down", .type = BD_CONCATPATH_DOWN},
140 {.str = "administratively-down", .type = BD_ADMIN_DOWN},
141 {.str = "reverse-concat-path-down", .type = BD_REVCONCATPATH_DOWN},
142 {.str = NULL},
143 };
144
145 struct bfd_state_str_list state_list[] = {
146 {.str = "admin-down", .type = PTM_BFD_ADM_DOWN},
147 {.str = "down", .type = PTM_BFD_DOWN},
148 {.str = "init", .type = PTM_BFD_INIT},
149 {.str = "up", .type = PTM_BFD_UP},
150 {.str = NULL},
151 };
152
153
154 static void bg_init(void)
155 {
156 TAILQ_INIT(&bglobal.bg_bcslist);
157 TAILQ_INIT(&bglobal.bg_obslist);
158
159 bglobal.bg_shop = bp_udp_shop();
160 bglobal.bg_mhop = bp_udp_mhop();
161 bglobal.bg_shop6 = bp_udp6_shop();
162 bglobal.bg_mhop6 = bp_udp6_mhop();
163 bglobal.bg_echo = bp_echo_socket();
164 bglobal.bg_echov6 = bp_echov6_socket();
165 }
166
167 int main(int argc, char *argv[])
168 {
169 const char *ctl_path = BFDD_CONTROL_SOCKET;
170 int opt;
171
172 frr_preinit(&bfdd_di, argc, argv);
173 frr_opt_add("", longopts,
174 " --bfdctl Specify bfdd control socket\n");
175
176 while (true) {
177 opt = frr_getopt(argc, argv, NULL);
178 if (opt == EOF)
179 break;
180
181 switch (opt) {
182 case OPTION_CTLSOCK:
183 ctl_path = optarg;
184 break;
185
186 default:
187 frr_help_exit(1);
188 break;
189 }
190 }
191
192 #if 0 /* TODO add support for JSON configuration files. */
193 parse_config(conf);
194 #endif
195
196 /* Initialize logging API. */
197 log_init(1, BLOG_DEBUG, &bfdd_di);
198
199 /* Initialize system sockets. */
200 bg_init();
201
202 /* Initialize control socket. */
203 control_init(ctl_path);
204
205 /* Initialize FRR infrastructure. */
206 master = frr_init();
207
208 /* Initialize BFD data structures. */
209 bfd_initialize();
210
211 /* Initialize zebra connection. */
212 bfdd_zclient_init(&bfdd_privs);
213
214 /* Add descriptors to the event loop. */
215 thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_shop,
216 &bglobal.bg_ev[0]);
217 thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_mhop,
218 &bglobal.bg_ev[1]);
219 thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_shop6,
220 &bglobal.bg_ev[2]);
221 thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_mhop6,
222 &bglobal.bg_ev[3]);
223 thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echo,
224 &bglobal.bg_ev[4]);
225 thread_add_read(master, bfd_recv_cb, NULL, bglobal.bg_echov6,
226 &bglobal.bg_ev[5]);
227 thread_add_read(master, control_accept, NULL, bglobal.bg_csock,
228 &bglobal.bg_csockev);
229
230 /* Install commands. */
231 bfdd_vty_init();
232
233 /* read configuration file and daemonize */
234 frr_config_fork();
235
236 frr_run(master);
237 /* NOTREACHED */
238
239 return 0;
240 }