Diff for /embedaddon/quagga/vtysh/vtysh.c between versions 1.1.1.2 and 1.1.1.4

version 1.1.1.2, 2012/10/09 09:22:29 version 1.1.1.4, 2016/11/02 10:09:10
Line 35 Line 35
 #include "vtysh/vtysh.h"  #include "vtysh/vtysh.h"
 #include "log.h"  #include "log.h"
 #include "bgpd/bgp_vty.h"  #include "bgpd/bgp_vty.h"
   #include "vrf.h"
   
 /* Struct VTY. */  /* Struct VTY. */
 struct vty *vty;  struct vty *vty;
Line 58  struct vtysh_client Line 59  struct vtysh_client
   { .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH},    { .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH},
   { .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH},    { .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH},
   { .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH},    { .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH},
  { .fd = -1, .name = "babeld", .flag = VTYSH_BABELD, .path = BABEL_VTYSH_PATH},  { .fd = -1, .name = "pimd", .flag = VTYSH_PIMD, .path = PIM_VTYSH_PATH},
 };  };
   
 #define VTYSH_INDEX_MAX (sizeof(vtysh_client)/sizeof(vtysh_client[0]))  
   
 /* We need direct access to ripd to implement vtysh_exit_ripd_only. */  /* We need direct access to ripd to implement vtysh_exit_ripd_only. */
 static struct vtysh_client *ripd_client = NULL;  static struct vtysh_client *ripd_client = NULL;
Line 87  vclient_close (struct vtysh_client *vclient) Line 87  vclient_close (struct vtysh_client *vclient)
   
 /* Following filled with debug code to trace a problematic condition  /* Following filled with debug code to trace a problematic condition
  * under load - it SHOULD handle it. */   * under load - it SHOULD handle it. */
#define ERR_WHERE_STRING "vtysh(): vtysh_client_config(): "#define ERR_WHERE_STRING "vtysh(): vtysh_client_execute(): "
 static int  static int
vtysh_client_config (struct vtysh_client *vclient, char *line)vtysh_client_execute (struct vtysh_client *vclient, const char *line, FILE *fp)
 {  {
   int ret;    int ret;
   char *buf;    char *buf;
Line 100  vtysh_client_config (struct vtysh_client *vclient, cha Line 100  vtysh_client_config (struct vtysh_client *vclient, cha
   int nbytes;    int nbytes;
   int i;    int i;
   int readln;    int readln;
     int numnulls = 0;
   
   if (vclient->fd < 0)    if (vclient->fd < 0)
     return CMD_SUCCESS;      return CMD_SUCCESS;
Line 145  vtysh_client_config (struct vtysh_client *vclient, cha Line 146  vtysh_client_config (struct vtysh_client *vclient, cha
           XFREE(MTYPE_TMP, buf);            XFREE(MTYPE_TMP, buf);
           return CMD_SUCCESS;            return CMD_SUCCESS;
         }          }
         /* If we have already seen 3 nulls, then current byte is ret code */
         if ((numnulls == 3) && (nbytes == 1))
           {
              ret = pbuf[0];
              break;
           }
   
       pbuf[nbytes] = '\0';        pbuf[nbytes] = '\0';
   
      if (nbytes >= 4)       /* If the config needs to be written in file or stdout */
        {       if (fp)
          i = nbytes - 4;       {
          if (pbuf[i] == '\0' && pbuf[i + 1] == '\0' && pbuf[i + 2] == '\0')         fputs(pbuf, fp);
            {         fflush (fp);
              ret = pbuf[i + 3];       }
              break; 
            } 
        } 
      pbuf += nbytes; 
   
      /* See if a line exists in buffer, if so parse and consume it, and       /* At max look last four bytes */
       * reset read position. */       if (nbytes >= 4)
      if ((eoln = strrchr(buf, '\n')) == NULL)       {
        continue;         i = nbytes - 4;
          numnulls = 0;
        }
        else
          i = 0;
   
      if (eoln >= ((buf + bufsz) - 1))       /* Count the numnulls */ 
        {       while (i < nbytes && numnulls <3)
          fprintf (stderr, ERR_WHERE_STRING \       {
                   "warning - eoln beyond buffer end.\n");         if (pbuf[i++] == '\0')
        }            numnulls++;
      vtysh_config_parse(buf);         else
             numnulls = 0;
        }
        /* We might have seen 3 consecutive nulls so store the ret code before updating pbuf*/
        ret = pbuf[nbytes-1];
        pbuf += nbytes;
   
      eoln++;       /* See if a line exists in buffer, if so parse and consume it, and
      left = (size_t)(buf + bufsz - eoln);        * reset read position. If 3 nulls has been encountered consume the buffer before 
      memmove(buf, eoln, left);        * next read.
      buf[bufsz-1] = '\0';        */
      pbuf = buf + strlen(buf);       if (((eoln = strrchr(buf, '\n')) == NULL) && (numnulls<3))
    }         continue;
   
  /* Parse anything left in the buffer. */       if (eoln >= ((buf + bufsz) - 1))
        {
           fprintf (stderr, ERR_WHERE_STRING \
                "warning - eoln beyond buffer end.\n");
        }
   
  vtysh_config_parse (buf);       /* If the config needs parsing, consume it */
        if(!fp)
          vtysh_config_parse(buf);
   
  XFREE(MTYPE_TMP, buf);       eoln++;
  return ret;       left = (size_t)(buf + bufsz - eoln);
}       /*
         * This check is required since when a config line split between two consecutive reads, 
         * then buf will have first half of config line and current read will bring rest of the 
         * line. So in this case eoln will be 1 here, hence calculation of left will be wrong. 
         * In this case we don't need to do memmove, because we have already seen 3 nulls.  
         */
        if(left < bufsz)
          memmove(buf, eoln, left);
   
static int       buf[bufsz-1] = '\0';
vtysh_client_execute (struct vtysh_client *vclient, const char *line, FILE *fp)       pbuf = buf + strlen(buf);
{       /* got 3 or more trailing NULs? */
  int ret;       if ((numnulls >=3) && (i < nbytes))
  char buf[1001];       {
  int nbytes;          break;
  int i;        }
  int numnulls = 0; 
 
  if (vclient->fd < 0) 
    return CMD_SUCCESS; 
 
  ret = write (vclient->fd, line, strlen (line) + 1); 
  if (ret <= 0) 
    { 
      vclient_close (vclient); 
      return CMD_SUCCESS; 
     }      }
           
   while (1)  
     {  
       nbytes = read (vclient->fd, buf, sizeof(buf)-1);  
   
      if (nbytes <= 0 && errno != EINTR)  if(!fp)
        {    vtysh_config_parse (buf);
          vclient_close (vclient); 
          return CMD_SUCCESS; 
        } 
   
      if (nbytes > 0)  XFREE(MTYPE_TMP, buf);
        {  return ret;
          if ((numnulls == 3) && (nbytes == 1)) 
            return buf[0]; 
 
          buf[nbytes] = '\0'; 
          fputs (buf, fp); 
          fflush (fp); 
           
          /* check for trailling \0\0\0<ret code>,  
           * even if split across reads  
           * (see lib/vty.c::vtysh_read) 
           */ 
          if (nbytes >= 4)  
            { 
              i = nbytes-4; 
              numnulls = 0; 
            } 
          else 
            i = 0; 
           
          while (i < nbytes && numnulls < 3) 
            { 
              if (buf[i++] == '\0') 
                numnulls++; 
              else 
                numnulls = 0; 
            } 
 
          /* got 3 or more trailing NULs? */ 
          if ((numnulls >= 3) && (i < nbytes)) 
            return (buf[nbytes-1]); 
        } 
    } 
 }  }
    
   
 void  void
 vtysh_exit_ripd_only (void)  
 {  
   if (ripd_client)  
     vtysh_client_execute (ripd_client, "exit", stdout);  
 }  
   
   
 void  
 vtysh_pager_init (void)  vtysh_pager_init (void)
 {  {
   char *pager_defined;    char *pager_defined;
Line 311  vtysh_execute_func (const char *line, int pager) Line 280  vtysh_execute_func (const char *line, int pager)
    * to move into node in the vtysh where it succeeded. */     * to move into node in the vtysh where it succeeded. */
   if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON || ret == CMD_WARNING)    if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON || ret == CMD_WARNING)
     {      {
      if ((saved_node == BGP_VPNV4_NODE || saved_node == BGP_IPV4_NODE      if ((saved_node == BGP_VPNV4_NODE || saved_node == BGP_VPNV6_NODE
            || saved_node == BGP_ENCAP_NODE || saved_node == BGP_ENCAPV6_NODE
            || saved_node == BGP_IPV4_NODE
            || saved_node == BGP_IPV6_NODE || saved_node == BGP_IPV4M_NODE             || saved_node == BGP_IPV6_NODE || saved_node == BGP_IPV4M_NODE
            || saved_node == BGP_IPV6M_NODE)             || saved_node == BGP_IPV6M_NODE)
           && (tried == 1))            && (tried == 1))
Line 374  vtysh_execute_func (const char *line, int pager) Line 345  vtysh_execute_func (const char *line, int pager)
   
         if (! strcmp(cmd->string,"configure terminal"))          if (! strcmp(cmd->string,"configure terminal"))
           {            {
            for (i = 0; i < VTYSH_INDEX_MAX; i++)            for (i = 0; i < array_size(vtysh_client); i++)
               {                {
                 cmd_stat = vtysh_client_execute(&vtysh_client[i], line, fp);                  cmd_stat = vtysh_client_execute(&vtysh_client[i], line, fp);
                 if (cmd_stat == CMD_WARNING)                  if (cmd_stat == CMD_WARNING)
Line 413  vtysh_execute_func (const char *line, int pager) Line 384  vtysh_execute_func (const char *line, int pager)
           }            }
   
         cmd_stat = CMD_SUCCESS;          cmd_stat = CMD_SUCCESS;
        for (i = 0; i < VTYSH_INDEX_MAX; i++)        for (i = 0; i < array_size(vtysh_client); i++)
           {            {
             if (cmd->daemon & vtysh_client[i].flag)              if (cmd->daemon & vtysh_client[i].flag)
               {                {
Line 457  int Line 428  int
 vtysh_config_from_file (struct vty *vty, FILE *fp)  vtysh_config_from_file (struct vty *vty, FILE *fp)
 {  {
   int ret;    int ret;
   vector vline;  
   struct cmd_element *cmd;    struct cmd_element *cmd;
   
   while (fgets (vty->buf, VTY_BUFSIZ, fp))    while (fgets (vty->buf, VTY_BUFSIZ, fp))
     {      {
      if (vty->buf[0] == '!' || vty->buf[1] == '#')      ret = command_config_read_one_line (vty, &cmd, 1);
        continue; 
   
       vline = cmd_make_strvec (vty->buf);  
   
       /* In case of comment line. */  
       if (vline == NULL)  
         continue;  
   
       /* Execute configuration command : this is strict match. */  
       ret = cmd_execute_command_strict (vline, vty, &cmd);  
   
       /* Try again with setting node to CONFIG_NODE. */  
       if (ret != CMD_SUCCESS   
           && ret != CMD_SUCCESS_DAEMON  
           && ret != CMD_WARNING)  
         {  
           if (vty->node == KEYCHAIN_KEY_NODE)  
             {  
               vty->node = KEYCHAIN_NODE;  
               vtysh_exit_ripd_only ();  
               ret = cmd_execute_command_strict (vline, vty, &cmd);  
   
               if (ret != CMD_SUCCESS   
                   && ret != CMD_SUCCESS_DAEMON   
                   && ret != CMD_WARNING)  
                 {  
                   vtysh_exit_ripd_only ();  
                   vty->node = CONFIG_NODE;  
                   ret = cmd_execute_command_strict (vline, vty, &cmd);  
                 }  
             }  
           else  
             {  
               vtysh_execute ("end");  
               vtysh_execute ("configure terminal");  
               vty->node = CONFIG_NODE;  
               ret = cmd_execute_command_strict (vline, vty, &cmd);  
             }  
         }           
   
       cmd_free_strvec (vline);  
   
       switch (ret)        switch (ret)
         {          {
         case CMD_WARNING:          case CMD_WARNING:
Line 525  vtysh_config_from_file (struct vty *vty, FILE *fp) Line 454  vtysh_config_from_file (struct vty *vty, FILE *fp)
             u_int i;              u_int i;
             int cmd_stat = CMD_SUCCESS;              int cmd_stat = CMD_SUCCESS;
   
            for (i = 0; i < VTYSH_INDEX_MAX; i++)            for (i = 0; i < array_size(vtysh_client); i++)
               {                {
                 if (cmd->daemon & vtysh_client[i].flag)                  if (cmd->daemon & vtysh_client[i].flag)
                   {                    {
Line 547  vtysh_config_from_file (struct vty *vty, FILE *fp) Line 476  vtysh_config_from_file (struct vty *vty, FILE *fp)
 }  }
   
 /* We don't care about the point of the cursor when '?' is typed. */  /* We don't care about the point of the cursor when '?' is typed. */
intstatic int
 vtysh_rl_describe (void)  vtysh_rl_describe (void)
 {  {
   int ret;    int ret;
Line 555  vtysh_rl_describe (void) Line 484  vtysh_rl_describe (void)
   vector vline;    vector vline;
   vector describe;    vector describe;
   int width;    int width;
  struct desc *desc;  struct cmd_token *token;
   
   vline = cmd_make_strvec (rl_line_buffer);    vline = cmd_make_strvec (rl_line_buffer);
   
Line 563  vtysh_rl_describe (void) Line 492  vtysh_rl_describe (void)
   if (vline == NULL)    if (vline == NULL)
     {      {
       vline = vector_init (1);        vline = vector_init (1);
      vector_set (vline, '\0');      vector_set (vline, NULL);
     }      }
   else     else 
     if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))      if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
      vector_set (vline, '\0');      vector_set (vline, NULL);
   
   describe = cmd_describe_command (vline, vty, &ret);    describe = cmd_describe_command (vline, vty, &ret);
   
Line 593  vtysh_rl_describe (void) Line 522  vtysh_rl_describe (void)
   /* Get width of command string. */    /* Get width of command string. */
   width = 0;    width = 0;
   for (i = 0; i < vector_active (describe); i++)    for (i = 0; i < vector_active (describe); i++)
    if ((desc = vector_slot (describe, i)) != NULL)    if ((token = vector_slot (describe, i)) != NULL)
       {        {
         int len;          int len;
   
        if (desc->cmd[0] == '\0')        if (token->cmd[0] == '\0')
           continue;            continue;
   
        len = strlen (desc->cmd);        len = strlen (token->cmd);
        if (desc->cmd[0] == '.')        if (token->cmd[0] == '.')
           len--;            len--;
   
         if (width < len)          if (width < len)
Line 609  vtysh_rl_describe (void) Line 538  vtysh_rl_describe (void)
       }        }
   
   for (i = 0; i < vector_active (describe); i++)    for (i = 0; i < vector_active (describe); i++)
    if ((desc = vector_slot (describe, i)) != NULL)    if ((token = vector_slot (describe, i)) != NULL)
       {        {
        if (desc->cmd[0] == '\0')        if (token->cmd[0] == '\0')
           continue;            continue;
   
        if (! desc->str)        if (! token->desc)
           fprintf (stdout,"  %-s\n",            fprintf (stdout,"  %-s\n",
                   desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd);                   token->cmd[0] == '.' ? token->cmd + 1 : token->cmd);
         else          else
           fprintf (stdout,"  %-*s  %s\n",            fprintf (stdout,"  %-*s  %s\n",
                    width,                     width,
                   desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,                   token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
                   desc->str);                   token->desc);
       }        }
   
   cmd_free_strvec (vline);    cmd_free_strvec (vline);
Line 657  command_generator (const char *text, int state) Line 586  command_generator (const char *text, int state)
         return NULL;          return NULL;
   
       if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))        if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
        vector_set (vline, '\0');        vector_set (vline, NULL);
   
       matched = cmd_complete_command (vline, vty, &complete_status);        matched = cmd_complete_command (vline, vty, &complete_status);
     }      }
Line 678  new_completion (char *text, int start, int end) Line 607  new_completion (char *text, int start, int end)
   if (matches)    if (matches)
     {      {
       rl_point = rl_end;        rl_point = rl_end;
      if (complete_status == CMD_COMPLETE_FULL_MATCH)      if (complete_status != CMD_COMPLETE_FULL_MATCH)
        rl_pending_input = ' ';        /* only append a space on full match */
         rl_completion_append_character = '\0';
     }      }
   
   return matches;    return matches;
Line 756  static struct cmd_node bgp_vpnv4_node = Line 686  static struct cmd_node bgp_vpnv4_node =
   "%s(config-router-af)# "    "%s(config-router-af)# "
 };  };
   
   static struct cmd_node bgp_vpnv6_node =
   {
     BGP_VPNV6_NODE,
     "%s(config-router-af)# "
   };
   
   static struct cmd_node bgp_encap_node =
   {
     BGP_ENCAP_NODE,
     "%s(config-router-af)# "
   };
   
   static struct cmd_node bgp_encapv6_node =
   {
     BGP_ENCAPV6_NODE,
     "%s(config-router-af)# "
   };
   
 static struct cmd_node bgp_ipv4_node =  static struct cmd_node bgp_ipv4_node =
 {  {
   BGP_IPV4_NODE,    BGP_IPV4_NODE,
Line 820  static struct cmd_node keychain_key_node = Line 768  static struct cmd_node keychain_key_node =
 extern struct cmd_node vty_node;  extern struct cmd_node vty_node;
   
 /* When '^Z' is received from vty, move down to the enable mode. */  /* When '^Z' is received from vty, move down to the enable mode. */
intstatic int
 vtysh_end (void)  vtysh_end (void)
 {  {
   switch (vty->node)    switch (vty->node)
Line 891  DEFUNSH (VTYSH_BGPD, Line 839  DEFUNSH (VTYSH_BGPD,
 }  }
   
 DEFUNSH (VTYSH_BGPD,  DEFUNSH (VTYSH_BGPD,
            address_family_vpnv6,
            address_family_vpnv6_cmd,
            "address-family vpnv6",
            "Enter Address Family command mode\n"
            "Address family\n")
   {
     vty->node = BGP_VPNV6_NODE;
     return CMD_SUCCESS;
   }
   
   DEFUNSH (VTYSH_BGPD,
            address_family_vpnv6_unicast,
            address_family_vpnv6_unicast_cmd,
            "address-family vpnv6 unicast",
            "Enter Address Family command mode\n"
            "Address family\n"
            "Address Family Modifier\n")
   {
     vty->node = BGP_VPNV6_NODE;
     return CMD_SUCCESS;
   }
   
   DEFUNSH (VTYSH_BGPD,
            address_family_encap,
            address_family_encap_cmd,
            "address-family encap",
            "Enter Address Family command mode\n"
            "Address family\n")
   {
     vty->node = BGP_ENCAP_NODE;
     return CMD_SUCCESS;
   }
   
   DEFUNSH (VTYSH_BGPD,
            address_family_encapv4,
            address_family_encapv4_cmd,
            "address-family encapv4",
            "Enter Address Family command mode\n"
            "Address family\n")
   {
     vty->node = BGP_ENCAP_NODE;
     return CMD_SUCCESS;
   }
   
   DEFUNSH (VTYSH_BGPD,
            address_family_encapv6,
            address_family_encapv6_cmd,
            "address-family encapv6",
            "Enter Address Family command mode\n"
            "Address family\n")
   {
     vty->node = BGP_ENCAPV6_NODE;
     return CMD_SUCCESS;
   }
   
   DEFUNSH (VTYSH_BGPD,
          address_family_ipv4_unicast,           address_family_ipv4_unicast,
          address_family_ipv4_unicast_cmd,           address_family_ipv4_unicast_cmd,
          "address-family ipv4 unicast",           "address-family ipv4 unicast",
Line 1016  DEFUNSH (VTYSH_OSPF6D, Line 1020  DEFUNSH (VTYSH_OSPF6D,
   return CMD_SUCCESS;    return CMD_SUCCESS;
 }  }
   
 DEFUNSH (VTYSH_BABELD,  
          router_babel,  
          router_babel_cmd,  
          "router babel",  
          ROUTER_STR  
          "Babel")  
 {  
   vty->node = BABEL_NODE;  
   return CMD_SUCCESS;  
 }  
   
 DEFUNSH (VTYSH_ISISD,  DEFUNSH (VTYSH_ISISD,
          router_isis,           router_isis,
          router_isis_cmd,           router_isis_cmd,
Line 1126  vtysh_exit (struct vty *vty) Line 1119  vtysh_exit (struct vty *vty)
       vty->node = CONFIG_NODE;        vty->node = CONFIG_NODE;
       break;        break;
     case BGP_VPNV4_NODE:      case BGP_VPNV4_NODE:
       case BGP_VPNV6_NODE:
       case BGP_ENCAP_NODE:
       case BGP_ENCAPV6_NODE:
     case BGP_IPV4_NODE:      case BGP_IPV4_NODE:
     case BGP_IPV4M_NODE:      case BGP_IPV4M_NODE:
     case BGP_IPV6_NODE:      case BGP_IPV6_NODE:
Line 1164  DEFUNSH (VTYSH_BGPD, Line 1160  DEFUNSH (VTYSH_BGPD,
   if (vty->node == BGP_IPV4_NODE    if (vty->node == BGP_IPV4_NODE
       || vty->node == BGP_IPV4M_NODE        || vty->node == BGP_IPV4M_NODE
       || vty->node == BGP_VPNV4_NODE        || vty->node == BGP_VPNV4_NODE
         || vty->node == BGP_VPNV6_NODE
         || vty->node == BGP_ENCAP_NODE
         || vty->node == BGP_ENCAPV6_NODE
       || vty->node == BGP_IPV6_NODE        || vty->node == BGP_IPV6_NODE
       || vty->node == BGP_IPV6M_NODE)        || vty->node == BGP_IPV6M_NODE)
     vty->node = BGP_NODE;      vty->node = BGP_NODE;
Line 1307  DEFUNSH (VTYSH_INTERFACE, Line 1306  DEFUNSH (VTYSH_INTERFACE,
   return CMD_SUCCESS;    return CMD_SUCCESS;
 }  }
   
   ALIAS_SH (VTYSH_ZEBRA,
            vtysh_interface,
            vtysh_interface_vrf_cmd,
            "interface IFNAME " VRF_CMD_STR,
            "Select an interface to configure\n"
            "Interface's name\n"
            VRF_CMD_HELP_STR)
   
 /* TODO Implement "no interface command in isisd. */  /* TODO Implement "no interface command in isisd. */
 DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D,  DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D,
        vtysh_no_interface_cmd,         vtysh_no_interface_cmd,
Line 1315  DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD Line 1322  DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD
        "Delete a pseudo interface's configuration\n"         "Delete a pseudo interface's configuration\n"
        "Interface's name\n")         "Interface's name\n")
   
   DEFSH (VTYSH_ZEBRA,
          vtysh_no_interface_vrf_cmd,
          "no interface IFNAME " VRF_CMD_STR,
          NO_STR
          "Delete a pseudo interface's configuration\n"
          "Interface's name\n"
          VRF_CMD_HELP_STR)
   
 /* TODO Implement interface description commands in ripngd, ospf6d  /* TODO Implement interface description commands in ripngd, ospf6d
  * and isisd. */   * and isisd. */
 DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,  DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
Line 1343  ALIAS (vtysh_exit_interface, Line 1358  ALIAS (vtysh_exit_interface,
        "quit",         "quit",
        "Exit current mode and down to previous mode\n")         "Exit current mode and down to previous mode\n")
   
   DEFUN (vtysh_show_thread,
          vtysh_show_thread_cmd,
          "show thread cpu [FILTER]",
         SHOW_STR
         "Thread information\n"
         "Thread CPU usage\n"
         "Display filter (rwtexb)\n")
   {
     unsigned int i;
     int ret = CMD_SUCCESS;
     char line[100];
   
     sprintf(line, "show thread cpu %s\n", (argc == 1) ? argv[0] : "");
     for (i = 0; i < array_size(vtysh_client); i++)
       if ( vtysh_client[i].fd >= 0 )
         {
           fprintf (stdout, "Thread statistics for %s:\n",
                    vtysh_client[i].name);
           ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
           fprintf (stdout,"\n");
         }
     return ret;
   }
   
   DEFUN (vtysh_show_work_queues,
          vtysh_show_work_queues_cmd,
          "show work-queues",
          SHOW_STR
          "Work Queue information\n")
   {
     unsigned int i;
     int ret = CMD_SUCCESS;
     char line[] = "show work-queues\n";
   
     for (i = 0; i < array_size(vtysh_client); i++)
       if ( vtysh_client[i].fd >= 0 )
         {
           fprintf (stdout, "Work queue statistics for %s:\n",
                    vtysh_client[i].name);
           ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
           fprintf (stdout,"\n");
         }
   
     return ret;
   }
   
 /* Memory */  /* Memory */
 DEFUN (vtysh_show_memory,  DEFUN (vtysh_show_memory,
        vtysh_show_memory_cmd,         vtysh_show_memory_cmd,
Line 1354  DEFUN (vtysh_show_memory, Line 1415  DEFUN (vtysh_show_memory,
   int ret = CMD_SUCCESS;    int ret = CMD_SUCCESS;
   char line[] = "show memory\n";    char line[] = "show memory\n";
       
  for (i = 0; i < VTYSH_INDEX_MAX; i++)  for (i = 0; i < array_size(vtysh_client); i++)
     if ( vtysh_client[i].fd >= 0 )      if ( vtysh_client[i].fd >= 0 )
       {        {
         fprintf (stdout, "Memory statistics for %s:\n",           fprintf (stdout, "Memory statistics for %s:\n", 
Line 1377  DEFUN (vtysh_show_logging, Line 1438  DEFUN (vtysh_show_logging,
   int ret = CMD_SUCCESS;    int ret = CMD_SUCCESS;
   char line[] = "show logging\n";    char line[] = "show logging\n";
       
  for (i = 0; i < VTYSH_INDEX_MAX; i++)  for (i = 0; i < array_size(vtysh_client); i++)
     if ( vtysh_client[i].fd >= 0 )      if ( vtysh_client[i].fd >= 0 )
       {        {
         fprintf (stdout,"Logging configuration for %s:\n",           fprintf (stdout,"Logging configuration for %s:\n", 
Line 1712  DEFUN (vtysh_write_terminal, Line 1773  DEFUN (vtysh_write_terminal,
        "Write to terminal\n")         "Write to terminal\n")
 {  {
   u_int i;    u_int i;
   int ret;  
   char line[] = "write terminal\n";    char line[] = "write terminal\n";
   FILE *fp = NULL;    FILE *fp = NULL;
   
Line 1733  DEFUN (vtysh_write_terminal, Line 1793  DEFUN (vtysh_write_terminal,
            VTY_NEWLINE);             VTY_NEWLINE);
   vty_out (vty, "!%s", VTY_NEWLINE);    vty_out (vty, "!%s", VTY_NEWLINE);
   
  for (i = 0; i < VTYSH_INDEX_MAX; i++)  for (i = 0; i < array_size(vtysh_client); i++)
    ret = vtysh_client_config (&vtysh_client[i], line);    vtysh_client_execute (&vtysh_client[i], line, NULL);
   
   /* Integrate vtysh specific configuration. */    /* Integrate vtysh specific configuration. */
   vtysh_config_write ();    vtysh_config_write ();
Line 1757  DEFUN (vtysh_write_terminal, Line 1817  DEFUN (vtysh_write_terminal,
   return CMD_SUCCESS;    return CMD_SUCCESS;
 }  }
   
   DEFUN (vtysh_write_terminal_daemon,
          vtysh_write_terminal_daemon_cmd,
          "write terminal (zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|babeld)",
          "Write running configuration to memory, network, or terminal\n"
          "Write to terminal\n"
          "For the zebra daemon\n"
          "For the rip daemon\n"
          "For the ripng daemon\n"
          "For the ospf daemon\n"
          "For the ospfv6 daemon\n"
          "For the bgp daemon\n"
          "For the isis daemon\n"
          "For the babel daemon\n")
   {
     unsigned int i;
     int ret = CMD_SUCCESS;
   
     for (i = 0; i < array_size(vtysh_client); i++)
       {
         if (strcmp(vtysh_client[i].name, argv[0]) == 0)
           break;
       }
   
     ret = vtysh_client_execute(&vtysh_client[i], "show running-config\n", stdout);
   
     return ret;
   }
   
 DEFUN (vtysh_integrated_config,  DEFUN (vtysh_integrated_config,
        vtysh_integrated_config_cmd,         vtysh_integrated_config_cmd,
        "service integrated-vtysh-config",         "service integrated-vtysh-config",
Line 1782  static int Line 1870  static int
 write_config_integrated(void)  write_config_integrated(void)
 {  {
   u_int i;    u_int i;
   int ret;  
   char line[] = "write terminal\n";    char line[] = "write terminal\n";
   FILE *fp;    FILE *fp;
   char *integrate_sav = NULL;    char *integrate_sav = NULL;
Line 1807  write_config_integrated(void) Line 1894  write_config_integrated(void)
       return CMD_SUCCESS;        return CMD_SUCCESS;
     }      }
   
  for (i = 0; i < VTYSH_INDEX_MAX; i++)  for (i = 0; i < array_size(vtysh_client); i++)
    ret = vtysh_client_config (&vtysh_client[i], line);    vtysh_client_execute (&vtysh_client[i], line, NULL);
   
   vtysh_config_dump (fp);    vtysh_config_dump (fp);
   
Line 1844  DEFUN (vtysh_write_memory, Line 1931  DEFUN (vtysh_write_memory,
   
   fprintf (stdout,"Building Configuration...\n");    fprintf (stdout,"Building Configuration...\n");
                       
  for (i = 0; i < VTYSH_INDEX_MAX; i++)  for (i = 0; i < array_size(vtysh_client); i++)
     ret = vtysh_client_execute (&vtysh_client[i], line, stdout);      ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
       
   fprintf (stdout,"[OK]\n");    fprintf (stdout,"[OK]\n");
Line 1876  ALIAS (vtysh_write_terminal, Line 1963  ALIAS (vtysh_write_terminal,
        SHOW_STR         SHOW_STR
        "Current operating configuration\n")         "Current operating configuration\n")
   
   ALIAS (vtysh_write_terminal_daemon,
          vtysh_show_running_config_daemon_cmd,
          "show running-config (zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|babeld)",
          SHOW_STR
          "Current operating configuration\n"
          "For the zebra daemon\n"
          "For the rip daemon\n"
          "For the ripng daemon\n"
          "For the ospf daemon\n"
          "For the ospfv6 daemon\n"
          "For the bgp daemon\n"
          "For the isis daemon\n"
          "For the babel daemon\n")
   
 DEFUN (vtysh_terminal_length,  DEFUN (vtysh_terminal_length,
        vtysh_terminal_length_cmd,         vtysh_terminal_length_cmd,
        "terminal length <0-512>",         "terminal length <0-512>",
Line 1934  DEFUN (vtysh_show_daemons, Line 2035  DEFUN (vtysh_show_daemons,
 {  {
   u_int i;    u_int i;
   
  for (i = 0; i < VTYSH_INDEX_MAX; i++)  for (i = 0; i < array_size(vtysh_client); i++)
     if ( vtysh_client[i].fd >= 0 )      if ( vtysh_client[i].fd >= 0 )
       vty_out(vty, " %s", vtysh_client[i].name);        vty_out(vty, " %s", vtysh_client[i].name);
   vty_out(vty, "%s", VTY_NEWLINE);    vty_out(vty, "%s", VTY_NEWLINE);
Line 1947  static int Line 2048  static int
 execute_command (const char *command, int argc, const char *arg1,  execute_command (const char *command, int argc, const char *arg1,
                  const char *arg2)                   const char *arg2)
 {  {
   int ret;  
   pid_t pid;    pid_t pid;
   int status;    int status;
   
Line 1966  execute_command (const char *command, int argc, const  Line 2066  execute_command (const char *command, int argc, const 
       switch (argc)        switch (argc)
         {          {
         case 0:          case 0:
          ret = execlp (command, command, (const char *)NULL);          execlp (command, command, (const char *)NULL);
           break;            break;
         case 1:          case 1:
          ret = execlp (command, command, arg1, (const char *)NULL);          execlp (command, command, arg1, (const char *)NULL);
           break;            break;
         case 2:          case 2:
          ret = execlp (command, command, arg1, arg2, (const char *)NULL);          execlp (command, command, arg1, arg2, (const char *)NULL);
           break;            break;
         }          }
   
Line 1984  execute_command (const char *command, int argc, const  Line 2084  execute_command (const char *command, int argc, const 
     {      {
       /* This is parent. */        /* This is parent. */
       execute_flag = 1;        execute_flag = 1;
      ret = wait4 (pid, &status, 0, NULL);      wait4 (pid, &status, 0, NULL);
       execute_flag = 0;        execute_flag = 0;
     }      }
   return 0;    return 0;
Line 2184  vtysh_connect_all(const char *daemon_name) Line 2284  vtysh_connect_all(const char *daemon_name)
   int rc = 0;    int rc = 0;
   int matches = 0;    int matches = 0;
   
  for (i = 0; i < VTYSH_INDEX_MAX; i++)  for (i = 0; i < array_size(vtysh_client); i++)
     {      {
       if (!daemon_name || !strcmp(daemon_name, vtysh_client[i].name))        if (!daemon_name || !strcmp(daemon_name, vtysh_client[i].name))
         {          {
Line 2212  void Line 2312  void
 vtysh_readline_init (void)  vtysh_readline_init (void)
 {  {
   /* readline related settings. */    /* readline related settings. */
  rl_bind_key ('?', (Function *) vtysh_rl_describe);  rl_bind_key ('?', (rl_command_func_t *) vtysh_rl_describe);
   rl_completion_entry_function = vtysh_completion_entry_function;    rl_completion_entry_function = vtysh_completion_entry_function;
  rl_attempted_completion_function = (CPPFunction *)new_completion;  rl_attempted_completion_function = (rl_completion_func_t *)new_completion;
  /* do not append space after completion. It will be appended 
   * in new_completion() function explicitly. */ 
  rl_completion_append_character = '\0'; 
 }  }
   
 char *  char *
Line 2260  vtysh_init_vty (void) Line 2357  vtysh_init_vty (void)
   install_node (&rmap_node, NULL);    install_node (&rmap_node, NULL);
   install_node (&zebra_node, NULL);    install_node (&zebra_node, NULL);
   install_node (&bgp_vpnv4_node, NULL);    install_node (&bgp_vpnv4_node, NULL);
     install_node (&bgp_vpnv6_node, NULL);
     install_node (&bgp_encap_node, NULL);
     install_node (&bgp_encapv6_node, NULL);
   install_node (&bgp_ipv4_node, NULL);    install_node (&bgp_ipv4_node, NULL);
   install_node (&bgp_ipv4m_node, NULL);    install_node (&bgp_ipv4m_node, NULL);
 /* #ifdef HAVE_IPV6 */  /* #ifdef HAVE_IPV6 */
Line 2286  vtysh_init_vty (void) Line 2386  vtysh_init_vty (void)
   vtysh_install_default (RMAP_NODE);    vtysh_install_default (RMAP_NODE);
   vtysh_install_default (ZEBRA_NODE);    vtysh_install_default (ZEBRA_NODE);
   vtysh_install_default (BGP_VPNV4_NODE);    vtysh_install_default (BGP_VPNV4_NODE);
     vtysh_install_default (BGP_VPNV6_NODE);
     vtysh_install_default (BGP_ENCAP_NODE);
     vtysh_install_default (BGP_ENCAPV6_NODE);
   vtysh_install_default (BGP_IPV4_NODE);    vtysh_install_default (BGP_IPV4_NODE);
   vtysh_install_default (BGP_IPV4M_NODE);    vtysh_install_default (BGP_IPV4M_NODE);
   vtysh_install_default (BGP_IPV6_NODE);    vtysh_install_default (BGP_IPV6_NODE);
Line 2322  vtysh_init_vty (void) Line 2425  vtysh_init_vty (void)
   install_element (BGP_NODE, &vtysh_quit_bgpd_cmd);    install_element (BGP_NODE, &vtysh_quit_bgpd_cmd);
   install_element (BGP_VPNV4_NODE, &vtysh_exit_bgpd_cmd);    install_element (BGP_VPNV4_NODE, &vtysh_exit_bgpd_cmd);
   install_element (BGP_VPNV4_NODE, &vtysh_quit_bgpd_cmd);    install_element (BGP_VPNV4_NODE, &vtysh_quit_bgpd_cmd);
     install_element (BGP_VPNV6_NODE, &vtysh_exit_bgpd_cmd);
     install_element (BGP_VPNV6_NODE, &vtysh_quit_bgpd_cmd);
     install_element (BGP_ENCAP_NODE, &vtysh_exit_bgpd_cmd);
     install_element (BGP_ENCAP_NODE, &vtysh_quit_bgpd_cmd);
     install_element (BGP_ENCAPV6_NODE, &vtysh_exit_bgpd_cmd);
     install_element (BGP_ENCAPV6_NODE, &vtysh_quit_bgpd_cmd);
   install_element (BGP_IPV4_NODE, &vtysh_exit_bgpd_cmd);    install_element (BGP_IPV4_NODE, &vtysh_exit_bgpd_cmd);
   install_element (BGP_IPV4_NODE, &vtysh_quit_bgpd_cmd);    install_element (BGP_IPV4_NODE, &vtysh_quit_bgpd_cmd);
   install_element (BGP_IPV4M_NODE, &vtysh_exit_bgpd_cmd);    install_element (BGP_IPV4M_NODE, &vtysh_exit_bgpd_cmd);
Line 2353  vtysh_init_vty (void) Line 2462  vtysh_init_vty (void)
   install_element (BGP_IPV4_NODE, &vtysh_end_all_cmd);    install_element (BGP_IPV4_NODE, &vtysh_end_all_cmd);
   install_element (BGP_IPV4M_NODE, &vtysh_end_all_cmd);    install_element (BGP_IPV4M_NODE, &vtysh_end_all_cmd);
   install_element (BGP_VPNV4_NODE, &vtysh_end_all_cmd);    install_element (BGP_VPNV4_NODE, &vtysh_end_all_cmd);
     install_element (BGP_VPNV6_NODE, &vtysh_end_all_cmd);
     install_element (BGP_ENCAP_NODE, &vtysh_end_all_cmd);
     install_element (BGP_ENCAPV6_NODE, &vtysh_end_all_cmd);
   install_element (BGP_IPV6_NODE, &vtysh_end_all_cmd);    install_element (BGP_IPV6_NODE, &vtysh_end_all_cmd);
   install_element (BGP_IPV6M_NODE, &vtysh_end_all_cmd);    install_element (BGP_IPV6M_NODE, &vtysh_end_all_cmd);
   install_element (ISIS_NODE, &vtysh_end_all_cmd);    install_element (ISIS_NODE, &vtysh_end_all_cmd);
Line 2374  vtysh_init_vty (void) Line 2486  vtysh_init_vty (void)
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
   install_element (CONFIG_NODE, &router_ospf6_cmd);    install_element (CONFIG_NODE, &router_ospf6_cmd);
 #endif  #endif
   install_element (CONFIG_NODE, &router_babel_cmd);  
   install_element (CONFIG_NODE, &router_isis_cmd);    install_element (CONFIG_NODE, &router_isis_cmd);
   install_element (CONFIG_NODE, &router_bgp_cmd);    install_element (CONFIG_NODE, &router_bgp_cmd);
   install_element (CONFIG_NODE, &router_bgp_view_cmd);    install_element (CONFIG_NODE, &router_bgp_view_cmd);
   install_element (BGP_NODE, &address_family_vpnv4_cmd);    install_element (BGP_NODE, &address_family_vpnv4_cmd);
   install_element (BGP_NODE, &address_family_vpnv4_unicast_cmd);    install_element (BGP_NODE, &address_family_vpnv4_unicast_cmd);
     install_element (BGP_NODE, &address_family_vpnv6_cmd);
     install_element (BGP_NODE, &address_family_vpnv6_unicast_cmd);
     install_element (BGP_NODE, &address_family_encap_cmd);
     install_element (BGP_NODE, &address_family_encapv6_cmd);
   install_element (BGP_NODE, &address_family_ipv4_unicast_cmd);    install_element (BGP_NODE, &address_family_ipv4_unicast_cmd);
   install_element (BGP_NODE, &address_family_ipv4_multicast_cmd);    install_element (BGP_NODE, &address_family_ipv4_multicast_cmd);
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
Line 2387  vtysh_init_vty (void) Line 2502  vtysh_init_vty (void)
   install_element (BGP_NODE, &address_family_ipv6_unicast_cmd);    install_element (BGP_NODE, &address_family_ipv6_unicast_cmd);
 #endif  #endif
   install_element (BGP_VPNV4_NODE, &exit_address_family_cmd);    install_element (BGP_VPNV4_NODE, &exit_address_family_cmd);
     install_element (BGP_VPNV6_NODE, &exit_address_family_cmd);
     install_element (BGP_ENCAP_NODE, &exit_address_family_cmd);
     install_element (BGP_ENCAPV6_NODE, &exit_address_family_cmd);
   install_element (BGP_IPV4_NODE, &exit_address_family_cmd);    install_element (BGP_IPV4_NODE, &exit_address_family_cmd);
   install_element (BGP_IPV4M_NODE, &exit_address_family_cmd);    install_element (BGP_IPV4M_NODE, &exit_address_family_cmd);
   install_element (BGP_IPV6_NODE, &exit_address_family_cmd);    install_element (BGP_IPV6_NODE, &exit_address_family_cmd);
Line 2399  vtysh_init_vty (void) Line 2517  vtysh_init_vty (void)
   install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd);    install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd);
   install_element (CONFIG_NODE, &vtysh_interface_cmd);    install_element (CONFIG_NODE, &vtysh_interface_cmd);
   install_element (CONFIG_NODE, &vtysh_no_interface_cmd);    install_element (CONFIG_NODE, &vtysh_no_interface_cmd);
     install_element (CONFIG_NODE, &vtysh_interface_vrf_cmd);
     install_element (CONFIG_NODE, &vtysh_no_interface_vrf_cmd);
   install_element (ENABLE_NODE, &vtysh_show_running_config_cmd);    install_element (ENABLE_NODE, &vtysh_show_running_config_cmd);
     install_element (ENABLE_NODE, &vtysh_show_running_config_daemon_cmd);
   install_element (ENABLE_NODE, &vtysh_copy_runningconfig_startupconfig_cmd);    install_element (ENABLE_NODE, &vtysh_copy_runningconfig_startupconfig_cmd);
   install_element (ENABLE_NODE, &vtysh_write_file_cmd);    install_element (ENABLE_NODE, &vtysh_write_file_cmd);
   install_element (ENABLE_NODE, &vtysh_write_cmd);    install_element (ENABLE_NODE, &vtysh_write_cmd);
   
   /* "write terminal" command. */    /* "write terminal" command. */
   install_element (ENABLE_NODE, &vtysh_write_terminal_cmd);    install_element (ENABLE_NODE, &vtysh_write_terminal_cmd);
     install_element (ENABLE_NODE, &vtysh_write_terminal_daemon_cmd);
     
   install_element (CONFIG_NODE, &vtysh_integrated_config_cmd);    install_element (CONFIG_NODE, &vtysh_integrated_config_cmd);
   install_element (CONFIG_NODE, &no_vtysh_integrated_config_cmd);    install_element (CONFIG_NODE, &no_vtysh_integrated_config_cmd);
Line 2448  vtysh_init_vty (void) Line 2570  vtysh_init_vty (void)
       
   install_element (VIEW_NODE, &vtysh_show_memory_cmd);    install_element (VIEW_NODE, &vtysh_show_memory_cmd);
   install_element (ENABLE_NODE, &vtysh_show_memory_cmd);    install_element (ENABLE_NODE, &vtysh_show_memory_cmd);
   
     install_element (VIEW_NODE, &vtysh_show_work_queues_cmd);
     install_element (ENABLE_NODE, &vtysh_show_work_queues_cmd);
   
     install_element (VIEW_NODE, &vtysh_show_thread_cmd);
     install_element (ENABLE_NODE, &vtysh_show_thread_cmd);
   
   /* Logging */    /* Logging */
   install_element (ENABLE_NODE, &vtysh_show_logging_cmd);    install_element (ENABLE_NODE, &vtysh_show_logging_cmd);

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>