diff options
| -rw-r--r-- | bgpd/bgp_vty.c | 95 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 74 | ||||
| -rwxr-xr-x | tools/quagga-reload.py | 50 | ||||
| -rw-r--r-- | vtysh/vtysh.c | 5 | ||||
| -rw-r--r-- | vtysh/vtysh_config.c | 13 | ||||
| -rw-r--r-- | zebra/interface.c | 6 |
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)) { |
