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