mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 23:58:44 +00:00
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:
commit
92eedda1fb
@ -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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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. */
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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)
|
||||||
@ -146,7 +143,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 */
|
||||||
/* withdraw redistribution if add cannot be done for client */
|
/* withdraw redistribution if add cannot be done for client */
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user