ospf6_zebra.c 18 KB

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