babeld.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /*
  2. * This file is free software: you may copy, redistribute and/or modify it
  3. * under the terms of the GNU General Public License as published by the
  4. * Free Software Foundation, either version 2 of the License, or (at your
  5. * option) any later version.
  6. *
  7. * This file is distributed in the hope that it will be useful, but
  8. * WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. * General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. *
  15. * This file incorporates work covered by the following copyright and
  16. * permission notice:
  17. *
  18. Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
  19. Permission is hereby granted, free of charge, to any person obtaining a copy
  20. of this software and associated documentation files (the "Software"), to deal
  21. in the Software without restriction, including without limitation the rights
  22. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  23. copies of the Software, and to permit persons to whom the Software is
  24. furnished to do so, subject to the following conditions:
  25. The above copyright notice and this permission notice shall be included in
  26. all copies or substantial portions of the Software.
  27. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  28. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  29. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  30. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  31. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  32. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  33. THE SOFTWARE.
  34. */
  35. #include <zebra.h>
  36. #include "command.h"
  37. #include "prefix.h"
  38. #include "memory.h"
  39. #include "memtypes.h"
  40. #include "table.h"
  41. #include "distribute.h"
  42. #include "prefix.h"
  43. #include "filter.h"
  44. #include "plist.h"
  45. #include "babel_main.h"
  46. #include "babeld.h"
  47. #include "util.h"
  48. #include "net.h"
  49. #include "kernel.h"
  50. #include "babel_interface.h"
  51. #include "neighbour.h"
  52. #include "route.h"
  53. #include "message.h"
  54. #include "resend.h"
  55. #include "babel_filter.h"
  56. #include "babel_zebra.h"
  57. static int babel_init_routing_process(struct thread *thread);
  58. static void babel_get_myid(void);
  59. static void babel_initial_noise(void);
  60. static int babel_read_protocol (struct thread *thread);
  61. static int babel_main_loop(struct thread *thread);
  62. static void babel_set_timer(struct timeval *timeout);
  63. static void babel_fill_with_next_timeout(struct timeval *tv);
  64. /* Informations relative to the babel running daemon. */
  65. static struct babel *babel_routing_process = NULL;
  66. static unsigned char *receive_buffer = NULL;
  67. static int receive_buffer_size = 0;
  68. /* timeouts */
  69. struct timeval check_neighbours_timeout;
  70. static time_t expiry_time;
  71. static time_t source_expiry_time;
  72. /* Babel node structure. */
  73. static struct cmd_node cmd_babel_node =
  74. {
  75. .node = BABEL_NODE,
  76. .prompt = "%s(config-router)# ",
  77. .vtysh = 1,
  78. };
  79. /* print current babel configuration on vty */
  80. static int
  81. babel_config_write (struct vty *vty)
  82. {
  83. int lines = 0;
  84. int i;
  85. /* list enabled debug modes */
  86. lines += debug_babel_config_write (vty);
  87. if (!babel_routing_process)
  88. return lines;
  89. vty_out (vty, "router babel%s", VTY_NEWLINE);
  90. if (resend_delay != BABEL_DEFAULT_RESEND_DELAY)
  91. {
  92. vty_out (vty, " babel resend-delay %u%s", resend_delay, VTY_NEWLINE);
  93. lines++;
  94. }
  95. /* list enabled interfaces */
  96. lines = 1 + babel_enable_if_config_write (vty);
  97. /* list redistributed protocols */
  98. for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
  99. if (i != zclient->redist_default && zclient->redist[i])
  100. {
  101. vty_out (vty, " redistribute %s%s", zebra_route_string (i), VTY_NEWLINE);
  102. lines++;
  103. }
  104. return lines;
  105. }
  106. static int
  107. babel_create_routing_process (void)
  108. {
  109. assert (babel_routing_process == NULL);
  110. /* Allocaste Babel instance. */
  111. babel_routing_process = XCALLOC (MTYPE_BABEL, sizeof (struct babel));
  112. /* Initialize timeouts */
  113. gettime(&babel_now);
  114. expiry_time = babel_now.tv_sec + roughly(30);
  115. source_expiry_time = babel_now.tv_sec + roughly(300);
  116. /* Make socket for Babel protocol. */
  117. protocol_socket = babel_socket(protocol_port);
  118. if (protocol_socket < 0) {
  119. zlog_err("Couldn't create link local socket: %s", safe_strerror(errno));
  120. goto fail;
  121. }
  122. /* Threads. */
  123. babel_routing_process->t_read =
  124. thread_add_read(master, &babel_read_protocol, NULL, protocol_socket);
  125. /* wait a little: zebra will announce interfaces, addresses, routes... */
  126. babel_routing_process->t_update =
  127. thread_add_timer_msec(master, &babel_init_routing_process, NULL, 200L);
  128. return 0;
  129. fail:
  130. XFREE(MTYPE_BABEL, babel_routing_process);
  131. babel_routing_process = NULL;
  132. return -1;
  133. }
  134. /* thread reading entries form others babel daemons */
  135. static int
  136. babel_read_protocol (struct thread *thread)
  137. {
  138. int rc;
  139. struct interface *ifp = NULL;
  140. struct sockaddr_in6 sin6;
  141. struct listnode *linklist_node = NULL;
  142. assert(babel_routing_process != NULL);
  143. assert(protocol_socket >= 0);
  144. rc = babel_recv(protocol_socket,
  145. receive_buffer, receive_buffer_size,
  146. (struct sockaddr*)&sin6, sizeof(sin6));
  147. if(rc < 0) {
  148. if(errno != EAGAIN && errno != EINTR) {
  149. zlog_err("recv: %s", safe_strerror(errno));
  150. }
  151. } else {
  152. FOR_ALL_INTERFACES(ifp, linklist_node) {
  153. if(!if_up(ifp))
  154. continue;
  155. if(ifp->ifindex == sin6.sin6_scope_id) {
  156. parse_packet((unsigned char*)&sin6.sin6_addr, ifp,
  157. receive_buffer, rc);
  158. break;
  159. }
  160. }
  161. }
  162. /* re-add thread */
  163. babel_routing_process->t_read =
  164. thread_add_read(master, &babel_read_protocol, NULL, protocol_socket);
  165. return 0;
  166. }
  167. /* Zebra will give some information, especially about interfaces. This function
  168. must be call with a litte timeout wich may give zebra the time to do his job,
  169. making these inits have sense. */
  170. static int
  171. babel_init_routing_process(struct thread *thread)
  172. {
  173. myseqno = (random() & 0xFFFF);
  174. babel_get_myid();
  175. babel_load_state_file();
  176. debugf(BABEL_DEBUG_COMMON, "My ID is : %s.", format_eui64(myid));
  177. babel_initial_noise();
  178. babel_main_loop(thread);/* this function self-add to the t_update thread */
  179. return 0;
  180. }
  181. /* fill "myid" with an unique id (only if myid != {0}). */
  182. static void
  183. babel_get_myid(void)
  184. {
  185. struct interface *ifp = NULL;
  186. struct listnode *linklist_node = NULL;
  187. int rc;
  188. int i;
  189. /* if we already have an id (from state file), we return. */
  190. if (memcmp(myid, zeroes, 8) != 0) {
  191. return;
  192. }
  193. FOR_ALL_INTERFACES(ifp, linklist_node) {
  194. /* ifp->ifindex is not necessarily valid at this point */
  195. int ifindex = if_nametoindex(ifp->name);
  196. if(ifindex > 0) {
  197. unsigned char eui[8];
  198. rc = if_eui64(ifp->name, ifindex, eui);
  199. if(rc < 0)
  200. continue;
  201. memcpy(myid, eui, 8);
  202. return;
  203. }
  204. }
  205. /* We failed to get a global EUI64 from the interfaces we were given.
  206. Let's try to find an interface with a MAC address. */
  207. for(i = 1; i < 256; i++) {
  208. char buf[IF_NAMESIZE], *ifname;
  209. unsigned char eui[8];
  210. ifname = if_indextoname(i, buf);
  211. if(ifname == NULL)
  212. continue;
  213. rc = if_eui64(ifname, i, eui);
  214. if(rc < 0)
  215. continue;
  216. memcpy(myid, eui, 8);
  217. return;
  218. }
  219. zlog_err("Warning: couldn't find router id -- using random value.");
  220. rc = read_random_bytes(myid, 8);
  221. if(rc < 0) {
  222. zlog_err("read(random): %s (cannot assign an ID)",safe_strerror(errno));
  223. exit(1);
  224. }
  225. /* Clear group and global bits */
  226. myid[0] &= ~3;
  227. }
  228. /* Make some noise so that others notice us, and send retractions in
  229. case we were restarted recently */
  230. static void
  231. babel_initial_noise(void)
  232. {
  233. struct interface *ifp = NULL;
  234. struct listnode *linklist_node = NULL;
  235. FOR_ALL_INTERFACES(ifp, linklist_node) {
  236. if(!if_up(ifp))
  237. continue;
  238. /* Apply jitter before we send the first message. */
  239. usleep(roughly(10000));
  240. gettime(&babel_now);
  241. send_hello(ifp);
  242. send_wildcard_retraction(ifp);
  243. }
  244. FOR_ALL_INTERFACES(ifp, linklist_node) {
  245. if(!if_up(ifp))
  246. continue;
  247. usleep(roughly(10000));
  248. gettime(&babel_now);
  249. send_hello(ifp);
  250. send_wildcard_retraction(ifp);
  251. send_self_update(ifp);
  252. send_request(ifp, NULL, 0);
  253. flushupdates(ifp);
  254. flushbuf(ifp);
  255. }
  256. }
  257. /* Delete all the added babel routes, make babeld only speak to zebra. */
  258. static void
  259. babel_clean_routing_process()
  260. {
  261. flush_all_routes();
  262. babel_interface_close_all();
  263. /* cancel threads */
  264. if (babel_routing_process->t_read != NULL) {
  265. thread_cancel(babel_routing_process->t_read);
  266. }
  267. if (babel_routing_process->t_update != NULL) {
  268. thread_cancel(babel_routing_process->t_update);
  269. }
  270. XFREE(MTYPE_BABEL, babel_routing_process);
  271. babel_routing_process = NULL;
  272. }
  273. /* Function used with timeout. */
  274. static int
  275. babel_main_loop(struct thread *thread)
  276. {
  277. struct timeval tv;
  278. struct interface *ifp = NULL;
  279. struct listnode *linklist_node = NULL;
  280. while(1) {
  281. gettime(&babel_now);
  282. /* timeouts --------------------------------------------------------- */
  283. /* get the next timeout */
  284. babel_fill_with_next_timeout(&tv);
  285. /* if there is no timeout, we must wait. */
  286. if(timeval_compare(&tv, &babel_now) > 0) {
  287. timeval_minus(&tv, &tv, &babel_now);
  288. debugf(BABEL_DEBUG_TIMEOUT, "babel main loop : timeout: %lld msecs",
  289. tv.tv_sec * 1000LL + tv.tv_usec / 1000LL);
  290. /* it happens often to have less than 1 ms, it's bad. */
  291. timeval_add_msec(&tv, &tv, 300);
  292. babel_set_timer(&tv);
  293. return 0;
  294. }
  295. gettime(&babel_now);
  296. /* update database -------------------------------------------------- */
  297. if(timeval_compare(&check_neighbours_timeout, &babel_now) < 0) {
  298. int msecs;
  299. msecs = check_neighbours();
  300. msecs = MAX(msecs, 10);
  301. schedule_neighbours_check(msecs, 1);
  302. }
  303. if(babel_now.tv_sec >= expiry_time) {
  304. expire_routes();
  305. expire_resend();
  306. expiry_time = babel_now.tv_sec + roughly(30);
  307. }
  308. if(babel_now.tv_sec >= source_expiry_time) {
  309. expire_sources();
  310. source_expiry_time = babel_now.tv_sec + roughly(300);
  311. }
  312. FOR_ALL_INTERFACES(ifp, linklist_node) {
  313. babel_interface_nfo *babel_ifp = NULL;
  314. if(!if_up(ifp))
  315. continue;
  316. babel_ifp = babel_get_if_nfo(ifp);
  317. if(timeval_compare(&babel_now, &babel_ifp->hello_timeout) >= 0)
  318. send_hello(ifp);
  319. if(timeval_compare(&babel_now, &babel_ifp->update_timeout) >= 0)
  320. send_update(ifp, 0, NULL, 0);
  321. if(timeval_compare(&babel_now,
  322. &babel_ifp->update_flush_timeout) >= 0)
  323. flushupdates(ifp);
  324. }
  325. if(resend_time.tv_sec != 0) {
  326. if(timeval_compare(&babel_now, &resend_time) >= 0)
  327. do_resend();
  328. }
  329. if(unicast_flush_timeout.tv_sec != 0) {
  330. if(timeval_compare(&babel_now, &unicast_flush_timeout) >= 0)
  331. flush_unicast(1);
  332. }
  333. FOR_ALL_INTERFACES(ifp, linklist_node) {
  334. babel_interface_nfo *babel_ifp = NULL;
  335. if(!if_up(ifp))
  336. continue;
  337. babel_ifp = babel_get_if_nfo(ifp);
  338. if(babel_ifp->flush_timeout.tv_sec != 0) {
  339. if(timeval_compare(&babel_now, &babel_ifp->flush_timeout) >= 0)
  340. flushbuf(ifp);
  341. }
  342. }
  343. }
  344. assert(0); /* this line should never be reach */
  345. }
  346. static void
  347. printIfMin(struct timeval *tv, int cmd, const char *tag, const char *ifname)
  348. {
  349. static struct timeval curr_tv;
  350. static char buffer[200];
  351. static const char *curr_tag = NULL;
  352. switch (cmd) {
  353. case 0: /* reset timeval */
  354. curr_tv = *tv;
  355. if(ifname != NULL) {
  356. snprintf(buffer, 200L, "interface: %s; %s", ifname, tag);
  357. curr_tag = buffer;
  358. } else {
  359. curr_tag = tag;
  360. }
  361. break;
  362. case 1: /* take the min */
  363. if (tv->tv_sec == 0 && tv->tv_usec == 0) { /* if (tv == ∞) */
  364. break;
  365. }
  366. if (tv->tv_sec < curr_tv.tv_sec ||(tv->tv_sec == curr_tv.tv_sec &&
  367. tv->tv_usec < curr_tv.tv_usec)) {
  368. curr_tv = *tv;
  369. if(ifname != NULL) {
  370. snprintf(buffer, 200L, "interface: %s; %s", ifname, tag);
  371. curr_tag = buffer;
  372. } else {
  373. curr_tag = tag;
  374. }
  375. }
  376. break;
  377. case 2: /* print message */
  378. debugf(BABEL_DEBUG_TIMEOUT, "next timeout due to: %s", curr_tag);
  379. break;
  380. default:
  381. break;
  382. }
  383. }
  384. static void
  385. babel_fill_with_next_timeout(struct timeval *tv)
  386. {
  387. #if (defined NO_DEBUG)
  388. #define printIfMin(a,b,c,d)
  389. #else
  390. #define printIfMin(a,b,c,d) \
  391. if (UNLIKELY(debug & BABEL_DEBUG_TIMEOUT)) {printIfMin(a,b,c,d);}
  392. struct interface *ifp = NULL;
  393. struct listnode *linklist_node = NULL;
  394. *tv = check_neighbours_timeout;
  395. printIfMin(tv, 0, "check_neighbours_timeout", NULL);
  396. timeval_min_sec(tv, expiry_time);
  397. printIfMin(tv, 1, "expiry_time", NULL);
  398. timeval_min_sec(tv, source_expiry_time);
  399. printIfMin(tv, 1, "source_expiry_time", NULL);
  400. timeval_min(tv, &resend_time);
  401. printIfMin(tv, 1, "resend_time", NULL);
  402. FOR_ALL_INTERFACES(ifp, linklist_node) {
  403. babel_interface_nfo *babel_ifp = NULL;
  404. if(!if_up(ifp))
  405. continue;
  406. babel_ifp = babel_get_if_nfo(ifp);
  407. timeval_min(tv, &babel_ifp->flush_timeout);
  408. printIfMin(tv, 1, "flush_timeout", ifp->name);
  409. timeval_min(tv, &babel_ifp->hello_timeout);
  410. printIfMin(tv, 1, "hello_timeout", ifp->name);
  411. timeval_min(tv, &babel_ifp->update_timeout);
  412. printIfMin(tv, 1, "update_timeout", ifp->name);
  413. timeval_min(tv, &babel_ifp->update_flush_timeout);
  414. printIfMin(tv, 1, "update_flush_timeout",ifp->name);
  415. }
  416. timeval_min(tv, &unicast_flush_timeout);
  417. printIfMin(tv, 1, "unicast_flush_timeout", NULL);
  418. printIfMin(tv, 2, NULL, NULL);
  419. #undef printIfMin
  420. #endif
  421. }
  422. /* set the t_update thread of the babel routing process to be launch in
  423. 'timeout' (approximate at the milisecond) */
  424. static void
  425. babel_set_timer(struct timeval *timeout)
  426. {
  427. long msecs = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
  428. if (babel_routing_process->t_update != NULL) {
  429. thread_cancel(babel_routing_process->t_update);
  430. }
  431. babel_routing_process->t_update =
  432. thread_add_timer_msec(master, &babel_main_loop, NULL, msecs);
  433. }
  434. /* Schedule a neighbours check after roughly 3/2 times msecs have elapsed. */
  435. void
  436. schedule_neighbours_check(int msecs, int override)
  437. {
  438. struct timeval timeout;
  439. timeval_add_msec(&timeout, &babel_now, roughly(msecs * 3 / 2));
  440. if(override)
  441. check_neighbours_timeout = timeout;
  442. else
  443. timeval_min(&check_neighbours_timeout, &timeout);
  444. }
  445. int
  446. resize_receive_buffer(int size)
  447. {
  448. if(size <= receive_buffer_size)
  449. return 0;
  450. if(receive_buffer == NULL) {
  451. receive_buffer = malloc(size);
  452. if(receive_buffer == NULL) {
  453. zlog_err("malloc(receive_buffer): %s", safe_strerror(errno));
  454. return -1;
  455. }
  456. receive_buffer_size = size;
  457. } else {
  458. unsigned char *new;
  459. new = realloc(receive_buffer, size);
  460. if(new == NULL) {
  461. zlog_err("realloc(receive_buffer): %s", safe_strerror(errno));
  462. return -1;
  463. }
  464. receive_buffer = new;
  465. receive_buffer_size = size;
  466. }
  467. return 1;
  468. }
  469. static void
  470. babel_distribute_update (struct distribute *dist)
  471. {
  472. struct interface *ifp;
  473. babel_interface_nfo *babel_ifp;
  474. struct access_list *alist;
  475. struct prefix_list *plist;
  476. if (! dist->ifname)
  477. return;
  478. ifp = if_lookup_by_name (dist->ifname);
  479. if (ifp == NULL)
  480. return;
  481. babel_ifp = babel_get_if_nfo(ifp);
  482. if (dist->list[DISTRIBUTE_IN]) {
  483. alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_IN]);
  484. if (alist)
  485. babel_ifp->list[BABEL_FILTER_IN] = alist;
  486. else
  487. babel_ifp->list[BABEL_FILTER_IN] = NULL;
  488. } else {
  489. babel_ifp->list[BABEL_FILTER_IN] = NULL;
  490. }
  491. if (dist->list[DISTRIBUTE_OUT]) {
  492. alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_OUT]);
  493. if (alist)
  494. babel_ifp->list[BABEL_FILTER_OUT] = alist;
  495. else
  496. babel_ifp->list[BABEL_FILTER_OUT] = NULL;
  497. } else {
  498. babel_ifp->list[BABEL_FILTER_OUT] = NULL;
  499. }
  500. if (dist->prefix[DISTRIBUTE_IN]) {
  501. plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_IN]);
  502. if (plist)
  503. babel_ifp->prefix[BABEL_FILTER_IN] = plist;
  504. else
  505. babel_ifp->prefix[BABEL_FILTER_IN] = NULL;
  506. } else {
  507. babel_ifp->prefix[BABEL_FILTER_IN] = NULL;
  508. }
  509. if (dist->prefix[DISTRIBUTE_OUT]) {
  510. plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_OUT]);
  511. if (plist)
  512. babel_ifp->prefix[BABEL_FILTER_OUT] = plist;
  513. else
  514. babel_ifp->prefix[BABEL_FILTER_OUT] = NULL;
  515. } else {
  516. babel_ifp->prefix[BABEL_FILTER_OUT] = NULL;
  517. }
  518. }
  519. static void
  520. babel_distribute_update_interface (struct interface *ifp)
  521. {
  522. struct distribute *dist;
  523. dist = distribute_lookup (ifp->name);
  524. if (dist)
  525. babel_distribute_update (dist);
  526. }
  527. /* Update all interface's distribute list. */
  528. static void
  529. babel_distribute_update_all (struct prefix_list *notused)
  530. {
  531. struct interface *ifp;
  532. struct listnode *node;
  533. for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
  534. babel_distribute_update_interface (ifp);
  535. }
  536. static void
  537. babel_distribute_update_all_wrapper (struct access_list *notused)
  538. {
  539. babel_distribute_update_all(NULL);
  540. }
  541. /* [Command] */
  542. DEFUN (router_babel,
  543. router_babel_cmd,
  544. "router babel",
  545. "Enable a routing process\n"
  546. "Make Babel instance command\n"
  547. "No attributes\n")
  548. {
  549. int ret;
  550. vty->node = BABEL_NODE;
  551. if (!babel_routing_process) {
  552. ret = babel_create_routing_process ();
  553. /* Notice to user we couldn't create Babel. */
  554. if (ret < 0) {
  555. zlog_warn ("can't create Babel");
  556. return CMD_WARNING;
  557. }
  558. }
  559. return CMD_SUCCESS;
  560. }
  561. /* [Command] */
  562. DEFUN (no_router_babel,
  563. no_router_babel_cmd,
  564. "no router babel",
  565. NO_STR
  566. "Disable a routing process\n"
  567. "Remove Babel instance command\n"
  568. "No attributes\n")
  569. {
  570. if(babel_routing_process)
  571. babel_clean_routing_process();
  572. return CMD_SUCCESS;
  573. }
  574. /* [Babel Command] */
  575. DEFUN (babel_set_resend_delay,
  576. babel_set_resend_delay_cmd,
  577. "babel resend-delay <20-655340>",
  578. "Babel commands\n"
  579. "Time before resending a message\n"
  580. "Milliseconds\n")
  581. {
  582. int interval;
  583. VTY_GET_INTEGER_RANGE("milliseconds", interval, argv[0], 20, 10 * 0xFFFE);
  584. resend_delay = interval;
  585. return CMD_SUCCESS;
  586. }
  587. void
  588. babeld_quagga_init(void)
  589. {
  590. install_node(&cmd_babel_node, &babel_config_write);
  591. install_element(CONFIG_NODE, &router_babel_cmd);
  592. install_element(CONFIG_NODE, &no_router_babel_cmd);
  593. install_default(BABEL_NODE);
  594. install_element(BABEL_NODE, &babel_set_resend_delay_cmd);
  595. babel_if_init();
  596. /* Access list install. */
  597. access_list_init ();
  598. access_list_add_hook (babel_distribute_update_all_wrapper);
  599. access_list_delete_hook (babel_distribute_update_all_wrapper);
  600. /* Prefix list initialize.*/
  601. prefix_list_init ();
  602. prefix_list_add_hook (babel_distribute_update_all);
  603. prefix_list_delete_hook (babel_distribute_update_all);
  604. /* Distribute list install. */
  605. distribute_list_init (BABEL_NODE);
  606. distribute_list_add_hook (babel_distribute_update);
  607. distribute_list_delete_hook (babel_distribute_update);
  608. }
  609. /* Stubs to adapt Babel's filtering calls to Quagga's infrastructure. */
  610. int
  611. input_filter(const unsigned char *id,
  612. const unsigned char *prefix, unsigned short plen,
  613. const unsigned char *neigh, unsigned int ifindex)
  614. {
  615. return babel_filter(0, prefix, plen, ifindex);
  616. }
  617. int
  618. output_filter(const unsigned char *id, const unsigned char *prefix,
  619. unsigned short plen, unsigned int ifindex)
  620. {
  621. return babel_filter(1, prefix, plen, ifindex);
  622. }
  623. /* There's no redistribute filter in Quagga -- the zebra daemon does its
  624. own filtering. */
  625. int
  626. redistribute_filter(const unsigned char *prefix, unsigned short plen,
  627. unsigned int ifindex, int proto)
  628. {
  629. return 0;
  630. }