2002-12-13 21:15:29 +01:00
|
|
|
/* Configuration generator.
|
|
|
|
Copyright (C) 2000 Kunihiro Ishiguro
|
|
|
|
|
|
|
|
This file is part of GNU Zebra.
|
|
|
|
|
|
|
|
GNU Zebra is free software; you can redistribute it and/or modify it
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
Free Software Foundation; either version 2, or (at your option) any
|
|
|
|
later version.
|
|
|
|
|
|
|
|
GNU Zebra is distributed in the hope that it will be useful, but
|
|
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with GNU Zebra; see the file COPYING. If not, write to the Free
|
|
|
|
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
02111-1307, USA. */
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "command.h"
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "memory.h"
|
|
|
|
|
|
|
|
#include "vtysh/vtysh.h"
|
2015-07-26 00:55:47 +02:00
|
|
|
#include "vtysh/vtysh_user.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-29 05:48:31 +02:00
|
|
|
DEFINE_MGROUP(MVTYSH, "vtysh")
|
|
|
|
DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CONFIG, "Vtysh configuration")
|
|
|
|
DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CONFIG_LINE, "Vtysh configuration line")
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
vector configvec;
|
|
|
|
|
|
|
|
struct config
|
|
|
|
{
|
|
|
|
/* Configuration node name. */
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
/* Configuration string line. */
|
|
|
|
struct list *line;
|
|
|
|
|
|
|
|
/* Configuration can be nest. */
|
|
|
|
struct config *config;
|
|
|
|
|
|
|
|
/* Index of this config. */
|
|
|
|
u_int32_t index;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct list *config_top;
|
2004-08-26 15:08:30 +02:00
|
|
|
|
2015-03-04 07:07:01 +01:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
line_cmp (char *c1, char *c2)
|
|
|
|
{
|
|
|
|
return strcmp (c1, c2);
|
|
|
|
}
|
|
|
|
|
2015-03-04 07:07:01 +01:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
line_del (char *line)
|
|
|
|
{
|
|
|
|
XFREE (MTYPE_VTYSH_CONFIG_LINE, line);
|
|
|
|
}
|
|
|
|
|
2015-03-04 07:07:01 +01:00
|
|
|
static struct config *
|
2015-11-23 21:43:15 +01:00
|
|
|
config_new (void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct config *config;
|
|
|
|
config = XCALLOC (MTYPE_VTYSH_CONFIG, sizeof (struct config));
|
|
|
|
return config;
|
|
|
|
}
|
|
|
|
|
2015-03-04 07:07:01 +01:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
config_cmp (struct config *c1, struct config *c2)
|
|
|
|
{
|
|
|
|
return strcmp (c1->name, c2->name);
|
|
|
|
}
|
|
|
|
|
2015-03-04 07:07:01 +01:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
config_del (struct config* config)
|
|
|
|
{
|
|
|
|
list_delete (config->line);
|
|
|
|
if (config->name)
|
|
|
|
XFREE (MTYPE_VTYSH_CONFIG_LINE, config->name);
|
|
|
|
XFREE (MTYPE_VTYSH_CONFIG, config);
|
|
|
|
}
|
|
|
|
|
2015-03-04 07:07:01 +01:00
|
|
|
static struct config *
|
2004-10-07 23:40:25 +02:00
|
|
|
config_get (int index, const char *line)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct config *config;
|
|
|
|
struct config *config_loop;
|
|
|
|
struct list *master;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
config = config_loop = NULL;
|
|
|
|
|
|
|
|
master = vector_lookup_ensure (configvec, index);
|
|
|
|
|
|
|
|
if (! master)
|
|
|
|
{
|
|
|
|
master = list_new ();
|
|
|
|
master->del = (void (*) (void *))config_del;
|
|
|
|
master->cmp = (int (*)(void *, void *)) config_cmp;
|
|
|
|
vector_set_index (configvec, index, master);
|
|
|
|
}
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (master, node, nnode, config_loop))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (strcmp (config_loop->name, line) == 0)
|
|
|
|
config = config_loop;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! config)
|
|
|
|
{
|
|
|
|
config = config_new ();
|
|
|
|
config->line = list_new ();
|
|
|
|
config->line->del = (void (*) (void *))line_del;
|
|
|
|
config->line->cmp = (int (*)(void *, void *)) line_cmp;
|
|
|
|
config->name = XSTRDUP (MTYPE_VTYSH_CONFIG_LINE, line);
|
|
|
|
config->index = index;
|
|
|
|
listnode_add (master, config);
|
|
|
|
}
|
|
|
|
return config;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-10-07 23:40:25 +02:00
|
|
|
config_add_line (struct list *config, const char *line)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
listnode_add (config, XSTRDUP (MTYPE_VTYSH_CONFIG_LINE, line));
|
|
|
|
}
|
|
|
|
|
2015-03-04 07:07:01 +01:00
|
|
|
static void
|
2004-10-07 23:40:25 +02:00
|
|
|
config_add_line_uniq (struct list *config, const char *line)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
2002-12-13 21:15:29 +01:00
|
|
|
char *pnt;
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (config, node, nnode, pnt))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (strcmp (pnt, line) == 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
listnode_add_sort (config, XSTRDUP (MTYPE_VTYSH_CONFIG_LINE, line));
|
|
|
|
}
|
|
|
|
|
2015-03-04 07:07:01 +01:00
|
|
|
static void
|
2004-10-07 23:40:25 +02:00
|
|
|
vtysh_config_parse_line (const char *line)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
char c;
|
|
|
|
static struct config *config = NULL;
|
|
|
|
|
|
|
|
if (! line)
|
|
|
|
return;
|
|
|
|
|
|
|
|
c = line[0];
|
|
|
|
|
|
|
|
if (c == '\0')
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* printf ("[%s]\n", line); */
|
|
|
|
|
|
|
|
switch (c)
|
|
|
|
{
|
2015-10-21 00:00:40 +02:00
|
|
|
/* Suppress exclamation points ! and commented lines. The !s are generated
|
|
|
|
* dynamically in vtysh_config_dump() */
|
2002-12-13 21:15:29 +01:00
|
|
|
case '!':
|
|
|
|
case '#':
|
|
|
|
break;
|
|
|
|
case ' ':
|
|
|
|
/* Store line to current configuration. */
|
|
|
|
if (config)
|
|
|
|
{
|
bgpd: add L3/L2VPN Virtual Network Control feature
This feature adds an L3 & L2 VPN application that makes use of the VPN
and Encap SAFIs. This code is currently used to support IETF NVO3 style
operation. In NVO3 terminology it provides the Network Virtualization
Authority (NVA) and the ability to import/export IP prefixes and MAC
addresses from Network Virtualization Edges (NVEs). The code supports
per-NVE tables.
The NVE-NVA protocol used to communicate routing and Ethernet / Layer 2
(L2) forwarding information between NVAs and NVEs is referred to as the
Remote Forwarder Protocol (RFP). OpenFlow is an example RFP. For
general background on NVO3 and RFP concepts see [1]. For information on
Openflow see [2].
RFPs are integrated with BGP via the RF API contained in the new "rfapi"
BGP sub-directory. Currently, only a simple example RFP is included in
Quagga. Developers may use this example as a starting point to integrate
Quagga with an RFP of their choosing, e.g., OpenFlow. The RFAPI code
also supports the ability import/export of routing information between
VNC and customer edge routers (CEs) operating within a virtual
network. Import/export may take place between BGP views or to the
default zebera VRF.
BGP, with IP VPNs and Tunnel Encapsulation, is used to distribute VPN
information between NVAs. BGP based IP VPN support is defined in
RFC4364, BGP/MPLS IP Virtual Private Networks (VPNs), and RFC4659,
BGP-MPLS IP Virtual Private Network (VPN) Extension for IPv6 VPN . Use
of both the Encapsulation Subsequent Address Family Identifier (SAFI)
and the Tunnel Encapsulation Attribute, RFC5512, The BGP Encapsulation
Subsequent Address Family Identifier (SAFI) and the BGP Tunnel
Encapsulation Attribute, are supported. MAC address distribution does
not follow any standard BGB encoding, although it was inspired by the
early IETF EVPN concepts.
The feature is conditionally compiled and disabled by default.
Use the --enable-bgp-vnc configure option to enable.
The majority of this code was authored by G. Paul Ziemba
<paulz@labn.net>.
[1] http://tools.ietf.org/html/draft-ietf-nvo3-nve-nva-cp-req
[2] https://www.opennetworking.org/sdn-resources/technical-library
Now includes changes needed to merge with cmaster-next.
2016-05-07 20:18:56 +02:00
|
|
|
if (strncmp (line, " address-family vpnv4",
|
|
|
|
strlen (" address-family vpnv4")) == 0)
|
|
|
|
config = config_get (BGP_VPNV4_NODE, line);
|
|
|
|
else if (strncmp (line, " address-family vpn6",
|
|
|
|
strlen (" address-family vpn6")) == 0)
|
|
|
|
config = config_get (BGP_VPNV6_NODE, line);
|
|
|
|
else if (strncmp (line, " address-family encapv6",
|
|
|
|
strlen (" address-family encapv6")) == 0)
|
|
|
|
config = config_get (BGP_ENCAPV6_NODE, line);
|
|
|
|
else if (strncmp (line, " address-family encap",
|
|
|
|
strlen (" address-family encap")) == 0)
|
|
|
|
config = config_get (BGP_ENCAP_NODE, line);
|
|
|
|
else if (strncmp (line, " address-family ipv4 multicast",
|
|
|
|
strlen (" address-family ipv4 multicast")) == 0)
|
|
|
|
config = config_get (BGP_IPV4M_NODE, line);
|
|
|
|
else if (strncmp (line, " address-family ipv6",
|
|
|
|
strlen (" address-family ipv6")) == 0)
|
|
|
|
config = config_get (BGP_IPV6_NODE, line);
|
|
|
|
else if (strncmp (line, " vnc defaults",
|
|
|
|
strlen (" vnc defaults")) == 0)
|
|
|
|
config = config_get (BGP_VNC_DEFAULTS_NODE, line);
|
|
|
|
else if (strncmp (line, " vnc nve-group",
|
|
|
|
strlen (" vnc nve-group")) == 0)
|
|
|
|
config = config_get (BGP_VNC_NVE_GROUP_NODE, line);
|
|
|
|
else if (strncmp (line, " vnc l2-group",
|
|
|
|
strlen (" vnc l2-group")) == 0)
|
|
|
|
config = config_get (BGP_VNC_L2_GROUP_NODE, line);
|
|
|
|
else if (config->index == RMAP_NODE ||
|
2004-10-03 22:11:32 +02:00
|
|
|
config->index == INTERFACE_NODE ||
|
2014-07-03 12:24:34 +02:00
|
|
|
config->index == NS_NODE ||
|
2004-10-03 22:11:32 +02:00
|
|
|
config->index == VTY_NODE)
|
2002-12-13 21:15:29 +01:00
|
|
|
config_add_line_uniq (config->line, line);
|
|
|
|
else
|
|
|
|
config_add_line (config->line, line);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
config_add_line (config_top, line);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (strncmp (line, "interface", strlen ("interface")) == 0)
|
|
|
|
config = config_get (INTERFACE_NODE, line);
|
2015-09-03 10:47:43 +02:00
|
|
|
else if (strncmp (line, "logical-router", strlen ("ns")) == 0)
|
2014-07-03 12:24:34 +02:00
|
|
|
config = config_get (NS_NODE, line);
|
2016-02-02 13:34:29 +01:00
|
|
|
else if (strncmp (line, "vrf", strlen ("vrf")) == 0)
|
|
|
|
config = config_get (VRF_NODE, line);
|
2004-12-22 12:53:09 +01:00
|
|
|
else if (strncmp (line, "router-id", strlen ("router-id")) == 0)
|
|
|
|
config = config_get (ZEBRA_NODE, line);
|
2002-12-13 21:15:29 +01:00
|
|
|
else if (strncmp (line, "router rip", strlen ("router rip")) == 0)
|
|
|
|
config = config_get (RIP_NODE, line);
|
2003-03-28 03:25:23 +01:00
|
|
|
else if (strncmp (line, "router ripng", strlen ("router ripng")) == 0)
|
2004-08-25 14:22:00 +02:00
|
|
|
config = config_get (RIPNG_NODE, line);
|
2002-12-13 21:15:29 +01:00
|
|
|
else if (strncmp (line, "router ospf", strlen ("router ospf")) == 0)
|
2004-08-25 14:22:00 +02:00
|
|
|
config = config_get (OSPF_NODE, line);
|
2003-03-28 03:25:23 +01:00
|
|
|
else if (strncmp (line, "router ospf6", strlen ("router ospf6")) == 0)
|
2004-08-25 14:22:00 +02:00
|
|
|
config = config_get (OSPF6_NODE, line);
|
2016-08-02 00:47:15 +02:00
|
|
|
else if (strncmp (line, "mpls ldp", strlen ("mpls ldp")) == 0)
|
|
|
|
config = config_get (LDP_NODE, line);
|
|
|
|
else if (strncmp (line, "l2vpn", strlen ("l2vpn")) == 0)
|
|
|
|
config = config_get (LDP_L2VPN_NODE, line);
|
2002-12-13 21:15:29 +01:00
|
|
|
else if (strncmp (line, "router bgp", strlen ("router bgp")) == 0)
|
|
|
|
config = config_get (BGP_NODE, line);
|
2004-01-15 02:00:49 +01:00
|
|
|
else if (strncmp (line, "router isis", strlen ("router isis")) == 0)
|
2003-12-23 11:39:08 +01:00
|
|
|
config = config_get (ISIS_NODE, line);
|
2002-12-13 21:15:29 +01:00
|
|
|
else if (strncmp (line, "route-map", strlen ("route-map")) == 0)
|
|
|
|
config = config_get (RMAP_NODE, line);
|
|
|
|
else if (strncmp (line, "access-list", strlen ("access-list")) == 0)
|
|
|
|
config = config_get (ACCESS_NODE, line);
|
2004-08-26 15:08:30 +02:00
|
|
|
else if (strncmp (line, "ipv6 access-list",
|
|
|
|
strlen ("ipv6 access-list")) == 0)
|
2004-08-25 14:22:00 +02:00
|
|
|
config = config_get (ACCESS_IPV6_NODE, line);
|
2004-08-26 15:08:30 +02:00
|
|
|
else if (strncmp (line, "ip prefix-list",
|
|
|
|
strlen ("ip prefix-list")) == 0)
|
2002-12-13 21:15:29 +01:00
|
|
|
config = config_get (PREFIX_NODE, line);
|
2004-08-26 15:08:30 +02:00
|
|
|
else if (strncmp (line, "ipv6 prefix-list",
|
|
|
|
strlen ("ipv6 prefix-list")) == 0)
|
2004-08-25 14:22:00 +02:00
|
|
|
config = config_get (PREFIX_IPV6_NODE, line);
|
2004-08-26 15:08:30 +02:00
|
|
|
else if (strncmp (line, "ip as-path access-list",
|
|
|
|
strlen ("ip as-path access-list")) == 0)
|
2002-12-13 21:15:29 +01:00
|
|
|
config = config_get (AS_LIST_NODE, line);
|
2015-11-18 19:54:23 +01:00
|
|
|
else if (strncmp (line, "ip community-list", strlen ("ip community-list")) == 0 ||
|
|
|
|
strncmp (line, "ip extcommunity-list", strlen ("ip extcommunity-list")) == 0)
|
2002-12-13 21:15:29 +01:00
|
|
|
config = config_get (COMMUNITY_LIST_NODE, line);
|
|
|
|
else if (strncmp (line, "ip route", strlen ("ip route")) == 0)
|
|
|
|
config = config_get (IP_NODE, line);
|
2003-03-28 03:25:23 +01:00
|
|
|
else if (strncmp (line, "ipv6 route", strlen ("ipv6 route")) == 0)
|
|
|
|
config = config_get (IP_NODE, line);
|
2002-12-13 21:15:29 +01:00
|
|
|
else if (strncmp (line, "key", strlen ("key")) == 0)
|
|
|
|
config = config_get (KEYCHAIN_NODE, line);
|
2004-10-03 22:11:32 +02:00
|
|
|
else if (strncmp (line, "line", strlen ("line")) == 0)
|
|
|
|
config = config_get (VTY_NODE, line);
|
|
|
|
else if ( (strncmp (line, "ipv6 forwarding",
|
|
|
|
strlen ("ipv6 forwarding")) == 0)
|
|
|
|
|| (strncmp (line, "ip forwarding",
|
|
|
|
strlen ("ip forwarding")) == 0) )
|
|
|
|
config = config_get (FORWARDING_NODE, line);
|
|
|
|
else if (strncmp (line, "service", strlen ("service")) == 0)
|
|
|
|
config = config_get (SERVICE_NODE, line);
|
2016-02-03 15:00:25 +01:00
|
|
|
else if (strncmp (line, "debug vrf", strlen ("debug vrf")) == 0)
|
|
|
|
config = config_get (VRF_DEBUG_NODE, line);
|
2004-12-22 12:53:09 +01:00
|
|
|
else if (strncmp (line, "debug", strlen ("debug")) == 0)
|
|
|
|
config = config_get (DEBUG_NODE, line);
|
2005-03-09 13:41:14 +01:00
|
|
|
else if (strncmp (line, "password", strlen ("password")) == 0
|
|
|
|
|| strncmp (line, "enable password",
|
|
|
|
strlen ("enable password")) == 0)
|
|
|
|
config = config_get (AAA_NODE, line);
|
2009-06-23 07:55:57 +02:00
|
|
|
else if (strncmp (line, "ip protocol", strlen ("ip protocol")) == 0)
|
|
|
|
config = config_get (PROTOCOL_NODE, line);
|
2015-10-21 07:21:39 +02:00
|
|
|
else if (strncmp (line, "ipv6 protocol", strlen ("ipv6 protocol")) == 0)
|
|
|
|
config = config_get (PROTOCOL_NODE, line);
|
|
|
|
else if (strncmp (line, "ip nht", strlen ("ip nht")) == 0)
|
|
|
|
config = config_get (PROTOCOL_NODE, line);
|
|
|
|
else if (strncmp (line, "ipv6 nht", strlen ("ipv6 nht")) == 0)
|
|
|
|
config = config_get (PROTOCOL_NODE, line);
|
2016-04-15 19:51:56 +02:00
|
|
|
else if (strncmp (line, "mpls", strlen ("mpls")) == 0)
|
|
|
|
config = config_get (MPLS_NODE, line);
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (strncmp (line, "log", strlen ("log")) == 0
|
|
|
|
|| strncmp (line, "hostname", strlen ("hostname")) == 0
|
2004-10-03 22:11:32 +02:00
|
|
|
)
|
2002-12-13 21:15:29 +01:00
|
|
|
config_add_line_uniq (config_top, line);
|
|
|
|
else
|
|
|
|
config_add_line (config_top, line);
|
|
|
|
config = NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
vtysh_config_parse (char *line)
|
|
|
|
{
|
|
|
|
char *begin;
|
|
|
|
char *pnt;
|
|
|
|
|
|
|
|
begin = pnt = line;
|
|
|
|
|
|
|
|
while (*pnt != '\0')
|
|
|
|
{
|
|
|
|
if (*pnt == '\n')
|
|
|
|
{
|
|
|
|
*pnt++ = '\0';
|
|
|
|
vtysh_config_parse_line (begin);
|
|
|
|
begin = pnt;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Macro to check delimiter is needed between each configuration line
|
2004-08-26 15:08:30 +02:00
|
|
|
* or not. */
|
2002-12-13 21:15:29 +01:00
|
|
|
#define NO_DELIMITER(I) \
|
|
|
|
((I) == ACCESS_NODE || (I) == PREFIX_NODE || (I) == IP_NODE \
|
2003-03-28 03:25:23 +01:00
|
|
|
|| (I) == AS_LIST_NODE || (I) == COMMUNITY_LIST_NODE || \
|
2004-10-03 22:11:32 +02:00
|
|
|
(I) == ACCESS_IPV6_NODE || (I) == PREFIX_IPV6_NODE \
|
2005-03-09 13:41:14 +01:00
|
|
|
|| (I) == SERVICE_NODE || (I) == FORWARDING_NODE || (I) == DEBUG_NODE \
|
2016-04-15 19:51:56 +02:00
|
|
|
|| (I) == AAA_NODE || (I) == VRF_DEBUG_NODE || (I) == MPLS_NODE)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2004-08-26 15:08:30 +02:00
|
|
|
/* Display configuration to file pointer. */
|
2002-12-13 21:15:29 +01:00
|
|
|
void
|
|
|
|
vtysh_config_dump (FILE *fp)
|
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct listnode *mnode, *mnnode;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct config *config;
|
|
|
|
struct list *master;
|
|
|
|
char *line;
|
2004-10-07 23:40:25 +02:00
|
|
|
unsigned int i;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (config_top, node, nnode, line))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
fprintf (fp, "%s\n", line);
|
|
|
|
fflush (fp);
|
|
|
|
}
|
|
|
|
fprintf (fp, "!\n");
|
|
|
|
fflush (fp);
|
|
|
|
|
2005-03-14 21:19:01 +01:00
|
|
|
for (i = 0; i < vector_active (configvec); i++)
|
2002-12-13 21:15:29 +01:00
|
|
|
if ((master = vector_slot (configvec, i)) != NULL)
|
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (master, node, nnode, config))
|
2016-07-18 08:08:05 +02:00
|
|
|
{
|
|
|
|
/* Don't print empty sections for interface/vrf. Route maps on the
|
|
|
|
* other hand could have a legitimate empty section at the end.
|
|
|
|
*/
|
|
|
|
if ((config->index == INTERFACE_NODE || (config->index == VRF_NODE))
|
|
|
|
&& list_isempty (config->line))
|
|
|
|
continue;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
fprintf (fp, "%s\n", config->name);
|
2004-08-25 14:22:00 +02:00
|
|
|
fflush (fp);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (config->line, mnode, mnnode, line))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
fprintf (fp, "%s\n", line);
|
|
|
|
fflush (fp);
|
|
|
|
}
|
|
|
|
if (! NO_DELIMITER (i))
|
|
|
|
{
|
|
|
|
fprintf (fp, "!\n");
|
|
|
|
fflush (fp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (NO_DELIMITER (i))
|
|
|
|
{
|
|
|
|
fprintf (fp, "!\n");
|
|
|
|
fflush (fp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-14 21:19:01 +01:00
|
|
|
for (i = 0; i < vector_active (configvec); i++)
|
2002-12-13 21:15:29 +01:00
|
|
|
if ((master = vector_slot (configvec, i)) != NULL)
|
|
|
|
{
|
|
|
|
list_delete (master);
|
|
|
|
vector_slot (configvec, i) = NULL;
|
|
|
|
}
|
|
|
|
list_delete_all_node (config_top);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Read up configuration file from file_name. */
|
2016-03-09 13:25:02 +01:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
vtysh_read_file (FILE *confp)
|
|
|
|
{
|
|
|
|
struct vty *vty;
|
2016-03-09 13:25:02 +01:00
|
|
|
int ret;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
vty = vty_new ();
|
|
|
|
vty->fd = 0; /* stdout */
|
|
|
|
vty->type = VTY_TERM;
|
|
|
|
vty->node = CONFIG_NODE;
|
|
|
|
|
|
|
|
vtysh_execute_no_pager ("enable");
|
|
|
|
vtysh_execute_no_pager ("configure terminal");
|
|
|
|
|
2004-08-26 15:08:30 +02:00
|
|
|
/* Execute configuration file. */
|
2016-03-09 13:25:02 +01:00
|
|
|
ret = vtysh_config_from_file (vty, confp);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
vtysh_execute_no_pager ("end");
|
|
|
|
vtysh_execute_no_pager ("disable");
|
|
|
|
|
|
|
|
vty_close (vty);
|
2016-03-09 13:25:02 +01:00
|
|
|
|
|
|
|
return (ret);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2004-10-03 22:11:32 +02:00
|
|
|
/* Read up configuration file from config_default_dir. */
|
|
|
|
int
|
2015-05-20 03:29:15 +02:00
|
|
|
vtysh_read_config (const char *config_default_dir)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
FILE *confp = NULL;
|
2016-03-09 13:25:02 +01:00
|
|
|
int ret;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-21 01:55:57 +02:00
|
|
|
host_config_set (config_default_dir);
|
2004-10-03 22:11:32 +02:00
|
|
|
confp = fopen (config_default_dir, "r");
|
|
|
|
if (confp == NULL)
|
2016-04-06 15:34:33 +02:00
|
|
|
{
|
|
|
|
fprintf (stderr, "%% Can't open configuration file %s due to '%s'.\n",
|
|
|
|
config_default_dir, safe_strerror (errno));
|
|
|
|
return (CMD_ERR_NO_FILE);
|
|
|
|
}
|
2004-08-27 00:21:31 +02:00
|
|
|
|
2016-03-09 13:25:02 +01:00
|
|
|
ret = vtysh_read_file (confp);
|
2002-12-13 21:15:29 +01:00
|
|
|
fclose (confp);
|
|
|
|
|
2016-03-09 13:25:02 +01:00
|
|
|
return (ret);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2004-10-03 22:11:32 +02:00
|
|
|
/* We don't write vtysh specific into file from vtysh. vtysh.conf should
|
|
|
|
* be edited by hand. So, we handle only "write terminal" case here and
|
|
|
|
* integrate vtysh specific conf with conf from daemons.
|
|
|
|
*/
|
2002-12-13 21:15:29 +01:00
|
|
|
void
|
2004-10-03 22:11:32 +02:00
|
|
|
vtysh_config_write ()
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-10-07 23:40:25 +02:00
|
|
|
char line[81];
|
2002-12-13 21:15:29 +01:00
|
|
|
extern struct host host;
|
|
|
|
|
|
|
|
if (host.name)
|
2004-10-03 22:11:32 +02:00
|
|
|
{
|
|
|
|
sprintf (line, "hostname %s", host.name);
|
|
|
|
vtysh_config_parse_line(line);
|
|
|
|
}
|
2016-09-26 22:01:37 +02:00
|
|
|
if (vtysh_write_integrated == WRITE_INTEGRATED_NO)
|
2016-07-18 08:38:51 +02:00
|
|
|
vtysh_config_parse_line ("no service integrated-vtysh-config");
|
2016-09-26 22:01:37 +02:00
|
|
|
if (vtysh_write_integrated == WRITE_INTEGRATED_YES)
|
|
|
|
vtysh_config_parse_line ("service integrated-vtysh-config");
|
2015-05-20 03:29:18 +02:00
|
|
|
|
|
|
|
user_config_write ();
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
vtysh_config_init ()
|
|
|
|
{
|
|
|
|
config_top = list_new ();
|
|
|
|
config_top->del = (void (*) (void *))line_del;
|
|
|
|
configvec = vector_init (1);
|
|
|
|
}
|