]>
Commit | Line | Data |
---|---|---|
edd7c245 | 1 | /* zebra daemon main routine. |
718e3744 | 2 | * Copyright (C) 1997, 98 Kunihiro Ishiguro |
3 | * | |
4 | * This file is part of GNU Zebra. | |
5 | * | |
6 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published by the | |
8 | * Free Software Foundation; either version 2, or (at your option) any | |
9 | * later version. | |
10 | * | |
11 | * GNU Zebra is distributed in the hope that it will be useful, but | |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * General Public License for more details. | |
15 | * | |
896014f4 DL |
16 | * You should have received a copy of the GNU General Public License along |
17 | * with this program; see the file COPYING; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
718e3744 | 19 | */ |
20 | ||
21 | #include <zebra.h> | |
22 | ||
5e4fa164 | 23 | #include <lib/version.h> |
718e3744 | 24 | #include "getopt.h" |
25 | #include "command.h" | |
26 | #include "thread.h" | |
27 | #include "filter.h" | |
28 | #include "memory.h" | |
4a1ab8e4 | 29 | #include "zebra_memory.h" |
fc7948fa | 30 | #include "memory_vty.h" |
718e3744 | 31 | #include "prefix.h" |
32 | #include "log.h" | |
7514fb77 | 33 | #include "plist.h" |
edd7c245 | 34 | #include "privs.h" |
2d75d052 | 35 | #include "sigevent.h" |
b72ede27 | 36 | #include "vrf.h" |
4f04a76b | 37 | #include "libfrr.h" |
718e3744 | 38 | |
39 | #include "zebra/rib.h" | |
40 | #include "zebra/zserv.h" | |
41 | #include "zebra/debug.h" | |
18a6dce6 | 42 | #include "zebra/router-id.h" |
ca776988 | 43 | #include "zebra/irdp.h" |
a1ac18c4 | 44 | #include "zebra/rtadv.h" |
244c1cdc | 45 | #include "zebra/zebra_ptm.h" |
fe18ee2d | 46 | #include "zebra/zebra_ns.h" |
e2b1be64 | 47 | #include "zebra/redistribute.h" |
7758e3f3 | 48 | #include "zebra/zebra_mpls.h" |
fea12efb | 49 | #include "zebra/label_manager.h" |
244c1cdc DS |
50 | |
51 | #define ZEBRA_PTM_SUPPORT | |
718e3744 | 52 | |
b21b19c5 | 53 | /* Zebra instance */ |
d62a17ae | 54 | struct zebra_t zebrad = { |
55 | .rtm_table_default = 0, | |
b21b19c5 | 56 | }; |
718e3744 | 57 | |
58 | /* process id. */ | |
718e3744 | 59 | pid_t pid; |
60 | ||
55c72803 | 61 | /* Pacify zclient.o in libfrr, which expects this variable. */ |
87efd646 | 62 | struct thread_master *master; |
63 | ||
718e3744 | 64 | /* Route retain mode flag. */ |
65 | int retain_mode = 0; | |
66 | ||
6baf7bb8 DS |
67 | /* Allow non-quagga entities to delete quagga routes */ |
68 | int allow_delete = 0; | |
69 | ||
718e3744 | 70 | /* Don't delete kernel route. */ |
71 | int keep_kernel_mode = 0; | |
72 | ||
c34b6b57 | 73 | #ifdef HAVE_NETLINK |
74 | /* Receive buffer size for netlink socket */ | |
b6286c70 | 75 | u_int32_t nl_rcvbufsize = 4194304; |
c34b6b57 | 76 | #endif /* HAVE_NETLINK */ |
77 | ||
718e3744 | 78 | /* Command line options. */ |
d62a17ae | 79 | struct option longopts[] = {{"batch", no_argument, NULL, 'b'}, |
80 | {"allow_delete", no_argument, NULL, 'a'}, | |
81 | {"keep_kernel", no_argument, NULL, 'k'}, | |
82 | {"socket", required_argument, NULL, 'z'}, | |
83 | {"ecmp", required_argument, NULL, 'e'}, | |
84 | {"label_socket", no_argument, NULL, 'l'}, | |
85 | {"retain", no_argument, NULL, 'r'}, | |
c34b6b57 | 86 | #ifdef HAVE_NETLINK |
d62a17ae | 87 | {"nl-bufsize", required_argument, NULL, 's'}, |
c34b6b57 | 88 | #endif /* HAVE_NETLINK */ |
d62a17ae | 89 | {0}}; |
718e3744 | 90 | |
d62a17ae | 91 | zebra_capabilities_t _caps_p[] = { |
9d303b37 | 92 | ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN, ZCAP_NET_RAW, |
edd7c245 | 93 | }; |
94 | ||
95 | /* zebra privileges to run with */ | |
d62a17ae | 96 | struct zebra_privs_t zserv_privs = { |
b2f36157 | 97 | #if defined(FRR_USER) && defined(FRR_GROUP) |
d62a17ae | 98 | .user = FRR_USER, |
99 | .group = FRR_GROUP, | |
edd7c245 | 100 | #endif |
101 | #ifdef VTY_GROUP | |
d62a17ae | 102 | .vty_group = VTY_GROUP, |
edd7c245 | 103 | #endif |
d62a17ae | 104 | .caps_p = _caps_p, |
105 | .cap_num_p = array_size(_caps_p), | |
106 | .cap_num_i = 0}; | |
edd7c245 | 107 | |
37fe7731 DS |
108 | unsigned int multipath_num = MULTIPATH_NUM; |
109 | ||
718e3744 | 110 | /* SIGHUP handler. */ |
d62a17ae | 111 | static void sighup(void) |
718e3744 | 112 | { |
d62a17ae | 113 | zlog_info("SIGHUP received"); |
718e3744 | 114 | |
d62a17ae | 115 | /* Reload of config file. */ |
116 | ; | |
718e3744 | 117 | } |
118 | ||
119 | /* SIGINT handler. */ | |
d62a17ae | 120 | static void sigint(void) |
718e3744 | 121 | { |
d62a17ae | 122 | struct vrf *vrf; |
123 | struct zebra_vrf *zvrf; | |
124 | struct zebra_ns *zns; | |
fe18ee2d | 125 | |
d62a17ae | 126 | zlog_notice("Terminating on signal"); |
718e3744 | 127 | |
03951374 | 128 | frr_early_fini(); |
718e3744 | 129 | |
d62a17ae | 130 | zebra_ptm_finish(); |
131 | list_delete_all_node(zebrad.client_list); | |
132 | ||
133 | if (retain_mode) | |
134 | RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) | |
135 | { | |
136 | zvrf = vrf->info; | |
137 | if (zvrf) | |
138 | SET_FLAG(zvrf->flags, ZEBRA_VRF_RETAIN); | |
139 | } | |
140 | vrf_terminate(); | |
141 | ||
142 | zns = zebra_ns_lookup(NS_DEFAULT); | |
143 | zebra_ns_disable(0, (void **)&zns); | |
144 | ||
145 | access_list_reset(); | |
146 | prefix_list_reset(); | |
147 | route_map_finish(); | |
03951374 | 148 | |
d62a17ae | 149 | list_delete(zebrad.client_list); |
150 | work_queue_free(zebrad.ribq); | |
151 | if (zebrad.lsp_process_q) | |
152 | work_queue_free(zebrad.lsp_process_q); | |
153 | meta_queue_free(zebrad.mq); | |
d62a17ae | 154 | |
03951374 | 155 | frr_fini(); |
d62a17ae | 156 | exit(0); |
718e3744 | 157 | } |
158 | ||
159 | /* SIGUSR1 handler. */ | |
d62a17ae | 160 | static void sigusr1(void) |
718e3744 | 161 | { |
d62a17ae | 162 | zlog_rotate(); |
718e3744 | 163 | } |
164 | ||
d62a17ae | 165 | struct quagga_signal_t zebra_signals[] = { |
166 | { | |
167 | .signal = SIGHUP, | |
168 | .handler = &sighup, | |
169 | }, | |
170 | { | |
171 | .signal = SIGUSR1, | |
172 | .handler = &sigusr1, | |
173 | }, | |
174 | { | |
175 | .signal = SIGINT, | |
176 | .handler = &sigint, | |
177 | }, | |
178 | { | |
179 | .signal = SIGTERM, | |
180 | .handler = &sigint, | |
181 | }, | |
2d75d052 | 182 | }; |
b72ede27 | 183 | |
d62a17ae | 184 | FRR_DAEMON_INFO( |
185 | zebra, ZEBRA, .vty_port = ZEBRA_VTY_PORT, .flags = FRR_NO_ZCLIENT, | |
4f04a76b | 186 | |
d62a17ae | 187 | .proghelp = |
188 | "Daemon which manages kernel routing table management " | |
4f04a76b DL |
189 | "and\nredistribution between different routing protocols.", |
190 | ||
d62a17ae | 191 | .signals = zebra_signals, .n_signals = array_size(zebra_signals), |
4f04a76b | 192 | |
d62a17ae | 193 | .privs = &zserv_privs, ) |
4f04a76b | 194 | |
718e3744 | 195 | /* Main startup routine. */ |
d62a17ae | 196 | int main(int argc, char **argv) |
718e3744 | 197 | { |
d62a17ae | 198 | // int batch_mode = 0; |
199 | char *zserv_path = NULL; | |
200 | /* Socket to external label manager */ | |
201 | char *lblmgr_path = NULL; | |
689f5a8c DL |
202 | struct sockaddr_storage dummy; |
203 | socklen_t dummylen; | |
fea12efb | 204 | |
d62a17ae | 205 | frr_preinit(&zebra_di, argc, argv); |
718e3744 | 206 | |
d62a17ae | 207 | frr_opt_add( |
208 | "bakz:e:l:r" | |
4f04a76b | 209 | #ifdef HAVE_NETLINK |
d62a17ae | 210 | "s:" |
c05795b1 | 211 | #endif |
d62a17ae | 212 | , |
213 | longopts, | |
214 | " -b, --batch Runs in batch mode\n" | |
215 | " -a, --allow_delete Allow other processes to delete zebra routes\n" | |
216 | " -z, --socket Set path of zebra socket\n" | |
217 | " -e, --ecmp Specify ECMP to use.\n" | |
218 | " -l, --label_socket Socket to external label manager\n" | |
219 | " -k, --keep_kernel Don't delete old routes which installed by zebra.\n" | |
220 | " -r, --retain When program terminates, retain added route by zebra.\n" | |
4f04a76b | 221 | #ifdef HAVE_NETLINK |
d62a17ae | 222 | " -s, --nl-bufsize Set netlink receive buffer size\n" |
4f04a76b | 223 | #endif /* HAVE_NETLINK */ |
9d303b37 | 224 | ); |
d62a17ae | 225 | |
226 | while (1) { | |
227 | int opt = frr_getopt(argc, argv, NULL); | |
228 | ||
229 | if (opt == EOF) | |
230 | break; | |
231 | ||
232 | switch (opt) { | |
233 | case 0: | |
234 | break; | |
235 | case 'b': | |
236 | // batch_mode = 1; | |
237 | break; | |
238 | case 'a': | |
239 | allow_delete = 1; | |
240 | break; | |
241 | case 'k': | |
242 | keep_kernel_mode = 1; | |
243 | break; | |
244 | case 'e': | |
245 | multipath_num = atoi(optarg); | |
246 | if (multipath_num > MULTIPATH_NUM | |
247 | || multipath_num <= 0) { | |
248 | zlog_err( | |
249 | "Multipath Number specified must be less than %d and greater than 0", | |
250 | MULTIPATH_NUM); | |
251 | return 1; | |
252 | } | |
253 | break; | |
254 | case 'z': | |
255 | zserv_path = optarg; | |
689f5a8c DL |
256 | if (!frr_zclient_addr(&dummy, &dummylen, optarg)) { |
257 | fprintf(stderr, | |
258 | "Invalid zserv socket path: %s\n", | |
259 | optarg); | |
260 | exit(1); | |
261 | } | |
d62a17ae | 262 | break; |
263 | case 'l': | |
264 | lblmgr_path = optarg; | |
265 | break; | |
266 | case 'r': | |
267 | retain_mode = 1; | |
268 | break; | |
c34b6b57 | 269 | #ifdef HAVE_NETLINK |
d62a17ae | 270 | case 's': |
271 | nl_rcvbufsize = atoi(optarg); | |
272 | break; | |
c34b6b57 | 273 | #endif /* HAVE_NETLINK */ |
d62a17ae | 274 | default: |
275 | frr_help_exit(1); | |
276 | break; | |
277 | } | |
718e3744 | 278 | } |
d62a17ae | 279 | |
280 | vty_config_lockless(); | |
281 | zebrad.master = frr_init(); | |
282 | ||
283 | /* Zebra related initialize. */ | |
284 | zebra_init(); | |
285 | rib_init(); | |
286 | zebra_if_init(); | |
287 | zebra_debug_init(); | |
288 | router_id_cmd_init(); | |
289 | zebra_vty_init(); | |
290 | access_list_init(); | |
291 | prefix_list_init(); | |
292 | #if defined(HAVE_RTADV) | |
293 | rtadv_cmd_init(); | |
36735ed9 | 294 | #endif |
d62a17ae | 295 | /* PTM socket */ |
244c1cdc | 296 | #ifdef ZEBRA_PTM_SUPPORT |
d62a17ae | 297 | zebra_ptm_init(); |
244c1cdc | 298 | #endif |
718e3744 | 299 | |
d62a17ae | 300 | zebra_mpls_init(); |
301 | zebra_mpls_vty_init(); | |
2dd0d726 | 302 | zebra_pw_vty_init(); |
7758e3f3 | 303 | |
d62a17ae | 304 | /* For debug purpose. */ |
305 | /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */ | |
718e3744 | 306 | |
d62a17ae | 307 | /* Initialize NS( and implicitly the VRF module), and make kernel |
308 | * routing socket. */ | |
309 | zebra_ns_init(); | |
718e3744 | 310 | |
d62a17ae | 311 | /* Process the configuration file. Among other configuration |
9d303b37 DL |
312 | * directives we can meet those installing static routes. Such |
313 | * requests will not be executed immediately, but queued in | |
314 | * zebra->ribq structure until we enter the main execution loop. | |
315 | * The notifications from kernel will show originating PID equal | |
316 | * to that after daemon() completes (if ever called). | |
317 | */ | |
d62a17ae | 318 | frr_config_fork(); |
718e3744 | 319 | |
d62a17ae | 320 | /* Clean up rib -- before fork (?) */ |
321 | /* rib_weed_tables (); */ | |
718e3744 | 322 | |
d62a17ae | 323 | /* After we have successfully acquired the pidfile, we can be sure |
9d303b37 DL |
324 | * about being the only copy of zebra process, which is submitting |
325 | * changes to the FIB. | |
326 | * Clean up zebra-originated routes. The requests will be sent to OS | |
327 | * immediately, so originating PID in notifications from kernel | |
328 | * will be equal to the current getpid(). To know about such routes, | |
329 | * we have to have route_read() called before. | |
330 | */ | |
d62a17ae | 331 | if (!keep_kernel_mode) |
332 | rib_sweep_route(); | |
91b7351d | 333 | |
d62a17ae | 334 | /* Needed for BSD routing socket. */ |
335 | pid = getpid(); | |
718e3744 | 336 | |
d62a17ae | 337 | /* This must be done only after locking pidfile (bug #403). */ |
338 | zebra_zserv_socket_init(zserv_path); | |
97be79f9 | 339 | |
d62a17ae | 340 | /* Init label manager */ |
341 | label_manager_init(lblmgr_path); | |
fea12efb | 342 | |
d62a17ae | 343 | frr_run(zebrad.master); |
718e3744 | 344 | |
d62a17ae | 345 | /* Not reached... */ |
346 | return 0; | |
718e3744 | 347 | } |