Merge branch stable/2.0 into stable/3.0

Conflicts:
	bgpd/bgp_fsm.c
	ospf6d/ospf6_lsa.c
	ospfd/ospf_vty.c
	zebra/redistribute.c

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
David Lamparter 2017-05-18 12:15:04 +02:00
commit 92eedda1fb
12 changed files with 106 additions and 51 deletions

View File

@ -1026,7 +1026,7 @@ bgp_stop (struct peer *peer)
zlog_info ("%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s", zlog_info ("%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s",
peer->host, peer->host,
(peer->hostname) ? peer->hostname : "Unknown", (peer->hostname) ? peer->hostname : "Unknown",
(vrf->vrf_id != VRF_DEFAULT) ? vrf->name : "Default", vrf ? ((vrf->vrf_id != VRF_DEFAULT) ? vrf->name : "Default") : "",
peer_down_str [(int) peer->last_reset]); peer_down_str [(int) peer->last_reset]);
} }

View File

@ -1128,6 +1128,9 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
else else
peer->v_holdtime = send_holdtime; peer->v_holdtime = send_holdtime;
if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
peer->v_keepalive = peer->keepalive;
else
peer->v_keepalive = peer->v_holdtime / 3; peer->v_keepalive = peer->v_holdtime / 3;
/* Open option part parse. */ /* Open option part parse. */

View File

@ -2704,7 +2704,12 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
} }
peer = peer_lookup_by_conf_if (bgp, conf_if); peer = peer_lookup_by_conf_if (bgp, conf_if);
if (!peer) if (peer)
{
if (as_str)
ret = peer_remote_as (bgp, &su, conf_if, &as, as_type, afi, safi);
}
else
{ {
if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4) if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)
&& afi == AFI_IP && safi == SAFI_UNICAST) && afi == AFI_IP && safi == SAFI_UNICAST)
@ -2728,7 +2733,8 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
if (peer->ifp) if (peer->ifp)
bgp_zebra_initiate_radv (bgp, peer); bgp_zebra_initiate_radv (bgp, peer);
} }
else if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) ||
if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) ||
(!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))) (!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)))
{ {
if (v6only) if (v6only)
@ -7433,6 +7439,7 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
u_int16_t i; u_int16_t i;
u_char *msg; u_char *msg;
json_object *json_neigh = NULL; json_object *json_neigh = NULL;
time_t epoch_tbuf;
bgp = p->bgp; bgp = p->bgp;
@ -7622,8 +7629,11 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
uptime = bgp_clock(); uptime = bgp_clock();
uptime -= p->uptime; uptime -= p->uptime;
tm = gmtime(&uptime); tm = gmtime(&uptime);
epoch_tbuf = time(NULL) - uptime;
json_object_int_add(json_neigh, "bgpTimerUp", (tm->tm_sec * 1000) + (tm->tm_min * 60000) + (tm->tm_hour * 3600000)); json_object_int_add(json_neigh, "bgpTimerUp", (tm->tm_sec * 1000) + (tm->tm_min * 60000) + (tm->tm_hour * 3600000));
json_object_string_add(json_neigh, "bgpTimerUpString", peer_uptime (p->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL));
json_object_int_add(json_neigh, "bgpTimerUpEstablishedEpoch", epoch_tbuf);
} }
else if (p->status == Active) else if (p->status == Active)

View File

@ -1470,7 +1470,8 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (!ifindex) if (!ifindex)
{ {
if (info->peer->conf_if || info->peer->ifname) if (info->peer->conf_if || info->peer->ifname)
ifindex = if_nametoindex (info->peer->conf_if ? info->peer->conf_if : info->peer->ifname); ifindex = ifname2ifindex_vrf (info->peer->conf_if ? info->peer->conf_if :
info->peer->ifname, bgp->vrf_id);
else if (info->peer->nexthop.ifp) else if (info->peer->nexthop.ifp)
ifindex = info->peer->nexthop.ifp->ifindex; ifindex = info->peer->nexthop.ifp->ifindex;
} }

View File

@ -6341,7 +6341,7 @@ peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
char * char *
peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object *json) peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object *json)
{ {
time_t uptime1; time_t uptime1, epoch_tbuf;
struct tm *tm; struct tm *tm;
/* Check buffer length. */ /* Check buffer length. */
@ -6395,8 +6395,10 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object
if (use_json) if (use_json)
{ {
epoch_tbuf = time(NULL) - uptime1;
json_object_string_add(json, "peerUptime", buf); json_object_string_add(json, "peerUptime", buf);
json_object_long_add(json, "peerUptimeMsec", uptime1 * 1000); json_object_long_add(json, "peerUptimeMsec", uptime1 * 1000);
json_object_int_add(json, "peerUptimeEstablishedEpoch", epoch_tbuf);
} }
return buf; return buf;

View File

@ -811,6 +811,7 @@ run_stop_schedule(void)
anykilled = 0; anykilled = 0;
retry_nr = 0; retry_nr = 0;
n_killed = 0;
if (schedule == NULL) { if (schedule == NULL) {
do_stop(signal_nr, quietmode, &n_killed, &n_notkilled, 0); do_stop(signal_nr, quietmode, &n_killed, &n_notkilled, 0);

View File

@ -6333,7 +6333,7 @@ DEFUN (no_ip_ospf_dead_interval,
{ {
VTY_DECLVAR_CONTEXT(interface, ifp); VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_ipv4 = argc - 1; int idx_ipv4 = argc - 1;
struct in_addr addr; struct in_addr addr = { .s_addr = 0L};
int ret; int ret;
struct ospf_if_params *params; struct ospf_if_params *params;
struct ospf_interface *oi; struct ospf_interface *oi;

View File

@ -109,9 +109,12 @@ class Config(object):
log.info('Loading Config object from file %s', filename) log.info('Loading Config object from file %s', filename)
try: try:
file_output = subprocess.check_output(['/usr/bin/vtysh', '-m', '-f', filename]) file_output = subprocess.check_output(['/usr/bin/vtysh', '-m', '-f', filename],
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
raise VtyshMarkException(str(e)) ve = VtyshMarkException(e)
ve.output = e.output
raise ve
for line in file_output.split('\n'): for line in file_output.split('\n'):
line = line.strip() line = line.strip()
@ -134,9 +137,11 @@ class Config(object):
try: try:
config_text = subprocess.check_output( config_text = subprocess.check_output(
"/usr/bin/vtysh -c 'show run' | /usr/bin/tail -n +4 | /usr/bin/vtysh -m -f -", "/usr/bin/vtysh -c 'show run' | /usr/bin/tail -n +4 | /usr/bin/vtysh -m -f -",
shell=True) shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
raise VtyshMarkException(str(e)) ve = VtyshMarkException(e)
ve.output = e.output
raise ve
for line in config_text.split('\n'): for line in config_text.split('\n'):
line = line.strip() line = line.strip()
@ -342,10 +347,12 @@ end
# the keywords that we know are single line contexts. bgp in this case # the keywords that we know are single line contexts. bgp in this case
# is not the main router bgp block, but enabling multi-instance # is not the main router bgp block, but enabling multi-instance
oneline_ctx_keywords = ("access-list ", oneline_ctx_keywords = ("access-list ",
"agentx",
"bgp ", "bgp ",
"debug ", "debug ",
"dump ", "dump ",
"enable ", "enable ",
"frr ",
"hostname ", "hostname ",
"ip ", "ip ",
"ipv6 ", "ipv6 ",
@ -815,6 +822,14 @@ def compare_context_objects(newconf, running):
elif "router bgp" in running_ctx_keys[0] and len(running_ctx_keys) > 1 and delete_bgpd: elif "router bgp" in running_ctx_keys[0] and len(running_ctx_keys) > 1 and delete_bgpd:
continue continue
elif ("router bgp" in running_ctx_keys[0] and
len(running_ctx_keys) > 1 and
running_ctx_keys[1].startswith('address-family')):
# There's no 'no address-family' support and so we have to
# delete each line individually again
for line in running_ctx.lines:
lines_to_del.append((running_ctx_keys, line))
# Non-global context # Non-global context
elif running_ctx_keys and not any("address-family" in key for key in running_ctx_keys): elif running_ctx_keys and not any("address-family" in key for key in running_ctx_keys):
lines_to_del.append((running_ctx_keys, None)) lines_to_del.append((running_ctx_keys, None))
@ -890,11 +905,15 @@ if __name__ == '__main__':
# Verify the new config file is valid # Verify the new config file is valid
if not os.path.isfile(args.filename): if not os.path.isfile(args.filename):
print "Filename %s does not exist" % args.filename msg = "Filename %s does not exist" % args.filename
print msg
log.error(msg)
sys.exit(1) sys.exit(1)
if not os.path.getsize(args.filename): if not os.path.getsize(args.filename):
print "Filename %s is an empty file" % args.filename msg = "Filename %s is an empty file" % args.filename
print msg
log.error(msg)
sys.exit(1) sys.exit(1)
# Verify that 'service integrated-vtysh-config' is configured # Verify that 'service integrated-vtysh-config' is configured
@ -911,7 +930,9 @@ if __name__ == '__main__':
break break
if not service_integrated_vtysh_config: if not service_integrated_vtysh_config:
print "'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'" msg = "'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'"
print msg
log.error(msg)
sys.exit(1) sys.exit(1)
if args.debug: if args.debug:
@ -922,6 +943,7 @@ if __name__ == '__main__':
# Create a Config object from the config generated by newconf # Create a Config object from the config generated by newconf
newconf = Config() newconf = Config()
newconf.load_from_file(args.filename) newconf.load_from_file(args.filename)
reload_ok = True
if args.test: if args.test:
@ -1064,7 +1086,7 @@ if __name__ == '__main__':
# 'no ip ospf authentication message-digest 1.1.1.1' in # 'no ip ospf authentication message-digest 1.1.1.1' in
# our example above # our example above
# - Split that last entry by whitespace and drop the last word # - Split that last entry by whitespace and drop the last word
log.warning('Failed to execute %s', ' '.join(cmd)) log.info('Failed to execute %s', ' '.join(cmd))
last_arg = cmd[-1].split(' ') last_arg = cmd[-1].split(' ')
if len(last_arg) <= 2: if len(last_arg) <= 2:
@ -1099,9 +1121,25 @@ if __name__ == '__main__':
with open(filename, 'w') as fh: with open(filename, 'w') as fh:
for line in lines_to_configure: for line in lines_to_configure:
fh.write(line + '\n') fh.write(line + '\n')
subprocess.call(['/usr/bin/vtysh', '-f', filename])
output = subprocess.check_output(['/usr/bin/vtysh', '-f', filename])
# exit non-zero if we see these errors
for x in ('BGP instance name and AS number mismatch',
'BGP instance is already running',
'% not a local address'):
for line in output.splitlines():
if x in line:
msg = "ERROR: %s" % x
log.error(msg)
print msg
reload_ok = False
os.unlink(filename) os.unlink(filename)
# Make these changes persistent # Make these changes persistent
if args.overwrite or args.filename != '/etc/frr/frr.conf': if args.overwrite or args.filename != '/etc/frr/frr.conf':
subprocess.call(['/usr/bin/vtysh', '-c', 'write']) subprocess.call(['/usr/bin/vtysh', '-c', 'write'])
if not reload_ok:
sys.exit(1)

View File

@ -646,7 +646,7 @@ vtysh_mark_file (const char *filename)
} }
} }
/* This is the end */ /* This is the end */
fprintf(stdout, "end\n"); fprintf(stdout, "\nend\n");
vty_close(vty); vty_close(vty);
XFREE(MTYPE_VTYSH_CMD, vty_buf_copy); XFREE(MTYPE_VTYSH_CMD, vty_buf_copy);

View File

@ -709,6 +709,10 @@ if_delete_update (struct interface *ifp)
for setting ifindex to IFINDEX_INTERNAL after processing the for setting ifindex to IFINDEX_INTERNAL after processing the
interface deletion message. */ interface deletion message. */
ifp->ifindex = IFINDEX_INTERNAL; ifp->ifindex = IFINDEX_INTERNAL;
/* if the ifp is in a vrf, move it to default so vrf can be deleted if desired */
if (ifp->vrf_id)
if_handle_vrf_change (ifp, VRF_DEFAULT);
} }
/* VRF change for an interface */ /* VRF change for an interface */

View File

@ -107,18 +107,15 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id)
/* Redistribute routes. */ /* Redistribute routes. */
static void static void
zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t vrf_id) zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t vrf_id, int afi)
{ {
struct rib *newrib; struct rib *newrib;
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
int afi;
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
{
table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id); table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id);
if (! table) if (! table)
continue; return;
for (rn = route_top (table); rn; rn = route_next (rn)) for (rn = route_top (table); rn; rn = route_next (rn))
RNODE_FOREACH_RIB (rn, newrib) RNODE_FOREACH_RIB (rn, newrib)
@ -145,7 +142,6 @@ zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t v
zsend_redistribute_route (1, client, dst_p, src_p, newrib); zsend_redistribute_route (1, client, dst_p, src_p, newrib);
} }
}
} }
/* Either advertise a route for redistribution to registered clients or */ /* Either advertise a route for redistribution to registered clients or */
@ -265,13 +261,13 @@ zebra_redistribute_add (int command, struct zserv *client, int length,
if (! redist_check_instance (&client->mi_redist[afi][type], instance)) if (! redist_check_instance (&client->mi_redist[afi][type], instance))
{ {
redist_add_instance (&client->mi_redist[afi][type], instance); redist_add_instance (&client->mi_redist[afi][type], instance);
zebra_redistribute (client, type, instance, zvrf_id (zvrf)); zebra_redistribute (client, type, instance, zvrf_id (zvrf), afi);
} }
} else { } else {
if (! vrf_bitmap_check (client->redist[afi][type], zvrf_id (zvrf))) if (! vrf_bitmap_check (client->redist[afi][type], zvrf_id (zvrf)))
{ {
vrf_bitmap_set (client->redist[afi][type], zvrf_id (zvrf)); vrf_bitmap_set (client->redist[afi][type], zvrf_id (zvrf));
zebra_redistribute (client, type, 0, zvrf_id (zvrf)); zebra_redistribute (client, type, 0, zvrf_id (zvrf), afi);
} }
} }
} }

View File

@ -555,7 +555,7 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family,
{ {
RNODE_FOREACH_RIB(static_rn, srib) RNODE_FOREACH_RIB(static_rn, srib)
{ {
if (srib->type == ZEBRA_ROUTE_STATIC) if (srib->type != ZEBRA_ROUTE_STATIC)
continue; continue;
/* Set the filter flag for the correct nexthop - static route may /* Set the filter flag for the correct nexthop - static route may