rip_zebra.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. /* RIPd and zebra interface.
  2. * Copyright (C) 1997, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
  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. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  18. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19. * 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include "command.h"
  23. #include "prefix.h"
  24. #include "stream.h"
  25. #include "routemap.h"
  26. #include "zclient.h"
  27. #include "log.h"
  28. #include "ripd/ripd.h"
  29. #include "ripd/rip_debug.h"
  30. #include "ripd/rip_interface.h"
  31. /* All information about zebra. */
  32. struct zclient *zclient = NULL;
  33. /* RIPd to zebra command interface. */
  34. void
  35. rip_zebra_ipv4_add (struct prefix_ipv4 *p, struct in_addr *nexthop,
  36. u_int32_t metric, u_char distance)
  37. {
  38. struct zapi_ipv4 api;
  39. if (zclient->redist[ZEBRA_ROUTE_RIP])
  40. {
  41. api.type = ZEBRA_ROUTE_RIP;
  42. api.flags = 0;
  43. api.message = 0;
  44. SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  45. api.nexthop_num = 1;
  46. api.nexthop = &nexthop;
  47. api.ifindex_num = 0;
  48. SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  49. api.metric = metric;
  50. if (distance && distance != ZEBRA_RIP_DISTANCE_DEFAULT)
  51. {
  52. SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
  53. api.distance = distance;
  54. }
  55. zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
  56. rip_global_route_changes++;
  57. }
  58. }
  59. void
  60. rip_zebra_ipv4_delete (struct prefix_ipv4 *p, struct in_addr *nexthop,
  61. u_int32_t metric)
  62. {
  63. struct zapi_ipv4 api;
  64. if (zclient->redist[ZEBRA_ROUTE_RIP])
  65. {
  66. api.type = ZEBRA_ROUTE_RIP;
  67. api.flags = 0;
  68. api.message = 0;
  69. SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  70. api.nexthop_num = 1;
  71. api.nexthop = &nexthop;
  72. api.ifindex_num = 0;
  73. SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  74. api.metric = metric;
  75. zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
  76. rip_global_route_changes++;
  77. }
  78. }
  79. /* Zebra route add and delete treatment. */
  80. static int
  81. rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
  82. {
  83. struct stream *s;
  84. struct zapi_ipv4 api;
  85. unsigned long ifindex;
  86. struct in_addr nexthop;
  87. struct prefix_ipv4 p;
  88. s = zclient->ibuf;
  89. ifindex = 0;
  90. nexthop.s_addr = 0;
  91. /* Type, flags, message. */
  92. api.type = stream_getc (s);
  93. api.flags = stream_getc (s);
  94. api.message = stream_getc (s);
  95. /* IPv4 prefix. */
  96. memset (&p, 0, sizeof (struct prefix_ipv4));
  97. p.family = AF_INET;
  98. p.prefixlen = stream_getc (s);
  99. stream_get (&p.prefix, s, PSIZE (p.prefixlen));
  100. /* Nexthop, ifindex, distance, metric. */
  101. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
  102. {
  103. api.nexthop_num = stream_getc (s);
  104. nexthop.s_addr = stream_get_ipv4 (s);
  105. }
  106. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
  107. {
  108. api.ifindex_num = stream_getc (s);
  109. ifindex = stream_getl (s);
  110. }
  111. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
  112. api.distance = stream_getc (s);
  113. else
  114. api.distance = 255;
  115. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
  116. api.metric = stream_getl (s);
  117. else
  118. api.metric = 0;
  119. /* Then fetch IPv4 prefixes. */
  120. if (command == ZEBRA_IPV4_ROUTE_ADD)
  121. rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex,
  122. &nexthop, api.metric, api.distance);
  123. else
  124. rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex);
  125. return 0;
  126. }
  127. void
  128. rip_zclient_reset (void)
  129. {
  130. zclient_reset (zclient);
  131. }
  132. /* RIP route-map set for redistribution */
  133. static void
  134. rip_routemap_set (int type, const char *name)
  135. {
  136. if (rip->route_map[type].name)
  137. free(rip->route_map[type].name);
  138. rip->route_map[type].name = strdup (name);
  139. rip->route_map[type].map = route_map_lookup_by_name (name);
  140. }
  141. static void
  142. rip_redistribute_metric_set (int type, unsigned int metric)
  143. {
  144. rip->route_map[type].metric_config = 1;
  145. rip->route_map[type].metric = metric;
  146. }
  147. static int
  148. rip_metric_unset (int type, unsigned int metric)
  149. {
  150. #define DONT_CARE_METRIC_RIP 17
  151. if (metric != DONT_CARE_METRIC_RIP &&
  152. rip->route_map[type].metric != metric)
  153. return 1;
  154. rip->route_map[type].metric_config = 0;
  155. rip->route_map[type].metric = 0;
  156. return 0;
  157. }
  158. /* RIP route-map unset for redistribution */
  159. static int
  160. rip_routemap_unset (int type, const char *name)
  161. {
  162. if (! rip->route_map[type].name ||
  163. (name != NULL && strcmp(rip->route_map[type].name,name)))
  164. return 1;
  165. free (rip->route_map[type].name);
  166. rip->route_map[type].name = NULL;
  167. rip->route_map[type].map = NULL;
  168. return 0;
  169. }
  170. /* Redistribution types */
  171. static struct {
  172. int type;
  173. int str_min_len;
  174. const char *str;
  175. } redist_type[] = {
  176. {ZEBRA_ROUTE_KERNEL, 1, "kernel"},
  177. {ZEBRA_ROUTE_CONNECT, 1, "connected"},
  178. {ZEBRA_ROUTE_STATIC, 1, "static"},
  179. {ZEBRA_ROUTE_OSPF, 1, "ospf"},
  180. {ZEBRA_ROUTE_BGP, 1, "bgp"},
  181. {0, 0, NULL}
  182. };
  183. DEFUN (router_zebra,
  184. router_zebra_cmd,
  185. "router zebra",
  186. "Enable a routing process\n"
  187. "Make connection to zebra daemon\n")
  188. {
  189. vty->node = ZEBRA_NODE;
  190. zclient->enable = 1;
  191. zclient_start (zclient);
  192. return CMD_SUCCESS;
  193. }
  194. DEFUN (no_router_zebra,
  195. no_router_zebra_cmd,
  196. "no router zebra",
  197. NO_STR
  198. "Enable a routing process\n"
  199. "Make connection to zebra daemon\n")
  200. {
  201. zclient->enable = 0;
  202. zclient_stop (zclient);
  203. return CMD_SUCCESS;
  204. }
  205. static int
  206. rip_redistribute_set (int type)
  207. {
  208. if (zclient->redist[type])
  209. return CMD_SUCCESS;
  210. zclient->redist[type] = 1;
  211. if (zclient->sock > 0)
  212. zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
  213. return CMD_SUCCESS;
  214. }
  215. static int
  216. rip_redistribute_unset (int type)
  217. {
  218. if (! zclient->redist[type])
  219. return CMD_SUCCESS;
  220. zclient->redist[type] = 0;
  221. if (zclient->sock > 0)
  222. zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
  223. /* Remove the routes from RIP table. */
  224. rip_redistribute_withdraw (type);
  225. return CMD_SUCCESS;
  226. }
  227. int
  228. rip_redistribute_check (int type)
  229. {
  230. return (zclient->redist[type]);
  231. }
  232. void
  233. rip_redistribute_clean (void)
  234. {
  235. int i;
  236. for (i = 0; redist_type[i].str; i++)
  237. {
  238. if (zclient->redist[redist_type[i].type])
  239. {
  240. if (zclient->sock > 0)
  241. zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
  242. zclient, redist_type[i].type);
  243. zclient->redist[redist_type[i].type] = 0;
  244. /* Remove the routes from RIP table. */
  245. rip_redistribute_withdraw (redist_type[i].type);
  246. }
  247. }
  248. }
  249. DEFUN (rip_redistribute_rip,
  250. rip_redistribute_rip_cmd,
  251. "redistribute rip",
  252. "Redistribute information from another routing protocol\n"
  253. "Routing Information Protocol (RIP)\n")
  254. {
  255. zclient->redist[ZEBRA_ROUTE_RIP] = 1;
  256. return CMD_SUCCESS;
  257. }
  258. DEFUN (no_rip_redistribute_rip,
  259. no_rip_redistribute_rip_cmd,
  260. "no redistribute rip",
  261. NO_STR
  262. "Redistribute information from another routing protocol\n"
  263. "Routing Information Protocol (RIP)\n")
  264. {
  265. zclient->redist[ZEBRA_ROUTE_RIP] = 0;
  266. return CMD_SUCCESS;
  267. }
  268. DEFUN (rip_redistribute_type,
  269. rip_redistribute_type_cmd,
  270. "redistribute " QUAGGA_REDIST_STR_RIPD,
  271. REDIST_STR
  272. QUAGGA_REDIST_HELP_STR_RIPD)
  273. {
  274. int i;
  275. for(i = 0; redist_type[i].str; i++)
  276. {
  277. if (strncmp (redist_type[i].str, argv[0],
  278. redist_type[i].str_min_len) == 0)
  279. {
  280. zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,
  281. redist_type[i].type);
  282. return CMD_SUCCESS;
  283. }
  284. }
  285. vty_out(vty, "Invalid type %s%s", argv[0],
  286. VTY_NEWLINE);
  287. return CMD_WARNING;
  288. }
  289. DEFUN (no_rip_redistribute_type,
  290. no_rip_redistribute_type_cmd,
  291. "no redistribute " QUAGGA_REDIST_STR_RIPD,
  292. NO_STR
  293. REDIST_STR
  294. QUAGGA_REDIST_HELP_STR_RIPD)
  295. {
  296. int i;
  297. for (i = 0; redist_type[i].str; i++)
  298. {
  299. if (strncmp(redist_type[i].str, argv[0],
  300. redist_type[i].str_min_len) == 0)
  301. {
  302. rip_metric_unset (redist_type[i].type, DONT_CARE_METRIC_RIP);
  303. rip_routemap_unset (redist_type[i].type,NULL);
  304. rip_redistribute_unset (redist_type[i].type);
  305. return CMD_SUCCESS;
  306. }
  307. }
  308. vty_out(vty, "Invalid type %s%s", argv[0],
  309. VTY_NEWLINE);
  310. return CMD_WARNING;
  311. }
  312. DEFUN (rip_redistribute_type_routemap,
  313. rip_redistribute_type_routemap_cmd,
  314. "redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
  315. REDIST_STR
  316. QUAGGA_REDIST_HELP_STR_RIPD
  317. "Route map reference\n"
  318. "Pointer to route-map entries\n")
  319. {
  320. int i;
  321. for (i = 0; redist_type[i].str; i++) {
  322. if (strncmp(redist_type[i].str, argv[0],
  323. redist_type[i].str_min_len) == 0)
  324. {
  325. rip_routemap_set (redist_type[i].type, argv[1]);
  326. zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
  327. return CMD_SUCCESS;
  328. }
  329. }
  330. vty_out(vty, "Invalid type %s%s", argv[0],
  331. VTY_NEWLINE);
  332. return CMD_WARNING;
  333. }
  334. DEFUN (no_rip_redistribute_type_routemap,
  335. no_rip_redistribute_type_routemap_cmd,
  336. "no redistribute " QUAGGA_REDIST_STR_RIPD " route-map WORD",
  337. NO_STR
  338. REDIST_STR
  339. QUAGGA_REDIST_HELP_STR_RIPD
  340. "Route map reference\n"
  341. "Pointer to route-map entries\n")
  342. {
  343. int i;
  344. for (i = 0; redist_type[i].str; i++)
  345. {
  346. if (strncmp(redist_type[i].str, argv[0],
  347. redist_type[i].str_min_len) == 0)
  348. {
  349. if (rip_routemap_unset (redist_type[i].type,argv[1]))
  350. return CMD_WARNING;
  351. rip_redistribute_unset (redist_type[i].type);
  352. return CMD_SUCCESS;
  353. }
  354. }
  355. vty_out(vty, "Invalid type %s%s", argv[0],
  356. VTY_NEWLINE);
  357. return CMD_WARNING;
  358. }
  359. DEFUN (rip_redistribute_type_metric,
  360. rip_redistribute_type_metric_cmd,
  361. "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
  362. REDIST_STR
  363. QUAGGA_REDIST_HELP_STR_RIPD
  364. "Metric\n"
  365. "Metric value\n")
  366. {
  367. int i;
  368. int metric;
  369. metric = atoi (argv[1]);
  370. for (i = 0; redist_type[i].str; i++) {
  371. if (strncmp(redist_type[i].str, argv[0],
  372. redist_type[i].str_min_len) == 0)
  373. {
  374. rip_redistribute_metric_set (redist_type[i].type, metric);
  375. zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
  376. return CMD_SUCCESS;
  377. }
  378. }
  379. vty_out(vty, "Invalid type %s%s", argv[0],
  380. VTY_NEWLINE);
  381. return CMD_WARNING;
  382. }
  383. DEFUN (no_rip_redistribute_type_metric,
  384. no_rip_redistribute_type_metric_cmd,
  385. "no redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16>",
  386. NO_STR
  387. REDIST_STR
  388. QUAGGA_REDIST_HELP_STR_RIPD
  389. "Metric\n"
  390. "Metric value\n")
  391. {
  392. int i;
  393. for (i = 0; redist_type[i].str; i++)
  394. {
  395. if (strncmp(redist_type[i].str, argv[0],
  396. redist_type[i].str_min_len) == 0)
  397. {
  398. if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
  399. return CMD_WARNING;
  400. rip_redistribute_unset (redist_type[i].type);
  401. return CMD_SUCCESS;
  402. }
  403. }
  404. vty_out(vty, "Invalid type %s%s", argv[0],
  405. VTY_NEWLINE);
  406. return CMD_WARNING;
  407. }
  408. DEFUN (rip_redistribute_type_metric_routemap,
  409. rip_redistribute_type_metric_routemap_cmd,
  410. "redistribute " QUAGGA_REDIST_STR_RIPD " metric <0-16> route-map WORD",
  411. REDIST_STR
  412. QUAGGA_REDIST_HELP_STR_RIPD
  413. "Metric\n"
  414. "Metric value\n"
  415. "Route map reference\n"
  416. "Pointer to route-map entries\n")
  417. {
  418. int i;
  419. int metric;
  420. metric = atoi (argv[1]);
  421. for (i = 0; redist_type[i].str; i++) {
  422. if (strncmp(redist_type[i].str, argv[0],
  423. redist_type[i].str_min_len) == 0)
  424. {
  425. rip_redistribute_metric_set (redist_type[i].type, metric);
  426. rip_routemap_set (redist_type[i].type, argv[2]);
  427. zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
  428. return CMD_SUCCESS;
  429. }
  430. }
  431. vty_out(vty, "Invalid type %s%s", argv[0],
  432. VTY_NEWLINE);
  433. return CMD_WARNING;
  434. }
  435. DEFUN (no_rip_redistribute_type_metric_routemap,
  436. no_rip_redistribute_type_metric_routemap_cmd,
  437. "no redistribute " QUAGGA_REDIST_STR_RIPD
  438. " metric <0-16> route-map WORD",
  439. NO_STR
  440. REDIST_STR
  441. QUAGGA_REDIST_HELP_STR_RIPD
  442. "Metric\n"
  443. "Metric value\n"
  444. "Route map reference\n"
  445. "Pointer to route-map entries\n")
  446. {
  447. int i;
  448. for (i = 0; redist_type[i].str; i++)
  449. {
  450. if (strncmp(redist_type[i].str, argv[0],
  451. redist_type[i].str_min_len) == 0)
  452. {
  453. if (rip_metric_unset (redist_type[i].type, atoi(argv[1])))
  454. return CMD_WARNING;
  455. if (rip_routemap_unset (redist_type[i].type, argv[2]))
  456. {
  457. rip_redistribute_metric_set(redist_type[i].type, atoi(argv[1]));
  458. return CMD_WARNING;
  459. }
  460. rip_redistribute_unset (redist_type[i].type);
  461. return CMD_SUCCESS;
  462. }
  463. }
  464. vty_out(vty, "Invalid type %s%s", argv[0],
  465. VTY_NEWLINE);
  466. return CMD_WARNING;
  467. }
  468. /* Default information originate. */
  469. DEFUN (rip_default_information_originate,
  470. rip_default_information_originate_cmd,
  471. "default-information originate",
  472. "Control distribution of default route\n"
  473. "Distribute a default route\n")
  474. {
  475. struct prefix_ipv4 p;
  476. if (! rip->default_information)
  477. {
  478. memset (&p, 0, sizeof (struct prefix_ipv4));
  479. p.family = AF_INET;
  480. rip->default_information = 1;
  481. rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0,
  482. NULL, 0, 0);
  483. }
  484. return CMD_SUCCESS;
  485. }
  486. DEFUN (no_rip_default_information_originate,
  487. no_rip_default_information_originate_cmd,
  488. "no default-information originate",
  489. NO_STR
  490. "Control distribution of default route\n"
  491. "Distribute a default route\n")
  492. {
  493. struct prefix_ipv4 p;
  494. if (rip->default_information)
  495. {
  496. memset (&p, 0, sizeof (struct prefix_ipv4));
  497. p.family = AF_INET;
  498. rip->default_information = 0;
  499. rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0);
  500. }
  501. return CMD_SUCCESS;
  502. }
  503. /* RIP configuration write function. */
  504. static int
  505. config_write_zebra (struct vty *vty)
  506. {
  507. if (! zclient->enable)
  508. {
  509. vty_out (vty, "no router zebra%s", VTY_NEWLINE);
  510. return 1;
  511. }
  512. else if (! zclient->redist[ZEBRA_ROUTE_RIP])
  513. {
  514. vty_out (vty, "router zebra%s", VTY_NEWLINE);
  515. vty_out (vty, " no redistribute rip%s", VTY_NEWLINE);
  516. return 1;
  517. }
  518. return 0;
  519. }
  520. int
  521. config_write_rip_redistribute (struct vty *vty, int config_mode)
  522. {
  523. int i;
  524. for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
  525. if (i != zclient->redist_default && zclient->redist[i])
  526. {
  527. if (config_mode)
  528. {
  529. if (rip->route_map[i].metric_config)
  530. {
  531. if (rip->route_map[i].name)
  532. vty_out (vty, " redistribute %s metric %d route-map %s%s",
  533. zebra_route_string(i), rip->route_map[i].metric,
  534. rip->route_map[i].name,
  535. VTY_NEWLINE);
  536. else
  537. vty_out (vty, " redistribute %s metric %d%s",
  538. zebra_route_string(i), rip->route_map[i].metric,
  539. VTY_NEWLINE);
  540. }
  541. else
  542. {
  543. if (rip->route_map[i].name)
  544. vty_out (vty, " redistribute %s route-map %s%s",
  545. zebra_route_string(i), rip->route_map[i].name,
  546. VTY_NEWLINE);
  547. else
  548. vty_out (vty, " redistribute %s%s", zebra_route_string(i),
  549. VTY_NEWLINE);
  550. }
  551. }
  552. else
  553. vty_out (vty, " %s", zebra_route_string(i));
  554. }
  555. return 0;
  556. }
  557. /* Zebra node structure. */
  558. struct cmd_node zebra_node =
  559. {
  560. ZEBRA_NODE,
  561. "%s(config-router)# ",
  562. };
  563. void
  564. rip_zclient_init ()
  565. {
  566. /* Set default value to the zebra client structure. */
  567. zclient = zclient_new ();
  568. zclient_init (zclient, ZEBRA_ROUTE_RIP);
  569. zclient->interface_add = rip_interface_add;
  570. zclient->interface_delete = rip_interface_delete;
  571. zclient->interface_address_add = rip_interface_address_add;
  572. zclient->interface_address_delete = rip_interface_address_delete;
  573. zclient->ipv4_route_add = rip_zebra_read_ipv4;
  574. zclient->ipv4_route_delete = rip_zebra_read_ipv4;
  575. zclient->interface_up = rip_interface_up;
  576. zclient->interface_down = rip_interface_down;
  577. /* Install zebra node. */
  578. install_node (&zebra_node, config_write_zebra);
  579. /* Install command elements to zebra node. */
  580. install_element (CONFIG_NODE, &router_zebra_cmd);
  581. install_element (CONFIG_NODE, &no_router_zebra_cmd);
  582. install_default (ZEBRA_NODE);
  583. install_element (ZEBRA_NODE, &rip_redistribute_rip_cmd);
  584. install_element (ZEBRA_NODE, &no_rip_redistribute_rip_cmd);
  585. /* Install command elements to rip node. */
  586. install_element (RIP_NODE, &rip_redistribute_type_cmd);
  587. install_element (RIP_NODE, &rip_redistribute_type_routemap_cmd);
  588. install_element (RIP_NODE, &rip_redistribute_type_metric_cmd);
  589. install_element (RIP_NODE, &rip_redistribute_type_metric_routemap_cmd);
  590. install_element (RIP_NODE, &no_rip_redistribute_type_cmd);
  591. install_element (RIP_NODE, &no_rip_redistribute_type_routemap_cmd);
  592. install_element (RIP_NODE, &no_rip_redistribute_type_metric_cmd);
  593. install_element (RIP_NODE, &no_rip_redistribute_type_metric_routemap_cmd);
  594. install_element (RIP_NODE, &rip_default_information_originate_cmd);
  595. install_element (RIP_NODE, &no_rip_default_information_originate_cmd);
  596. }