]> git.proxmox.com Git - mirror_frr.git/blame - babeld/babeld.c
babeld: Install route to RIB if parse_update_subtlv() is false
[mirror_frr.git] / babeld / babeld.c
CommitLineData
ca10883e
DS
1/*
2Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20THE SOFTWARE.
21*/
22
23#include <zebra.h>
24#include "command.h"
25#include "prefix.h"
26#include "memory.h"
27#include "table.h"
28#include "distribute.h"
29#include "prefix.h"
30#include "filter.h"
31#include "plist.h"
f135ba52 32#include "lib_errors.h"
5920b3eb 33#include "network.h"
3682bd90 34#include "if.h"
ca10883e
DS
35
36#include "babel_main.h"
37#include "babeld.h"
38#include "util.h"
39#include "net.h"
40#include "kernel.h"
41#include "babel_interface.h"
42#include "neighbour.h"
43#include "route.h"
44#include "message.h"
45#include "resend.h"
46#include "babel_filter.h"
47#include "babel_zebra.h"
f135ba52 48#include "babel_errors.h"
ca10883e 49
bf8d3d6a
DL
50DEFINE_MGROUP(BABELD, "babeld");
51DEFINE_MTYPE_STATIC(BABELD, BABEL, "Babel Structure");
8b7454e9 52
cc9f21da 53static void babel_init_routing_process(struct thread *thread);
ca10883e
DS
54static void babel_get_myid(void);
55static void babel_initial_noise(void);
cc9f21da
DS
56static void babel_read_protocol(struct thread *thread);
57static void babel_main_loop(struct thread *thread);
ca10883e
DS
58static void babel_set_timer(struct timeval *timeout);
59static void babel_fill_with_next_timeout(struct timeval *tv);
03a38493
PG
60static void
61babel_distribute_update (struct distribute_ctx *ctx, struct distribute *dist);
ca10883e
DS
62
63/* Informations relative to the babel running daemon. */
64static struct babel *babel_routing_process = NULL;
65static unsigned char *receive_buffer = NULL;
66static int receive_buffer_size = 0;
67
68/* timeouts */
69struct timeval check_neighbours_timeout;
70static time_t expiry_time;
71static time_t source_expiry_time;
72
73/* Babel node structure. */
612c2c15 74static int babel_config_write (struct vty *vty);
ca10883e
DS
75static struct cmd_node cmd_babel_node =
76{
f4b8291f 77 .name = "babel",
ca10883e 78 .node = BABEL_NODE,
24389580 79 .parent_node = CONFIG_NODE,
ca10883e 80 .prompt = "%s(config-router)# ",
612c2c15 81 .config_write = babel_config_write,
ca10883e
DS
82};
83
84/* print current babel configuration on vty */
85static int
86babel_config_write (struct vty *vty)
87{
88 int lines = 0;
dd8765ca 89 int afi;
ca10883e
DS
90 int i;
91
92 /* list enabled debug modes */
93 lines += debug_babel_config_write (vty);
94
95 if (!babel_routing_process)
96 return lines;
5c7571d4 97 vty_out (vty, "router babel\n");
ca10883e
DS
98 if (diversity_kind != DIVERSITY_NONE)
99 {
5c7571d4 100 vty_out (vty, " babel diversity\n");
ca10883e
DS
101 lines++;
102 }
103 if (diversity_factor != BABEL_DEFAULT_DIVERSITY_FACTOR)
104 {
5c7571d4 105 vty_out (vty, " babel diversity-factor %d\n",diversity_factor);
ca10883e
DS
106 lines++;
107 }
108 if (resend_delay != BABEL_DEFAULT_RESEND_DELAY)
109 {
5c7571d4 110 vty_out (vty, " babel resend-delay %u\n", resend_delay);
ca10883e
DS
111 lines++;
112 }
113 if (smoothing_half_life != BABEL_DEFAULT_SMOOTHING_HALF_LIFE)
114 {
5c7571d4 115 vty_out (vty, " babel smoothing-half-life %u\n",
96ade3ed 116 smoothing_half_life);
ca10883e
DS
117 lines++;
118 }
119 /* list enabled interfaces */
120 lines = 1 + babel_enable_if_config_write (vty);
121 /* list redistributed protocols */
dd8765ca
RW
122 for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
123 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
124 if (i != zclient->redist_default &&
125 vrf_bitmap_check (zclient->redist[afi][i], VRF_DEFAULT)) {
126 vty_out (vty, " redistribute %s %s\n",
127 (afi == AFI_IP) ? "ipv4" : "ipv6",
128 zebra_route_string(i));
129 lines++;
130 }
ca10883e 131 }
dd8765ca 132 }
ca10883e 133
03a38493 134 lines += config_write_distribute (vty, babel_routing_process->distribute_ctx);
ca10883e 135
07679ad9
IR
136 vty_out (vty, "exit\n");
137
ca10883e
DS
138 return lines;
139}
140
141
142static int
143babel_create_routing_process (void)
144{
145 assert (babel_routing_process == NULL);
146
147 /* Allocaste Babel instance. */
0d6f7fd6 148 babel_routing_process = XCALLOC(MTYPE_BABEL, sizeof(struct babel));
ca10883e
DS
149
150 /* Initialize timeouts */
151 gettime(&babel_now);
152 expiry_time = babel_now.tv_sec + roughly(30);
153 source_expiry_time = babel_now.tv_sec + roughly(300);
154
155 /* Make socket for Babel protocol. */
156 protocol_socket = babel_socket(protocol_port);
157 if (protocol_socket < 0) {
450971aa 158 flog_err_sys(EC_LIB_SOCKET, "Couldn't create link local socket: %s",
f135ba52 159 safe_strerror(errno));
ca10883e
DS
160 goto fail;
161 }
162
163 /* Threads. */
164 thread_add_read(master, &babel_read_protocol, NULL, protocol_socket, &babel_routing_process->t_read);
165 /* wait a little: zebra will announce interfaces, addresses, routes... */
166 thread_add_timer_msec(master, babel_init_routing_process, NULL, 200L, &babel_routing_process->t_update);
ca10883e 167
03a38493
PG
168 /* Distribute list install. */
169 babel_routing_process->distribute_ctx = distribute_list_ctx_create (vrf_lookup_by_id(VRF_DEFAULT));
170 distribute_list_add_hook (babel_routing_process->distribute_ctx, babel_distribute_update);
171 distribute_list_delete_hook (babel_routing_process->distribute_ctx, babel_distribute_update);
172 return 0;
ca10883e
DS
173fail:
174 XFREE(MTYPE_BABEL, babel_routing_process);
ca10883e
DS
175 return -1;
176}
177
178/* thread reading entries form others babel daemons */
cc9f21da 179static void babel_read_protocol(struct thread *thread)
ca10883e
DS
180{
181 int rc;
f4e14fdb 182 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
ca10883e
DS
183 struct interface *ifp = NULL;
184 struct sockaddr_in6 sin6;
ca10883e
DS
185
186 assert(babel_routing_process != NULL);
187 assert(protocol_socket >= 0);
188
189 rc = babel_recv(protocol_socket,
190 receive_buffer, receive_buffer_size,
191 (struct sockaddr*)&sin6, sizeof(sin6));
192 if(rc < 0) {
193 if(errno != EAGAIN && errno != EINTR) {
450971aa 194 flog_err_sys(EC_LIB_SOCKET, "recv: %s", safe_strerror(errno));
ca10883e
DS
195 }
196 } else {
f4e14fdb 197 FOR_ALL_INTERFACES(vrf, ifp) {
ca10883e
DS
198 if(!if_up(ifp))
199 continue;
200 if(ifp->ifindex == (ifindex_t)sin6.sin6_scope_id) {
201 parse_packet((unsigned char*)&sin6.sin6_addr, ifp,
202 receive_buffer, rc);
203 break;
204 }
205 }
206 }
207
208 /* re-add thread */
209 thread_add_read(master, &babel_read_protocol, NULL, protocol_socket, &babel_routing_process->t_read);
ca10883e
DS
210}
211
212/* Zebra will give some information, especially about interfaces. This function
213 must be call with a litte timeout wich may give zebra the time to do his job,
214 making these inits have sense. */
cc9f21da 215static void babel_init_routing_process(struct thread *thread)
ca10883e 216{
5920b3eb 217 myseqno = (frr_weak_random() & 0xFFFF);
ca10883e
DS
218 babel_get_myid();
219 babel_load_state_file();
220 debugf(BABEL_DEBUG_COMMON, "My ID is : %s.", format_eui64(myid));
221 babel_initial_noise();
222 babel_main_loop(thread);/* this function self-add to the t_update thread */
ca10883e
DS
223}
224
225/* fill "myid" with an unique id (only if myid != {0}). */
226static void
227babel_get_myid(void)
228{
f4e14fdb 229 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
ca10883e 230 struct interface *ifp = NULL;
ca10883e
DS
231 int rc;
232 int i;
233
234 /* if we already have an id (from state file), we return. */
235 if (memcmp(myid, zeroes, 8) != 0) {
236 return;
237 }
238
f4e14fdb 239 FOR_ALL_INTERFACES(vrf, ifp) {
ca10883e
DS
240 /* ifp->ifindex is not necessarily valid at this point */
241 int ifindex = if_nametoindex(ifp->name);
242 if(ifindex > 0) {
243 unsigned char eui[8];
edb1d4a0 244 rc = if_eui64(ifindex, eui);
ca10883e
DS
245 if(rc < 0)
246 continue;
247 memcpy(myid, eui, 8);
248 return;
249 }
250 }
251
252 /* We failed to get a global EUI64 from the interfaces we were given.
253 Let's try to find an interface with a MAC address. */
254 for(i = 1; i < 256; i++) {
3682bd90 255 char buf[INTERFACE_NAMSIZ], *ifname;
ca10883e
DS
256 unsigned char eui[8];
257 ifname = if_indextoname(i, buf);
258 if(ifname == NULL)
259 continue;
edb1d4a0 260 rc = if_eui64(i, eui);
ca10883e
DS
261 if(rc < 0)
262 continue;
263 memcpy(myid, eui, 8);
264 return;
265 }
266
5c997d29 267 flog_err(EC_BABEL_CONFIG, "Couldn't find router id -- using random value.");
ca10883e
DS
268
269 rc = read_random_bytes(myid, 8);
270 if(rc < 0) {
5b003f31 271 flog_err(EC_BABEL_CONFIG, "read(random): %s (cannot assign an ID)",
e33b116c 272 safe_strerror(errno));
ca10883e
DS
273 exit(1);
274 }
275 /* Clear group and global bits */
276 myid[0] &= ~3;
277}
278
279/* Make some noise so that others notice us, and send retractions in
280 case we were restarted recently */
281static void
282babel_initial_noise(void)
283{
f4e14fdb 284 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
ca10883e 285 struct interface *ifp = NULL;
ca10883e 286
f4e14fdb 287 FOR_ALL_INTERFACES(vrf, ifp) {
ca10883e
DS
288 if(!if_up(ifp))
289 continue;
290 /* Apply jitter before we send the first message. */
291 usleep(roughly(10000));
292 gettime(&babel_now);
293 send_hello(ifp);
294 send_wildcard_retraction(ifp);
295 }
296
f4e14fdb 297 FOR_ALL_INTERFACES(vrf, ifp) {
ca10883e
DS
298 if(!if_up(ifp))
299 continue;
300 usleep(roughly(10000));
301 gettime(&babel_now);
302 send_hello(ifp);
303 send_wildcard_retraction(ifp);
304 send_self_update(ifp);
305 send_request(ifp, NULL, 0);
306 flushupdates(ifp);
307 flushbuf(ifp);
308 }
309}
310
311/* Delete all the added babel routes, make babeld only speak to zebra. */
312static void
4d762f26 313babel_clean_routing_process(void)
ca10883e
DS
314{
315 flush_all_routes();
316 babel_interface_close_all();
317
b3d6bc6e
MS
318 /* cancel events */
319 thread_cancel(&babel_routing_process->t_read);
320 thread_cancel(&babel_routing_process->t_update);
ca10883e 321
03a38493 322 distribute_list_delete(&babel_routing_process->distribute_ctx);
ca10883e 323 XFREE(MTYPE_BABEL, babel_routing_process);
ca10883e
DS
324}
325
326/* Function used with timeout. */
cc9f21da 327static void babel_main_loop(struct thread *thread)
ca10883e
DS
328{
329 struct timeval tv;
f4e14fdb 330 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
ca10883e 331 struct interface *ifp = NULL;
ca10883e
DS
332
333 while(1) {
334 gettime(&babel_now);
335
336 /* timeouts --------------------------------------------------------- */
337 /* get the next timeout */
338 babel_fill_with_next_timeout(&tv);
339 /* if there is no timeout, we must wait. */
340 if(timeval_compare(&tv, &babel_now) > 0) {
341 timeval_minus(&tv, &tv, &babel_now);
a97986ff
DL
342 debugf(BABEL_DEBUG_TIMEOUT, "babel main loop : timeout: %lld msecs",
343 (long long)tv.tv_sec * 1000 + tv.tv_usec / 1000);
ca10883e
DS
344 /* it happens often to have less than 1 ms, it's bad. */
345 timeval_add_msec(&tv, &tv, 300);
346 babel_set_timer(&tv);
cc9f21da
DS
347 return;
348 }
ca10883e
DS
349
350 gettime(&babel_now);
351
352 /* update database -------------------------------------------------- */
353 if(timeval_compare(&check_neighbours_timeout, &babel_now) < 0) {
354 int msecs;
355 msecs = check_neighbours();
356 /* Multiply by 3/2 to allow neighbours to expire. */
357 msecs = MAX(3 * msecs / 2, 10);
358 schedule_neighbours_check(msecs, 1);
359 }
360
361 if(babel_now.tv_sec >= expiry_time) {
362 expire_routes();
363 expire_resend();
364 expiry_time = babel_now.tv_sec + roughly(30);
365 }
366
367 if(babel_now.tv_sec >= source_expiry_time) {
368 expire_sources();
369 source_expiry_time = babel_now.tv_sec + roughly(300);
370 }
371
f4e14fdb 372 FOR_ALL_INTERFACES(vrf, ifp) {
ca10883e
DS
373 babel_interface_nfo *babel_ifp = NULL;
374 if(!if_up(ifp))
375 continue;
376 babel_ifp = babel_get_if_nfo(ifp);
377 if(timeval_compare(&babel_now, &babel_ifp->hello_timeout) >= 0)
378 send_hello(ifp);
379 if(timeval_compare(&babel_now, &babel_ifp->update_timeout) >= 0)
380 send_update(ifp, 0, NULL, 0);
381 if(timeval_compare(&babel_now,
382 &babel_ifp->update_flush_timeout) >= 0)
383 flushupdates(ifp);
384 }
385
386 if(resend_time.tv_sec != 0) {
387 if(timeval_compare(&babel_now, &resend_time) >= 0)
388 do_resend();
389 }
390
391 if(unicast_flush_timeout.tv_sec != 0) {
392 if(timeval_compare(&babel_now, &unicast_flush_timeout) >= 0)
393 flush_unicast(1);
394 }
395
f4e14fdb 396 FOR_ALL_INTERFACES(vrf, ifp) {
ca10883e
DS
397 babel_interface_nfo *babel_ifp = NULL;
398 if(!if_up(ifp))
399 continue;
400 babel_ifp = babel_get_if_nfo(ifp);
401 if(babel_ifp->flush_timeout.tv_sec != 0) {
402 if(timeval_compare(&babel_now, &babel_ifp->flush_timeout) >= 0)
403 flushbuf(ifp);
404 }
405 }
406 }
407
408 assert(0); /* this line should never be reach */
409}
410
411static void
412printIfMin(struct timeval *tv, int cmd, const char *tag, const char *ifname)
413{
414 static struct timeval curr_tv;
415 static char buffer[200];
416 static const char *curr_tag = NULL;
417
418 switch (cmd) {
419 case 0: /* reset timeval */
420 curr_tv = *tv;
421 if(ifname != NULL) {
422 snprintf(buffer, 200L, "interface: %s; %s", ifname, tag);
423 curr_tag = buffer;
424 } else {
425 curr_tag = tag;
426 }
427 break;
428 case 1: /* take the min */
429 if (tv->tv_sec == 0 && tv->tv_usec == 0) { /* if (tv == ∞) */
430 break;
431 }
432 if (tv->tv_sec < curr_tv.tv_sec ||(tv->tv_sec == curr_tv.tv_sec &&
433 tv->tv_usec < curr_tv.tv_usec)) {
434 curr_tv = *tv;
435 if(ifname != NULL) {
436 snprintf(buffer, 200L, "interface: %s; %s", ifname, tag);
437 curr_tag = buffer;
438 } else {
439 curr_tag = tag;
440 }
441 }
442 break;
443 case 2: /* print message */
444 debugf(BABEL_DEBUG_TIMEOUT, "next timeout due to: %s", curr_tag);
445 break;
446 default:
447 break;
448 }
449}
450
451static void
452babel_fill_with_next_timeout(struct timeval *tv)
453{
454#if (defined NO_DEBUG)
455#define printIfMin(a,b,c,d)
456#else
457#define printIfMin(a,b,c,d) \
458 if (UNLIKELY(debug & BABEL_DEBUG_TIMEOUT)) {printIfMin(a,b,c,d);}
459
f4e14fdb 460 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
ca10883e 461 struct interface *ifp = NULL;
ca10883e
DS
462
463 *tv = check_neighbours_timeout;
464 printIfMin(tv, 0, "check_neighbours_timeout", NULL);
465 timeval_min_sec(tv, expiry_time);
466 printIfMin(tv, 1, "expiry_time", NULL);
467 timeval_min_sec(tv, source_expiry_time);
468 printIfMin(tv, 1, "source_expiry_time", NULL);
469 timeval_min(tv, &resend_time);
470 printIfMin(tv, 1, "resend_time", NULL);
f4e14fdb 471 FOR_ALL_INTERFACES(vrf, ifp) {
ca10883e
DS
472 babel_interface_nfo *babel_ifp = NULL;
473 if(!if_up(ifp))
474 continue;
475 babel_ifp = babel_get_if_nfo(ifp);
476 timeval_min(tv, &babel_ifp->flush_timeout);
477 printIfMin(tv, 1, "flush_timeout", ifp->name);
478 timeval_min(tv, &babel_ifp->hello_timeout);
479 printIfMin(tv, 1, "hello_timeout", ifp->name);
480 timeval_min(tv, &babel_ifp->update_timeout);
481 printIfMin(tv, 1, "update_timeout", ifp->name);
482 timeval_min(tv, &babel_ifp->update_flush_timeout);
483 printIfMin(tv, 1, "update_flush_timeout",ifp->name);
484 }
485 timeval_min(tv, &unicast_flush_timeout);
486 printIfMin(tv, 1, "unicast_flush_timeout", NULL);
487 printIfMin(tv, 2, NULL, NULL);
488#undef printIfMin
489#endif
490}
491
492/* set the t_update thread of the babel routing process to be launch in
493 'timeout' (approximate at the milisecond) */
494static void
495babel_set_timer(struct timeval *timeout)
496{
497 long msecs = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
b3d6bc6e 498 thread_cancel(&(babel_routing_process->t_update));
ca10883e
DS
499 thread_add_timer_msec(master, babel_main_loop, NULL, msecs, &babel_routing_process->t_update);
500}
501
502void
503schedule_neighbours_check(int msecs, int override)
504{
505 struct timeval timeout;
506
507 timeval_add_msec(&timeout, &babel_now, msecs);
508 if(override)
509 check_neighbours_timeout = timeout;
510 else
511 timeval_min(&check_neighbours_timeout, &timeout);
512}
513
514int
515resize_receive_buffer(int size)
516{
517 if(size <= receive_buffer_size)
518 return 0;
519
520 if(receive_buffer == NULL) {
521 receive_buffer = malloc(size);
522 if(receive_buffer == NULL) {
5b003f31 523 flog_err(EC_BABEL_MEMORY, "malloc(receive_buffer): %s",
f135ba52 524 safe_strerror(errno));
ca10883e
DS
525 return -1;
526 }
527 receive_buffer_size = size;
528 } else {
529 unsigned char *new;
530 new = realloc(receive_buffer, size);
531 if(new == NULL) {
5b003f31 532 flog_err(EC_BABEL_MEMORY, "realloc(receive_buffer): %s",
f135ba52 533 safe_strerror(errno));
ca10883e
DS
534 return -1;
535 }
536 receive_buffer = new;
537 receive_buffer_size = size;
538 }
539 return 1;
540}
541
542static void
03a38493 543babel_distribute_update (struct distribute_ctx *ctx, struct distribute *dist)
ca10883e
DS
544{
545 struct interface *ifp;
546 babel_interface_nfo *babel_ifp;
547 int type;
548 int family;
549
550 if (! dist->ifname)
551 return;
552
a36898e7 553 ifp = if_lookup_by_name (dist->ifname, VRF_DEFAULT);
ca10883e
DS
554 if (ifp == NULL)
555 return;
556
557 babel_ifp = babel_get_if_nfo(ifp);
558
559 for (type = 0; type < DISTRIBUTE_MAX; type++) {
560 family = type == DISTRIBUTE_V4_IN || type == DISTRIBUTE_V4_OUT ?
561 AFI_IP : AFI_IP6;
562 if (dist->list[type])
563 babel_ifp->list[type] = access_list_lookup (family,
564 dist->list[type]);
565 else
566 babel_ifp->list[type] = NULL;
567 if (dist->prefix[type])
568 babel_ifp->prefix[type] = prefix_list_lookup (family,
569 dist->prefix[type]);
570 else
571 babel_ifp->prefix[type] = NULL;
572 }
573}
574
575static void
576babel_distribute_update_interface (struct interface *ifp)
577{
03a38493 578 struct distribute *dist = NULL;
ca10883e 579
03a38493
PG
580 if (babel_routing_process)
581 dist = distribute_lookup(babel_routing_process->distribute_ctx, ifp->name);
ca10883e 582 if (dist)
03a38493 583 babel_distribute_update (babel_routing_process->distribute_ctx, dist);
ca10883e
DS
584}
585
586/* Update all interface's distribute list. */
587static void
588babel_distribute_update_all (struct prefix_list *notused)
589{
f4e14fdb 590 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
ca10883e 591 struct interface *ifp;
ca10883e 592
451fda4f 593 FOR_ALL_INTERFACES (vrf, ifp)
ca10883e
DS
594 babel_distribute_update_interface (ifp);
595}
596
597static void
598babel_distribute_update_all_wrapper (struct access_list *notused)
599{
600 babel_distribute_update_all(NULL);
601}
602
603
604/* [Command] */
f84d11d1
DS
605DEFUN_NOSH (router_babel,
606 router_babel_cmd,
607 "router babel",
608 "Enable a routing process\n"
609 "Make Babel instance command\n")
ca10883e
DS
610{
611 int ret;
612
613 vty->node = BABEL_NODE;
614
615 if (!babel_routing_process) {
616 ret = babel_create_routing_process ();
617
618 /* Notice to user we couldn't create Babel. */
619 if (ret < 0) {
620 zlog_warn ("can't create Babel");
621 return CMD_WARNING;
622 }
623 }
624
625 return CMD_SUCCESS;
626}
627
628/* [Command] */
629DEFUN (no_router_babel,
630 no_router_babel_cmd,
631 "no router babel",
632 NO_STR
633 "Disable a routing process\n"
7111c1a0 634 "Remove Babel instance command\n")
ca10883e
DS
635{
636 if(babel_routing_process)
637 babel_clean_routing_process();
638 return CMD_SUCCESS;
639}
640
641/* [Babel Command] */
642DEFUN (babel_diversity,
643 babel_diversity_cmd,
644 "babel diversity",
645 "Babel commands\n"
646 "Enable diversity-aware routing.\n")
647{
648 diversity_kind = DIVERSITY_CHANNEL;
649 return CMD_SUCCESS;
650}
651
652/* [Babel Command] */
653DEFUN (no_babel_diversity,
654 no_babel_diversity_cmd,
655 "no babel diversity",
656 NO_STR
657 "Babel commands\n"
658 "Disable diversity-aware routing.\n")
659{
660 diversity_kind = DIVERSITY_NONE;
661 return CMD_SUCCESS;
662}
663
664/* [Babel Command] */
665DEFUN (babel_diversity_factor,
666 babel_diversity_factor_cmd,
667 "babel diversity-factor (1-256)",
668 "Babel commands\n"
669 "Set the diversity factor.\n"
670 "Factor in units of 1/256.\n")
671{
672 int factor;
673
facfee22 674 factor = strtoul(argv[2]->arg, NULL, 10);
ca10883e
DS
675
676 diversity_factor = factor;
677 return CMD_SUCCESS;
678}
679
680/* [Babel Command] */
681DEFUN (babel_set_resend_delay,
682 babel_set_resend_delay_cmd,
683 "babel resend-delay (20-655340)",
684 "Babel commands\n"
685 "Time before resending a message\n"
686 "Milliseconds\n")
687{
688 int interval;
689
facfee22 690 interval = strtoul(argv[2]->arg, NULL, 10);
ca10883e
DS
691
692 resend_delay = interval;
693 return CMD_SUCCESS;
694}
695
696/* [Babel Command] */
697DEFUN (babel_set_smoothing_half_life,
698 babel_set_smoothing_half_life_cmd,
699 "babel smoothing-half-life (0-65534)",
700 "Babel commands\n"
701 "Smoothing half-life\n"
702 "Seconds (0 to disable)\n")
703{
704 int seconds;
705
facfee22 706 seconds = strtoul(argv[2]->arg, NULL, 10);
ca10883e
DS
707
708 change_smoothing_half_life(seconds);
709 return CMD_SUCCESS;
710}
711
32282a6e
DS
712DEFUN (babel_distribute_list,
713 babel_distribute_list_cmd,
c60dec36 714 "distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
32282a6e
DS
715 "Filter networks in routing updates\n"
716 "Specify a prefix\n"
717 "Access-list name\n"
718 "Filter incoming routing updates\n"
719 "Filter outgoing routing updates\n"
720 "Interface name\n")
721{
722 const char *ifname = NULL;
723 int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
724
725 if (argv[argc - 1]->type == VARIABLE_TKN)
726 ifname = argv[argc - 1]->arg;
727
728 return distribute_list_parser(prefix, true, argv[2 + prefix]->text,
729 argv[1 + prefix]->arg, ifname);
730}
731
732DEFUN (babel_no_distribute_list,
733 babel_no_distribute_list_cmd,
c60dec36 734 "no distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
32282a6e
DS
735 NO_STR
736 "Filter networks in routing updates\n"
737 "Specify a prefix\n"
738 "Access-list name\n"
739 "Filter incoming routing updates\n"
740 "Filter outgoing routing updates\n"
741 "Interface name\n")
742{
743 const char *ifname = NULL;
744 int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
745
746 if (argv[argc - 1]->type == VARIABLE_TKN)
747 ifname = argv[argc - 1]->arg;
748
749 return distribute_list_no_parser(vty, prefix, true,
750 argv[3 + prefix]->text,
751 argv[2 + prefix]->arg, ifname);
752}
753
754DEFUN (babel_ipv6_distribute_list,
755 babel_ipv6_distribute_list_cmd,
c60dec36 756 "ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
32282a6e
DS
757 "IPv6\n"
758 "Filter networks in routing updates\n"
759 "Specify a prefix\n"
760 "Access-list name\n"
761 "Filter incoming routing updates\n"
762 "Filter outgoing routing updates\n"
763 "Interface name\n")
764{
765 const char *ifname = NULL;
766 int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
767
768 if (argv[argc - 1]->type == VARIABLE_TKN)
769 ifname = argv[argc - 1]->arg;
770
771 return distribute_list_parser(prefix, false, argv[3 + prefix]->text,
772 argv[2 + prefix]->arg, ifname);
773}
774
775DEFUN (babel_no_ipv6_distribute_list,
776 babel_no_ipv6_distribute_list_cmd,
c60dec36 777 "no ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
32282a6e
DS
778 NO_STR
779 "IPv6\n"
780 "Filter networks in routing updates\n"
781 "Specify a prefix\n"
782 "Access-list name\n"
783 "Filter incoming routing updates\n"
784 "Filter outgoing routing updates\n"
785 "Interface name\n")
786{
787 const char *ifname = NULL;
788 int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0;
789
790 if (argv[argc - 1]->type == VARIABLE_TKN)
791 ifname = argv[argc - 1]->arg;
792
793 return distribute_list_no_parser(vty, prefix, false,
794 argv[4 + prefix]->text,
795 argv[3 + prefix]->arg, ifname);
796}
797
ca10883e
DS
798void
799babeld_quagga_init(void)
800{
801
612c2c15 802 install_node(&cmd_babel_node);
ca10883e
DS
803
804 install_element(CONFIG_NODE, &router_babel_cmd);
805 install_element(CONFIG_NODE, &no_router_babel_cmd);
806
807 install_default(BABEL_NODE);
808 install_element(BABEL_NODE, &babel_diversity_cmd);
809 install_element(BABEL_NODE, &no_babel_diversity_cmd);
810 install_element(BABEL_NODE, &babel_diversity_factor_cmd);
811 install_element(BABEL_NODE, &babel_set_resend_delay_cmd);
812 install_element(BABEL_NODE, &babel_set_smoothing_half_life_cmd);
813
32282a6e
DS
814 install_element(BABEL_NODE, &babel_distribute_list_cmd);
815 install_element(BABEL_NODE, &babel_no_distribute_list_cmd);
816 install_element(BABEL_NODE, &babel_ipv6_distribute_list_cmd);
817 install_element(BABEL_NODE, &babel_no_ipv6_distribute_list_cmd);
818
cfc369c4 819 vrf_cmd_init(NULL);
f5eef2d5 820
ca10883e
DS
821 babel_if_init();
822
823 /* Access list install. */
824 access_list_init ();
825 access_list_add_hook (babel_distribute_update_all_wrapper);
826 access_list_delete_hook (babel_distribute_update_all_wrapper);
827
828 /* Prefix list initialize.*/
829 prefix_list_init ();
830 prefix_list_add_hook (babel_distribute_update_all);
831 prefix_list_delete_hook (babel_distribute_update_all);
ca10883e
DS
832}
833
834/* Stubs to adapt Babel's filtering calls to Quagga's infrastructure. */
835
836int
837input_filter(const unsigned char *id,
838 const unsigned char *prefix, unsigned short plen,
839 const unsigned char *neigh, unsigned int ifindex)
840{
841 return babel_filter(0, prefix, plen, ifindex);
842}
843
844int
845output_filter(const unsigned char *id, const unsigned char *prefix,
846 unsigned short plen, unsigned int ifindex)
847{
848 return babel_filter(1, prefix, plen, ifindex);
849}
850
851/* There's no redistribute filter in Quagga -- the zebra daemon does its
852 own filtering. */
853int
854redistribute_filter(const unsigned char *prefix, unsigned short plen,
855 unsigned int ifindex, int proto)
856{
857 return 0;
858}
859
03a38493
PG
860struct babel *babel_lookup(void)
861{
862 return babel_routing_process;
863}