summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--babeld/babeld.c8
-rw-r--r--bfdd/bfdd_vty.c5
-rw-r--r--bgpd/bgp_label.h4
-rw-r--r--bgpd/bgp_route.c69
-rw-r--r--bgpd/bgp_route.h2
-rw-r--r--bgpd/bgp_routemap.c8
-rw-r--r--bgpd/bgp_vty.c8
-rw-r--r--debian/changelog16
-rw-r--r--doc/developer/building-frr-for-archlinux.rst4
-rw-r--r--doc/developer/building-frr-for-centos7.rst4
-rw-r--r--doc/developer/building-frr-for-centos8.rst4
-rw-r--r--doc/developer/building-frr-for-debian9.rst4
-rw-r--r--doc/developer/building-frr-for-fedora.rst4
-rw-r--r--doc/developer/building-frr-for-freebsd10.rst4
-rw-r--r--doc/developer/building-frr-for-freebsd11.rst4
-rw-r--r--doc/developer/building-frr-for-opensuse.rst4
-rw-r--r--doc/developer/building-frr-for-ubuntu1804.rst4
-rw-r--r--doc/developer/building-frr-for-ubuntu2004.rst4
-rw-r--r--doc/developer/building-libunwind-note.rst6
-rw-r--r--doc/developer/conf.py1
-rw-r--r--doc/developer/subdir.am1
-rw-r--r--doc/user/basic.rst36
-rw-r--r--doc/user/bgp.rst4
-rw-r--r--eigrpd/eigrp_routemap.c12
-rw-r--r--isisd/isis_circuit.c10
-rw-r--r--isisd/isis_circuit.h1
-rw-r--r--isisd/isis_cli.c144
-rw-r--r--isisd/isis_events.c7
-rw-r--r--isisd/isis_ldp_sync.c3
-rw-r--r--isisd/isis_nb_config.c97
-rw-r--r--isisd/isisd.c8
-rw-r--r--ldpd/ldp_vty_cmds.c10
-rw-r--r--lib/atomlist.c2
-rw-r--r--lib/elf_py.c3
-rw-r--r--lib/filter.c58
-rw-r--r--lib/filter_cli.c14
-rw-r--r--lib/frrcu.h2
-rw-r--r--lib/log_vty.c61
-rw-r--r--lib/resolver.c178
-rw-r--r--lib/routemap_cli.c12
-rw-r--r--lib/typerb.h1
-rw-r--r--lib/typesafe.c1
-rw-r--r--lib/typesafe.h1
-rw-r--r--lib/vector.c11
-rw-r--r--lib/vector.h1
-rw-r--r--lib/xref.c4
-rw-r--r--lib/xref.h13
-rw-r--r--lib/zlog.c97
-rw-r--r--lib/zlog.h22
-rw-r--r--ospf6d/ospf6_area.c12
-rw-r--r--ospf6d/ospf6_gr.h2
-rw-r--r--ospf6d/ospf6_gr_helper.c26
-rw-r--r--ospfd/ospf_vty.c534
-rw-r--r--pimd/pim_cmd.c2
-rw-r--r--pimd/pim_msdp.c7
-rw-r--r--pimd/pim_upstream.c4
-rw-r--r--redhat/frr.spec.in430
-rw-r--r--ripd/rip_cli.c6
-rw-r--r--ripngd/ripng_cli.c6
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/lib/cli/common_cli.c3
-rw-r--r--tests/lib/cli/common_cli.h2
-rw-r--r--tests/lib/test_resolver.c81
-rw-r--r--tests/subdir.am10
-rwxr-xr-xtests/topotests/bfd_ospf_topo1/test_bfd_ospf_topo1.py12
-rw-r--r--tests/topotests/isis_topo1_vrf/r3/r3_topology.json12
-rw-r--r--tests/topotests/lib/bgprib.py2
-rw-r--r--tests/topotests/ospf_gr_helper/test_ospf_gr_helper.py2
-rwxr-xr-xtests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py2
-rw-r--r--zebra/rtadv.c4
-rw-r--r--zebra/table_manager.c1
-rw-r--r--zebra/zebra_ptm.c2
-rw-r--r--zebra/zebra_vrf.c2
73 files changed, 1183 insertions, 963 deletions
diff --git a/babeld/babeld.c b/babeld/babeld.c
index f61eac000f..0104620cd5 100644
--- a/babeld/babeld.c
+++ b/babeld/babeld.c
@@ -716,7 +716,7 @@ DEFUN (babel_set_smoothing_half_life,
DEFUN (babel_distribute_list,
babel_distribute_list_cmd,
- "distribute-list [prefix] WORD <in|out> [WORD]",
+ "distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
"Filter networks in routing updates\n"
"Specify a prefix\n"
"Access-list name\n"
@@ -736,7 +736,7 @@ DEFUN (babel_distribute_list,
DEFUN (babel_no_distribute_list,
babel_no_distribute_list_cmd,
- "no distribute-list [prefix] WORD <in|out> [WORD]",
+ "no distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
NO_STR
"Filter networks in routing updates\n"
"Specify a prefix\n"
@@ -758,7 +758,7 @@ DEFUN (babel_no_distribute_list,
DEFUN (babel_ipv6_distribute_list,
babel_ipv6_distribute_list_cmd,
- "ipv6 distribute-list [prefix] WORD <in|out> [WORD]",
+ "ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
"IPv6\n"
"Filter networks in routing updates\n"
"Specify a prefix\n"
@@ -779,7 +779,7 @@ DEFUN (babel_ipv6_distribute_list,
DEFUN (babel_no_ipv6_distribute_list,
babel_no_ipv6_distribute_list_cmd,
- "no ipv6 distribute-list [prefix] WORD <in|out> [WORD]",
+ "no ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
NO_STR
"IPv6\n"
"Filter networks in routing updates\n"
diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c
index a03fb9f216..4091ab9caa 100644
--- a/bfdd/bfdd_vty.c
+++ b/bfdd/bfdd_vty.c
@@ -579,7 +579,7 @@ _find_peer_or_error(struct vty *vty, int argc, struct cmd_token **argv,
pl = pl_find(label);
if (pl)
bs = pl->pl_bs;
- } else {
+ } else if (peer_str) {
strtosa(peer_str, &psa);
if (local_str) {
strtosa(local_str, &lsa);
@@ -599,6 +599,9 @@ _find_peer_or_error(struct vty *vty, int argc, struct cmd_token **argv,
}
bs = bs_peer_find(&bpc);
+ } else {
+ vty_out(vty, "%% Invalid arguments\n");
+ return NULL;
}
/* Find peer data. */
diff --git a/bgpd/bgp_label.h b/bgpd/bgp_label.h
index d227cf7241..cafcc8e9c7 100644
--- a/bgpd/bgp_label.h
+++ b/bgpd/bgp_label.h
@@ -65,7 +65,7 @@ static inline int bgp_is_withdraw_label(mpls_label_t *label)
return 0;
}
-static inline int bgp_is_valid_label(mpls_label_t *label)
+static inline int bgp_is_valid_label(const mpls_label_t *label)
{
uint8_t *t = (uint8_t *)label;
if (!t)
@@ -99,7 +99,7 @@ static inline void bgp_unregister_for_label(struct bgp_dest *dest)
}
/* Label stream to value */
-static inline uint32_t label_pton(mpls_label_t *label)
+static inline uint32_t label_pton(const mpls_label_t *label)
{
uint8_t *t = (uint8_t *)label;
return ((((unsigned int)t[0]) << 12) | (((unsigned int)t[1]) << 4)
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 4b798cc264..fdaee9b600 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -102,6 +102,10 @@ DEFINE_HOOK(bgp_rpki_prefix_status,
const struct prefix *prefix),
(peer, attr, prefix));
+/* Render dest to prefix_rd based on safi */
+static const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
+ safi_t safi);
+
/* Extern from bgp_dump.c */
extern const char *bgp_origin_str[];
extern const char *bgp_origin_long_str[];
@@ -10712,14 +10716,15 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp,
static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
struct bgp_table *table, enum bgp_show_type type,
- void *output_arg, char *rd, int is_last,
+ void *output_arg, const char *rd, int is_last,
unsigned long *output_cum, unsigned long *total_cum,
unsigned long *json_header_depth, uint16_t show_flags,
enum rpki_states rpki_target_state)
{
struct bgp_path_info *pi;
struct bgp_dest *dest;
- int header = 1;
+ bool header = true;
+ bool json_detail_header = false;
int display;
unsigned long output_count = 0;
unsigned long total_count = 0;
@@ -10731,7 +10736,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
if (output_cum && *output_cum != 0)
- header = 0;
+ header = false;
if (use_json && !*json_header_depth) {
if (all)
@@ -10761,10 +10766,19 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
vty_out(vty, " \"%s\" : { ", rd);
}
+ /* Check for 'json detail', where we need header output once per dest */
+ if (use_json && CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL) &&
+ type != bgp_show_type_dampend_paths &&
+ type != bgp_show_type_damp_neighbor &&
+ type != bgp_show_type_flap_statistics &&
+ type != bgp_show_type_flap_neighbor)
+ json_detail_header = true;
+
/* Start processing of routes. */
for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
const struct prefix *dest_p = bgp_dest_get_prefix(dest);
enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
+ bool json_detail = json_detail_header;
pi = bgp_dest_get_bgp_path_info(dest);
if (pi == NULL)
@@ -11016,8 +11030,28 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
else
vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
: BGP_SHOW_HEADER));
- header = 0;
+ header = false;
+
+ } else if (json_detail && json_paths != NULL) {
+ const struct prefix_rd *prd;
+ json_object *jtemp;
+
+ /* Use common detail header, for most types;
+ * need a json 'object'.
+ */
+
+ jtemp = json_object_new_object();
+ prd = bgp_rd_from_dest(dest, safi);
+
+ route_vty_out_detail_header(
+ vty, bgp, dest, prd, table->afi,
+ safi, jtemp);
+
+ json_object_array_add(json_paths, jtemp);
+
+ json_detail = false;
}
+
if (rd != NULL && !display && !output_count) {
if (!use_json)
vty_out(vty,
@@ -11176,6 +11210,7 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
}
return CMD_SUCCESS;
}
+
static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
enum bgp_show_type type, void *output_arg,
uint16_t show_flags, enum rpki_states rpki_target_state)
@@ -11260,7 +11295,8 @@ static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
/* Header of detailed BGP route information */
void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
- struct bgp_dest *dest, struct prefix_rd *prd,
+ struct bgp_dest *dest,
+ const struct prefix_rd *prd,
afi_t afi, safi_t safi, json_object *json)
{
struct bgp_path_info *pi;
@@ -11470,7 +11506,7 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
}
}
-static void bgp_show_path_info(struct prefix_rd *pfx_rd,
+static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
struct bgp_dest *bgp_node, struct vty *vty,
struct bgp *bgp, afi_t afi, safi_t safi,
json_object *json, enum bgp_path_type pathtype,
@@ -11530,6 +11566,23 @@ static void bgp_show_path_info(struct prefix_rd *pfx_rd,
}
}
+/*
+ * Return rd based on safi
+ */
+static const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
+ safi_t safi)
+{
+ switch (safi) {
+ case SAFI_MPLS_VPN:
+ case SAFI_ENCAP:
+ case SAFI_EVPN:
+ return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
+ default:
+ return NULL;
+
+ }
+}
+
/* Display specified route of BGP table. */
static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
struct bgp_table *rib, const char *ip_str,
@@ -12484,7 +12537,7 @@ DEFPY (show_ip_bgp_instance_all,
JSON_STR
"Increase table width for longer prefixes\n")
{
- afi_t afi = AFI_IP;
+ afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
struct bgp *bgp = NULL;
int idx = 0;
@@ -14086,7 +14139,7 @@ DEFUN (show_ip_bgp_flowspec_routes_detailed,
"Detailed information on flowspec entries\n"
JSON_STR)
{
- afi_t afi = AFI_IP;
+ afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
struct bgp *bgp = NULL;
int idx = 0;
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 46802d0d14..2fd80495d9 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -784,7 +784,7 @@ extern bool bgp_zebra_has_route_changed(struct bgp_path_info *selected);
extern void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
struct bgp_dest *dest,
- struct prefix_rd *prd, afi_t afi,
+ const struct prefix_rd *prd, afi_t afi,
safi_t safi, json_object *json);
extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
struct bgp_dest *bn,
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 3fc478bc97..aa59499b04 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -4004,7 +4004,7 @@ static void bgp_route_map_event(const char *rmap_name)
DEFUN_YANG (match_mac_address,
match_mac_address_cmd,
- "match mac address WORD",
+ "match mac address ACCESSLIST_MAC_NAME",
MATCH_STR
"mac address\n"
"Match address of route\n"
@@ -4024,7 +4024,7 @@ DEFUN_YANG (match_mac_address,
DEFUN_YANG (no_match_mac_address,
no_match_mac_address_cmd,
- "no match mac address WORD",
+ "no match mac address ACCESSLIST_MAC_NAME",
NO_STR
MATCH_STR
"mac\n"
@@ -4576,7 +4576,7 @@ DEFUN_YANG (no_match_probability,
DEFPY_YANG (match_ip_route_source,
match_ip_route_source_cmd,
- "match ip route-source WORD",
+ "match ip route-source ACCESSLIST4_NAME",
MATCH_STR
IP_STR
"Match advertising source address of route\n"
@@ -4600,7 +4600,7 @@ DEFPY_YANG (match_ip_route_source,
DEFUN_YANG (no_match_ip_route_source,
no_match_ip_route_source_cmd,
- "no match ip route-source [WORD]",
+ "no match ip route-source [ACCESSLIST4_NAME]",
NO_STR
MATCH_STR
IP_STR
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 65806bb5f4..3725f242e1 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -7048,7 +7048,7 @@ DEFUN (no_neighbor_interface,
DEFUN (neighbor_distribute_list,
neighbor_distribute_list_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list WORD <in|out>",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list ACCESSLIST_NAME <in|out>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Filter updates to/from this neighbor\n"
@@ -7079,7 +7079,7 @@ DEFUN (neighbor_distribute_list,
ALIAS_HIDDEN(
neighbor_distribute_list, neighbor_distribute_list_hidden_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list WORD <in|out>",
+ "neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list ACCESSLIST_NAME <in|out>",
NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"Filter updates to/from this neighbor\n"
"IP Access-list name\n"
@@ -7088,7 +7088,7 @@ ALIAS_HIDDEN(
DEFUN (no_neighbor_distribute_list,
no_neighbor_distribute_list_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list WORD <in|out>",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list ACCESSLIST_NAME <in|out>",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
@@ -7118,7 +7118,7 @@ DEFUN (no_neighbor_distribute_list,
ALIAS_HIDDEN(
no_neighbor_distribute_list, no_neighbor_distribute_list_hidden_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list WORD <in|out>",
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> distribute-list ACCESSLIST_NAME <in|out>",
NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"Filter updates to/from this neighbor\n"
"IP Access-list name\n"
diff --git a/debian/changelog b/debian/changelog
index 99c75106db..f5b392274a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,20 @@
-frr (8.1~dev-1) UNRELEASED; urgency=medium
+frr (8.2~dev-1) UNRELEASED; urgency=medium
* New upstream release...
- -- Ondřej Surý <ondrej@debian.org> Tue, 04 May 2021 22:52:47 +0200
+ -- Jafar Al-Gharaibeh <jafar@atcorp.com> Mon, 08 Nov 2021 10:00:00 +0500
+
+frr (8.1-0) unstable; urgency=medium
+
+ * New upstream release FRR 8.1
+
+ -- Jafar Al-Gharaibeh <jafar@atcorp.com> Tue, 02 Nov 2021 14:00:00 +0500
+
+frr (8.0-0) unstable; urgency=medium
+
+ * New upstream release FRR 8.0
+
+ -- Martin Winter <mwinter@opensourcerouting.org> Wed, 21 Jul 2021 13:42:00 +0200
frr (7.5.1-1) unstable; urgency=medium
diff --git a/doc/developer/building-frr-for-archlinux.rst b/doc/developer/building-frr-for-archlinux.rst
index af1677e89e..406d22d618 100644
--- a/doc/developer/building-frr-for-archlinux.rst
+++ b/doc/developer/building-frr-for-archlinux.rst
@@ -11,7 +11,9 @@ Installing Dependencies
git autoconf automake libtool make cmake pcre readline texinfo \
pkg-config pam json-c bison flex python-pytest \
c-ares python python2-ipaddress python-sphinx \
- net-snmp perl libcap libelf
+ net-snmp perl libcap libelf libunwind
+
+.. include:: building-libunwind-note.rst
.. include:: building-libyang.rst
diff --git a/doc/developer/building-frr-for-centos7.rst b/doc/developer/building-frr-for-centos7.rst
index ce11126f70..c40b5de594 100644
--- a/doc/developer/building-frr-for-centos7.rst
+++ b/doc/developer/building-frr-for-centos7.rst
@@ -22,7 +22,9 @@ Add packages:
readline-devel texinfo net-snmp-devel groff pkgconfig \
json-c-devel pam-devel bison flex pytest c-ares-devel \
python-devel python-sphinx libcap-devel \
- elfutils-libelf-devel
+ elfutils-libelf-devel libunwind-devel
+
+.. include:: building-libunwind-note.rst
.. include:: building-libyang.rst
diff --git a/doc/developer/building-frr-for-centos8.rst b/doc/developer/building-frr-for-centos8.rst
index 109a7866d9..659752f6df 100644
--- a/doc/developer/building-frr-for-centos8.rst
+++ b/doc/developer/building-frr-for-centos8.rst
@@ -15,7 +15,9 @@ Add packages:
automake libtool make readline-devel texinfo net-snmp-devel pkgconfig \
groff pkgconfig json-c-devel pam-devel bison flex python2-pytest \
c-ares-devel python2-devel libcap-devel \
- elfutils-libelf-devel
+ elfutils-libelf-devel libunwind-devel
+
+.. include:: building-libunwind-note.rst
.. include:: building-libyang.rst
diff --git a/doc/developer/building-frr-for-debian9.rst b/doc/developer/building-frr-for-debian9.rst
index f8d8025f62..b2fdef9990 100644
--- a/doc/developer/building-frr-for-debian9.rst
+++ b/doc/developer/building-frr-for-debian9.rst
@@ -11,7 +11,9 @@ Add packages:
sudo apt-get install git autoconf automake libtool make \
libreadline-dev texinfo libjson-c-dev pkg-config bison flex \
libc-ares-dev python3-dev python3-pytest python3-sphinx build-essential \
- libsnmp-dev libcap-dev libelf-dev
+ libsnmp-dev libcap-dev libelf-dev libunwind-dev
+
+.. include:: building-libunwind-note.rst
.. include:: building-libyang.rst
diff --git a/doc/developer/building-frr-for-fedora.rst b/doc/developer/building-frr-for-fedora.rst
index 6ce76ba158..dc869ece10 100644
--- a/doc/developer/building-frr-for-fedora.rst
+++ b/doc/developer/building-frr-for-fedora.rst
@@ -15,7 +15,9 @@ Installing Dependencies
readline-devel texinfo net-snmp-devel groff pkgconfig json-c-devel \
pam-devel python3-pytest bison flex c-ares-devel python3-devel \
python3-sphinx perl-core patch libcap-devel \
- elfutils-libelf-devel
+ elfutils-libelf-devel libunwind-devel
+
+.. include:: building-libunwind-note.rst
.. include:: building-libyang.rst
diff --git a/doc/developer/building-frr-for-freebsd10.rst b/doc/developer/building-frr-for-freebsd10.rst
index e85cb80053..5e70b81d43 100644
--- a/doc/developer/building-frr-for-freebsd10.rst
+++ b/doc/developer/building-frr-for-freebsd10.rst
@@ -17,7 +17,9 @@ is first package install and asked)
::
pkg install git autoconf automake libtool gmake json-c pkgconf \
- bison flex py36-pytest c-ares python3.6 py36-sphinx
+ bison flex py36-pytest c-ares python3.6 py36-sphinx libunwind
+
+.. include:: building-libunwind-note.rst
Make sure there is no /usr/bin/flex preinstalled (and use the newly
installed in /usr/local/bin): (FreeBSD frequently provides a older flex
diff --git a/doc/developer/building-frr-for-freebsd11.rst b/doc/developer/building-frr-for-freebsd11.rst
index b97538b763..808207b831 100644
--- a/doc/developer/building-frr-for-freebsd11.rst
+++ b/doc/developer/building-frr-for-freebsd11.rst
@@ -17,7 +17,9 @@ is first package install and asked)
.. code-block:: shell
pkg install git autoconf automake libtool gmake json-c pkgconf \
- bison flex py36-pytest c-ares python3.6 py36-sphinx texinfo
+ bison flex py36-pytest c-ares python3.6 py36-sphinx texinfo libunwind
+
+.. include:: building-libunwind-note.rst
Make sure there is no /usr/bin/flex preinstalled (and use the newly
installed in /usr/local/bin): (FreeBSD frequently provides a older flex
diff --git a/doc/developer/building-frr-for-opensuse.rst b/doc/developer/building-frr-for-opensuse.rst
index ee6a36a14b..d9800a1638 100644
--- a/doc/developer/building-frr-for-opensuse.rst
+++ b/doc/developer/building-frr-for-opensuse.rst
@@ -14,7 +14,9 @@ Installing Dependencies
readline-devel texinfo net-snmp-devel groff pkgconfig libjson-c-devel\
pam-devel python3-pytest bison flex c-ares-devel python3-devel\
python3-Sphinx perl patch libcap-devel libyang-devel \
- libelf-devel
+ libelf-devel libunwind-devel
+
+.. include:: building-libunwind-note.rst
Building & Installing FRR
-------------------------
diff --git a/doc/developer/building-frr-for-ubuntu1804.rst b/doc/developer/building-frr-for-ubuntu1804.rst
index 3e8c6c0d0b..fcfd94ec2c 100644
--- a/doc/developer/building-frr-for-ubuntu1804.rst
+++ b/doc/developer/building-frr-for-ubuntu1804.rst
@@ -15,7 +15,9 @@ Installing Dependencies
pkg-config libpam0g-dev libjson-c-dev bison flex \
libc-ares-dev python3-dev python3-sphinx \
install-info build-essential libsnmp-dev perl libcap-dev \
- libelf-dev
+ libelf-dev libunwind-dev
+
+.. include:: building-libunwind-note.rst
.. include:: building-libyang.rst
diff --git a/doc/developer/building-frr-for-ubuntu2004.rst b/doc/developer/building-frr-for-ubuntu2004.rst
index 28e7ca6518..fdfc25da9d 100644
--- a/doc/developer/building-frr-for-ubuntu2004.rst
+++ b/doc/developer/building-frr-for-ubuntu2004.rst
@@ -15,7 +15,9 @@ Installing Dependencies
pkg-config libpam0g-dev libjson-c-dev bison flex \
libc-ares-dev python3-dev python3-sphinx \
install-info build-essential libsnmp-dev perl \
- libcap-dev python2 libelf-dev
+ libcap-dev python2 libelf-dev libunwind-dev
+
+.. include:: building-libunwind-note.rst
Note that Ubuntu 20 no longer installs python 2.x, so it must be
installed explicitly. Ensure that your system has a symlink named
diff --git a/doc/developer/building-libunwind-note.rst b/doc/developer/building-libunwind-note.rst
new file mode 100644
index 0000000000..0beb1f8d37
--- /dev/null
+++ b/doc/developer/building-libunwind-note.rst
@@ -0,0 +1,6 @@
+.. note::
+
+ The ``libunwind`` library is optional but highly recommended, as it improves
+ backtraces printed for crashes and debugging. However, if it is not
+ available for some reason, it can simply be left out without any loss of
+ functionality.
diff --git a/doc/developer/conf.py b/doc/developer/conf.py
index 61df6e0e60..79f8233978 100644
--- a/doc/developer/conf.py
+++ b/doc/developer/conf.py
@@ -136,6 +136,7 @@ language = None
# directories to ignore when looking for source files.
exclude_patterns = [
"_build",
+ "building-libunwind-note.rst",
"building-libyang.rst",
"topotests-snippets.rst",
"topotests-markers.rst",
diff --git a/doc/developer/subdir.am b/doc/developer/subdir.am
index d16420c7e7..c8654d6725 100644
--- a/doc/developer/subdir.am
+++ b/doc/developer/subdir.am
@@ -23,6 +23,7 @@ dev_RSTFILES = \
doc/developer/building-frr-for-ubuntu1604.rst \
doc/developer/building-frr-for-ubuntu1804.rst \
doc/developer/building-frr-for-ubuntu2004.rst \
+ doc/developer/building-libunwind-note.rst \
doc/developer/building-libyang.rst \
doc/developer/building.rst \
doc/developer/cli.rst \
diff --git a/doc/user/basic.rst b/doc/user/basic.rst
index 16708adb50..69f276d551 100644
--- a/doc/user/basic.rst
+++ b/doc/user/basic.rst
@@ -244,6 +244,42 @@ Basic Config Commands
Use unbuffered output for log and debug messages; normally there is
some internal buffering.
+.. clicmd:: log unique-id
+
+ Include ``[XXXXX-XXXXX]`` log message unique identifier in the textual part
+ of log messages. This is enabled by default, but can be disabled with
+ ``no log unique-id``. Please make sure the IDs are enabled when including
+ logs for FRR bug reports.
+
+ The unique identifiers are automatically generated based on source code
+ file name, format string (before filling out) and severity. They do not
+ change "randomly", but some cleanup work may cause large chunks of ID
+ changes between releases. The IDs always start with a letter, consist of
+ letters and numbers (and a dash for readability), are case insensitive, and
+ ``I``, ``L``, ``O`` & ``U`` are excluded.
+
+ This option will not affect future logging targets which allow putting the
+ unique identifier in auxiliary metadata outside the log message text
+ content. (No such logging target exists currently, but RFC5424 syslog and
+ systemd's journald both support it.)
+
+.. clicmd:: debug unique-id XXXXX-XXXXX backtrace
+
+ Print backtraces (call stack) for specific log messages, identified by
+ their unique ID (see above.) Includes source code location and current
+ event handler being executed. On some systems you may need to install a
+ `debug symbols` package to get proper function names rather than raw code
+ pointers.
+
+ This command can be issued inside and outside configuration mode, and is
+ saved to configuration only if it was given in configuration mode.
+
+ .. warning::
+
+ Printing backtraces can significantly slow down logging calls and cause
+ log files to quickly balloon in size. Remember to disable backtraces
+ when they're no longer needed.
+
.. clicmd:: service password-encryption
Encrypt password.
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 68b4d74dd6..db59c42773 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -3006,8 +3006,8 @@ following zebra command -
.. clicmd:: evpn mh startup-delay (0-3600)
-+Support with VRF network namespace backend
-+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Support with VRF network namespace backend
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
It is possible to separate overlay networks contained in VXLAN interfaces from
underlay networks by using VRFs. VRF-lite and VRF-netns backends can be used for
that. In the latter case, it is necessary to set both bridge and vxlan interface
diff --git a/eigrpd/eigrp_routemap.c b/eigrpd/eigrp_routemap.c
index 65fa95b652..d9b500a8fd 100644
--- a/eigrpd/eigrp_routemap.c
+++ b/eigrpd/eigrp_routemap.c
@@ -858,7 +858,7 @@ ALIAS(no_match_interface, no_match_interface_val_cmd, "no match interface WORD",
DEFUN (match_ip_next_hop,
match_ip_next_hop_cmd,
- "match ip next-hop WORD",
+ "match ip next-hop ACCESSLIST4_NAME",
MATCH_STR
IP_STR
"Match next-hop address of route\n"
@@ -884,7 +884,7 @@ DEFUN (no_match_ip_next_hop,
}
ALIAS(no_match_ip_next_hop, no_match_ip_next_hop_val_cmd,
- "no match ip next-hop WORD", NO_STR MATCH_STR IP_STR
+ "no match ip next-hop ACCESSLIST4_NAME", NO_STR MATCH_STR IP_STR
"Match next-hop address of route\n"
"IP Access-list name\n")
@@ -927,7 +927,7 @@ ALIAS(no_match_ip_next_hop_prefix_list,
DEFUN (match_ip_address,
match_ip_address_cmd,
- "match ip address WORD",
+ "match ip address ACCESSLIST4_NAME",
MATCH_STR
IP_STR
"Match address of route\n"
@@ -952,7 +952,7 @@ DEFUN (no_match_ip_address,
}
ALIAS(no_match_ip_address, no_match_ip_address_val_cmd,
- "no match ip address WORD", NO_STR MATCH_STR IP_STR
+ "no match ip address ACCESSLIST4_NAME", NO_STR MATCH_STR IP_STR
"Match address of route\n"
"IP Access-list name\n")
@@ -1124,7 +1124,7 @@ ALIAS(no_set_tag, no_set_tag_val_cmd, "no set tag (0-65535)", NO_STR SET_STR
DEFUN (eigrp_distribute_list,
eigrp_distribute_list_cmd,
- "distribute-list [prefix] WORD <in|out> [WORD]",
+ "distribute-list [prefix] ACCESSLIST_NAME <in|out> [WORD]",
"Filter networks in routing updates\n"
"Specify a prefix\n"
"Access-list name\n"
@@ -1144,7 +1144,7 @@ DEFUN (eigrp_distribute_list,
DEFUN (eigrp_no_distribute_list,
eigrp_no_distribute_list_cmd,
- "no distribute-list [prefix] WORD <in|out> [WORD]",
+ "no distribute-list [prefix] ACCESSLIST_NAME <in|out> [WORD]",
NO_STR
"Filter networks in routing updates\n"
"Specify a prefix\n"
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index c09bdf4f4f..8810d6107d 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -116,7 +116,7 @@ struct isis_circuit *isis_circuit_new(struct interface *ifp, const char *tag)
* Default values
*/
#ifndef FABRICD
- circuit->is_type = yang_get_default_enum(
+ circuit->is_type_config = yang_get_default_enum(
"/frr-interface:lib/interface/frr-isisd:isis/circuit-type");
circuit->flags = 0;
@@ -156,7 +156,7 @@ struct isis_circuit *isis_circuit_new(struct interface *ifp, const char *tag)
circuit->level_arg[i].circuit = circuit;
}
#else
- circuit->is_type = IS_LEVEL_1_AND_2;
+ circuit->is_type_config = IS_LEVEL_1_AND_2;
circuit->flags = 0;
circuit->pad_hellos = 1;
for (i = 0; i < 2; i++) {
@@ -172,6 +172,8 @@ struct isis_circuit *isis_circuit_new(struct interface *ifp, const char *tag)
}
#endif /* ifndef FABRICD */
+ circuit->is_type = circuit->is_type_config;
+
circuit_mt_init(circuit);
isis_lfa_excluded_ifaces_init(circuit, ISIS_LEVEL1);
isis_lfa_excluded_ifaces_init(circuit, ISIS_LEVEL2);
@@ -253,6 +255,10 @@ void isis_circuit_deconfigure(struct isis_circuit *circuit,
/* Free the index of SRM and SSN flags */
flags_free_index(&area->flags, circuit->idx);
circuit->idx = 0;
+
+ /* Reset IS type to configured */
+ circuit->is_type = circuit->is_type_config;
+
/* Remove circuit from area */
assert(circuit->area == area);
listnode_delete(area->circuit_list, circuit);
diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h
index e7b7a2434d..e286194d3e 100644
--- a/isisd/isis_circuit.h
+++ b/isisd/isis_circuit.h
@@ -122,6 +122,7 @@ struct isis_circuit {
*/
char *tag; /* area tag */
struct isis_passwd passwd; /* Circuit rx/tx password */
+ int is_type_config; /* configured circuit is type */
int is_type; /* circuit is type == level of circuit
* differentiated from circuit type (media) */
uint32_t hello_interval[ISIS_LEVELS]; /* hello-interval in seconds */
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index 195a3fcd2f..bf03d0a050 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -70,43 +70,12 @@ DEFPY_YANG_NOSH(router_isis, router_isis_cmd,
return ret;
}
-struct if_iter {
- struct vty *vty;
- const char *tag;
-};
-
-static int if_iter_cb(const struct lyd_node *dnode, void *arg)
-{
- struct if_iter *iter = arg;
- const char *tag;
-
- if (!yang_dnode_exists(dnode, "frr-isisd:isis/area-tag"))
- return YANG_ITER_CONTINUE;
-
- tag = yang_dnode_get_string(dnode, "frr-isisd:isis/area-tag");
- if (strmatch(tag, iter->tag)) {
- char xpath[XPATH_MAXLEN];
- const char *name = yang_dnode_get_string(dnode, "name");
- const char *vrf = yang_dnode_get_string(dnode, "vrf");
-
- snprintf(
- xpath, XPATH_MAXLEN,
- "/frr-interface:lib/interface[name='%s'][vrf='%s']/frr-isisd:isis",
- name, vrf);
- nb_cli_enqueue_change(iter->vty, xpath, NB_OP_DESTROY, NULL);
- }
-
- return YANG_ITER_CONTINUE;
-}
-
DEFPY_YANG(no_router_isis, no_router_isis_cmd,
"no router isis WORD$tag [vrf NAME$vrf_name]",
NO_STR ROUTER_STR
"ISO IS-IS\n"
"ISO Routing area tag\n" VRF_CMD_HELP_STR)
{
- struct if_iter iter;
-
if (!vrf_name)
vrf_name = VRF_DEFAULT_NAME;
@@ -118,12 +87,6 @@ DEFPY_YANG(no_router_isis, no_router_isis_cmd,
return CMD_ERR_NOTHING_TODO;
}
- iter.vty = vty;
- iter.tag = tag;
-
- yang_dnode_iterate(if_iter_cb, &iter, vty->candidate_config->dnode,
- "/frr-interface:lib/interface[vrf='%s']", vrf_name);
-
nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
return nb_cli_apply_changes_clear_pending(
@@ -164,45 +127,11 @@ DEFPY_YANG(ip_router_isis, ip_router_isis_cmd,
"IS-IS routing protocol\n"
"Routing process tag\n")
{
- char inst_xpath[XPATH_MAXLEN];
- const struct lyd_node *if_dnode, *inst_dnode;
- const char *circ_type = NULL;
- const char *vrf_name;
- struct interface *ifp;
-
- if_dnode = yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
- if (!if_dnode) {
- vty_out(vty, "%% Failed to get iface dnode in candidate DB\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vrf_name = yang_dnode_get_string(if_dnode, "vrf");
-
- snprintf(inst_xpath, XPATH_MAXLEN,
- "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag,
- vrf_name);
-
- /* if instance exists then inherit its type, create it otherwise */
- inst_dnode = yang_dnode_get(vty->candidate_config->dnode, inst_xpath);
- if (inst_dnode)
- circ_type = yang_dnode_get_string(inst_dnode, "is-type");
- else
- nb_cli_enqueue_change(vty, inst_xpath, NB_OP_CREATE, NULL);
-
nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE, NULL);
nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag", NB_OP_MODIFY,
tag);
nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv4-routing",
NB_OP_MODIFY, "true");
- if (circ_type)
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
- NB_OP_MODIFY, circ_type);
-
- /* check if the interface is a loopback and if so set it as passive */
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
- if (ifp && if_is_loopback_or_vrf(ifp))
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
- NB_OP_MODIFY, "true");
return nb_cli_apply_changes(vty, NULL);
}
@@ -221,45 +150,11 @@ DEFPY_YANG(ip6_router_isis, ip6_router_isis_cmd,
"IS-IS routing protocol\n"
"Routing process tag\n")
{
- char inst_xpath[XPATH_MAXLEN];
- const struct lyd_node *if_dnode, *inst_dnode;
- const char *circ_type = NULL;
- const char *vrf_name;
- struct interface *ifp;
-
- if_dnode = yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
- if (!if_dnode) {
- vty_out(vty, "%% Failed to get iface dnode in candidate DB\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vrf_name = yang_dnode_get_string(if_dnode, "vrf");
-
- snprintf(inst_xpath, XPATH_MAXLEN,
- "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag,
- vrf_name);
-
- /* if instance exists then inherit its type, create it otherwise */
- inst_dnode = yang_dnode_get(vty->candidate_config->dnode, inst_xpath);
- if (inst_dnode)
- circ_type = yang_dnode_get_string(inst_dnode, "is-type");
- else
- nb_cli_enqueue_change(vty, inst_xpath, NB_OP_CREATE, NULL);
-
nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE, NULL);
nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag", NB_OP_MODIFY,
tag);
nb_cli_enqueue_change(vty, "./frr-isisd:isis/ipv6-routing",
NB_OP_MODIFY, "true");
- if (circ_type)
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
- NB_OP_MODIFY, circ_type);
-
- /* check if the interface is a loopback and if so set it as passive */
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
- if (ifp && if_is_loopback_or_vrf(ifp))
- nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
- NB_OP_MODIFY, "true");
return nb_cli_apply_changes(vty, NULL);
}
@@ -1116,7 +1011,7 @@ void cli_show_isis_spf_ietf_backoff(struct vty *vty,
* XPath: /frr-isisd:isis/instance/spf/prefix-priorities/medium/access-list-name
*/
DEFPY_YANG(spf_prefix_priority, spf_prefix_priority_cmd,
- "spf prefix-priority <critical|high|medium>$priority WORD$acl_name",
+ "spf prefix-priority <critical|high|medium>$priority ACCESSLIST_NAME$acl_name",
"SPF configuration\n"
"Configure a prefix priority list\n"
"Specify critical priority prefixes\n"
@@ -1134,7 +1029,7 @@ DEFPY_YANG(spf_prefix_priority, spf_prefix_priority_cmd,
}
DEFPY_YANG(no_spf_prefix_priority, no_spf_prefix_priority_cmd,
- "no spf prefix-priority <critical|high|medium>$priority [WORD]",
+ "no spf prefix-priority <critical|high|medium>$priority [ACCESSLIST_NAME]",
NO_STR
"SPF configuration\n"
"Configure a prefix priority list\n"
@@ -2545,41 +2440,8 @@ DEFPY_YANG(no_isis_circuit_type, no_isis_circuit_type_cmd,
"Level-1-2 adjacencies are formed\n"
"Level-2 only adjacencies are formed\n")
{
- char inst_xpath[XPATH_MAXLEN];
- const struct lyd_node *if_dnode, *inst_dnode;
- const char *vrf_name;
- const char *tag;
- const char *circ_type = NULL;
-
- /*
- * Default value depends on whether the circuit is part of an area,
- * and the is-type of the area if there is one. So we need to do this
- * here.
- */
- if_dnode = yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
- if (!if_dnode) {
- vty_out(vty, "%% Failed to get iface dnode in candidate DB\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (!yang_dnode_exists(if_dnode, "frr-isisd:isis/area-tag")) {
- vty_out(vty, "%% ISIS is not configured on the interface\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- vrf_name = yang_dnode_get_string(if_dnode, "vrf");
- tag = yang_dnode_get_string(if_dnode, "frr-isisd:isis/area-tag");
-
- snprintf(inst_xpath, XPATH_MAXLEN,
- "/frr-isisd:isis/instance[area-tag='%s'][vrf='%s']", tag,
- vrf_name);
-
- inst_dnode = yang_dnode_get(vty->candidate_config->dnode, inst_xpath);
- if (inst_dnode)
- circ_type = yang_dnode_get_string(inst_dnode, "is-type");
-
nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
- NB_OP_MODIFY, circ_type);
+ NB_OP_MODIFY, NULL);
return nb_cli_apply_changes(vty, NULL);
}
diff --git a/isisd/isis_events.c b/isisd/isis_events.c
index 0b987fc5cf..26c68db762 100644
--- a/isisd/isis_events.c
+++ b/isisd/isis_events.c
@@ -128,7 +128,7 @@ static void circuit_resign_level(struct isis_circuit *circuit, int level)
void isis_circuit_is_type_set(struct isis_circuit *circuit, int newtype)
{
- if (circuit->state != C_STATE_UP) {
+ if (!circuit->area) {
circuit->is_type = newtype;
return;
}
@@ -151,6 +151,11 @@ void isis_circuit_is_type_set(struct isis_circuit *circuit, int newtype)
return;
}
+ if (circuit->state != C_STATE_UP) {
+ circuit->is_type = newtype;
+ return;
+ }
+
if (!circuit->is_passive) {
switch (circuit->is_type) {
case IS_LEVEL_1:
diff --git a/isisd/isis_ldp_sync.c b/isisd/isis_ldp_sync.c
index 62d8b8334a..9d494121c8 100644
--- a/isisd/isis_ldp_sync.c
+++ b/isisd/isis_ldp_sync.c
@@ -486,6 +486,9 @@ void isis_if_ldp_sync_enable(struct isis_circuit *circuit)
if (if_is_loopback(circuit->interface))
return;
+ if (circuit->interface->vrf->vrf_id != VRF_DEFAULT)
+ return;
+
ils_debug("ldp_sync: enable if %s", circuit->interface->name);
if (!CHECK_FLAG(area->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE))
diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c
index 4a01c728f0..07af46c04a 100644
--- a/isisd/isis_nb_config.c
+++ b/isisd/isis_nb_config.c
@@ -2526,31 +2526,12 @@ int lib_interface_isis_destroy(struct nb_cb_destroy_args *args)
int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args)
{
struct isis_circuit *circuit;
- struct interface *ifp;
- struct vrf *vrf;
- const char *area_tag, *ifname, *vrfname;
if (args->event == NB_EV_VALIDATE) {
- /* libyang doesn't like relative paths across module boundaries
- */
- ifname = yang_dnode_get_string(
- lyd_parent(lyd_parent(args->dnode)), "./name");
- vrfname = yang_dnode_get_string(
- lyd_parent(lyd_parent(args->dnode)), "./vrf");
- vrf = vrf_lookup_by_name(vrfname);
- assert(vrf);
- ifp = if_lookup_by_name(ifname, vrf->vrf_id);
-
- if (!ifp)
- return NB_OK;
-
- circuit = circuit_scan_by_ifp(ifp);
- area_tag = yang_dnode_get_string(args->dnode, NULL);
- if (circuit && circuit->area && circuit->area->area_tag
- && strcmp(circuit->area->area_tag, area_tag)) {
+ circuit = nb_running_get_entry_non_rec(lyd_parent(args->dnode), NULL, false);
+ if (circuit) {
snprintf(args->errmsg, args->errmsg_len,
- "ISIS circuit is already defined on %s",
- circuit->area->area_tag);
+ "Changing area tag is not allowed");
return NB_ERR_VALIDATION;
}
}
@@ -2565,39 +2546,15 @@ int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args)
{
int circ_type = yang_dnode_get_enum(args->dnode, NULL);
struct isis_circuit *circuit;
- struct interface *ifp;
- struct vrf *vrf;
- const char *ifname, *vrfname;
switch (args->event) {
case NB_EV_VALIDATE:
- /* libyang doesn't like relative paths across module boundaries
- */
- ifname = yang_dnode_get_string(
- lyd_parent(lyd_parent(args->dnode)), "./name");
- vrfname = yang_dnode_get_string(
- lyd_parent(lyd_parent(args->dnode)), "./vrf");
- vrf = vrf_lookup_by_name(vrfname);
- assert(vrf);
- ifp = if_lookup_by_name(ifname, vrf->vrf_id);
- if (!ifp)
- break;
-
- circuit = circuit_scan_by_ifp(ifp);
- if (circuit && circuit->state == C_STATE_UP
- && circuit->area->is_type != IS_LEVEL_1_AND_2
- && circuit->area->is_type != circ_type) {
- snprintf(args->errmsg, args->errmsg_len,
- "Invalid circuit level for area %s",
- circuit->area->area_tag);
- return NB_ERR_VALIDATION;
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
case NB_EV_APPLY:
circuit = nb_running_get_entry(args->dnode, NULL, true);
+ circuit->is_type_config = circ_type;
isis_circuit_is_type_set(circuit, circ_type);
break;
}
@@ -2979,24 +2936,8 @@ int lib_interface_isis_network_type_modify(struct nb_cb_modify_args *args)
int lib_interface_isis_passive_modify(struct nb_cb_modify_args *args)
{
struct isis_circuit *circuit;
- struct interface *ifp;
bool passive = yang_dnode_get_bool(args->dnode, NULL);
- /* validation only applies if we are setting passive to false */
- if (!passive && args->event == NB_EV_VALIDATE) {
- circuit = nb_running_get_entry(args->dnode, NULL, false);
- if (!circuit)
- return NB_OK;
- ifp = circuit->interface;
- if (!ifp)
- return NB_OK;
- if (if_is_loopback_or_vrf(ifp)) {
- snprintf(args->errmsg, args->errmsg_len,
- "Loopback is always passive");
- return NB_ERR_VALIDATION;
- }
- }
-
if (args->event != NB_EV_APPLY)
return NB_OK;
@@ -3204,19 +3145,9 @@ int lib_interface_isis_mpls_ldp_sync_modify(struct nb_cb_modify_args *args)
struct isis_circuit *circuit;
struct ldp_sync_info *ldp_sync_info;
bool ldp_sync_enable;
- const char *vrfname;
switch (args->event) {
case NB_EV_VALIDATE:
- vrfname = yang_dnode_get_string(
- lyd_parent(lyd_parent(lyd_parent(args->dnode))),
- "./vrf");
- if (strcmp(vrfname, VRF_DEFAULT_NAME)) {
- snprintf(args->errmsg, args->errmsg_len,
- "LDP-Sync only runs on Default VRF");
- return NB_ERR_VALIDATION;
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
@@ -3248,19 +3179,9 @@ int lib_interface_isis_mpls_holddown_modify(struct nb_cb_modify_args *args)
struct isis_circuit *circuit;
struct ldp_sync_info *ldp_sync_info;
uint16_t holddown;
- const char *vrfname;
switch (args->event) {
case NB_EV_VALIDATE:
- vrfname = yang_dnode_get_string(
- lyd_parent(lyd_parent(lyd_parent(args->dnode))),
- "./vrf");
- if (strcmp(vrfname, VRF_DEFAULT_NAME)) {
- snprintf(args->errmsg, args->errmsg_len,
- "LDP-Sync only runs on Default VRF");
- return NB_ERR_VALIDATION;
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
@@ -3281,19 +3202,9 @@ int lib_interface_isis_mpls_holddown_destroy(struct nb_cb_destroy_args *args)
{
struct isis_circuit *circuit;
struct ldp_sync_info *ldp_sync_info;
- const char *vrfname;
switch (args->event) {
case NB_EV_VALIDATE:
- vrfname = yang_dnode_get_string(
- lyd_parent(lyd_parent(lyd_parent(args->dnode))),
- "./vrf");
- if (strcmp(vrfname, VRF_DEFAULT_NAME)) {
- snprintf(args->errmsg, args->errmsg_len,
- "LDP-Sync only runs on Default VRF");
- return NB_ERR_VALIDATION;
- }
- break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 8c26a57bef..b33f272f56 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -2656,10 +2656,16 @@ void isis_area_is_type_set(struct isis_area *area, int is_type)
area->is_type = is_type;
- /* override circuit's is_type */
+ /*
+ * If area's IS type is strict Level-1 or Level-2, override circuit's
+ * IS type. Otherwise use circuit's configured IS type.
+ */
if (area->is_type != IS_LEVEL_1_AND_2) {
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
isis_circuit_is_type_set(circuit, is_type);
+ } else {
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
+ isis_circuit_is_type_set(circuit, circuit->is_type_config);
}
spftree_area_init(area);
diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c
index 9d3d1a606e..11d6930f06 100644
--- a/ldpd/ldp_vty_cmds.c
+++ b/ldpd/ldp_vty_cmds.c
@@ -253,7 +253,7 @@ DEFPY (ldp_allow_broken_lsps,
DEFPY (ldp_discovery_targeted_hello_accept,
ldp_discovery_targeted_hello_accept_cmd,
- "[no] discovery targeted-hello accept [from WORD$from_acl]",
+ "[no] discovery targeted-hello accept [from ACCESSLIST_NAME$from_acl]",
NO_STR
"Configure discovery parameters\n"
"LDP Targeted Hellos\n"
@@ -288,7 +288,7 @@ DEFPY (ldp_discovery_transport_address_ipv6,
DEFPY (ldp_label_local_advertise,
ldp_label_local_advertise_cmd,
- "[no] label local advertise [{to WORD$to_acl|for WORD$for_acl}]",
+ "[no] label local advertise [{to ACCESSLIST_NAME$to_acl|for ACCESSLIST_NAME$for_acl}]",
NO_STR
"Configure label control and policies\n"
"Configure local label control and policies\n"
@@ -303,7 +303,7 @@ DEFPY (ldp_label_local_advertise,
DEFPY (ldp_label_local_advertise_explicit_null,
ldp_label_local_advertise_explicit_null_cmd,
- "[no] label local advertise explicit-null [for WORD$for_acl]",
+ "[no] label local advertise explicit-null [for ACCESSLIST_NAME$for_acl]",
NO_STR
"Configure label control and policies\n"
"Configure local label control and policies\n"
@@ -317,7 +317,7 @@ DEFPY (ldp_label_local_advertise_explicit_null,
DEFPY (ldp_label_local_allocate,
ldp_label_local_allocate_cmd,
- "[no] label local allocate <host-routes$host_routes|for WORD$for_acl>",
+ "[no] label local allocate <host-routes$host_routes|for ACCESSLIST_NAME$for_acl>",
NO_STR
"Configure label control and policies\n"
"Configure local label control and policies\n"
@@ -331,7 +331,7 @@ DEFPY (ldp_label_local_allocate,
DEFPY (ldp_label_remote_accept,
ldp_label_remote_accept_cmd,
- "[no] label remote accept {from WORD$from_acl|for WORD$for_acl}",
+ "[no] label remote accept {from ACCESSLIST_NAME$from_acl|for ACCESSLIST_NAME$for_acl}",
NO_STR
"Configure label control and policies\n"
"Configure remote/peer label control and policies\n"
diff --git a/lib/atomlist.c b/lib/atomlist.c
index 3668b083d0..b7c9516a00 100644
--- a/lib/atomlist.c
+++ b/lib/atomlist.c
@@ -18,6 +18,8 @@
#include "config.h"
#endif
+#include <assert.h>
+
#include "atomlist.h"
void atomlist_add_head(struct atomlist_head *h, struct atomlist_item *item)
diff --git a/lib/elf_py.c b/lib/elf_py.c
index 1c306893ad..f230add695 100644
--- a/lib/elf_py.c
+++ b/lib/elf_py.c
@@ -636,6 +636,9 @@ static Elf_Scn *elf_find_addr(struct elffile *ef, uint64_t addr, size_t *idx)
Elf_Scn *scn = elf_getscn(ef->elf, i);
GElf_Shdr _shdr, *shdr = gelf_getshdr(scn, &_shdr);
+ /* virtual address is kinda meaningless for TLS sections */
+ if (shdr->sh_flags & SHF_TLS)
+ continue;
if (addr < shdr->sh_addr ||
addr >= shdr->sh_addr + shdr->sh_size)
continue;
diff --git a/lib/filter.c b/lib/filter.c
index 3a86fbce93..9c80808fe8 100644
--- a/lib/filter.c
+++ b/lib/filter.c
@@ -612,7 +612,7 @@ DEFUN (show_mac_access_list,
DEFUN (show_mac_access_list_name,
show_mac_access_list_name_cmd,
- "show mac access-list WORD",
+ "show mac access-list ACCESSLIST_MAC_NAME",
SHOW_STR
"mac access lists\n"
"List mac access lists\n"
@@ -635,7 +635,7 @@ DEFUN (show_ip_access_list,
DEFUN (show_ip_access_list_name,
show_ip_access_list_name_cmd,
- "show ip access-list WORD [json]",
+ "show ip access-list ACCESSLIST4_NAME [json]",
SHOW_STR
IP_STR
"List IP access lists\n"
@@ -661,7 +661,7 @@ DEFUN (show_ipv6_access_list,
DEFUN (show_ipv6_access_list_name,
show_ipv6_access_list_name_cmd,
- "show ipv6 access-list WORD [json]",
+ "show ipv6 access-list ACCESSLIST6_NAME [json]",
SHOW_STR
IPV6_STR
"List IPv6 access lists\n"
@@ -839,12 +839,62 @@ static void access_list_init_ipv4(void)
install_element(ENABLE_NODE, &show_ip_access_list_name_cmd);
}
+static void access_list_autocomplete_afi(afi_t afi, vector comps,
+ struct cmd_token *token)
+{
+ struct access_list *access;
+ struct access_list *next;
+ struct access_master *master;
+
+ master = access_master_get(afi);
+ if (master == NULL)
+ return;
+
+ for (access = master->str.head; access; access = next) {
+ next = access->next;
+ vector_set(comps, XSTRDUP(MTYPE_COMPLETION, access->name));
+ }
+}
+
static struct cmd_node access_ipv6_node = {
.name = "ipv6 access list",
.node = ACCESS_IPV6_NODE,
.prompt = "",
};
+static void access_list_autocomplete(vector comps, struct cmd_token *token)
+{
+ access_list_autocomplete_afi(AFI_IP, comps, token);
+ access_list_autocomplete_afi(AFI_IP6, comps, token);
+ access_list_autocomplete_afi(AFI_L2VPN, comps, token);
+}
+
+static void access_list4_autocomplete(vector comps, struct cmd_token *token)
+{
+ access_list_autocomplete_afi(AFI_IP, comps, token);
+}
+
+static void access_list6_autocomplete(vector comps, struct cmd_token *token)
+{
+ access_list_autocomplete_afi(AFI_IP6, comps, token);
+}
+
+static void access_list_mac_autocomplete(vector comps, struct cmd_token *token)
+{
+ access_list_autocomplete_afi(AFI_L2VPN, comps, token);
+}
+
+static const struct cmd_variable_handler access_list_handlers[] = {
+ {.tokenname = "ACCESSLIST_NAME",
+ .completions = access_list_autocomplete},
+ {.tokenname = "ACCESSLIST4_NAME",
+ .completions = access_list4_autocomplete},
+ {.tokenname = "ACCESSLIST6_NAME",
+ .completions = access_list6_autocomplete},
+ {.tokenname = "ACCESSLIST_MAC_NAME",
+ .completions = access_list_mac_autocomplete},
+ {.completions = NULL}};
+
static void access_list_reset_ipv6(void)
{
struct access_list *access;
@@ -874,6 +924,8 @@ static void access_list_init_ipv6(void)
void access_list_init(void)
{
+ cmd_variable_handler_register(access_list_handlers);
+
access_list_init_ipv4();
access_list_init_ipv6();
access_list_init_mac();
diff --git a/lib/filter_cli.c b/lib/filter_cli.c
index 43618094ac..fb40c527dd 100644
--- a/lib/filter_cli.c
+++ b/lib/filter_cli.c
@@ -822,7 +822,7 @@ DEFPY_YANG(
ALIAS(
no_ipv6_access_list_remark, no_ipv6_access_list_remark_line_cmd,
- "no ipv6 access-list WORD$name remark LINE...",
+ "no ipv6 access-list ACCESSLIST6_NAME$name remark LINE...",
NO_STR
IPV6_STR
ACCESS_LIST_STR
@@ -832,7 +832,7 @@ ALIAS(
DEFPY_YANG(
mac_access_list, mac_access_list_cmd,
- "mac access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X:X:X:X:X$mac|any>",
+ "mac access-list ACCESSLIST_MAC_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X:X:X:X:X$mac|any>",
MAC_STR
ACCESS_LIST_STR
ACCESS_LIST_ZEBRA_STR
@@ -898,7 +898,7 @@ DEFPY_YANG(
DEFPY_YANG(
no_mac_access_list, no_mac_access_list_cmd,
- "no mac access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X:X:X:X:X$mac|any>",
+ "no mac access-list ACCESSLIST_MAC_NAME$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X:X:X:X:X$mac|any>",
NO_STR
MAC_STR
ACCESS_LIST_STR
@@ -938,7 +938,7 @@ DEFPY_YANG(
DEFPY_YANG(
no_mac_access_list_all, no_mac_access_list_all_cmd,
- "no mac access-list WORD$name",
+ "no mac access-list ACCESSLIST_MAC_NAME$name",
NO_STR
MAC_STR
ACCESS_LIST_STR
@@ -955,7 +955,7 @@ DEFPY_YANG(
DEFPY_YANG(
mac_access_list_remark, mac_access_list_remark_cmd,
- "mac access-list WORD$name remark LINE...",
+ "mac access-list ACCESSLIST_MAC_NAME$name remark LINE...",
MAC_STR
ACCESS_LIST_STR
ACCESS_LIST_ZEBRA_STR
@@ -980,7 +980,7 @@ DEFPY_YANG(
DEFPY_YANG(
no_mac_access_list_remark, no_mac_access_list_remark_cmd,
- "no mac access-list WORD$name remark",
+ "no mac access-list ACCESSLIST_MAC_NAME$name remark",
NO_STR
MAC_STR
ACCESS_LIST_STR
@@ -1004,7 +1004,7 @@ DEFPY_YANG(
ALIAS(
no_mac_access_list_remark, no_mac_access_list_remark_line_cmd,
- "no mac access-list WORD$name remark LINE...",
+ "no mac access-list ACCESSLIST_MAC_NAME$name remark LINE...",
NO_STR
MAC_STR
ACCESS_LIST_STR
diff --git a/lib/frrcu.h b/lib/frrcu.h
index 3808259040..ae840926b5 100644
--- a/lib/frrcu.h
+++ b/lib/frrcu.h
@@ -17,6 +17,8 @@
#ifndef _FRRCU_H
#define _FRRCU_H
+#include <assert.h>
+
#include "memory.h"
#include "atomlist.h"
diff --git a/lib/log_vty.c b/lib/log_vty.c
index cbb8de8976..9911323553 100644
--- a/lib/log_vty.c
+++ b/lib/log_vty.c
@@ -36,6 +36,8 @@
DEFINE_HOOK(zlog_rotate, (), ());
DEFINE_HOOK(zlog_cli_show, (struct vty * vty), (vty));
+static unsigned logmsgs_with_persist_bt;
+
static const int log_default_lvl = LOG_DEBUG;
static int log_config_stdout_lvl = ZLOG_DISABLED;
@@ -267,6 +269,44 @@ DEFUN_HIDDEN (no_config_log_monitor,
return CMD_SUCCESS;
}
+DEFPY (debug_uid_backtrace,
+ debug_uid_backtrace_cmd,
+ "[no] debug unique-id UID backtrace",
+ NO_STR
+ DEBUG_STR
+ "Options per individual log message, by unique ID\n"
+ "Log message unique ID (XXXXX-XXXXX)\n"
+ "Add backtrace to log when message is printed\n")
+{
+ struct xrefdata search, *xrd;
+ struct xrefdata_logmsg *xrdl;
+ uint8_t flag;
+
+ strlcpy(search.uid, uid, sizeof(search.uid));
+ xrd = xrefdata_uid_find(&xrefdata_uid, &search);
+
+ if (!xrd) {
+ vty_out(vty, "%% no log message with ID \"%s\" found\n", uid);
+ return CMD_WARNING;
+ }
+ if (xrd->xref->type != XREFT_LOGMSG) {
+ vty_out(vty, "%% ID \"%s\" is not a log message\n", uid);
+ return CMD_WARNING;
+ }
+ xrdl = container_of(xrd, struct xrefdata_logmsg, xrefdata);
+
+ flag = (vty->node == CONFIG_NODE) ? LOGMSG_FLAG_PERSISTENT
+ : LOGMSG_FLAG_EPHEMERAL;
+
+ if ((xrdl->fl_print_bt & flag) == (no ? 0 : flag))
+ return CMD_SUCCESS;
+ if (flag == LOGMSG_FLAG_PERSISTENT)
+ logmsgs_with_persist_bt += no ? -1 : 1;
+
+ xrdl->fl_print_bt ^= flag;
+ return CMD_SUCCESS;
+}
+
static int set_log_file(struct zlog_cfg_file *target, struct vty *vty,
const char *fname, int loglevel)
{
@@ -751,6 +791,24 @@ void log_config_write(struct vty *vty)
vty_out(vty, "no log error-category\n");
if (!zlog_get_prefix_xid())
vty_out(vty, "no log unique-id\n");
+
+ if (logmsgs_with_persist_bt) {
+ struct xrefdata *xrd;
+ struct xrefdata_logmsg *xrdl;
+
+ vty_out(vty, "!\n");
+
+ frr_each (xrefdata_uid, &xrefdata_uid, xrd) {
+ if (xrd->xref->type != XREFT_LOGMSG)
+ continue;
+
+ xrdl = container_of(xrd, struct xrefdata_logmsg,
+ xrefdata);
+ if (xrdl->fl_print_bt & LOGMSG_FLAG_PERSISTENT)
+ vty_out(vty, "debug unique-id %s backtrace\n",
+ xrd->uid);
+ }
+ }
}
static int log_vty_init(const char *progname, const char *protoname,
@@ -801,4 +859,7 @@ void log_cmd_init(void)
install_element(CONFIG_NODE, &config_log_filterfile_cmd);
install_element(CONFIG_NODE, &no_config_log_filterfile_cmd);
install_element(CONFIG_NODE, &log_immediate_mode_cmd);
+
+ install_element(ENABLE_NODE, &debug_uid_backtrace_cmd);
+ install_element(CONFIG_NODE, &debug_uid_backtrace_cmd);
}
diff --git a/lib/resolver.c b/lib/resolver.c
index 4aba909f25..e3dba5f8ae 100644
--- a/lib/resolver.c
+++ b/lib/resolver.c
@@ -14,7 +14,8 @@
#include <ares.h>
#include <ares_version.h>
-#include "vector.h"
+#include "typesafe.h"
+#include "jhash.h"
#include "thread.h"
#include "lib_errors.h"
#include "resolver.h"
@@ -27,13 +28,78 @@ struct resolver_state {
ares_channel channel;
struct thread_master *master;
struct thread *timeout;
- vector read_threads, write_threads;
};
static struct resolver_state state;
static bool resolver_debug;
-#define THREAD_RUNNING ((struct thread *)-1)
+/* a FD doesn't necessarily map 1:1 to a request; we could be talking to
+ * multiple caches simultaneously, to see which responds fastest.
+ * Theoretically we could also be using the same fd for multiple lookups,
+ * but the c-ares API guarantees an n:1 mapping for fd => channel.
+ *
+ * Either way c-ares makes that decision and we just need to deal with
+ * whatever FDs it gives us.
+ */
+
+DEFINE_MTYPE_STATIC(LIB, ARES_FD, "c-ares (DNS) file descriptor information");
+PREDECL_HASH(resolver_fds);
+
+struct resolver_fd {
+ struct resolver_fds_item itm;
+
+ int fd;
+ struct resolver_state *state;
+ struct thread *t_read, *t_write;
+};
+
+static int resolver_fd_cmp(const struct resolver_fd *a,
+ const struct resolver_fd *b)
+{
+ return numcmp(a->fd, b->fd);
+}
+
+static uint32_t resolver_fd_hash(const struct resolver_fd *item)
+{
+ return jhash_1word(item->fd, 0xacd04c9e);
+}
+
+DECLARE_HASH(resolver_fds, struct resolver_fd, itm, resolver_fd_cmp,
+ resolver_fd_hash);
+
+static struct resolver_fds_head resfds[1] = {INIT_HASH(resfds[0])};
+
+static struct resolver_fd *resolver_fd_get(int fd,
+ struct resolver_state *newstate)
+{
+ struct resolver_fd ref = {.fd = fd}, *res;
+
+ res = resolver_fds_find(resfds, &ref);
+ if (!res && newstate) {
+ res = XCALLOC(MTYPE_ARES_FD, sizeof(*res));
+ res->fd = fd;
+ res->state = newstate;
+ resolver_fds_add(resfds, res);
+
+ if (resolver_debug)
+ zlog_debug("c-ares registered FD %d", fd);
+ }
+ return res;
+}
+
+static void resolver_fd_drop_maybe(struct resolver_fd *resfd)
+{
+ if (resfd->t_read || resfd->t_write)
+ return;
+
+ if (resolver_debug)
+ zlog_debug("c-ares unregistered FD %d", resfd->fd);
+
+ resolver_fds_del(resfds, resfd);
+ XFREE(MTYPE_ARES_FD, resfd);
+}
+
+/* end of FD housekeeping */
static void resolver_update_timeouts(struct resolver_state *r);
@@ -41,9 +107,7 @@ static int resolver_cb_timeout(struct thread *t)
{
struct resolver_state *r = THREAD_ARG(t);
- r->timeout = THREAD_RUNNING;
ares_process(r->channel, NULL, NULL);
- r->timeout = NULL;
resolver_update_timeouts(r);
return 0;
@@ -51,17 +115,16 @@ static int resolver_cb_timeout(struct thread *t)
static int resolver_cb_socket_readable(struct thread *t)
{
- struct resolver_state *r = THREAD_ARG(t);
- int fd = THREAD_FD(t);
- struct thread **t_ptr;
-
- vector_set_index(r->read_threads, fd, THREAD_RUNNING);
- ares_process_fd(r->channel, fd, ARES_SOCKET_BAD);
- if (vector_lookup(r->read_threads, fd) == THREAD_RUNNING) {
- t_ptr = (struct thread **)vector_get_index(r->read_threads, fd);
- thread_add_read(r->master, resolver_cb_socket_readable, r, fd,
- t_ptr);
- }
+ struct resolver_fd *resfd = THREAD_ARG(t);
+ struct resolver_state *r = resfd->state;
+
+ thread_add_read(r->master, resolver_cb_socket_readable, resfd,
+ resfd->fd, &resfd->t_read);
+ /* ^ ordering important:
+ * ares_process_fd may transitively call THREAD_OFF(resfd->t_read)
+ * combined with resolver_fd_drop_maybe, so resfd may be free'd after!
+ */
+ ares_process_fd(r->channel, resfd->fd, ARES_SOCKET_BAD);
resolver_update_timeouts(r);
return 0;
@@ -69,17 +132,16 @@ static int resolver_cb_socket_readable(struct thread *t)
static int resolver_cb_socket_writable(struct thread *t)
{
- struct resolver_state *r = THREAD_ARG(t);
- int fd = THREAD_FD(t);
- struct thread **t_ptr;
-
- vector_set_index(r->write_threads, fd, THREAD_RUNNING);
- ares_process_fd(r->channel, ARES_SOCKET_BAD, fd);
- if (vector_lookup(r->write_threads, fd) == THREAD_RUNNING) {
- t_ptr = (struct thread **)vector_get_index(r->write_threads, fd);
- thread_add_write(r->master, resolver_cb_socket_writable, r, fd,
- t_ptr);
- }
+ struct resolver_fd *resfd = THREAD_ARG(t);
+ struct resolver_state *r = resfd->state;
+
+ thread_add_write(r->master, resolver_cb_socket_writable, resfd,
+ resfd->fd, &resfd->t_write);
+ /* ^ ordering important:
+ * ares_process_fd may transitively call THREAD_OFF(resfd->t_write)
+ * combined with resolver_fd_drop_maybe, so resfd may be free'd after!
+ */
+ ares_process_fd(r->channel, ARES_SOCKET_BAD, resfd->fd);
resolver_update_timeouts(r);
return 0;
@@ -89,13 +151,11 @@ static void resolver_update_timeouts(struct resolver_state *r)
{
struct timeval *tv, tvbuf;
- if (r->timeout == THREAD_RUNNING)
- return;
-
THREAD_OFF(r->timeout);
tv = ares_timeout(r->channel, NULL, &tvbuf);
if (tv) {
unsigned int timeoutms = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+
thread_add_timer_msec(r->master, resolver_cb_timeout, r,
timeoutms, &r->timeout);
}
@@ -105,43 +165,27 @@ static void ares_socket_cb(void *data, ares_socket_t fd, int readable,
int writable)
{
struct resolver_state *r = (struct resolver_state *)data;
- struct thread *t, **t_ptr;
-
- if (readable) {
- t = vector_lookup(r->read_threads, fd);
- if (!t) {
- t_ptr = (struct thread **)vector_get_index(
- r->read_threads, fd);
- thread_add_read(r->master, resolver_cb_socket_readable,
- r, fd, t_ptr);
- }
- } else {
- t = vector_lookup(r->read_threads, fd);
- if (t) {
- if (t != THREAD_RUNNING) {
- THREAD_OFF(t);
- }
- vector_unset(r->read_threads, fd);
- }
- }
+ struct resolver_fd *resfd;
- if (writable) {
- t = vector_lookup(r->write_threads, fd);
- if (!t) {
- t_ptr = (struct thread **)vector_get_index(
- r->write_threads, fd);
- thread_add_read(r->master, resolver_cb_socket_writable,
- r, fd, t_ptr);
- }
- } else {
- t = vector_lookup(r->write_threads, fd);
- if (t) {
- if (t != THREAD_RUNNING) {
- THREAD_OFF(t);
- }
- vector_unset(r->write_threads, fd);
- }
- }
+ resfd = resolver_fd_get(fd, (readable || writable) ? r : NULL);
+ if (!resfd)
+ return;
+
+ assert(resfd->state == r);
+
+ if (!readable)
+ THREAD_OFF(resfd->t_read);
+ else if (!resfd->t_read)
+ thread_add_read(r->master, resolver_cb_socket_readable, resfd,
+ fd, &resfd->t_read);
+
+ if (!writable)
+ THREAD_OFF(resfd->t_write);
+ else if (!resfd->t_write)
+ thread_add_write(r->master, resolver_cb_socket_writable, resfd,
+ fd, &resfd->t_write);
+
+ resolver_fd_drop_maybe(resfd);
}
@@ -271,8 +315,6 @@ void resolver_init(struct thread_master *tm)
struct ares_options ares_opts;
state.master = tm;
- state.read_threads = vector_init(1);
- state.write_threads = vector_init(1);
ares_opts = (struct ares_options){
.sock_state_cb = &ares_socket_cb,
diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c
index 918a2ebdcb..d7d4a9a81f 100644
--- a/lib/routemap_cli.c
+++ b/lib/routemap_cli.c
@@ -166,7 +166,7 @@ DEFPY_YANG(
DEFPY_YANG(
match_ip_address, match_ip_address_cmd,
- "match ip address WORD$name",
+ "match ip address ACCESSLIST4_NAME$name",
MATCH_STR
IP_STR
"Match address of route\n"
@@ -186,7 +186,7 @@ DEFPY_YANG(
DEFPY_YANG(
no_match_ip_address, no_match_ip_address_cmd,
- "no match ip address [WORD]",
+ "no match ip address [ACCESSLIST4_NAME]",
NO_STR
MATCH_STR
IP_STR
@@ -243,7 +243,7 @@ DEFPY_YANG(
DEFPY_YANG(
match_ip_next_hop, match_ip_next_hop_cmd,
- "match ip next-hop WORD$name",
+ "match ip next-hop ACCESSLIST4_NAME$name",
MATCH_STR
IP_STR
"Match next-hop address of route\n"
@@ -263,7 +263,7 @@ DEFPY_YANG(
DEFPY_YANG(
no_match_ip_next_hop, no_match_ip_next_hop_cmd,
- "no match ip next-hop [WORD]",
+ "no match ip next-hop [ACCESSLIST4_NAME]",
NO_STR
MATCH_STR
IP_STR
@@ -358,7 +358,7 @@ DEFPY_YANG(
DEFPY_YANG(
match_ipv6_address, match_ipv6_address_cmd,
- "match ipv6 address WORD$name",
+ "match ipv6 address ACCESSLIST6_NAME$name",
MATCH_STR
IPV6_STR
"Match IPv6 address of route\n"
@@ -378,7 +378,7 @@ DEFPY_YANG(
DEFPY_YANG(
no_match_ipv6_address, no_match_ipv6_address_cmd,
- "no match ipv6 address [WORD]",
+ "no match ipv6 address [ACCESSLIST6_NAME]",
NO_STR
MATCH_STR
IPV6_STR
diff --git a/lib/typerb.h b/lib/typerb.h
index d22d864aae..75a1de77b3 100644
--- a/lib/typerb.h
+++ b/lib/typerb.h
@@ -20,6 +20,7 @@
#ifndef _FRR_TYPERB_H
#define _FRR_TYPERB_H
+#include <string.h>
#include "typesafe.h"
#ifdef __cplusplus
diff --git a/lib/typesafe.c b/lib/typesafe.c
index f90b59daf0..3b65a2d02a 100644
--- a/lib/typesafe.c
+++ b/lib/typesafe.c
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
#include "typesafe.h"
#include "memory.h"
diff --git a/lib/typesafe.h b/lib/typesafe.h
index 44c42ffbca..b284397d98 100644
--- a/lib/typesafe.h
+++ b/lib/typesafe.h
@@ -20,7 +20,6 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
-#include <assert.h>
#include "compiler.h"
#ifdef __cplusplus
diff --git a/lib/vector.c b/lib/vector.c
index 38f9b1b85f..5497c24280 100644
--- a/lib/vector.c
+++ b/lib/vector.c
@@ -136,17 +136,6 @@ int vector_set_index(vector v, unsigned int i, void *val)
return i;
}
-/* Make a specified index slot active and return its address. */
-void **vector_get_index(vector v, unsigned int i)
-{
- vector_ensure(v, i);
-
- if (v->active <= i)
- v->active = i + 1;
-
- return &v->index[i];
-}
-
/* Look up vector. */
void *vector_lookup(vector v, unsigned int i)
{
diff --git a/lib/vector.h b/lib/vector.h
index 6208be1cc7..71c497a1b7 100644
--- a/lib/vector.h
+++ b/lib/vector.h
@@ -55,7 +55,6 @@ extern void vector_ensure(vector v, unsigned int num);
extern int vector_empty_slot(vector v);
extern int vector_set(vector v, void *val);
extern int vector_set_index(vector v, unsigned int i, void *val);
-extern void **vector_get_index(vector v, unsigned int i);
extern void vector_unset(vector v, unsigned int i);
extern void vector_unset_value(vector v, void *val);
extern void vector_remove(vector v, unsigned int ix);
diff --git a/lib/xref.c b/lib/xref.c
index a41f91a228..0d3549d062 100644
--- a/lib/xref.c
+++ b/lib/xref.c
@@ -35,6 +35,8 @@
struct xref_block *xref_blocks;
static struct xref_block **xref_block_last = &xref_blocks;
+struct xrefdata_uid_head xrefdata_uid = INIT_RBTREE_UNIQ(xrefdata_uid);
+
static void base32(uint8_t **inpos, int *bitpos,
char *out, size_t n_chars)
{
@@ -109,6 +111,8 @@ static void xref_add_one(const struct xref *xref)
base32(&h, &bitpos, &xrefdata->uid[0], 5);
xrefdata->uid[5] = '-';
base32(&h, &bitpos, &xrefdata->uid[6], 5);
+
+ xrefdata_uid_add(&xrefdata_uid, xrefdata);
}
void xref_gcc_workaround(const struct xref *xref)
diff --git a/lib/xref.h b/lib/xref.h
index 6cff1a3769..0e3f00f690 100644
--- a/lib/xref.h
+++ b/lib/xref.h
@@ -22,6 +22,7 @@
#include <limits.h>
#include <errno.h>
#include "compiler.h"
+#include "typesafe.h"
#ifdef __cplusplus
extern "C" {
@@ -63,6 +64,8 @@ struct xref {
/* type-specific bits appended by embedding this struct */
};
+PREDECL_RBTREE_UNIQ(xrefdata_uid);
+
struct xrefdata {
/* pointer back to the const part; this will be initialized at
* program startup by xref_block_add(). (Creating structs with
@@ -88,8 +91,18 @@ struct xrefdata {
uint32_t hashu32[2];
/* -- 32 bytes (on 64bit) -- */
+ struct xrefdata_uid_item xui;
};
+static inline int xrefdata_uid_cmp(const struct xrefdata *a,
+ const struct xrefdata *b)
+{
+ return strcmp(a->uid, b->uid);
+}
+
+DECLARE_RBTREE_UNIQ(xrefdata_uid, struct xrefdata, xui, xrefdata_uid_cmp);
+extern struct xrefdata_uid_head xrefdata_uid;
+
/* linker "magic" is used to create an array of pointers to struct xref.
* the result is a contiguous block of pointers, each pointing to an xref
* somewhere in the code. The linker gives us start and end pointers, we
diff --git a/lib/zlog.c b/lib/zlog.c
index 6fd52cae62..1b0751559d 100644
--- a/lib/zlog.c
+++ b/lib/zlog.c
@@ -47,12 +47,19 @@
#include <mach/mach_traps.h>
#endif
+#ifdef HAVE_LIBUNWIND
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+#include <dlfcn.h>
+#endif
+
#include "memory.h"
#include "atomlist.h"
#include "printfrr.h"
#include "frrcu.h"
#include "zlog.h"
#include "libfrr_trace.h"
+#include "thread.h"
DEFINE_MTYPE_STATIC(LIB, LOG_MESSAGE, "log message");
DEFINE_MTYPE_STATIC(LIB, LOG_TLSBUF, "log thread-local buffer");
@@ -508,6 +515,87 @@ static void vzlog_tls(struct zlog_tls *zlog_tls, const struct xref_logmsg *xref,
XFREE(MTYPE_LOG_MESSAGE, msg->text);
}
+static void zlog_backtrace_msg(const struct xref_logmsg *xref, int prio)
+{
+ struct thread *tc = pthread_getspecific(thread_current);
+ const char *uid = xref->xref.xrefdata->uid;
+ bool found_thread = false;
+
+ zlog(prio, "| (%s) message in thread %jd, at %s(), %s:%d", uid,
+ zlog_gettid(), xref->xref.func, xref->xref.file, xref->xref.line);
+
+#ifdef HAVE_LIBUNWIND
+ const char *threadfunc = tc ? tc->xref->funcname : NULL;
+ bool found_caller = false;
+ unw_cursor_t cursor;
+ unw_context_t uc;
+ unw_word_t ip, off, sp;
+ Dl_info dlinfo;
+
+ unw_getcontext(&uc);
+
+ unw_init_local(&cursor, &uc);
+ while (unw_step(&cursor) > 0) {
+ char buf[96], name[128] = "?";
+ bool is_thread = false;
+
+ unw_get_reg(&cursor, UNW_REG_IP, &ip);
+ unw_get_reg(&cursor, UNW_REG_SP, &sp);
+
+ if (unw_is_signal_frame(&cursor))
+ zlog(prio, "| (%s) ---- signal ----", uid);
+
+ if (!unw_get_proc_name(&cursor, buf, sizeof(buf), &off)) {
+ if (!strcmp(buf, xref->xref.func))
+ found_caller = true;
+ if (threadfunc && !strcmp(buf, threadfunc))
+ found_thread = is_thread = true;
+
+ snprintf(name, sizeof(name), "%s+%#lx", buf, (long)off);
+ }
+
+ if (!found_caller)
+ continue;
+
+ if (dladdr((void *)ip, &dlinfo))
+ zlog(prio, "| (%s) %-36s %16lx+%08lx %16lx %s", uid,
+ name, (long)dlinfo.dli_fbase,
+ (long)ip - (long)dlinfo.dli_fbase, (long)sp,
+ dlinfo.dli_fname);
+ else
+ zlog(prio, "| (%s) %-36s %16lx %16lx", uid, name,
+ (long)ip, (long)sp);
+
+ if (is_thread)
+ zlog(prio, "| (%s) ^- scheduled from %s(), %s:%u", uid,
+ tc->xref->xref.func, tc->xref->xref.file,
+ tc->xref->xref.line);
+ }
+#elif defined(HAVE_GLIBC_BACKTRACE)
+ void *frames[64];
+ char **names = NULL;
+ int n_frames, i;
+
+ n_frames = backtrace(frames, array_size(frames));
+ if (n_frames < 0)
+ n_frames = 0;
+ if (n_frames)
+ names = backtrace_symbols(frames, n_frames);
+
+ for (i = 0; i < n_frames; i++) {
+ void *retaddr = frames[i];
+ char *loc = names[i];
+
+ zlog(prio, "| (%s) %16lx %-36s", uid, (long)retaddr, loc);
+ }
+ free(names);
+#endif
+ if (!found_thread && tc)
+ zlog(prio, "| (%s) scheduled from %s(), %s:%u", uid,
+ tc->xref->xref.func, tc->xref->xref.file,
+ tc->xref->xref.line);
+}
+
void vzlogx(const struct xref_logmsg *xref, int prio,
const char *fmt, va_list ap)
{
@@ -545,6 +633,15 @@ void vzlogx(const struct xref_logmsg *xref, int prio,
vzlog_tls(zlog_tls, xref, prio, fmt, ap);
else
vzlog_notls(xref, prio, fmt, ap);
+
+ if (xref) {
+ struct xrefdata_logmsg *xrdl;
+
+ xrdl = container_of(xref->xref.xrefdata, struct xrefdata_logmsg,
+ xrefdata);
+ if (xrdl->fl_print_bt)
+ zlog_backtrace_msg(xref, prio);
+ }
}
void zlog_sigsafe(const char *text, size_t len)
diff --git a/lib/zlog.h b/lib/zlog.h
index d9c8952ac5..6e84fe8923 100644
--- a/lib/zlog.h
+++ b/lib/zlog.h
@@ -54,10 +54,14 @@ struct xref_logmsg {
const char *args;
};
+/* whether flag was added in config mode or enable mode */
+#define LOGMSG_FLAG_EPHEMERAL (1 << 0)
+#define LOGMSG_FLAG_PERSISTENT (1 << 1)
+
struct xrefdata_logmsg {
struct xrefdata xrefdata;
- /* nothing more here right now */
+ uint8_t fl_print_bt;
};
/* These functions are set up to write to stdout/stderr without explicit
@@ -94,15 +98,19 @@ static inline void zlog_ref(const struct xref_logmsg *xref,
#define _zlog_ecref(ec_, prio, msg, ...) \
do { \
- static struct xrefdata _xrefdata = { \
- .xref = NULL, \
- .uid = {}, \
- .hashstr = (msg), \
- .hashu32 = {(prio), (ec_)}, \
+ static struct xrefdata_logmsg _xrefdata = { \
+ .xrefdata = \
+ { \
+ .xref = NULL, \
+ .uid = {}, \
+ .hashstr = (msg), \
+ .hashu32 = {(prio), (ec_)}, \
+ }, \
}; \
static const struct xref_logmsg _xref __attribute__( \
(used)) = { \
- .xref = XREF_INIT(XREFT_LOGMSG, &_xrefdata, __func__), \
+ .xref = XREF_INIT(XREFT_LOGMSG, &_xrefdata.xrefdata, \
+ __func__), \
.fmtstring = (msg), \
.priority = (prio), \
.ec = (ec_), \
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index 6caee259b6..f35971ba8c 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -879,12 +879,12 @@ void ospf6_plist_update(struct prefix_list *plist)
DEFUN (area_import_list,
area_import_list_cmd,
- "area <A.B.C.D|(0-4294967295)> import-list NAME",
+ "area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST6_NAME",
"OSPF6 area parameters\n"
"OSPF6 area ID in IP address format\n"
"OSPF6 area ID as a decimal value\n"
"Set the filter for networks from other areas announced to the specified one\n"
- "Name of the acess-list\n")
+ "Name of the access-list\n")
{
int idx_ipv4 = 1;
int idx_name = 3;
@@ -911,7 +911,7 @@ DEFUN (area_import_list,
DEFUN (no_area_import_list,
no_area_import_list_cmd,
- "no area <A.B.C.D|(0-4294967295)> import-list NAME",
+ "no area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST6_NAME",
NO_STR
"OSPF6 area parameters\n"
"OSPF6 area ID in IP address format\n"
@@ -940,12 +940,12 @@ DEFUN (no_area_import_list,
DEFUN (area_export_list,
area_export_list_cmd,
- "area <A.B.C.D|(0-4294967295)> export-list NAME",
+ "area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST6_NAME",
"OSPF6 area parameters\n"
"OSPF6 area ID in IP address format\n"
"OSPF6 area ID as a decimal value\n"
"Set the filter for networks announced to other areas\n"
- "Name of the acess-list\n")
+ "Name of the access-list\n")
{
int idx_ipv4 = 1;
int idx_name = 3;
@@ -974,7 +974,7 @@ DEFUN (area_export_list,
DEFUN (no_area_export_list,
no_area_export_list_cmd,
- "no area <A.B.C.D|(0-4294967295)> export-list NAME",
+ "no area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST6_NAME",
NO_STR
"OSPF6 area parameters\n"
"OSPF6 area ID in IP address format\n"
diff --git a/ospf6d/ospf6_gr.h b/ospf6d/ospf6_gr.h
index 6406e8efee..28798d8717 100644
--- a/ospf6d/ospf6_gr.h
+++ b/ospf6d/ospf6_gr.h
@@ -93,7 +93,7 @@ struct tlv_header {
#define TLV_BODY_SIZE(tlvh) (ROUNDUP(ntohs((tlvh)->length), sizeof(uint32_t)))
-#define TLV_SIZE(tlvh) (TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh))
+#define TLV_SIZE(tlvh) (uint32_t)(TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh))
#define TLV_HDR_TOP(lsah) \
(struct tlv_header *)((char *)(lsah) + OSPF6_LSA_HEADER_SIZE)
diff --git a/ospf6d/ospf6_gr_helper.c b/ospf6d/ospf6_gr_helper.c
index 78f842db6c..4dc2d8af83 100644
--- a/ospf6d/ospf6_gr_helper.c
+++ b/ospf6d/ospf6_gr_helper.c
@@ -157,8 +157,18 @@ static int ospf6_extract_grace_lsa_fields(struct ospf6_lsa *lsa,
length = ntohs(lsah->length) - OSPF6_LSA_HEADER_SIZE;
- for (tlvh = TLV_HDR_TOP(lsah); sum < length;
+ for (tlvh = TLV_HDR_TOP(lsah); sum < length && tlvh;
tlvh = TLV_HDR_NEXT(tlvh)) {
+
+ /* Check TLV len against overall LSA */
+ if (sum + TLV_SIZE(tlvh) > length) {
+ if (IS_DEBUG_OSPF6_GR)
+ zlog_debug(
+ "%s: Malformed packet: Invalid TLV len:%d",
+ __func__, TLV_SIZE(tlvh));
+ return OSPF6_FAILURE;
+ }
+
switch (ntohs(tlvh->type)) {
case GRACE_PERIOD_TYPE:
gracePeriod = (struct grace_tlv_graceperiod *)tlvh;
@@ -1235,8 +1245,20 @@ static int ospf6_grace_lsa_show_info(struct vty *vty, struct ospf6_lsa *lsa,
zlog_debug(" TLV info:");
}
- for (tlvh = TLV_HDR_TOP(lsah); sum < length;
+ for (tlvh = TLV_HDR_TOP(lsah); sum < length && tlvh;
tlvh = TLV_HDR_NEXT(tlvh)) {
+
+ /* Check TLV len */
+ if (sum + TLV_SIZE(tlvh) > length) {
+ if (vty)
+ vty_out(vty, "%% Invalid TLV length: %d\n",
+ TLV_SIZE(tlvh));
+ else if (IS_DEBUG_OSPF6_GR)
+ zlog_debug("%% Invalid TLV length: %d",
+ TLV_SIZE(tlvh));
+ return OSPF6_FAILURE;
+ }
+
switch (ntohs(tlvh->type)) {
case GRACE_PERIOD_TYPE:
gracePeriod = (struct grace_tlv_graceperiod *)tlvh;
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index bbb458d8ef..e7f18ae79c 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -1775,7 +1775,7 @@ DEFUN (no_ospf_area_default_cost,
DEFUN (ospf_area_export_list,
ospf_area_export_list_cmd,
- "area <A.B.C.D|(0-4294967295)> export-list NAME",
+ "area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST4_NAME",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
@@ -1799,7 +1799,7 @@ DEFUN (ospf_area_export_list,
DEFUN (no_ospf_area_export_list,
no_ospf_area_export_list_cmd,
- "no area <A.B.C.D|(0-4294967295)> export-list NAME",
+ "no area <A.B.C.D|(0-4294967295)> export-list ACCESSLIST4_NAME",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
@@ -1827,7 +1827,7 @@ DEFUN (no_ospf_area_export_list,
DEFUN (ospf_area_import_list,
ospf_area_import_list_cmd,
- "area <A.B.C.D|(0-4294967295)> import-list NAME",
+ "area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST4_NAME",
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
"OSPF area ID as a decimal value\n"
@@ -1851,7 +1851,7 @@ DEFUN (ospf_area_import_list,
DEFUN (no_ospf_area_import_list,
no_ospf_area_import_list_cmd,
- "no area <A.B.C.D|(0-4294967295)> import-list NAME",
+ "no area <A.B.C.D|(0-4294967295)> import-list ACCESSLIST4_NAME",
NO_STR
"OSPF area parameters\n"
"OSPF area ID in IP address format\n"
@@ -9347,7 +9347,7 @@ DEFUN (no_ospf_redistribute_instance_source,
DEFUN (ospf_distribute_list_out,
ospf_distribute_list_out_cmd,
- "distribute-list WORD out " FRR_REDIST_STR_OSPFD,
+ "distribute-list ACCESSLIST4_NAME out " FRR_REDIST_STR_OSPFD,
"Filter networks in routing updates\n"
"Access-list name\n"
OUT_STR
@@ -9369,7 +9369,7 @@ DEFUN (ospf_distribute_list_out,
DEFUN (no_ospf_distribute_list_out,
no_ospf_distribute_list_out_cmd,
- "no distribute-list WORD out " FRR_REDIST_STR_OSPFD,
+ "no distribute-list ACCESSLIST4_NAME out " FRR_REDIST_STR_OSPFD,
NO_STR
"Filter networks in routing updates\n"
"Access-list name\n"
@@ -9863,161 +9863,10 @@ DEFUN (no_ospf_proactive_arp,
return CMD_SUCCESS;
}
-/* Graceful Restart HELPER Commands */
-DEFPY(ospf_gr_helper_enable, ospf_gr_helper_enable_cmd,
- "graceful-restart helper enable [A.B.C.D$address]",
- "OSPF Graceful Restart\n"
- "OSPF GR Helper\n"
- "Enable Helper support\n"
- "Advertising Router-ID\n")
-{
- VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
-
- if (address_str) {
- ospf_gr_helper_support_set_per_routerid(ospf, &address,
- OSPF_GR_TRUE);
- return CMD_SUCCESS;
- }
-
- ospf_gr_helper_support_set(ospf, OSPF_GR_TRUE);
-
- return CMD_SUCCESS;
-}
-
-DEFPY(no_ospf_gr_helper_enable,
- no_ospf_gr_helper_enable_cmd,
- "no graceful-restart helper enable [A.B.C.D$address]",
- NO_STR
- "OSPF Graceful Restart\n"
- "OSPF GR Helper\n"
- "Enable Helper support\n"
- "Advertising Router-ID\n")
-{
- VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
-
- if (address_str) {
- ospf_gr_helper_support_set_per_routerid(ospf, &address,
- OSPF_GR_FALSE);
- return CMD_SUCCESS;
- }
-
- ospf_gr_helper_support_set(ospf, OSPF_GR_FALSE);
- return CMD_SUCCESS;
-}
-
-#if CONFDATE > 20220921
-CPP_NOTICE(
- "Time to remove the deprecated \"[no] graceful-restart helper-only\" commands")
+#if CONFDATE > 20211209
+CPP_NOTICE("Time to remove broken OSPF GR helper")
#endif
-DEFPY_HIDDEN(ospf_gr_helper_only, ospf_gr_helper_only_cmd,
- "graceful-restart helper-only [A.B.C.D]",
- "OSPF Graceful Restart\n"
- "Enable Helper support\n"
- "Advertising router id\n")
-{
- VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
- struct in_addr addr;
- int ret;
-
- vty_out(vty,
- "%% This command is deprecated. Please, use `graceful-restart helper enable` instead.\n");
-
- if (argc == 3) {
- ret = inet_aton(argv[2]->arg, &addr);
- if (!ret) {
- vty_out(vty,
- "Please specify the valid routerid address.\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- ospf_gr_helper_support_set_per_routerid(ospf, &addr, OSPF_GR_TRUE);
- return CMD_SUCCESS;
- }
-
- ospf_gr_helper_support_set(ospf, OSPF_GR_TRUE);
-
- return CMD_SUCCESS;
-}
-
-ALIAS_HIDDEN(no_ospf_gr_helper_enable,
- no_ospf_gr_helper_only_cmd,
- "no graceful-restart helper-only [A.B.C.D]",
- NO_STR
- "OSPF Graceful Restart\n"
- "Disable Helper support\n"
- "Advertising router id\n")
-
-DEFPY(ospf_gr_helper_enable_lsacheck,
- ospf_gr_helper_enable_lsacheck_cmd,
- "graceful-restart helper strict-lsa-checking",
- "OSPF Graceful Restart\n"
- "OSPF GR Helper\n"
- "Enable strict LSA check\n")
-{
- VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
-
- ospf_gr_helper_lsa_check_set(ospf, OSPF_GR_TRUE);
- return CMD_SUCCESS;
-}
-
-DEFPY(no_ospf_gr_helper_enable_lsacheck,
- no_ospf_gr_helper_enable_lsacheck_cmd,
- "no graceful-restart helper strict-lsa-checking",
- NO_STR
- "OSPF Graceful Restart\n"
- "OSPF GR Helper\n"
- "Disable strict LSA check\n")
-{
- VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
-
- ospf_gr_helper_lsa_check_set(ospf, OSPF_GR_FALSE);
- return CMD_SUCCESS;
-}
-
-DEFPY(ospf_gr_helper_supported_grace_time,
- ospf_gr_helper_supported_grace_time_cmd,
- "graceful-restart helper supported-grace-time (10-1800)$interval",
- "OSPF Graceful Restart\n"
- "OSPF GR Helper\n"
- "Supported grace timer\n"
- "Grace interval(in seconds)\n")
-{
- VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
-
- ospf_gr_helper_supported_gracetime_set(ospf, interval);
- return CMD_SUCCESS;
-}
-
-DEFPY(no_ospf_gr_helper_supported_grace_time,
- no_ospf_gr_helper_supported_grace_time_cmd,
- "no graceful-restart helper supported-grace-time (10-1800)$interval",
- NO_STR
- "OSPF Graceful Restart\n"
- "OSPF GR Helper\n"
- "Supported grace timer\n"
- "Grace interval(in seconds)\n")
-{
- VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
-
- ospf_gr_helper_supported_gracetime_set(ospf, OSPF_MAX_GRACE_INTERVAL);
- return CMD_SUCCESS;
-}
-
-DEFPY(ospf_gr_helper_planned_only,
- ospf_gr_helper_planned_only_cmd,
- "graceful-restart helper planned-only",
- "OSPF Graceful Restart\n"
- "OSPF GR Helper\n"
- "Supported only planned restart\n")
-{
- VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
-
- ospf_gr_helper_set_supported_planned_only_restart(ospf, OSPF_GR_TRUE);
-
- return CMD_SUCCESS;
-}
-
/* External Route Aggregation */
DEFUN (ospf_external_route_aggregation,
ospf_external_route_aggregation_cmd,
@@ -10100,256 +9949,6 @@ DEFUN (no_ospf_external_route_aggregation,
return CMD_SUCCESS;
}
-DEFPY(no_ospf_gr_helper_planned_only,
- no_ospf_gr_helper_planned_only_cmd,
- "no graceful-restart helper planned-only",
- NO_STR
- "OSPF Graceful Restart\n"
- "OSPF GR Helper\n"
- "Supported only for planned restart\n")
-{
- VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
-
- ospf_gr_helper_set_supported_planned_only_restart(ospf, OSPF_GR_FALSE);
-
- return CMD_SUCCESS;
-}
-
-static int ospf_print_vty_helper_dis_rtr_walkcb(struct hash_bucket *bucket,
- void *arg)
-{
- struct advRtr *rtr = bucket->data;
- struct vty *vty = (struct vty *)arg;
- static unsigned int count;
-
- vty_out(vty, "%-6pI4,", &rtr->advRtrAddr);
- count++;
-
- if (count % 5 == 0)
- vty_out(vty, "\n");
-
- return HASHWALK_CONTINUE;
-}
-
-static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf,
- uint8_t use_vrf, json_object *json,
- bool uj, bool detail)
-{
- struct listnode *node;
- struct ospf_interface *oi;
- char buf[PREFIX_STRLEN];
- json_object *json_vrf = NULL;
-
- if (uj) {
- if (use_vrf)
- json_vrf = json_object_new_object();
- else
- json_vrf = json;
- }
-
- if (ospf->instance) {
- if (uj)
- json_object_int_add(json, "ospfInstance",
- ospf->instance);
- else
- vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
- }
-
- ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
-
- if (uj) {
- if (use_vrf)
- json_object_object_add(json, ospf_get_name(ospf),
- json_vrf);
- } else
- vty_out(vty, "\n");
-
- /* Show Router ID. */
- if (uj) {
- json_object_string_add(json_vrf, "routerId",
- inet_ntop(AF_INET, &ospf->router_id,
- buf, sizeof(buf)));
- } else {
- vty_out(vty, "\n OSPF Router with ID (%pI4)\n\n",
- &ospf->router_id);
- }
-
- if (!uj) {
-
- if (ospf->is_helper_supported)
- vty_out(vty,
- " Graceful restart helper support enabled.\n");
- else
- vty_out(vty,
- " Graceful restart helper support disabled.\n");
-
- if (ospf->strict_lsa_check)
- vty_out(vty, " Strict LSA check is enabled.\n");
- else
- vty_out(vty, " Strict LSA check is disabled.\n");
-
- if (ospf->only_planned_restart)
- vty_out(vty,
- " Helper supported for planned restarts only.\n");
- else
- vty_out(vty,
- " Helper supported for Planned and Unplanned Restarts.\n");
-
- vty_out(vty,
- " Supported Graceful restart interval: %d(in seconds).\n",
- ospf->supported_grace_time);
-
- if (OSPF_HELPER_ENABLE_RTR_COUNT(ospf)) {
- vty_out(vty, " Enable Router list:\n");
- vty_out(vty, " ");
- hash_walk(ospf->enable_rtr_list,
- ospf_print_vty_helper_dis_rtr_walkcb, vty);
- vty_out(vty, "\n\n");
- }
-
- if (ospf->last_exit_reason != OSPF_GR_HELPER_EXIT_NONE) {
- vty_out(vty, " Last Helper exit Reason :%s\n",
- ospf_exit_reason2str(ospf->last_exit_reason));
- }
-
- if (ospf->active_restarter_cnt)
- vty_out(vty,
- " Number of Active neighbours in graceful restart: %d\n",
- ospf->active_restarter_cnt);
- else
- vty_out(vty, "\n");
-
- } else {
- json_object_string_add(
- json_vrf, "helperSupport",
- (ospf->is_helper_supported) ? "Enabled" : "Disabled");
- json_object_string_add(json_vrf, "strictLsaCheck",
- (ospf->strict_lsa_check) ? "Enabled"
- : "Disabled");
- json_object_string_add(
- json_vrf, "restartSupoort",
- (ospf->only_planned_restart)
- ? "Planned Restart only"
- : "Planned and Unplanned Restarts");
-
- json_object_int_add(json_vrf, "supportedGracePeriod",
- ospf->supported_grace_time);
-
- if (ospf->last_exit_reason != OSPF_GR_HELPER_EXIT_NONE)
- json_object_string_add(
- json_vrf, "LastExitReason",
- ospf_exit_reason2str(ospf->last_exit_reason));
-
- if (ospf->active_restarter_cnt)
- json_object_int_add(json_vrf, "activeRestarterCnt",
- ospf->active_restarter_cnt);
- }
-
-
- if (detail) {
- int cnt = 1;
- json_object *json_neighbors = NULL;
-
- for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
- struct route_node *rn;
- struct ospf_neighbor *nbr;
- json_object *json_neigh;
-
- if (ospf_interface_neighbor_count(oi) == 0)
- continue;
-
- if (uj) {
- json_object_object_get_ex(json_vrf, "Neighbors",
- &json_neighbors);
- if (!json_neighbors) {
- json_neighbors =
- json_object_new_object();
- json_object_object_add(json_vrf,
- "Neighbors",
- json_neighbors);
- }
- }
-
- for (rn = route_top(oi->nbrs); rn;
- rn = route_next(rn)) {
-
- if (!rn->info)
- continue;
-
- nbr = rn->info;
-
- if (!OSPF_GR_IS_ACTIVE_HELPER(nbr))
- continue;
-
- if (!uj) {
- vty_out(vty, " Neighbour %d :\n", cnt);
- vty_out(vty, " Address : %pI4\n",
- &nbr->address.u.prefix4);
- vty_out(vty, " Routerid : %pI4\n",
- &nbr->router_id);
- vty_out(vty,
- " Received Grace period : %d(in seconds).\n",
- nbr->gr_helper_info
- .recvd_grace_period);
- vty_out(vty,
- " Actual Grace period : %d(in seconds)\n",
- nbr->gr_helper_info
- .actual_grace_period);
- vty_out(vty,
- " Remaining GraceTime:%ld(in seconds).\n",
- thread_timer_remain_second(
- nbr->gr_helper_info
- .t_grace_timer));
- vty_out(vty,
- " Graceful Restart reason: %s.\n\n",
- ospf_restart_reason2str(
- nbr->gr_helper_info
- .gr_restart_reason));
- cnt++;
- } else {
- json_neigh = json_object_new_object();
- json_object_string_add(
- json_neigh, "srcAddr",
- inet_ntop(AF_INET, &nbr->src,
- buf, sizeof(buf)));
-
- json_object_string_add(
- json_neigh, "routerid",
- inet_ntop(AF_INET,
- &nbr->router_id,
- buf, sizeof(buf)));
- json_object_int_add(
- json_neigh,
- "recvdGraceInterval",
- nbr->gr_helper_info
- .recvd_grace_period);
- json_object_int_add(
- json_neigh,
- "actualGraceInterval",
- nbr->gr_helper_info
- .actual_grace_period);
- json_object_int_add(
- json_neigh, "remainGracetime",
- thread_timer_remain_second(
- nbr->gr_helper_info
- .t_grace_timer));
- json_object_string_add(
- json_neigh, "restartReason",
- ospf_restart_reason2str(
- nbr->gr_helper_info
- .gr_restart_reason));
- json_object_object_add(
- json_neighbors,
- inet_ntop(AF_INET, &nbr->src,
- buf, sizeof(buf)),
- json_neigh);
- }
- }
- }
- }
- return CMD_SUCCESS;
-}
-
DEFUN (ospf_external_route_aggregation_no_adrvertise,
ospf_external_route_aggregation_no_adrvertise_cmd,
"summary-address A.B.C.D/M no-advertise",
@@ -10438,108 +10037,6 @@ DEFUN (ospf_route_aggregation_timer,
return CMD_SUCCESS;
}
-DEFPY (show_ip_ospf_gr_helper,
- show_ip_ospf_gr_helper_cmd,
- "show ip ospf [vrf <NAME|all>] graceful-restart helper [detail] [json]",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- VRF_CMD_HELP_STR
- "All VRFs\n"
- "OSPF Graceful Restart\n"
- "Helper details in the router\n"
- "Detailed informtion\n"
- JSON_STR)
-{
- char *vrf_name = NULL;
- bool all_vrf = false;
- int ret = CMD_SUCCESS;
- int idx_vrf = 0;
- int idx = 0;
- uint8_t use_vrf = 0;
- bool uj = use_json(argc, argv);
- struct ospf *ospf = NULL;
- json_object *json = NULL;
- struct listnode *node = NULL;
- int inst = 0;
- bool detail = false;
-
- OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
-
- if (argv_find(argv, argc, "detail", &idx))
- detail = true;
-
- if (uj)
- json = json_object_new_object();
-
- /* vrf input is provided */
- if (vrf_name) {
- use_vrf = 1;
-
- if (all_vrf) {
- for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
- if (!ospf->oi_running)
- continue;
-
- ret = ospf_show_gr_helper_details(
- vty, ospf, use_vrf, json, uj, detail);
- }
-
- if (uj) {
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
-
- return ret;
- }
-
- ospf = ospf_lookup_by_inst_name(inst, vrf_name);
-
- if (ospf == NULL || !ospf->oi_running) {
-
- if (uj) {
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- } else
- vty_out(vty, "%% OSPF instance not found\n");
-
- return CMD_SUCCESS;
- }
-
- } else {
- /* Default Vrf */
- ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
-
- if (ospf == NULL || !ospf->oi_running) {
-
- if (uj) {
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- } else
- vty_out(vty, "%% OSPF instance not found\n");
-
- return CMD_SUCCESS;
- }
-
- ospf_show_gr_helper_details(vty, ospf, use_vrf, json, uj,
- detail);
- }
-
- if (uj) {
- vty_out(vty, "%s\n", json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
-
- return CMD_SUCCESS;
-}
-/* Graceful Restart HELPER commands end */
DEFUN (no_ospf_route_aggregation_timer,
no_ospf_route_aggregation_timer_cmd,
"no aggregation timer",
@@ -12608,9 +12105,6 @@ void ospf_vty_show_init(void)
/* "show ip ospf vrfs" commands. */
install_element(VIEW_NODE, &show_ip_ospf_vrfs_cmd);
- /* "show ip ospf gr-helper details" command */
- install_element(VIEW_NODE, &show_ip_ospf_gr_helper_cmd);
-
/* "show ip ospf summary-address" command */
install_element(VIEW_NODE, &show_ip_ospf_external_aggregator_cmd);
}
@@ -12721,18 +12215,6 @@ static void ospf_vty_zebra_init(void)
install_element(OSPF_NODE, &no_ospf_distance_ospf_cmd);
install_element(OSPF_NODE, &ospf_distance_ospf_cmd);
- /*Ospf garcefull restart helper configurations */
- install_element(OSPF_NODE, &ospf_gr_helper_enable_cmd);
- install_element(OSPF_NODE, &no_ospf_gr_helper_enable_cmd);
- install_element(OSPF_NODE, &ospf_gr_helper_only_cmd);
- install_element(OSPF_NODE, &no_ospf_gr_helper_only_cmd);
- install_element(OSPF_NODE, &ospf_gr_helper_enable_lsacheck_cmd);
- install_element(OSPF_NODE, &no_ospf_gr_helper_enable_lsacheck_cmd);
- install_element(OSPF_NODE, &ospf_gr_helper_supported_grace_time_cmd);
- install_element(OSPF_NODE, &no_ospf_gr_helper_supported_grace_time_cmd);
- install_element(OSPF_NODE, &ospf_gr_helper_planned_only_cmd);
- install_element(OSPF_NODE, &no_ospf_gr_helper_planned_only_cmd);
-
/* External LSA summarisation config commands.*/
install_element(OSPF_NODE, &ospf_external_route_aggregation_cmd);
install_element(OSPF_NODE, &no_ospf_external_route_aggregation_cmd);
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 4cd94e0df9..e5ee7a82ad 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -2446,8 +2446,6 @@ static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
case PIM_REG_PRUNE:
strlcpy(state_str, "RegP", state_str_len);
break;
- default:
- strlcpy(state_str, "Unk", state_str_len);
}
return state_str;
}
diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c
index ddba33ff9d..fa7f1da79a 100644
--- a/pimd/pim_msdp.c
+++ b/pimd/pim_msdp.c
@@ -1304,7 +1304,6 @@ int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
struct pim_msdp_mg *mg;
struct listnode *mbrnode;
struct pim_msdp_mg_mbr *mbr;
- char mbr_str[INET_ADDRSTRLEN];
char src_str[INET_ADDRSTRLEN];
int count = 0;
@@ -1321,10 +1320,8 @@ int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty,
}
for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) {
- pim_inet4_dump("<mbr?>", mbr->mbr_ip, mbr_str,
- sizeof(mbr_str));
- vty_out(vty, "%sip msdp mesh-group %s member %s\n",
- spaces, mg->mesh_group_name, mbr_str);
+ vty_out(vty, "%sip msdp mesh-group %s member %pI4\n",
+ spaces, mg->mesh_group_name, &mbr->mbr_ip);
++count;
}
}
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index d21c7b4008..d0d120523d 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -1720,8 +1720,6 @@ const char *pim_reg_state2str(enum pim_reg_state reg_state, char *state_str,
case PIM_REG_PRUNE:
strlcpy(state_str, "RegPrune", state_str_len);
break;
- default:
- strlcpy(state_str, "RegUnknown", state_str_len);
}
return state_str;
}
@@ -1785,7 +1783,7 @@ static int pim_upstream_register_stop_timer(struct thread *t)
}
pim_null_register_send(up);
break;
- default:
+ case PIM_REG_NOINFO:
break;
}
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index a7286d1878..229104baff 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -199,6 +199,8 @@ Requires: initscripts
BuildRequires: pam-devel
%endif
%if "%{initsystem}" == "systemd"
+BuildRequires: systemd
+BuildRequires: systemd-devel
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
@@ -394,6 +396,9 @@ routing state through standard SNMP MIBs.
--disable-bgp-vnc \
%endif
--enable-isisd \
+%if "%{initsystem}" == "systemd"
+ --enable-systemd \
+%endif
--enable-rpki \
%if %{with_bfdd}
--enable-bfdd \
@@ -768,9 +773,428 @@ sed -i 's/ -M rpki//' %{_sysconfdir}/frr/daemons
%changelog
-* Fri Oct 30 2020 Martin Winter <mwinter@opensourcerouting.org> - %{version}
-- Moved RPKI to subpackage
-- Added SNMP subpackage
+* Tue Nov 4 2021 Martin Winter <mwinter@opensourcerouting.org> - %{version}
+
+* Tue Nov 2 2021 Jafar Al-Gharaibeh <jafar@atcorp.com> - 8.1
+- FRR 8.1 brings a long list of enhancements and fixes with 1200 commits from
+- 75 developers. Thanks to all contributers.
+- New Features:
+- Lua hooks are now feature complete, with one hook available for use (http://docs.frrouting.org/en/latest/scripting.html)
+- Improvements to SRv6 (Segment Routing over IPv6) (http://docs.frrouting.org/en/latest/zebra.html#segment-routing-ipv6)
+- Improvements to Prefix-SID (Type 5)
+- EVPN route type-5 gateway IP overlay Index (http://docs.frrouting.org/en/latest/bgp.html#evpn-overlay-index-gateway-ip)
+- OSPFv3 NSSA and NSSA totally stub areas (http://docs.frrouting.org/en/latest/ospf6d.html#ospf6-area)
+- OSPFv3 ASBR summarization (http://docs.frrouting.org/en/latest/ospf6d.html#asbr-summarisation-support-in-ospfv3)
+- OSPFv3 Graceful Restart (http://docs.frrouting.org/en/latest/ospf6d.html#graceful-restart)
+- OSPFv2 Graceful Restart (restarting mode added, helper was already implemented) (http://docs.frrouting.org/en/latest/ospfd.html#graceful-restart)
+- Behavior Changes
+- Every node in running config now has an explicit "exit" tag
+- Link bandwidth in BGP is now correctly encoded according to IEEE 754. To stay with old incorrect encoding use:
+- `neighbor PEER disable-link-bw-encoding-ieee`
+- Changelog
+- alpine:
+ Fix path for daemons file install
+- BGP:
+- Add "json" option to "show bgp as-path-access-list"
+- Add `disable-addpath-rx` knob
+- Add an ability to set extcommunity to none in route-maps
+- Add counter of displayed show bgp summary when filtering
+- Add knob to config cond-adv scanner period
+- Add route-map `match alias` command
+- Add rpki source address configuration
+- Add show bgp summary filter by neighbor or as
+- Add terse display option on show bgp summary
+- Allow for auto-completion of community alias's created
+- Bgp knob to teardown session immediately when peer is unreachable
+- Expand 'bgp default <afi>-<safi>' cmds
+- Extend evpn next hop tracking to type-1 and type-4 routes
+- Fix "no router bgp x vrf default"
+- Flowspec redirect vrf uses vrf table instead of allocated table id
+- Handle quick flaps of an evpn prefix properly
+- Initial batch of evpn lttng tracepoints
+- Limit processing to what is needed in rpki validation
+- Modify vrf/view display in show bgp summary
+- Set 4096 instead of 65535 as new max packet size for a new peer
+- Set extended msg size only if we advertised and received capability
+- Show bgp community alias in json community list output
+- Show bgp prefixes by community alias
+- Show max packet size per update-group
+- Split soft reconfigure table task into several jobs to not block vtysh
+- Store distance received from a redistribute statement
+- Update route-type-1 legend to match output
+- ISIS:
+- Fix sending of lsp with null seqno
+- lib:
+- Add "json" option to "show ip[v6] access-list"
+- Add "json" option to "show ip[v6] prefix-list"
+- Add "json" option to "show route-map"
+- Prevent grpc assert on missing yang node
+- NHRP:
+- Clear cache when shortcuts are cleared
+- Fix corrupt address being shown for shortcuts with no cache entry
+- Set prefix correctly in resolution request
+- OSPF6:
+- Add debug commands for lsa all and route all
+- Add warning log for late hello packets
+- Add write-multiplier configuration
+- Don't update router-id if at least one adjacency is full
+- Extend the "redistribute" command with more options
+- Fix issue when displaying the redistribute command
+- Fix logging of border router routes
+- Json output for database dump show command
+- Link state id in lsa database json output
+- Send lsa update immediately when ospf instance is deleted
+- OSPF:
+- Fix crash when creating vlink in unknown vrf
+- Gr conformance fix for hello packet dr election
+- Print extra lsa information in some log messages
+- Rfc conformance test case 25.23 issue fix
+- Show ip ospf route json does not shown metric and tag
+- Summary lsa is not originated when process is reset
+- pathd:
+- Handle pcinitiated configuration, main thread
+- Handle pcinitiated messages, thread controller
+- Handle srp_id correctly
+- If pce ret no-path to pcreq don't retry pcreq nor delegate
+- PBR:
+- Add `match ip-protocol [tcp|udp]`
+- Add ability to set/unset src and dest ports
+- Nhg "add" edge case for last in table range
+- Start inclusion of src and dst ports for pbrd
+- PIM:
+- Add tos/ttl check for igmp conformance
+- Allow join prune intervals to be as small as 5 seconds
+- Allow msdp group name 'default'
+- Fix register suppress timer code
+- Fix uaf/heap corruption in bsm code
+- Fix command "no ip msdp mesh-group member"
+- Igmp groups are not getting timeout
+- Igmp memberships are not querier specific
+- Igmp sockets need to be iface-bound too
+- Prevent uninited usage of nexthop
+- Support msdp global timers configuration
+- vtysh
+- Add cli timestamp '-t' flag
+- Add error code if daemon is not running
+- Fix searching commands in parent nodes
+- yang:
+- Add msdp timer configuration
+- Fix bgp multicast prefix type
+- Mark a couple of prefix-list/access-list leafs as mandatory
+- Move multicast prefix type definition
+- Replace an empty pattern with a zero-length restriction
+- Rework pim msdp mesh group
+- Simplify msdp peer handling
+- zebra :
+- Add "json" option to "show interface"
+- Various improvment to dataplane interface
+- Add message counts for `show zebra client`
+- Add nhg id to show ip route json
+- Add show command for ra interface lists
+- Fix ipv4 routes with ipv6 link local next hops install in fpm
+- Handle bridge mac address update in evpn contexts
+- Move individual lines to table in `show zebra client` command
+- Refresh vxlan evpn contexts, when bridge interface goes up
+- Update zl3vni when bridge link refreshed in other namespaces
+
+* Wed Jul 21 2021 Martin Winter <mwinter@opensourcerouting.org> - 8.0
+- Major changes
+- New daemon pathd for segment routing
+- EVPN Multihoming is now fully supported
+- OSPFv3 now supports VRFs
+- TI-LFA has been implemented in IS-IS and OSPF
+- Ability for Zebra to dump netlink messages in a human-friendly format
+- LDP gained SNMP support
+- libyang minimun version is now 2.0
+- BABEL:
+- Add `distribute-list` commands
+- Fix memory leak in connected route handling
+- BGP:
+- Add support for use of aliases with communities
+- Add support of tcp-mss for neighbors
+- Add support for EVPN Multihoming
+- Add ability to show BGP routes from a particular table version
+- Add support for for RFC 8050 (MRT add-path)
+- Add SNMP support for MPLS VPN
+- Add `show bgp summary wide` command to show more detailed output
+ on wide terminals
+- Add ability for peer-groups to have `ttl-security hops` configured
+- Add support for conditional Advertisement
+- Add support for RFC 4271 Delay Open Timer
+- Add a knob to not advertise until route is installed in fib
+- Add BGP-wide configuration for graceful shutdown
+- Add support for RFC 8654 extended messages
+- Improve RPKI reporting as well as new show commands
+- Improve handling of VRF route leaking
+- Improve scaling behavior for dynamic neighbors
+- Improve LL nexthop tracking to be interface based
+- Improve route reachability handling with respect to blackhole routes
+- Improve SNMP traps to RFC 4273 notifications
+- Improve EVPN routes to use L3 NHG's where applicable
+- Improvements to EVPN
+- Improvements to update behavior
+- Fix various issues with connection resolution
+- Fix statistics commands in some situations
+- Fix non-determistic locally-originated paths in bestpath selection
+- Continue working on transitioning to YANG/Northbound configuration
+- Various bug fixes and performance improvements
+- EIGRP:
+- Add `distribute-list` commands
+- Ensure received AS number is the same as ours in all situations
+- Properly validate TLV lengths in some situations
+- IS-IS:
+- Add ldb-sync functionality
+- Add TI-LFA functionality
+- Add support for Anycast-SID's
+- Add support for classic LFA RFC 5286
+- Add `show isis fast-reroute summary` command
+- Add support for Remote LFA RFC 7490
+- Fix Attach-bit processing in some scenarios
+- Cleanup BFD integration
+- Various bug fixes and performance improvements
+- LDP:
+- Add SNMP support
+- Support for LDP IGP Synchronization
+- Support for RLFA clients
+- Various bug fixes and performance improvements
+- LIBFRR:
+- Various bugfixes and performance improvements
+- NHRP:
+- Add `nhrp multicast-nflog-group (1-65535)` command
+- Add configuration options for vici socket path
+- Add support for forwarding multicast packets
+- Fix handling of MTU
+- Fix handling of NAT extension
+- Retry IPsec under some conditions
+- OSPFv2:
+- Add OSPF GR helper support
+- Add JSON support for various commands
+- Add `summary-address A.B.C.D/M ...` commands
+- Add `area X nssa suppress-fa` command
+- Add support for TI-LFA
+- Add support for BFD profiles
+- Add support for Traffic Engineering database
+- Add support for usage of DMPVPN with OSPF
+- Add `clear ip ospf neighbor` commands
+- Add YANG support for route-maps
+- Improvements to SNMP
+- Fixes for type 5 and type 7 LSA handling
+- Various bug fixes and performance improvements
+- OSPFv3:
+- Add support for VRFs
+- Add JSON support to a bunch of commands
+- Add ability to control maximum paths for routes
+- Add `show ipv6 ospf6 vrfs` command
+- Add support for BFD profiles
+- Fix to not send hellos on loopbacks
+- Cleanup area handling around interfaces
+- YANG support for route-maps
+- Various bug fixes and performance improvements
+- OSPFCLIENT:
+- Cleanup trust of user input
+- PATHd:
+- Add support of SR-TE policy management daemon
+- Add optional support for PCEP to pathd
+- Integrate PCEP-LIB into FRR
+- PBR:
+- Add `set installable` nhg command
+- Improve interface up/down event handling
+- PIM:
+- Add YANG integration
+- Add JSON support to various commands
+- Add BFD profile support
+- Fixes to IGMP conformance
+- Fixes to behavior surrounding Prune and Prune-pending
+- Various bug fixes and performance improvements
+- RIPNG:
+- Fix interface wakeup after shutdown
+- SHARP:
+- Add ability to use Nexthop Groups
+- Add v4 redistribute watching
+- Add TED support
+- Various bug fixes
+- STATIC:
+- Fix nexthop handling in some situations
+- Forbid blackhole and non-blackhole nexthops in a single route
+- VRRP:
+- printf formatting cleanups
+- VTYSH:
+- Add a `show history` command
+- Add `show memory <daemon>` support
+- Start deprecation cycle for `address-family evpn`
+- Display version with --help
+- Various bug fixes
+- WATCHFRR:
+- Fix some crashes
+- ZEBRA:
+- Add JSON support to various commands
+- Add Human readable netlink dumps
+- Add L2 NHG support
+- Add support for LSPs to FPM dataplane
+- Add ability for other protocol daemons to install nexthop groups into the kernel
+- Add YANG support for route-maps
+- Improve scale performance when handling a large number of VRF's
+- Improve network namespace handling
+- Improve asic-offload handling
+- Improve FreeBSD interface and route handling
+- Improve handling of neighbors in kernel dataplane plugin
+- Improve label manager
+- Improve route-map processing
+- Improve debug-ability of routes and VRFs
+- Improve FPM dataplane plugin
+- Improve handling of reachability / nexthop tracking on shutdown interfaces
+- Improve EVPN support
+- Fix startup handling of `set src X`
+- Various bug fixes and performance improvements
+
+* Wed Mar 3 2021 Martin Winter <mwinter@opensourcerouting.org> - 7.5.1
+- BABEL:
+- Fix connected route leak on change
+- BFD:
+- Session lookup was sometimes wrong
+- Memory leak and handling cleanups
+- In some situations handle vrf appropriately when receiving packets
+- BGP:
+- Peer Group Inheritance Fixes
+- Dissallow attempt to peer peers reachable via blackholes
+- Send BMP down message when reachability fails
+- Cleanup handling of aggregator data when the AGG AS is 0
+- Handle `neighbor <peer-group allowas-in` config changes properly
+- Properly parse community and lcommunity values in some circumstances
+- Allow peer-groups to configure `ttl-security hops`
+- Prevent v6 routes with v4 nexthops from being installed
+- Allow `default-originate` to be cleared from a peer group
+- Fix evpn route-map vni filter at origin
+- local routes were using non-default distance
+- Properly track if the nexthop was updated in some circumstances
+- Cleanup `show running` when running bgp with `-e X` values
+- Various Memory leaks in show commands
+- Properly withdraw exported routes when deleting a VRF
+- Avoid resetting ebgp-multihop if peer setting is the same as peer-group
+- Properly encode flowspec rules to zebra in some rare circumstances
+- Generate statistics for routes in bgp when we have exactly 1 route
+- Properly apply route-map for the default-originate command
+- EIGRP:
+- Properly set MTU for eigrp packets sent
+- Various memory leaks and using uninited data fixes
+- ISIS:
+- When last area address is removed, resign if we were the DR
+- Various memory leaks and using uninited data fixes
+- LDP:
+- Various memory leaks and using uninited data fixes
+- NHRP:
+- Use onlink routes when prefix == nh
+- Shortcut routes are installed with proper nexthop
+- OSPF:
+- Prevent duplicate packet read in multiple vrf situation
+- Fix area removal at interface level
+- Restore Point to MultiPoint interface types
+- Correctly handle MTU change on startup
+- Multi Instance initialization sometimes was not successful
+- NSSA translate-always was not working properly
+- OSPFv3:
+- Don't send hellos on loopback interfaces
+- Handle ECMP better when a sub-path is removed
+- Memory leak and handling fixes
+- Fix Link LSA not updating when router priority is modified
+- Some output from show commands was wrong
+- Intra area remote connected prefixes sometimes not installed
+- PBR:
+- Various memory leaks and using uninited data fixes
+- PIM:
+- SGRpt prune received during prune didn't override holdtime
+- Various memory leaks and using uninited data fixes
+- STATIC:
+- Fix VRF and usage on startup in some instances
+- Tableid was being mishandled in some cases
+- VTYSH:
+- Disable bracketed paste in readline.
+- WATCHFRR:
+- Various memory leaks and using uninited data fixes
+- ZEBRA:
+- Always install blackhole routes using kernel routes instead of nexthops
+- Various memory leaks and using uninited data fixes
+- Dissallow resolution to duplicate nexthops that created infinite nexthops
+- Apply the route-map delay-timer globally
+- Some routes were stuck in Queued state when using the FPM
+- Better handle vrf creation when using namespaces
+- Set NUD_NOARP on sticky mac entries in addtion to NTF_STICKY
+- Allow `set src X` to work on startup
+- FRR Library:
+- Fix a variety of memory leaks
+- Fix VRF Creation in some instances
+- RPKI context editing was not properly handled in reload situations
+- routemap code was not properly handling modification of CLI in some instances
+- SNAPCRAFT:
+- Update to using rtrlib 0.7.0
+- Fix passthrough path for Libyang 1.x
+- ALPINE:
+- Remove old docker deps
+
+* Mon Nov 2 2020 Donald Sharp <sharpd@nvidia.com> - 7.5
+- BFD
+- Profile support
+- Minimum ttl support
+- BGP
+- rpki VRF support
+- GR fixes
+- Add wide option to display of routes
+- Add `maximum-prefix <num> force`
+- Add `bestpath-routes` to neighbor command
+- Add `bgp shutdown message MSG...` command
+- Add v6 Flowspec support
+- Add `neighbor <neigh> shutdown rtt` command
+- Allow update-delay to be applied globaly
+- EVPN
+- Beginning of MultiHoming Support
+- ISIS
+- Segment Routing Support
+- VRF Support
+- Guard against adj timer display overflow
+- Add support for Anycast-SIDs
+- Add support for Topology Independent LFA (TI-LFA)
+- Add `lsp-gen-interval 2` to isis configuration
+- OSPF
+- Segment Routing support for ECMP
+- Various LSA fixes
+- Prevent crash if transferring config amongst instances
+- PBR
+- Adding json support to commands
+- DSCP/ECN based PBR Matching
+- PIM
+- Add more json support to commands
+- Fix missing mesh-group commands
+- MSDP SA forwarding
+- Clear (s,g,rpt) ifchannel on (*, G) prune received
+- Fix igmp querier election and IP address mapping
+- Crash fix when RP is removed
+- STATIC
+- Northbound Support
+- YANG
+- Filter and route-map Support
+- OSPF model definition
+- BGP model definition
+- VTYSH
+- Speed up output across daemons
+- Fix build-time errors for some --enable flags
+- Speed up output of configuration across daemons
+- ZEBRA
+- nexthop group support for FPM
+- northbound support for rib model
+- Backup nexthop support
+- netlink batching support
+- Allow upper level protocols to request ARP
+- Add json output for zebra ES, ES-EVI and access vlan dumps
+-
+- Upgrade to using libyang1.0.184
+-
+- RPM
+- Moved RPKI to subpackage
+- Added SNMP subpackage
+-
+- As always there are too many bugfixes to list individually. This release
+- compromises just over 1k of commits by the community, with contributors from
+- 70 people.
* Tue Jun 30 2020 Martin Winter <mwinter@opensourcerouting.org> - 7.4
- BGPd
diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c
index 5590b1833d..58c28e54c0 100644
--- a/ripd/rip_cli.c
+++ b/ripd/rip_cli.c
@@ -327,7 +327,7 @@ void cli_show_rip_network_interface(struct vty *vty,
*/
DEFPY_YANG (rip_offset_list,
rip_offset_list_cmd,
- "[no] offset-list WORD$acl <in|out>$direction (0-16)$metric [IFNAME]",
+ "[no] offset-list ACCESSLIST4_NAME$acl <in|out>$direction (0-16)$metric [IFNAME]",
NO_STR
"Modify RIP metric\n"
"Access-list name\n"
@@ -1026,7 +1026,7 @@ DEFPY_YANG (clear_ip_rip,
DEFUN (rip_distribute_list,
rip_distribute_list_cmd,
- "distribute-list [prefix] WORD <in|out> [WORD]",
+ "distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
"Filter networks in routing updates\n"
"Specify a prefix\n"
"Access-list name\n"
@@ -1046,7 +1046,7 @@ DEFUN (rip_distribute_list,
DEFUN (rip_no_distribute_list,
rip_no_distribute_list_cmd,
- "no distribute-list [prefix] WORD <in|out> [WORD]",
+ "no distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
NO_STR
"Filter networks in routing updates\n"
"Specify a prefix\n"
diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c
index 63b75e723d..5bf3103a78 100644
--- a/ripngd/ripng_cli.c
+++ b/ripngd/ripng_cli.c
@@ -233,7 +233,7 @@ void cli_show_ripng_network_interface(struct vty *vty,
*/
DEFPY_YANG (ripng_offset_list,
ripng_offset_list_cmd,
- "[no] offset-list WORD$acl <in|out>$direction (0-16)$metric [IFNAME]",
+ "[no] offset-list ACCESSLIST6_NAME$acl <in|out>$direction (0-16)$metric [IFNAME]",
NO_STR
"Modify RIPng metric\n"
"Access-list name\n"
@@ -511,7 +511,7 @@ DEFPY_YANG (clear_ipv6_rip,
DEFUN (ripng_ipv6_distribute_list,
ripng_ipv6_distribute_list_cmd,
- "ipv6 distribute-list [prefix] WORD <in|out> [WORD]",
+ "ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
"IPv6\n"
"Filter networks in routing updates\n"
"Specify a prefix\n"
@@ -532,7 +532,7 @@ DEFUN (ripng_ipv6_distribute_list,
DEFUN (ripng_no_ipv6_distribute_list,
ripng_no_ipv6_distribute_list_cmd,
- "no ipv6 distribute-list [prefix] WORD <in|out> [WORD]",
+ "no ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
NO_STR
"IPv6\n"
"Filter networks in routing updates\n"
diff --git a/tests/.gitignore b/tests/.gitignore
index 8cc2aa98f9..53dbd68c9a 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -41,6 +41,7 @@
/lib/test_prefix2str
/lib/test_printfrr
/lib/test_privs
+/lib/test_resolver
/lib/test_ringbuf
/lib/test_segv
/lib/test_seqlock
diff --git a/tests/lib/cli/common_cli.c b/tests/lib/cli/common_cli.c
index 8be81cc4cb..7c9febe2ca 100644
--- a/tests/lib/cli/common_cli.c
+++ b/tests/lib/cli/common_cli.c
@@ -60,6 +60,7 @@ static void vty_do_exit(int isexit)
}
const struct frr_yang_module_info *const *test_yang_modules = NULL;
+int test_log_prio = ZLOG_DISABLED;
/* main routine. */
int main(int argc, char **argv)
@@ -73,7 +74,7 @@ int main(int argc, char **argv)
/* master init. */
master = thread_master_create(NULL);
- zlog_aux_init("NONE: ", ZLOG_DISABLED);
+ zlog_aux_init("NONE: ", test_log_prio);
/* Library inits. */
cmd_init(1);
diff --git a/tests/lib/cli/common_cli.h b/tests/lib/cli/common_cli.h
index 3042ff5b12..6660b27ef7 100644
--- a/tests/lib/cli/common_cli.h
+++ b/tests/lib/cli/common_cli.h
@@ -37,6 +37,8 @@ extern void test_init(int argc, char **argv);
*/
extern struct thread_master *master;
+extern int test_log_prio;
+
extern int dump_args(struct vty *vty, const char *descr, int argc,
struct cmd_token *argv[]);
diff --git a/tests/lib/test_resolver.c b/tests/lib/test_resolver.c
new file mode 100644
index 0000000000..0b3dccc820
--- /dev/null
+++ b/tests/lib/test_resolver.c
@@ -0,0 +1,81 @@
+/*
+ * FRR c-ares integration test
+ * Copyright (C) 2021 David Lamparter for NetDEF, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* this test is not run automatically since tests MUST NOT rely on any outside
+ * state. DNS is most definitely "outside state". A testbed may not have any
+ * internet connectivity at all. It may not have working DNS. Or worst of
+ * all, whatever name we use to test may have a temporary failure entirely
+ * beyond our control.
+ *
+ * The only way this test could be run in a testbed is with an all-local DNS
+ * setup, which considering the resolver code is rarely touched is not worth
+ * the time at all. Instead, after touching the resolver code, manually run
+ * this test and throw some names at it.
+ */
+
+#include <zebra.h>
+
+#include "vty.h"
+#include "command.h"
+#include "resolver.h"
+#include "log.h"
+#include "sockunion.h"
+
+#include "tests/lib/cli/common_cli.h"
+
+extern struct thread_master *master;
+
+static void resolver_result(struct resolver_query *resq, const char *errstr,
+ int numaddrs, union sockunion *addr)
+{
+ int i;
+
+ if (numaddrs <= 0) {
+ zlog_warn("hostname resolution failed: %s", errstr);
+ return;
+ }
+
+ for (i = 0; i < numaddrs; i++)
+ zlog_info("resolver result: %pSU", &addr[i]);
+}
+
+struct resolver_query query;
+
+DEFUN (test_resolve,
+ test_resolve_cmd,
+ "resolve WORD",
+ "DNS resolver\n"
+ "Name to resolve\n")
+{
+ resolver_resolve(&query, AF_UNSPEC, argv[1]->arg, resolver_result);
+ return CMD_SUCCESS;
+}
+
+__attribute__((_CONSTRUCTOR(2000)))
+static void test_setup(void)
+{
+ test_log_prio = LOG_DEBUG;
+}
+
+void test_init(int argc, char **argv)
+{
+ resolver_init(master);
+
+ install_element(VIEW_NODE, &test_resolve_cmd);
+}
diff --git a/tests/subdir.am b/tests/subdir.am
index f21e12ecbb..cd6e4101dd 100644
--- a/tests/subdir.am
+++ b/tests/subdir.am
@@ -132,6 +132,12 @@ check_PROGRAMS += \
# end
endif
+if CARES
+check_PROGRAMS += \
+ tests/lib/test_resolver \
+ # end
+endif
+
tests/lib/cli/test_commands_defun.c: vtysh/vtysh_cmd.c
mkdir -p tests/lib/cli
sed \
@@ -351,6 +357,10 @@ tests_lib_test_privs_CFLAGS = $(TESTS_CFLAGS)
tests_lib_test_privs_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_lib_test_privs_LDADD = $(ALL_TESTS_LDADD)
tests_lib_test_privs_SOURCES = tests/lib/test_privs.c
+tests_lib_test_resolver_CFLAGS = $(TESTS_CFLAGS)
+tests_lib_test_resolver_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_lib_test_resolver_LDADD = $(ALL_TESTS_LDADD) lib/libfrrcares.la
+tests_lib_test_resolver_SOURCES = tests/lib/test_resolver.c tests/lib/cli/common_cli.c
tests_lib_test_ringbuf_CFLAGS = $(TESTS_CFLAGS)
tests_lib_test_ringbuf_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_lib_test_ringbuf_LDADD = $(ALL_TESTS_LDADD)
diff --git a/tests/topotests/bfd_ospf_topo1/test_bfd_ospf_topo1.py b/tests/topotests/bfd_ospf_topo1/test_bfd_ospf_topo1.py
index f35c20e16c..93a2339299 100755
--- a/tests/topotests/bfd_ospf_topo1/test_bfd_ospf_topo1.py
+++ b/tests/topotests/bfd_ospf_topo1/test_bfd_ospf_topo1.py
@@ -195,16 +195,16 @@ def test_bfd_ospf_interface_failure_rt2_step3():
# By default BFD provides a recovery time of 900ms plus jitter, so let's wait
# initial 2 seconds to let the CI not suffer.
- topotest.sleep(2, 'Wait for BFD down notification')
+ topotest.sleep(2, "Wait for BFD down notification")
router_compare_json_output(
"rt1", "show ip route ospf json", "step3/show_ip_route_rt2_down.ref", 10, 2
)
router_compare_json_output(
- "rt1", "show ipv6 route ospf json", "step3/show_ipv6_route_rt2_down.ref", 1, 0
+ "rt1", "show ipv6 route ospf json", "step3/show_ipv6_route_rt2_down.ref", 10, 2
)
router_compare_json_output(
- "rt1", "show bfd peers json", "step3/show_bfd_peers_rt2_down.ref", 1, 0
+ "rt1", "show bfd peers json", "step3/show_bfd_peers_rt2_down.ref", 10, 2
)
# Check recovery, this can take some time
@@ -234,15 +234,15 @@ def test_bfd_ospf_interface_failure_rt3_step3():
# By default BFD provides a recovery time of 900ms plus jitter, so let's wait
# initial 2 seconds to let the CI not suffer.
- topotest.sleep(2, 'Wait for BFD down notification')
+ topotest.sleep(2, "Wait for BFD down notification")
router_compare_json_output(
"rt1", "show ip route ospf json", "step3/show_ip_route_rt3_down.ref", 10, 2
)
router_compare_json_output(
- "rt1", "show ipv6 route ospf json", "step3/show_ipv6_route_rt3_down.ref", 1, 0
+ "rt1", "show ipv6 route ospf json", "step3/show_ipv6_route_rt3_down.ref", 10, 2
)
router_compare_json_output(
- "rt1", "show bfd peers json", "step3/show_bfd_peers_rt3_down.ref", 1, 0
+ "rt1", "show bfd peers json", "step3/show_bfd_peers_rt3_down.ref", 10, 2
)
# Check recovery, this can take some time
diff --git a/tests/topotests/isis_topo1_vrf/r3/r3_topology.json b/tests/topotests/isis_topo1_vrf/r3/r3_topology.json
index 34892d4a3a..044a6c0438 100644
--- a/tests/topotests/isis_topo1_vrf/r3/r3_topology.json
+++ b/tests/topotests/isis_topo1_vrf/r3/r3_topology.json
@@ -94,16 +94,16 @@
{
"interface": "r3-eth0",
"metric": "10",
- "next-hop": "r3",
+ "next-hop": "r1",
"parent": "r3(4)",
"type": "TE-IS",
- "vertex": "r3"
+ "vertex": "r1"
},
{
"interface": "r3-eth0",
"metric": "10",
- "next-hop": "r3",
- "parent": "r3(4)",
+ "next-hop": "r1",
+ "parent": "r1(4)",
"type": "IP TE",
"vertex": "10.0.20.0/24"
}
@@ -121,10 +121,10 @@
{
"interface": "r3-eth0",
"metric": "10",
- "next-hop": "r3",
+ "next-hop": "r1",
"parent": "r3(4)",
"type": "TE-IS",
- "vertex": "r3"
+ "vertex": "r1"
}
]
}
diff --git a/tests/topotests/lib/bgprib.py b/tests/topotests/lib/bgprib.py
index a216e3588e..35a57d0a99 100644
--- a/tests/topotests/lib/bgprib.py
+++ b/tests/topotests/lib/bgprib.py
@@ -122,7 +122,7 @@ class BgpRib:
luResult(target, True, title, logstr)
def RequireUnicastRoutes(self, target, afi, vrf, title, wantroutes, debug=0):
- logstr = "RequireVpnRoutes %s" % str(wantroutes)
+ logstr = "RequireUnicastRoutes %s" % str(wantroutes)
vrfstr = ""
if vrf != "":
vrfstr = "vrf %s" % (vrf)
diff --git a/tests/topotests/ospf_gr_helper/test_ospf_gr_helper.py b/tests/topotests/ospf_gr_helper/test_ospf_gr_helper.py
index 2c7c6df37e..b7a10d630a 100644
--- a/tests/topotests/ospf_gr_helper/test_ospf_gr_helper.py
+++ b/tests/topotests/ospf_gr_helper/test_ospf_gr_helper.py
@@ -100,6 +100,8 @@ TC8. Verify helper functionality when dut is helping RR and new grace lsa
def setup_module(mod):
+ return pytest.skip("OSPF GR helper mode is currently broken")
+
"""
Sets up the pytest environment
diff --git a/tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py b/tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py
index debf7ad766..4b69d82887 100755
--- a/tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py
+++ b/tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py
@@ -139,6 +139,8 @@ def build_topo(tgen):
def setup_module(mod):
+ return pytest.skip("OSPF GR helper mode is currently broken")
+
"Sets up the pytest environment"
tgen = Topogen(build_topo, mod.__name__)
tgen.start_topology()
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 9610f71d09..ab3e55d100 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -493,8 +493,8 @@ static int rtadv_timer(struct thread *thread)
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
FOR_ALL_INTERFACES (vrf, ifp) {
- if (if_is_loopback_or_vrf(ifp)
- || !if_is_operative(ifp))
+ if (if_is_loopback_or_vrf(ifp) || !if_is_operative(ifp)
+ || (vrf_is_backend_netns() && ifp->vrf_id != zvrf->vrf->vrf_id))
continue;
zif = ifp->info;
diff --git a/zebra/table_manager.c b/zebra/table_manager.c
index 9f3b44f944..82d6a0a6a2 100644
--- a/zebra/table_manager.c
+++ b/zebra/table_manager.c
@@ -82,7 +82,6 @@ void table_manager_enable(struct zebra_vrf *zvrf)
zvrf->tbl_mgr = XCALLOC(MTYPE_TM_TABLE, sizeof(struct table_manager));
zvrf->tbl_mgr->lc_list = list_new();
zvrf->tbl_mgr->lc_list->del = delete_table_chunk;
- hook_register(zserv_client_close, release_daemon_table_chunks);
}
/**
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index ec68f585e3..b1d2f1f0b3 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -613,7 +613,7 @@ static int zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt)
int count = 0;
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
- ifp = if_lookup_by_name_vrf(ifname, vrf);
+ ifp = if_lookup_by_name_vrf(port_str, vrf);
if (ifp) {
count++;
if (!vrf_is_backend_netns())
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index d051ed67a0..66d6d4b4f2 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -705,6 +705,8 @@ void zebra_vrf_init(void)
vrf_init(zebra_vrf_new, zebra_vrf_enable, zebra_vrf_disable,
zebra_vrf_delete, zebra_vrf_update);
+ hook_register(zserv_client_close, release_daemon_table_chunks);
+
vrf_cmd_init(vrf_config_write);
if (vrf_is_backend_netns() && ns_have_netns()) {