ospf6_zebra.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. /*
  2. * Copyright (C) 2003 Yasuhiro Ohara
  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
  18. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. * Boston, MA 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include "log.h"
  23. #include "vty.h"
  24. #include "command.h"
  25. #include "prefix.h"
  26. #include "stream.h"
  27. #include "zclient.h"
  28. #include "memory.h"
  29. #include "ospf6_proto.h"
  30. #include "ospf6_top.h"
  31. #include "ospf6_interface.h"
  32. #include "ospf6_route.h"
  33. #include "ospf6_lsa.h"
  34. #include "ospf6_lsdb.h"
  35. #include "ospf6_asbr.h"
  36. #include "ospf6_zebra.h"
  37. #include "ospf6d.h"
  38. unsigned char conf_debug_ospf6_zebra = 0;
  39. /* information about zebra. */
  40. struct zclient *zclient = NULL;
  41. /* redistribute function */
  42. void
  43. ospf6_zebra_redistribute (int type)
  44. {
  45. if (zclient->redist[type])
  46. return;
  47. zclient->redist[type] = 1;
  48. if (zclient->sock > 0)
  49. zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);
  50. }
  51. void
  52. ospf6_zebra_no_redistribute (int type)
  53. {
  54. if (! zclient->redist[type])
  55. return;
  56. zclient->redist[type] = 0;
  57. if (zclient->sock > 0)
  58. zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);
  59. }
  60. /* Inteface addition message from zebra. */
  61. int
  62. ospf6_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length)
  63. {
  64. struct interface *ifp;
  65. ifp = zebra_interface_add_read (zclient->ibuf);
  66. if (IS_OSPF6_DEBUG_ZEBRA (RECV))
  67. zlog_info ("Zebra Interface add: %s index %d mtu %d",
  68. ifp->name, ifp->ifindex, ifp->mtu6);
  69. ospf6_interface_if_add (ifp);
  70. return 0;
  71. }
  72. int
  73. ospf6_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length)
  74. {
  75. #if 0
  76. struct interface *ifp;
  77. ifp = zebra_interface_delete_read (zclient->ibuf);
  78. if (IS_OSPF6_DEBUG_ZEBRA (RECV))
  79. zlog_info ("Zebra Interface delete: %s index %d mtu %d",
  80. ifp->name, ifp->ifindex, ifp->mtu6);
  81. ospf6_interface_if_del (ifp);
  82. #endif /*0*/
  83. return 0;
  84. }
  85. int
  86. ospf6_zebra_if_state_update (int command, struct zclient *zclient,
  87. zebra_size_t length)
  88. {
  89. struct interface *ifp;
  90. ifp = zebra_interface_state_read (zclient->ibuf);
  91. if (IS_OSPF6_DEBUG_ZEBRA (RECV))
  92. zlog_info ("Zebra Interface state change: "
  93. "%s index %d flags %ld metric %d mtu %d",
  94. ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu6);
  95. ospf6_interface_state_update (ifp);
  96. return 0;
  97. }
  98. int
  99. ospf6_zebra_if_address_update_add (int command, struct zclient *zclient,
  100. zebra_size_t length)
  101. {
  102. struct connected *c;
  103. char buf[128];
  104. c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, zclient->ibuf);
  105. if (c == NULL)
  106. return 0;
  107. if (IS_OSPF6_DEBUG_ZEBRA (RECV))
  108. zlog_info ("Zebra Interface address add: %s %5s %s/%d",
  109. c->ifp->name, prefix_family_str (c->address),
  110. inet_ntop (c->address->family, &c->address->u.prefix,
  111. buf, sizeof (buf)), c->address->prefixlen);
  112. if (c->address->family == AF_INET6)
  113. ospf6_interface_connected_route_update (c->ifp);
  114. return 0;
  115. }
  116. int
  117. ospf6_zebra_if_address_update_delete (int command, struct zclient *zclient,
  118. zebra_size_t length)
  119. {
  120. struct connected *c;
  121. char buf[128];
  122. c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf);
  123. if (c == NULL)
  124. return 0;
  125. if (IS_OSPF6_DEBUG_ZEBRA (RECV))
  126. zlog_info ("Zebra Interface address delete: %s %5s %s/%d",
  127. c->ifp->name, prefix_family_str (c->address),
  128. inet_ntop (c->address->family, &c->address->u.prefix,
  129. buf, sizeof (buf)), c->address->prefixlen);
  130. if (c->address->family == AF_INET6)
  131. ospf6_interface_connected_route_update (c->ifp);
  132. return 0;
  133. }
  134. const char *zebra_route_name[ZEBRA_ROUTE_MAX] =
  135. { "System", "Kernel", "Connect", "Static", "RIP", "RIPng", "OSPF",
  136. "OSPF6", "BGP" };
  137. const char *zebra_route_abname[ZEBRA_ROUTE_MAX] =
  138. { "X", "K", "C", "S", "r", "R", "o", "O", "B" };
  139. int
  140. ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
  141. zebra_size_t length)
  142. {
  143. struct stream *s;
  144. struct zapi_ipv6 api;
  145. unsigned long ifindex;
  146. struct prefix_ipv6 p;
  147. struct in6_addr *nexthop;
  148. s = zclient->ibuf;
  149. ifindex = 0;
  150. nexthop = NULL;
  151. memset (&api, 0, sizeof (api));
  152. /* Type, flags, message. */
  153. api.type = stream_getc (s);
  154. api.flags = stream_getc (s);
  155. api.message = stream_getc (s);
  156. /* IPv6 prefix. */
  157. memset (&p, 0, sizeof (struct prefix_ipv6));
  158. p.family = AF_INET6;
  159. p.prefixlen = stream_getc (s);
  160. stream_get (&p.prefix, s, PSIZE (p.prefixlen));
  161. /* Nexthop, ifindex, distance, metric. */
  162. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
  163. {
  164. api.nexthop_num = stream_getc (s);
  165. nexthop = (struct in6_addr *)
  166. malloc (api.nexthop_num * sizeof (struct in6_addr));
  167. stream_get (nexthop, s, api.nexthop_num * sizeof (struct in6_addr));
  168. }
  169. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
  170. {
  171. api.ifindex_num = stream_getc (s);
  172. ifindex = stream_getl (s);
  173. }
  174. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
  175. api.distance = stream_getc (s);
  176. else
  177. api.distance = 0;
  178. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
  179. api.metric = stream_getl (s);
  180. else
  181. api.metric = 0;
  182. if (IS_OSPF6_DEBUG_ZEBRA (RECV))
  183. {
  184. char prefixstr[128], nexthopstr[128];
  185. prefix2str ((struct prefix *)&p, prefixstr, sizeof (prefixstr));
  186. if (nexthop)
  187. inet_ntop (AF_INET6, nexthop, nexthopstr, sizeof (nexthopstr));
  188. else
  189. snprintf (nexthopstr, sizeof (nexthopstr), "::");
  190. zlog_info ("Zebra Receive route %s: %s %s nexthop %s ifindex %ld",
  191. (command == ZEBRA_IPV6_ROUTE_ADD ? "add" : "delete"),
  192. zebra_route_name[api.type], prefixstr, nexthopstr, ifindex);
  193. }
  194. if (command == ZEBRA_IPV6_ROUTE_ADD)
  195. ospf6_asbr_redistribute_add (api.type, ifindex, (struct prefix *) &p,
  196. api.nexthop_num, nexthop);
  197. else
  198. ospf6_asbr_redistribute_remove (api.type, ifindex, (struct prefix *) &p);
  199. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
  200. free (nexthop);
  201. return 0;
  202. }
  203. DEFUN (show_zebra,
  204. show_zebra_cmd,
  205. "show zebra",
  206. SHOW_STR
  207. "Zebra information\n")
  208. {
  209. int i;
  210. if (zclient == NULL)
  211. {
  212. vty_out (vty, "Not connected to zebra%s", VNL);
  213. return CMD_SUCCESS;
  214. }
  215. vty_out (vty, "Zebra Infomation%s", VNL);
  216. vty_out (vty, " enable: %d fail: %d%s",
  217. zclient->enable, zclient->fail, VNL);
  218. vty_out (vty, " redistribute default: %d%s", zclient->redist_default,
  219. VNL);
  220. vty_out (vty, " redistribute:");
  221. for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
  222. {
  223. if (zclient->redist[i])
  224. vty_out (vty, " %s", zebra_route_name[i]);
  225. }
  226. vty_out (vty, "%s", VNL);
  227. return CMD_SUCCESS;
  228. }
  229. DEFUN (router_zebra,
  230. router_zebra_cmd,
  231. "router zebra",
  232. "Enable a routing process\n"
  233. "Make connection to zebra daemon\n")
  234. {
  235. vty->node = ZEBRA_NODE;
  236. zclient->enable = 1;
  237. zclient_start (zclient);
  238. return CMD_SUCCESS;
  239. }
  240. DEFUN (no_router_zebra,
  241. no_router_zebra_cmd,
  242. "no router zebra",
  243. NO_STR
  244. "Configure routing process\n"
  245. "Disable connection to zebra daemon\n")
  246. {
  247. zclient->enable = 0;
  248. zclient_stop (zclient);
  249. return CMD_SUCCESS;
  250. }
  251. /* Zebra configuration write function. */
  252. int
  253. config_write_ospf6_zebra (struct vty *vty)
  254. {
  255. if (! zclient->enable)
  256. {
  257. vty_out (vty, "no router zebra%s", VNL);
  258. vty_out (vty, "!%s", VNL);
  259. }
  260. else if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
  261. {
  262. vty_out (vty, "router zebra%s", VNL);
  263. vty_out (vty, " no redistribute ospf6%s", VNL);
  264. vty_out (vty, "!%s", VNL);
  265. }
  266. return 0;
  267. }
  268. /* Zebra node structure. */
  269. struct cmd_node zebra_node =
  270. {
  271. ZEBRA_NODE,
  272. "%s(config-zebra)# ",
  273. };
  274. #define ADD 0
  275. #define REM 1
  276. static void
  277. ospf6_zebra_route_update (int type, struct ospf6_route *request)
  278. {
  279. struct zapi_ipv6 api;
  280. char buf[64], ifname[IFNAMSIZ];
  281. int nhcount;
  282. struct in6_addr **nexthops;
  283. unsigned int *ifindexes;
  284. int i, ret = 0;
  285. struct prefix_ipv6 *dest;
  286. if (IS_OSPF6_DEBUG_ZEBRA (SEND))
  287. {
  288. prefix2str (&request->prefix, buf, sizeof (buf));
  289. zlog_info ("Send %s route: %s",
  290. (type == REM ? "remove" : "add"), buf);
  291. }
  292. if (zclient->sock < 0)
  293. {
  294. if (IS_OSPF6_DEBUG_ZEBRA (SEND))
  295. zlog_info (" Not connected to Zebra");
  296. return;
  297. }
  298. if (request->path.origin.adv_router == ospf6->router_id &&
  299. (request->path.type == OSPF6_PATH_TYPE_EXTERNAL1 ||
  300. request->path.type == OSPF6_PATH_TYPE_EXTERNAL2))
  301. {
  302. if (IS_OSPF6_DEBUG_ZEBRA (SEND))
  303. zlog_info (" Ignore self-originated external route");
  304. return;
  305. }
  306. /* If removing is the best path and if there's another path,
  307. treat this request as add the secondary path */
  308. if (type == REM && ospf6_route_is_best (request) &&
  309. request->next && ospf6_route_is_same (request, request->next))
  310. {
  311. if (IS_OSPF6_DEBUG_ZEBRA (SEND))
  312. zlog_info (" Best-path removal resulted Sencondary addition");
  313. type = ADD;
  314. request = request->next;
  315. }
  316. /* Only the best path will be sent to zebra. */
  317. if (! ospf6_route_is_best (request))
  318. {
  319. /* this is not preferred best route, ignore */
  320. if (IS_OSPF6_DEBUG_ZEBRA (SEND))
  321. zlog_info (" Ignore non-best route");
  322. return;
  323. }
  324. nhcount = 0;
  325. for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
  326. if (ospf6_nexthop_is_set (&request->nexthop[i]))
  327. nhcount++;
  328. if (nhcount == 0)
  329. {
  330. if (IS_OSPF6_DEBUG_ZEBRA (SEND))
  331. zlog_info (" No nexthop, ignore");
  332. return;
  333. }
  334. /* allocate memory for nexthop_list */
  335. nexthops = XCALLOC (MTYPE_OSPF6_OTHER,
  336. nhcount * sizeof (struct in6_addr *));
  337. if (nexthops == NULL)
  338. {
  339. zlog_warn ("Can't send route to zebra: malloc failed");
  340. return;
  341. }
  342. /* allocate memory for ifindex_list */
  343. ifindexes = XCALLOC (MTYPE_OSPF6_OTHER,
  344. nhcount * sizeof (unsigned int));
  345. if (ifindexes == NULL)
  346. {
  347. zlog_warn ("Can't send route to zebra: malloc failed");
  348. XFREE (MTYPE_OSPF6_OTHER, nexthops);
  349. return;
  350. }
  351. for (i = 0; i < nhcount; i++)
  352. {
  353. if (IS_OSPF6_DEBUG_ZEBRA (SEND))
  354. {
  355. inet_ntop (AF_INET6, &request->nexthop[i].address,
  356. buf, sizeof (buf));
  357. if_indextoname (request->nexthop[i].ifindex, ifname);
  358. zlog_info (" nexthop: %s%%%s(%d)", buf, ifname,
  359. request->nexthop[i].ifindex);
  360. }
  361. nexthops[i] = &request->nexthop[i].address;
  362. ifindexes[i] = request->nexthop[i].ifindex;
  363. }
  364. api.type = ZEBRA_ROUTE_OSPF6;
  365. api.flags = 0;
  366. api.message = 0;
  367. SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  368. api.nexthop_num = nhcount;
  369. api.nexthop = nexthops;
  370. SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
  371. api.ifindex_num = nhcount;
  372. api.ifindex = ifindexes;
  373. SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  374. api.metric = (request->path.metric_type == 2 ?
  375. request->path.cost_e2 : request->path.cost);
  376. dest = (struct prefix_ipv6 *) &request->prefix;
  377. if (type == REM)
  378. ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, &api);
  379. else
  380. ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, &api);
  381. if (ret < 0)
  382. zlog_err ("zapi_ipv6_route() %s failed: %s",
  383. (type == REM ? "delete" : "add"), strerror (errno));
  384. XFREE (MTYPE_OSPF6_OTHER, nexthops);
  385. XFREE (MTYPE_OSPF6_OTHER, ifindexes);
  386. return;
  387. }
  388. void
  389. ospf6_zebra_route_update_add (struct ospf6_route *request)
  390. {
  391. if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
  392. {
  393. ospf6->route_table->hook_add = NULL;
  394. ospf6->route_table->hook_remove = NULL;
  395. return;
  396. }
  397. ospf6_zebra_route_update (ADD, request);
  398. }
  399. void
  400. ospf6_zebra_route_update_remove (struct ospf6_route *request)
  401. {
  402. if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
  403. {
  404. ospf6->route_table->hook_add = NULL;
  405. ospf6->route_table->hook_remove = NULL;
  406. return;
  407. }
  408. ospf6_zebra_route_update (REM, request);
  409. }
  410. DEFUN (redistribute_ospf6,
  411. redistribute_ospf6_cmd,
  412. "redistribute ospf6",
  413. "Redistribute control\n"
  414. "OSPF6 route\n")
  415. {
  416. struct ospf6_route *route;
  417. if (zclient->redist[ZEBRA_ROUTE_OSPF6])
  418. return CMD_SUCCESS;
  419. zclient->redist[ZEBRA_ROUTE_OSPF6] = 1;
  420. if (ospf6 == NULL)
  421. return CMD_SUCCESS;
  422. /* send ospf6 route to zebra route table */
  423. for (route = ospf6_route_head (ospf6->route_table); route;
  424. route = ospf6_route_next (route))
  425. ospf6_zebra_route_update_add (route);
  426. ospf6->route_table->hook_add = ospf6_zebra_route_update_add;
  427. ospf6->route_table->hook_remove = ospf6_zebra_route_update_remove;
  428. return CMD_SUCCESS;
  429. }
  430. DEFUN (no_redistribute_ospf6,
  431. no_redistribute_ospf6_cmd,
  432. "no redistribute ospf6",
  433. NO_STR
  434. "Redistribute control\n"
  435. "OSPF6 route\n")
  436. {
  437. struct ospf6_route *route;
  438. if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
  439. return CMD_SUCCESS;
  440. zclient->redist[ZEBRA_ROUTE_OSPF6] = 0;
  441. if (ospf6 == NULL)
  442. return CMD_SUCCESS;
  443. ospf6->route_table->hook_add = NULL;
  444. ospf6->route_table->hook_remove = NULL;
  445. /* withdraw ospf6 route from zebra route table */
  446. for (route = ospf6_route_head (ospf6->route_table); route;
  447. route = ospf6_route_next (route))
  448. ospf6_zebra_route_update_remove (route);
  449. return CMD_SUCCESS;
  450. }
  451. void
  452. ospf6_zebra_init ()
  453. {
  454. /* Allocate zebra structure. */
  455. zclient = zclient_new ();
  456. zclient_init (zclient, ZEBRA_ROUTE_OSPF6);
  457. zclient->interface_add = ospf6_zebra_if_add;
  458. zclient->interface_delete = ospf6_zebra_if_del;
  459. zclient->interface_up = ospf6_zebra_if_state_update;
  460. zclient->interface_down = ospf6_zebra_if_state_update;
  461. zclient->interface_address_add = ospf6_zebra_if_address_update_add;
  462. zclient->interface_address_delete = ospf6_zebra_if_address_update_delete;
  463. zclient->ipv4_route_add = NULL;
  464. zclient->ipv4_route_delete = NULL;
  465. zclient->ipv6_route_add = ospf6_zebra_read_ipv6;
  466. zclient->ipv6_route_delete = ospf6_zebra_read_ipv6;
  467. /* redistribute connected route by default */
  468. /* ospf6_zebra_redistribute (ZEBRA_ROUTE_CONNECT); */
  469. /* Install zebra node. */
  470. install_node (&zebra_node, config_write_ospf6_zebra);
  471. /* Install command element for zebra node. */
  472. install_element (VIEW_NODE, &show_zebra_cmd);
  473. install_element (ENABLE_NODE, &show_zebra_cmd);
  474. install_element (CONFIG_NODE, &router_zebra_cmd);
  475. install_element (CONFIG_NODE, &no_router_zebra_cmd);
  476. install_default (ZEBRA_NODE);
  477. install_element (ZEBRA_NODE, &redistribute_ospf6_cmd);
  478. install_element (ZEBRA_NODE, &no_redistribute_ospf6_cmd);
  479. return;
  480. }
  481. /* Debug */
  482. DEFUN (debug_ospf6_zebra_sendrecv,
  483. debug_ospf6_zebra_sendrecv_cmd,
  484. "debug ospf6 zebra (send|recv)",
  485. DEBUG_STR
  486. OSPF6_STR
  487. "Debug connection between zebra\n"
  488. "Debug Sending zebra\n"
  489. "Debug Receiving zebra\n"
  490. )
  491. {
  492. unsigned char level = 0;
  493. if (argc)
  494. {
  495. if (! strncmp (argv[0], "s", 1))
  496. level = OSPF6_DEBUG_ZEBRA_SEND;
  497. else if (! strncmp (argv[0], "r", 1))
  498. level = OSPF6_DEBUG_ZEBRA_RECV;
  499. }
  500. else
  501. level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV;
  502. OSPF6_DEBUG_ZEBRA_ON (level);
  503. return CMD_SUCCESS;
  504. }
  505. ALIAS (debug_ospf6_zebra_sendrecv,
  506. debug_ospf6_zebra_cmd,
  507. "debug ospf6 zebra",
  508. DEBUG_STR
  509. OSPF6_STR
  510. "Debug connection between zebra\n"
  511. );
  512. DEFUN (no_debug_ospf6_zebra_sendrecv,
  513. no_debug_ospf6_zebra_sendrecv_cmd,
  514. "no debug ospf6 zebra (send|recv)",
  515. NO_STR
  516. DEBUG_STR
  517. OSPF6_STR
  518. "Debug connection between zebra\n"
  519. "Debug Sending zebra\n"
  520. "Debug Receiving zebra\n"
  521. )
  522. {
  523. unsigned char level = 0;
  524. if (argc)
  525. {
  526. if (! strncmp (argv[0], "s", 1))
  527. level = OSPF6_DEBUG_ZEBRA_SEND;
  528. else if (! strncmp (argv[0], "r", 1))
  529. level = OSPF6_DEBUG_ZEBRA_RECV;
  530. }
  531. else
  532. level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV;
  533. OSPF6_DEBUG_ZEBRA_OFF (level);
  534. return CMD_SUCCESS;
  535. }
  536. ALIAS (no_debug_ospf6_zebra_sendrecv,
  537. no_debug_ospf6_zebra_cmd,
  538. "no debug ospf6 zebra",
  539. NO_STR
  540. DEBUG_STR
  541. OSPF6_STR
  542. "Debug connection between zebra\n"
  543. );
  544. int
  545. config_write_ospf6_debug_zebra (struct vty *vty)
  546. {
  547. if (IS_OSPF6_DEBUG_ZEBRA (SEND) && IS_OSPF6_DEBUG_ZEBRA (RECV))
  548. vty_out (vty, "debug ospf6 zebra%s", VNL);
  549. else
  550. {
  551. if (IS_OSPF6_DEBUG_ZEBRA (SEND))
  552. vty_out (vty, "debug ospf6 zebra send%s", VNL);
  553. if (IS_OSPF6_DEBUG_ZEBRA (RECV))
  554. vty_out (vty, "debug ospf6 zebra recv%s", VNL);
  555. }
  556. return 0;
  557. }
  558. void
  559. install_element_ospf6_debug_zebra ()
  560. {
  561. install_element (ENABLE_NODE, &debug_ospf6_zebra_cmd);
  562. install_element (ENABLE_NODE, &no_debug_ospf6_zebra_cmd);
  563. install_element (ENABLE_NODE, &debug_ospf6_zebra_sendrecv_cmd);
  564. install_element (ENABLE_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
  565. install_element (CONFIG_NODE, &debug_ospf6_zebra_cmd);
  566. install_element (CONFIG_NODE, &no_debug_ospf6_zebra_cmd);
  567. install_element (CONFIG_NODE, &debug_ospf6_zebra_sendrecv_cmd);
  568. install_element (CONFIG_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
  569. }