ospf6_zebra.c 18 KB

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