diff options
| -rw-r--r-- | bgpd/bgp_fsm.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_packet.c | 5 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 16 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 3 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 4 | ||||
| -rwxr-xr-x | tools/frr-reload.py | 72 | ||||
| -rw-r--r-- | vtysh/vtysh.c | 2 | ||||
| -rw-r--r-- | zebra/interface.c | 4 | ||||
| -rw-r--r-- | zebra/redistribute.c | 60 | ||||
| -rw-r--r-- | zebra/zebra_mpls_vty.c | 4 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_rnh.c | 2 |
12 files changed, 121 insertions, 55 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 2f37f39ffd..18a171ab80 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 796a57f054..5ac982d565 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1118,7 +1118,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 4187654244..9d5a4bd1cf 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -2872,7 +2872,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) @@ -2896,8 +2901,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); @@ -11081,6 +11087,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; @@ -11271,8 +11278,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 3d3bd90f5b..d07fc65bdf 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1469,7 +1469,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 c6997a9b83..c1635bdb41 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -6250,7 +6250,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. */ @@ -6304,8 +6304,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/tools/frr-reload.py b/tools/frr-reload.py index 80d2d6a2a3..a9151e3e7d 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,14 +347,17 @@ 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 ", "log ", + "no ", "password ", "ptm-enable", "router-id ", @@ -813,6 +821,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)) @@ -888,11 +904,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 @@ -909,7 +929,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: @@ -920,6 +942,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: @@ -993,7 +1016,20 @@ if __name__ == '__main__': (lines_to_add, lines_to_del) = compare_context_objects(newconf, running) - if lines_to_del: + # Only do deletes on the first pass. The reason being if we + # configure a bgp neighbor via "neighbor swp1 interface" frr + # will automatically add: + # + # interface swp1 + # ipv6 nd ra-interval 10 + # no ipv6 nd suppress-ra + # ! + # + # but those lines aren't in the config we are reloading against so + # on the 2nd pass they will show up in lines_to_del. This could + # apply to other scenarios as well where configuring FOO adds BAR + # to the config. + if lines_to_del and x == 0: for (ctx_keys, line) in lines_to_del: if line == '!': @@ -1029,7 +1065,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: @@ -1064,9 +1100,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 51f71a46bb..2994c3507a 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -635,7 +635,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 39c20e6289..524183a434 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -693,6 +693,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 9c7ef5f12c..5d7dbd5b00 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -108,42 +108,38 @@ 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) - { - 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 (&rn->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 (&rn->p)) - continue; - - zsend_redistribute_route (1, client, &rn->p, newrib); - } - } + for (rn = route_top (table); rn; rn = route_next (rn)) + RNODE_FOREACH_RIB (rn, newrib) + { + 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 (&rn->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 (&rn->p)) + continue; + + zsend_redistribute_route (1, client, &rn->p, newrib); + } } /* Either advertise a route for redistribution to registered clients or */ @@ -262,13 +258,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_mpls_vty.c b/zebra/zebra_mpls_vty.c index 8b967c3af8..343f2975e8 100644 --- a/zebra/zebra_mpls_vty.c +++ b/zebra/zebra_mpls_vty.c @@ -472,7 +472,7 @@ DEFUN (no_ip_route_tag_distance_label, DEFUN (no_ip_route_mask_distance_label, no_ip_route_mask_distance_label_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>", + "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> label WORD", NO_STR IP_STR "Establish static routes\n" @@ -486,7 +486,7 @@ DEFUN (no_ip_route_mask_distance_label, "One or more labels separated by '/'\n") { return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL, - argv[3], NULL, argv[5]); + argv[3], NULL, argv[4]); } DEFUN (no_ip_route_mask_tag_distance_label, diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index e48da0479b..23c4c9ebea 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -366,7 +366,6 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, if (set) { UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - zebra_deregister_rnh_static_nexthops(rib->vrf_id, nexthop->resolved, top); nexthops_free(nexthop->resolved); nexthop->resolved = NULL; rib->nexthop_mtu = 0; @@ -597,7 +596,6 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set, if (set) { UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - zebra_deregister_rnh_static_nexthops (rib->vrf_id, nexthop->resolved, top); nexthops_free(nexthop->resolved); nexthop->resolved = NULL; } diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index b679803b06..1032d5405f 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -546,7 +546,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 |
