summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_vty.c95
-rw-r--r--bgpd/bgpd.c74
-rwxr-xr-xtools/quagga-reload.py50
-rw-r--r--vtysh/vtysh.c5
-rw-r--r--vtysh/vtysh_config.c13
-rw-r--r--zebra/interface.c6
6 files changed, 209 insertions, 34 deletions
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index e62a225b0f..c429623e7e 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -523,7 +523,7 @@ bgp_clear_vty (struct vty *vty, const char *name, afi_t afi, safi_t safi,
}
else
{
- bgp = bgp_get_default ();
+ bgp = (vty->index) ? vty->index : bgp_get_default ();
if (bgp == NULL)
{
vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
@@ -2834,9 +2834,11 @@ DEFUN (neighbor_remote_as,
static int
peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
- safi_t safi, int v6only, const char *peer_group_name)
+ safi_t safi, int v6only, const char *peer_group_name,
+ const char *as_str)
{
- as_t as;
+ as_t as = 0;
+ int as_type = AS_UNSPECIFIED;
struct bgp *bgp;
struct peer *peer;
struct peer_group *group;
@@ -2852,14 +2854,34 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
return CMD_WARNING;
}
+ if (as_str)
+ {
+ if (strncmp(as_str, "internal", strlen("internal")) == 0)
+ {
+ as_type = AS_INTERNAL;
+ }
+ else if (strncmp(as_str, "external", strlen("external")) == 0)
+ {
+ as_type = AS_EXTERNAL;
+ }
+ else
+ {
+ /* Get AS number. */
+ VTY_GET_INTEGER_RANGE ("AS", as, as_str, 1, BGP_AS4_MAX);
+ as_type = AS_SPECIFIED;
+ }
+ }
+
peer = peer_lookup_by_conf_if (bgp, conf_if);
if (!peer)
{
if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)
&& afi == AFI_IP && safi == SAFI_UNICAST)
- peer = peer_create (NULL, conf_if, bgp, bgp->as, 0, AS_UNSPECIFIED, 0, 0, NULL);
+ peer = peer_create (NULL, conf_if, bgp, bgp->as, as, as_type, 0, 0,
+ NULL);
else
- peer = peer_create (NULL, conf_if, bgp, bgp->as, 0, AS_UNSPECIFIED, afi, safi, NULL);
+ peer = peer_create (NULL, conf_if, bgp, bgp->as, as, as_type, afi, safi,
+ NULL);
if (peer && v6only)
SET_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY);
@@ -2870,7 +2892,10 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
* gets deleted later etc.)
*/
if (peer->ifp)
- bgp_zebra_initiate_radv (bgp, peer);
+ {
+ bgp_zebra_initiate_radv (bgp, peer);
+ }
+ peer_flag_set (peer, PEER_FLAG_CAPABILITY_ENHE);
}
else if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) ||
(!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)))
@@ -2917,9 +2942,11 @@ DEFUN (neighbor_interface_config,
"Enable BGP on interface\n")
{
if (argc == 2)
- return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0, argv[1]);
+ return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0,
+ argv[1], NULL);
else
- return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0, NULL);
+ return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0,
+ NULL, NULL);
}
ALIAS (neighbor_interface_config,
@@ -2940,9 +2967,11 @@ DEFUN (neighbor_interface_config_v6only,
"Enable BGP with v6 link-local only\n")
{
if (argc == 2)
- return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1, argv[1]);
+ return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1,
+ argv[1], NULL);
else
- return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1, NULL);
+ return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1,
+ NULL, NULL);
}
ALIAS (neighbor_interface_config_v6only,
@@ -2955,6 +2984,30 @@ ALIAS (neighbor_interface_config_v6only,
"Member of the peer-group\n"
"peer-group name\n")
+DEFUN (neighbor_interface_config_remote_as,
+ neighbor_interface_config_remote_as_cmd,
+ "neighbor WORD interface remote-as (" CMD_AS_RANGE "|external|internal)",
+ NEIGHBOR_STR
+ "Interface name or neighbor tag\n"
+ "Enable BGP on interface\n"
+ AS_STR)
+{
+ return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0,
+ NULL, argv[1]);
+}
+
+DEFUN (neighbor_interface_v6only_config_remote_as,
+ neighbor_interface_v6only_config_remote_as_cmd,
+ "neighbor WORD interface v6only remote-as (" CMD_AS_RANGE "|external|internal)",
+ NEIGHBOR_STR
+ "Interface name or neighbor tag\n"
+ "Enable BGP on interface\n"
+ AS_STR)
+{
+ return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1,
+ NULL, argv[1]);
+}
+
DEFUN (neighbor_peer_group,
neighbor_peer_group_cmd,
"neighbor WORD peer-group",
@@ -3105,6 +3158,24 @@ ALIAS (no_neighbor_interface_config,
"Member of the peer-group\n"
"peer-group name\n")
+ALIAS (no_neighbor_interface_config,
+ no_neighbor_interface_config_remote_as_cmd,
+ "no neighbor WORD interface remote-as (" CMD_AS_RANGE "|internal|external)",
+ NO_STR
+ NEIGHBOR_STR
+ "Interface name\n"
+ "Configure BGP on interface\n"
+ AS_STR)
+
+ALIAS (no_neighbor_interface_config,
+ no_neighbor_interface_config_v6only_remote_as_cmd,
+ "no neighbor WORD interface v6only remote-as (" CMD_AS_RANGE "|internal|external)",
+ NO_STR
+ NEIGHBOR_STR
+ "Interface name\n"
+ "Configure BGP on interface\n"
+ "Enable BGP with v6 link-local only\n"
+ AS_STR)
DEFUN (no_neighbor_peer_group,
no_neighbor_peer_group_cmd,
@@ -14596,12 +14667,16 @@ bgp_vty_init (void)
install_element (BGP_NODE, &neighbor_interface_config_v6only_cmd);
install_element (BGP_NODE, &neighbor_interface_config_peergroup_cmd);
install_element (BGP_NODE, &neighbor_interface_config_v6only_peergroup_cmd);
+ install_element (BGP_NODE, &neighbor_interface_config_remote_as_cmd);
+ install_element (BGP_NODE, &neighbor_interface_v6only_config_remote_as_cmd);
install_element (BGP_NODE, &no_neighbor_cmd);
install_element (BGP_NODE, &no_neighbor_remote_as_cmd);
install_element (BGP_NODE, &no_neighbor_interface_config_cmd);
install_element (BGP_NODE, &no_neighbor_interface_config_v6only_cmd);
install_element (BGP_NODE, &no_neighbor_interface_config_peergroup_cmd);
install_element (BGP_NODE, &no_neighbor_interface_config_v6only_peergroup_cmd);
+ install_element (BGP_NODE, &no_neighbor_interface_config_remote_as_cmd);
+ install_element (BGP_NODE, &no_neighbor_interface_config_v6only_remote_as_cmd);
/* "neighbor peer-group" commands. */
install_element (BGP_NODE, &neighbor_peer_group_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 05f1751e53..a06e95e244 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -2546,6 +2546,7 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, struct peer *peer,
int first_member = 0;
afi_t afi;
safi_t safi;
+ int cap_enhe_preset = 0;
/* Lookup the peer. */
if (!peer)
@@ -2580,8 +2581,18 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, struct peer *peer,
first_member = 1;
}
+ if (CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE))
+ cap_enhe_preset = 1;
+
peer_group2peer_config_copy(group, peer);
+ /*
+ * Capability extended-nexthop is enabled for an interface neighbor by
+ * default. So, fix that up here.
+ */
+ if (peer->ifp && cap_enhe_preset)
+ peer_flag_set (peer, PEER_FLAG_CAPABILITY_ENHE);
+
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
@@ -6269,6 +6280,8 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
struct peer *g_peer = NULL;
char buf[SU_ADDRSTRLEN];
char *addr;
+ int if_pg_printed = FALSE;
+ int if_ras_printed = FALSE;
/* Skip dynamic neighbors. */
if (peer_dynamic_neighbor (peer))
@@ -6290,7 +6303,25 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
vty_out (vty, " neighbor %s interface", addr);
if (peer_group_active (peer))
- vty_out (vty, " peer-group %s", peer->group->name);
+ {
+ vty_out (vty, " peer-group %s", peer->group->name);
+ if_pg_printed = TRUE;
+ }
+ else if (peer->as_type == AS_SPECIFIED)
+ {
+ vty_out (vty, " remote-as %u", peer->as);
+ if_ras_printed = TRUE;
+ }
+ else if (peer->as_type == AS_INTERNAL)
+ {
+ vty_out (vty, " remote-as internal");
+ if_ras_printed = TRUE;
+ }
+ else if (peer->as_type == AS_EXTERNAL)
+ {
+ vty_out (vty, " remote-as external");
+ if_ras_printed = TRUE;
+ }
vty_out (vty, "%s", VTY_NEWLINE);
}
@@ -6301,7 +6332,7 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
{
g_peer = peer->group->conf;
- if (g_peer->as_type == AS_UNSPECIFIED)
+ if (g_peer->as_type == AS_UNSPECIFIED && !if_ras_printed)
{
if (peer->as_type == AS_SPECIFIED)
{
@@ -6320,7 +6351,7 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
/* For swpX peers we displayed the peer-group
* via 'neighbor swpX interface peer-group WORD' */
- if (!peer->conf_if)
+ if (!if_pg_printed)
vty_out (vty, " neighbor %s peer-group %s%s", addr,
peer->group->name, VTY_NEWLINE);
}
@@ -6335,18 +6366,21 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
VTY_NEWLINE);
}
- if (peer->as_type == AS_SPECIFIED)
- {
- vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
- VTY_NEWLINE);
- }
- else if (peer->as_type == AS_INTERNAL)
- {
- vty_out (vty, " neighbor %s remote-as internal%s", addr, VTY_NEWLINE);
- }
- else if (peer->as_type == AS_EXTERNAL)
+ if (!if_ras_printed)
{
- vty_out (vty, " neighbor %s remote-as external%s", addr, VTY_NEWLINE);
+ if (peer->as_type == AS_SPECIFIED)
+ {
+ vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
+ VTY_NEWLINE);
+ }
+ else if (peer->as_type == AS_INTERNAL)
+ {
+ vty_out (vty, " neighbor %s remote-as internal%s", addr, VTY_NEWLINE);
+ }
+ else if (peer->as_type == AS_EXTERNAL)
+ {
+ vty_out (vty, " neighbor %s remote-as external%s", addr, VTY_NEWLINE);
+ }
}
}
@@ -6541,7 +6575,17 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
}
/* capability extended-nexthop */
- if (CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE))
+ if (peer->ifp && !CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE))
+ {
+ if (! peer_group_active (peer) ||
+ ! CHECK_FLAG (g_peer->flags, PEER_FLAG_CAPABILITY_ENHE))
+ {
+ vty_out (vty, " no neighbor %s capability extended-nexthop%s", addr,
+ VTY_NEWLINE);
+ }
+ }
+
+ if (!peer->ifp && CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE))
{
if (! peer_group_active (peer) ||
! CHECK_FLAG (g_peer->flags, PEER_FLAG_CAPABILITY_ENHE))
diff --git a/tools/quagga-reload.py b/tools/quagga-reload.py
index 9650822d1e..22d44b3369 100755
--- a/tools/quagga-reload.py
+++ b/tools/quagga-reload.py
@@ -507,6 +507,56 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
lines_to_add_to_del.append((ctx_keys, swpx_interface))
lines_to_add_to_del.append((tmp_ctx_keys, swpx_peergroup))
+ """
+ In 3.0.1 we changed how we display neighbor interface command. Older
+ versions of quagga would display the following:
+ neighbor swp1 interface
+ neighbor swp1 remote-as external
+ neighbor swp1 capability extended-nexthop
+
+ but today we display via a single line
+ neighbor swp1 interface remote-as external
+
+ and capability extended-nexthop is no longer needed because we
+ automatically enable it when the neighbor is of type interface.
+
+ This change confuses quagga-reload.py so check to see if we are deleting
+ neighbor swp1 interface remote-as (external|internal|ASNUM)
+
+ and adding
+ neighbor swp1 interface
+ neighbor swp1 remote-as (external|internal|ASNUM)
+ neighbor swp1 capability extended-nexthop
+
+ If so then chop the del line and the corresponding add lines
+ """
+ re_swpx_int_remoteas = re.search('neighbor (\S+) interface remote-as (\S+)', line)
+ re_swpx_int_v6only_remoteas = re.search('neighbor (\S+) interface v6only remote-as (\S+)', line)
+
+ if re_swpx_int_remoteas or re_swpx_int_v6only_remoteas:
+ swpx_interface = None
+ swpx_remoteas = None
+
+ if re_swpx_int_remoteas:
+ swpx = re_swpx_int_remoteas.group(1)
+ remoteas = re_swpx_int_remoteas.group(2)
+ swpx_interface = "neighbor %s interface" % swpx
+ elif re_swpx_int_v6only_remoteas:
+ swpx = re_swpx_int_v6only_remoteas.group(1)
+ remoteas = re_swpx_int_v6only_remoteas.group(2)
+ swpx_interface = "neighbor %s interface v6only" % swpx
+
+ swpx_remoteas = "neighbor %s remote-as %s" % (swpx, remoteas)
+ found_add_swpx_interface = line_exist(lines_to_add, ctx_keys, swpx_interface)
+ found_add_swpx_remoteas = line_exist(lines_to_add, ctx_keys, swpx_remoteas)
+ tmp_ctx_keys = tuple(list(ctx_keys))
+
+ if found_add_swpx_interface and found_add_swpx_remoteas:
+ deleted = True
+ lines_to_del_to_del.append((ctx_keys, line))
+ lines_to_add_to_del.append((ctx_keys, swpx_interface))
+ lines_to_add_to_del.append((tmp_ctx_keys, swpx_remoteas))
+
if not deleted:
found_add_line = line_exist(lines_to_add, ctx_keys, line)
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index ecb6c5c6ac..abd5d04f44 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -2097,7 +2097,8 @@ DEFUN (vtysh_write_terminal,
vty_out (vty, "!%s", VTY_NEWLINE);
for (i = 0; i < array_size(vtysh_client); i++)
- vtysh_client_config (&vtysh_client[i], line);
+ if ((argc < 1 ) || (begins_with(vtysh_client[i].name, argv[0])))
+ vtysh_client_config (&vtysh_client[i], line);
/* Integrate vtysh specific configuration. */
vtysh_config_write ();
@@ -2317,7 +2318,7 @@ ALIAS (vtysh_write_terminal,
SHOW_STR
"Current operating configuration\n")
-ALIAS (vtysh_write_terminal_daemon,
+ALIAS (vtysh_write_terminal,
vtysh_show_running_config_daemon_cmd,
"show running-config (zebra|ripd|ripngd|ospfd|ospf6d|bgpd|isisd|pimd)",
SHOW_STR
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index fcad333b9f..e678fc1a8b 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -318,7 +318,14 @@ vtysh_config_dump (FILE *fp)
if ((master = vector_slot (configvec, i)) != NULL)
{
for (ALL_LIST_ELEMENTS (master, node, nnode, config))
- {
+ {
+ /* 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;
+
fprintf (fp, "%s\n", config->name);
fflush (fp);
@@ -412,8 +419,8 @@ vtysh_config_write ()
sprintf (line, "hostname %s", host.name);
vtysh_config_parse_line(line);
}
- if (vtysh_writeconfig_integrated)
- vtysh_config_parse_line ("service integrated-vtysh-config");
+ if (!vtysh_writeconfig_integrated)
+ vtysh_config_parse_line ("no service integrated-vtysh-config");
user_config_write ();
}
diff --git a/zebra/interface.c b/zebra/interface.c
index 87a426fdc4..c3ce83dd4a 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -2114,10 +2114,8 @@ if_config_write (struct vty *vty)
if (ifp->bandwidth != 0)
vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
- if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
- vty_out(vty, " link-detect%s", VTY_NEWLINE);
- else
- vty_out(vty, " no link-detect%s", VTY_NEWLINE);
+ if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
+ vty_out(vty, " no link-detect%s", VTY_NEWLINE);
for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc))
{