ospf6_zebra.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:18k
源码类别:

网络

开发平台:

Unix_Linux

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