diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 424eec55c4..fbca83c750 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1026,7 +1026,7 @@ bgp_stop (struct peer *peer) zlog_info ("%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s", peer->host, (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]); } diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 853fcc8697..661dce133c 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1128,7 +1128,10 @@ bgp_open_receive (struct peer *peer, bgp_size_t size) else peer->v_holdtime = send_holdtime; - peer->v_keepalive = peer->v_holdtime / 3; + if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER)) + peer->v_keepalive = peer->keepalive; + else + peer->v_keepalive = peer->v_holdtime / 3; /* Open option part parse. */ if (optlen != 0) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 0c6648d562..1372e820f9 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -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); - 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) && afi == AFI_IP && safi == SAFI_UNICAST) @@ -2728,8 +2733,9 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi, if (peer->ifp) bgp_zebra_initiate_radv (bgp, peer); } - else if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) || - (!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))) { if (v6only) SET_FLAG(peer->flags, PEER_FLAG_IFPEER_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_char *msg; json_object *json_neigh = NULL; + time_t epoch_tbuf; 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 -= p->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_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) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 72bd081a7e..4e00367aff 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1470,7 +1470,8 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, if (!ifindex) { 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) ifindex = info->peer->nexthop.ifp->ifindex; } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 7343d3714f..1da69c9f32 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -6341,7 +6341,7 @@ peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi, char * 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; /* 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) { + epoch_tbuf = time(NULL) - uptime1; json_object_string_add(json, "peerUptime", buf); json_object_long_add(json, "peerUptimeMsec", uptime1 * 1000); + json_object_int_add(json, "peerUptimeEstablishedEpoch", epoch_tbuf); } return buf; diff --git a/cumulus/start-stop-daemon.c b/cumulus/start-stop-daemon.c index c123f87e92..f1a252a26f 100644 --- a/cumulus/start-stop-daemon.c +++ b/cumulus/start-stop-daemon.c @@ -811,6 +811,7 @@ run_stop_schedule(void) anykilled = 0; retry_nr = 0; + n_killed = 0; if (schedule == NULL) { do_stop(signal_nr, quietmode, &n_killed, &n_notkilled, 0); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 44bf1b8667..f409aa8bb4 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -6333,7 +6333,7 @@ DEFUN (no_ip_ospf_dead_interval, { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_ipv4 = argc - 1; - struct in_addr addr; + struct in_addr addr = { .s_addr = 0L}; int ret; struct ospf_if_params *params; struct ospf_interface *oi; diff --git a/tools/frr-reload.py b/tools/frr-reload.py index c91392da15..a7a04be639 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -109,9 +109,12 @@ class Config(object): log.info('Loading Config object from file %s', filename) 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: - raise VtyshMarkException(str(e)) + ve = VtyshMarkException(e) + ve.output = e.output + raise ve for line in file_output.split('\n'): line = line.strip() @@ -134,9 +137,11 @@ class Config(object): try: config_text = subprocess.check_output( "/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: - raise VtyshMarkException(str(e)) + ve = VtyshMarkException(e) + ve.output = e.output + raise ve for line in config_text.split('\n'): line = line.strip() @@ -342,10 +347,12 @@ end # the keywords that we know are single line contexts. bgp in this case # is not the main router bgp block, but enabling multi-instance oneline_ctx_keywords = ("access-list ", + "agentx", "bgp ", "debug ", "dump ", "enable ", + "frr ", "hostname ", "ip ", "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: 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 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)) @@ -890,11 +905,15 @@ if __name__ == '__main__': # Verify the new config file is valid 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) 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) # Verify that 'service integrated-vtysh-config' is configured @@ -911,7 +930,9 @@ if __name__ == '__main__': break 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) if args.debug: @@ -922,6 +943,7 @@ if __name__ == '__main__': # Create a Config object from the config generated by newconf newconf = Config() newconf.load_from_file(args.filename) + reload_ok = True if args.test: @@ -1064,7 +1086,7 @@ if __name__ == '__main__': # 'no ip ospf authentication message-digest 1.1.1.1' in # our example above # - 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(' ') if len(last_arg) <= 2: @@ -1099,9 +1121,25 @@ if __name__ == '__main__': with open(filename, 'w') as fh: for line in lines_to_configure: 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) # Make these changes persistent if args.overwrite or args.filename != '/etc/frr/frr.conf': subprocess.call(['/usr/bin/vtysh', '-c', 'write']) + + if not reload_ok: + sys.exit(1) diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 5c39e1ee90..337925c6e8 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -646,7 +646,7 @@ vtysh_mark_file (const char *filename) } } /* This is the end */ - fprintf(stdout, "end\n"); + fprintf(stdout, "\nend\n"); vty_close(vty); XFREE(MTYPE_VTYSH_CMD, vty_buf_copy); diff --git a/zebra/interface.c b/zebra/interface.c index 78ac0258ca..317cc722b4 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -709,6 +709,10 @@ if_delete_update (struct interface *ifp) for setting ifindex to IFINDEX_INTERNAL after processing the interface deletion message. */ 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 */ diff --git a/zebra/redistribute.c b/zebra/redistribute.c index c7ed209d3c..e1ec22463a 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -107,45 +107,41 @@ zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id) /* Redistribute routes. */ 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 route_table *table; struct route_node *rn; - int afi; - for (afi = AFI_IP; afi <= AFI_IP6; afi++) - { - table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id); - if (! table) - continue; + table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id); + if (! table) + return; - for (rn = route_top (table); rn; rn = route_next (rn)) - RNODE_FOREACH_RIB (rn, newrib) - { - struct prefix *dst_p, *src_p; - srcdest_rnode_prefixes(rn, &dst_p, &src_p); + for (rn = route_top (table); rn; rn = route_next (rn)) + RNODE_FOREACH_RIB (rn, newrib) + { + struct prefix *dst_p, *src_p; + srcdest_rnode_prefixes(rn, &dst_p, &src_p); - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug("%s: checking: selected=%d, type=%d, distance=%d, " - "zebra_check_addr=%d", __func__, - CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED), - newrib->type, newrib->distance, - zebra_check_addr (dst_p)); + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("%s: checking: selected=%d, type=%d, distance=%d, " + "zebra_check_addr=%d", __func__, + CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED), + newrib->type, newrib->distance, + zebra_check_addr (dst_p)); - if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)) - continue; - if ((type != ZEBRA_ROUTE_ALL && - (newrib->type != type || newrib->instance != instance))) - continue; - if (newrib->distance == DISTANCE_INFINITY) - continue; - if (! zebra_check_addr (dst_p)) - continue; + if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)) + continue; + if ((type != ZEBRA_ROUTE_ALL && + (newrib->type != type || newrib->instance != instance))) + continue; + if (newrib->distance == DISTANCE_INFINITY) + continue; + if (! zebra_check_addr (dst_p)) + continue; - 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 */ @@ -265,13 +261,13 @@ zebra_redistribute_add (int command, struct zserv *client, int length, if (! redist_check_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 { if (! vrf_bitmap_check (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); } } } diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 67859fd46b..5096e95395 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -555,7 +555,7 @@ zebra_rnh_process_static_routes (vrf_id_t vrfid, int family, { RNODE_FOREACH_RIB(static_rn, srib) { - if (srib->type == ZEBRA_ROUTE_STATIC) + if (srib->type != ZEBRA_ROUTE_STATIC) continue; /* Set the filter flag for the correct nexthop - static route may