frr: update to 7.4 and latest backports

changelogs: https://github.com/FRRouting/frr/releases/tag/frr-7.4

Signed-off-by: Lucian Cristian <lucian.cristian@gmail.com>
This commit is contained in:
Lucian Cristian 2020-07-24 18:50:07 +03:00
parent 9441e45176
commit 8c0d17cf5d
17 changed files with 1518 additions and 6424 deletions

View File

@ -7,14 +7,17 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=frr
PKG_VERSION:=7.3.1
PKG_VERSION:=7.4
PKG_RELEASE:=1
PKG_SOURCE_URL:=https://github.com/FRRouting/frr/releases/download/$(PKG_NAME)-$(PKG_VERSION)/
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_HASH:=85571b63d2774329b7e97871e4761f852066a17e99a8daae9972c6bd7a533e05
PKG_SOURCE_URL:=https://github.com/FRRouting/frr/archive/
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_HASH:=3c8204fda1c9b178d8446562579bbbc49d134b98f3ad02aa56f68724a2f9e40a
PKG_MAINTAINER:=Lucian Cristian <lucian.cristian@gmail.com>
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_NAME)-$(PKG_VERSION)
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_NAME)-$(PKG_VERSION)
PKG_LICENSE:=GPL-2.0-only LGPL-2.1-only
PKG_DAEMON_AVAILABLE:= \

View File

@ -0,0 +1,69 @@
From 34f6d0c67a48e2117c061f6ccdcf1f512982fe8f Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@cumulusnetworks.com>
Date: Tue, 2 Jun 2020 16:10:48 -0400
Subject: [PATCH] bgpd: Actually find the sequence number for `bgp
extcommunity-list...`
The code in the bgp extcommunity-list function was using
argv_find to get the correct idx. The problem was that
we had already done argv_finds before and idx was non-zero
thus having us always set the seq pointer to what was last
looked up. This causes us to pass in a value to the
underlying function and it would just wisely ignore it
causing a seq number of 0.
We would then write this seq number of 0 and then immediately
reject it on read in again. BOO!
Actually handle argv_find the way it was meant to be.
Ticket:CM-29926
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
---
bgpd/bgp_vty.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 3669205ee3..9c8f1e1def 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -17617,8 +17617,7 @@ DEFUN (extcommunity_list_standard,
argv_find(argv, argc, "WORD", &idx);
cl_number_or_name = argv[idx]->arg;
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
+ if (argv_find(argv, argc, "(1-4294967295)", &idx))
seq = argv[idx]->arg;
direct = argv_find(argv, argc, "permit", &idx) ? COMMUNITY_PERMIT
@@ -17663,8 +17662,7 @@ DEFUN (extcommunity_list_name_expanded,
argv_find(argv, argc, "WORD", &idx);
cl_number_or_name = argv[idx]->arg;
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
+ if (argv_find(argv, argc, "(1-4294967295)", &idx))
seq = argv[idx]->arg;
direct = argv_find(argv, argc, "permit", &idx) ? COMMUNITY_PERMIT
@@ -17707,8 +17705,7 @@ DEFUN (no_extcommunity_list_standard_all,
char *seq = NULL;
int idx = 0;
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
+ if (argv_find(argv, argc, "(1-4294967295)", &idx))
seq = argv[idx]->arg;
idx = 0;
@@ -17772,8 +17769,7 @@ DEFUN (no_extcommunity_list_expanded_all,
char *seq = NULL;
int idx = 0;
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
+ if (argv_find(argv, argc, "(1-4294967295)", &idx))
seq = argv[idx]->arg;
idx = 0;

View File

@ -0,0 +1,83 @@
From acf6f22d150b0050afbdaf5887b8e25d1614db4c Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas.abraitis@gmail.com>
Date: Thu, 2 Jul 2020 11:08:29 +0300
Subject: [PATCH 1/2] bgpd: Return bool type for ecommunity_add_val and
subgroup_announce_check
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
---
bgpd/bgp_ecommunity.c | 6 +++---
bgpd/bgp_route.c | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index d13da74b04..7d5cac4d62 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -107,14 +107,14 @@ bool ecommunity_add_val(struct ecommunity *ecom, struct ecommunity_val *eval,
p[1] == eval->val[1]) {
if (overwrite) {
memcpy(p, eval->val, ECOMMUNITY_SIZE);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
}
int ret = memcmp(p, eval->val, ECOMMUNITY_SIZE);
if (ret == 0)
- return 0;
+ return false;
if (ret > 0) {
if (!unique)
break;
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 6ae7a59a14..7bfefde482 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1941,7 +1941,7 @@ bool subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
/* Codification of AS 0 Processing */
if (aspath_check_as_zero(attr->aspath))
- return 0;
+ return false;
if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
if (peer->sort == BGP_PEER_IBGP
From d5a157b7c377081d23b136b5ba4849abdcbecd97 Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas.abraitis@gmail.com>
Date: Thu, 2 Jul 2020 11:39:40 +0300
Subject: [PATCH 2/2] bgpd: Actually find the sequence number for
large-community-list
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
---
bgpd/bgp_vty.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 9c8f1e1def..67ff31df8f 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -17235,8 +17235,7 @@ static int lcommunity_list_set_vty(struct vty *vty, int argc,
char *cl_name;
char *seq = NULL;
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
+ if (argv_find(argv, argc, "(1-4294967295)", &idx))
seq = argv[idx]->arg;
idx = 0;
@@ -17285,8 +17284,7 @@ static int lcommunity_list_unset_vty(struct vty *vty, int argc,
int idx = 0;
char *seq = NULL;
- argv_find(argv, argc, "(1-4294967295)", &idx);
- if (idx)
+ if (argv_find(argv, argc, "(1-4294967295)", &idx))
seq = argv[idx]->arg;
idx = 0;

View File

@ -1,26 +0,0 @@
--- a/zebra/zebra_nhg.c 2019-10-18 01:59:17.582282539 +0300
+++ b/zebra/zebra_nhg.c 2019-10-18 02:00:17.501997253 +0300
@@ -1456,20 +1456,9 @@
while (rn) {
route_unlock_node(rn);
- /* Lookup should halt if we've matched against ourselves ('top',
- * if specified) - i.e., we cannot have a nexthop NH1 is
- * resolved by a route NH1. The exception is if the route is a
- * host route.
- */
- if (top && rn == top)
- if (((afi == AFI_IP) && (rn->p.prefixlen != 32))
- || ((afi == AFI_IP6) && (rn->p.prefixlen != 128))) {
- if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug(
- "\t%s: Matched against ourself and prefix length is not max bit length",
- __PRETTY_FUNCTION__);
- return 0;
- }
+ /* If lookup self prefix return immediately. */
+ if (rn == top)
+ return 0;
/* Pick up selected route. */
/* However, do not resolve over default route unless explicitly

View File

@ -0,0 +1,29 @@
From cc45875e0d2af0b53100ec78364dc51b39a12ac9 Mon Sep 17 00:00:00 2001
From: Rafael Zalamena <rzalamena@opensourcerouting.org>
Date: Mon, 6 Jul 2020 11:39:27 -0300
Subject: [PATCH] lib: fix route map description memory leak
Route map entries are not getting a chance to call `description` string
deallocation on shutdown or when the parent entry is destroyed, so lets
add a code to handle this in the `route_map_index_delete` function.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
(cherry picked from commit f0951335830203426074ddca4317f84b477e4afb)
---
lib/routemap.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/routemap.c b/lib/routemap.c
index 3d69a3495a..3b45133450 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -971,6 +971,9 @@ void route_map_index_delete(struct route_map_index *index, int notify)
zlog_debug("Deleting route-map %s sequence %d",
index->map->name, index->pref);
+ /* Free route map entry description. */
+ XFREE(MTYPE_TMP, index->description);
+
/* Free route map northbound hook contexts. */
while ((rhc = TAILQ_FIRST(&index->rhclist)) != NULL)
routemap_hook_context_free(rhc);

View File

@ -0,0 +1,288 @@
From 2939f712d152f7e3ae438cc0f1d96dd9485e7487 Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas.abraitis@gmail.com>
Date: Thu, 9 Jul 2020 16:00:27 +0300
Subject: [PATCH 1/2] bgpd: Add command to show only established sessions
```
exit1-debian-9# show bgp summary
IPv4 Unicast Summary:
BGP router identifier 192.168.0.1, local AS number 100 vrf-id 0
BGP table version 8
RIB entries 15, using 2880 bytes of memory
Peers 2, using 43 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt
192.168.0.2 4 200 10 6 0 0 0 00:00:35 8 8
2a02:4780::2 4 0 0 1 0 0 0 never Active 0
Total number of neighbors 2
exit1-debian-9# show bgp summary established
IPv4 Unicast Summary:
BGP router identifier 192.168.0.1, local AS number 100 vrf-id 0
BGP table version 8
RIB entries 15, using 2880 bytes of memory
Peers 2, using 43 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt
192.168.0.2 4 200 10 6 0 0 0 00:00:39 8 8
Total number of neighbors 2
exit1-debian-9# show bgp summary failed
IPv4 Unicast Summary:
BGP router identifier 192.168.0.1, local AS number 100 vrf-id 0
BGP table version 8
RIB entries 15, using 2880 bytes of memory
Peers 2, using 43 KiB of memory
Neighbor EstdCnt DropCnt ResetTime Reason
2a02:4780::2 0 0 never Waiting for peer OPEN
Total number of neighbors 2
exit1-debian-9#
```
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
---
bgpd/bgp_evpn_vty.c | 11 ++++++++---
bgpd/bgp_vty.c | 43 +++++++++++++++++++++++++++++++------------
bgpd/bgp_vty.h | 3 ++-
3 files changed, 41 insertions(+), 16 deletions(-)
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 85604d856d..42987117d4 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -4077,7 +4077,7 @@ DEFUN(show_bgp_l2vpn_evpn_es,
*/
DEFUN(show_bgp_l2vpn_evpn_summary,
show_bgp_l2vpn_evpn_summary_cmd,
- "show bgp [vrf VRFNAME] l2vpn evpn summary [failed] [json]",
+ "show bgp [vrf VRFNAME] l2vpn evpn summary [established|failed] [json]",
SHOW_STR
BGP_STR
"bgp vrf\n"
@@ -4085,6 +4085,7 @@ DEFUN(show_bgp_l2vpn_evpn_summary,
L2VPN_HELP_STR
EVPN_HELP_STR
"Summary of BGP neighbor status\n"
+ "Show only sessions in Established state\n"
"Show only sessions not in Established state\n"
JSON_STR)
{
@@ -4092,13 +4093,17 @@ DEFUN(show_bgp_l2vpn_evpn_summary,
bool uj = use_json(argc, argv);
char *vrf = NULL;
bool show_failed = false;
+ bool show_established = false;
if (argv_find(argv, argc, "vrf", &idx_vrf))
vrf = argv[++idx_vrf]->arg;
if (argv_find(argv, argc, "failed", &idx_vrf))
show_failed = true;
- return bgp_show_summary_vty(vty, vrf, AFI_L2VPN, SAFI_EVPN,
- show_failed, uj);
+ if (argv_find(argv, argc, "established", &idx_vrf))
+ show_established = true;
+
+ return bgp_show_summary_vty(vty, vrf, AFI_L2VPN, SAFI_EVPN, show_failed,
+ show_established, uj);
}
/*
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 67ff31df8f..78521457fd 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -8772,7 +8772,8 @@ static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp,
/* Show BGP peer's summary information. */
static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
- bool show_failed, bool use_json)
+ bool show_failed, bool show_established,
+ bool use_json)
{
struct peer *peer;
struct listnode *node, *nnode;
@@ -9104,6 +9105,10 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
bgp_show_failed_summary(vty, bgp, peer,
json_peer, 0, use_json);
} else if (!show_failed) {
+ if (show_established
+ && bgp_has_peer_failed(peer, afi, safi))
+ continue;
+
json_peer = json_object_new_object();
if (peer_dynamic_neighbor(peer)) {
json_object_boolean_true_add(json_peer,
@@ -9193,6 +9198,10 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
max_neighbor_width,
use_json);
} else if (!show_failed) {
+ if (show_established
+ && bgp_has_peer_failed(peer, afi, safi))
+ continue;
+
memset(dn_flag, '\0', sizeof(dn_flag));
if (peer_dynamic_neighbor(peer)) {
dn_flag[0] = '*';
@@ -9315,7 +9324,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
}
static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
- int safi, bool show_failed, bool use_json)
+ int safi, bool show_failed,
+ bool show_established, bool use_json)
{
int is_first = 1;
int afi_wildcard = (afi == AFI_MAX);
@@ -9358,7 +9368,8 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
false));
}
}
- bgp_show_summary(vty, bgp, afi, safi, show_failed,
+ bgp_show_summary(vty, bgp, afi, safi,
+ show_failed, show_established,
use_json);
}
safi++;
@@ -9382,6 +9393,7 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
safi_t safi, bool show_failed,
+ bool show_established,
bool use_json)
{
struct listnode *node, *nnode;
@@ -9411,7 +9423,7 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
: bgp->name);
}
bgp_show_summary_afi_safi(vty, bgp, afi, safi, show_failed,
- use_json);
+ show_established, use_json);
}
if (use_json)
@@ -9421,15 +9433,16 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
}
int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
- safi_t safi, bool show_failed, bool use_json)
+ safi_t safi, bool show_failed, bool show_established,
+ bool use_json)
{
struct bgp *bgp;
if (name) {
if (strmatch(name, "all")) {
- bgp_show_all_instances_summary_vty(vty, afi, safi,
- show_failed,
- use_json);
+ bgp_show_all_instances_summary_vty(
+ vty, afi, safi, show_failed, show_established,
+ use_json);
return CMD_SUCCESS;
} else {
bgp = bgp_lookup_by_name(name);
@@ -9444,7 +9457,8 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
}
bgp_show_summary_afi_safi(vty, bgp, afi, safi,
- show_failed, use_json);
+ show_failed, show_established,
+ use_json);
return CMD_SUCCESS;
}
}
@@ -9453,7 +9467,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
if (bgp)
bgp_show_summary_afi_safi(vty, bgp, afi, safi, show_failed,
- use_json);
+ show_established, use_json);
else {
if (use_json)
vty_out(vty, "{}\n");
@@ -9468,7 +9482,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
/* `show [ip] bgp summary' commands. */
DEFUN (show_ip_bgp_summary,
show_ip_bgp_summary_cmd,
- "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] summary [failed] [json]",
+ "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] summary [established|failed] [json]",
SHOW_STR
IP_STR
BGP_STR
@@ -9476,6 +9490,7 @@ DEFUN (show_ip_bgp_summary,
BGP_AFI_HELP_STR
BGP_SAFI_WITH_LABEL_HELP_STR
"Summary of BGP neighbor status\n"
+ "Show only sessions in Established state\n"
"Show only sessions not in Established state\n"
JSON_STR)
{
@@ -9483,6 +9498,7 @@ DEFUN (show_ip_bgp_summary,
afi_t afi = AFI_MAX;
safi_t safi = SAFI_MAX;
bool show_failed = false;
+ bool show_established = false;
int idx = 0;
@@ -9504,10 +9520,13 @@ DEFUN (show_ip_bgp_summary,
if (argv_find(argv, argc, "failed", &idx))
show_failed = true;
+ if (argv_find(argv, argc, "established", &idx))
+ show_established = true;
bool uj = use_json(argc, argv);
- return bgp_show_summary_vty(vty, vrf, afi, safi, show_failed, uj);
+ return bgp_show_summary_vty(vty, vrf, afi, safi, show_failed,
+ show_established, uj);
}
const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json)
diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h
index d6ca198d09..95eefbc36f 100644
--- a/bgpd/bgp_vty.h
+++ b/bgpd/bgp_vty.h
@@ -178,6 +178,7 @@ extern int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
int bgp_vty_find_and_parse_bgp(struct vty *vty, struct cmd_token **argv,
int argc, struct bgp **bgp, bool use_json);
extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
- safi_t safi, bool show_failed, bool use_json);
+ safi_t safi, bool show_failed,
+ bool show_established, bool use_json);
#endif /* _QUAGGA_BGP_VTY_H */
From 2600443342d8e21d30df2b6ca095a5f2d0d4de2d Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas.abraitis@gmail.com>
Date: Thu, 9 Jul 2020 16:05:08 +0300
Subject: [PATCH 2/2] doc: Add 'show bgp summary established' command
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
---
doc/user/bgp.rst | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index cb343e8dad..36227db604 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -2710,6 +2710,12 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`.
Show a bgp peer summary for peers that are not succesfully exchanging routes
for the specified address family, and subsequent address-family.
+.. index:: show bgp [afi] [safi] summary established [json]
+.. clicmd:: show bgp [afi] [safi] summary established [json]
+
+ Show a bgp peer summary for peers that are succesfully exchanging routes
+ for the specified address family, and subsequent address-family.
+
.. index:: show bgp [afi] [safi] neighbor [PEER]
.. clicmd:: show bgp [afi] [safi] neighbor [PEER]

View File

@ -0,0 +1,57 @@
From 692ce87393de9497a7821e9e0856ff70a7973ff6 Mon Sep 17 00:00:00 2001
From: Paul Manley <paul.manley@wholefoods.com>
Date: Thu, 9 Jul 2020 11:21:16 -0500
Subject: [PATCH 1/2] tools: create sub-context for bfd peers
add lines starting with 'peer' to the list of sub-contexts that are handled by frr-reload.py.
https://github.com/FRRouting/frr/issues/6511#issuecomment-655163833
Signed-off-by: Paul Manley <paul.manley@wholefoods.com>
(cherry picked from commit 1c23a0aaa1c5d20af50af75b070e93e1eff21222)
---
tools/frr-reload.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index d4020cdfc9..e9641b2b13 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -496,6 +496,7 @@ def load_contexts(self):
line.startswith("vnc defaults") or
line.startswith("vnc l2-group") or
line.startswith("vnc nve-group") or
+ line.startswith("peer") or
line.startswith("member pseudowire")):
main_ctx_key = []
From 2604086c3d9face0aca2497a982782c865bb2b59 Mon Sep 17 00:00:00 2001
From: Paul Manley <paul.manley@wholefoods.com>
Date: Thu, 9 Jul 2020 11:25:34 -0500
Subject: [PATCH 2/2] vtysh: properly exit BFD_PEER_NODE when marking file
vtysh needs to be aware of how to properly exit a bfd peer when subsequent commands only succeed in a higher context.
https://github.com/FRRouting/frr/issues/6511#issuecomment-656166206
Signed-off-by: Paul Manley <paul.manley@wholefoods.com>
(cherry picked from commit b727c12aabf1afc2b6e33f8590c9786e349e4fcb)
---
vtysh/vtysh.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 15ec866fc9..4fdf68c0e6 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -809,6 +809,9 @@ int vtysh_mark_file(const char *filename)
} else if ((prev_node == KEYCHAIN_KEY_NODE)
&& (tried == 1)) {
vty_out(vty, "exit\n");
+ } else if ((prev_node == BFD_PEER_NODE)
+ && (tried == 1)) {
+ vty_out(vty, "exit\n");
} else if (tried) {
vty_out(vty, "end\n");
}

View File

@ -0,0 +1,120 @@
From cc5934ed5939315ba5d95bfaf052625762107205 Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@cumulusnetworks.com>
Date: Tue, 30 Jun 2020 08:59:46 -0400
Subject: [PATCH 1/2] vtysh: master is a non-sorted list
The commit:
a798241265a5808083a06b14ce1637d1ddf6a45a
attempted to use sorted master lists to do faster lookups
by using a RB Tree. Unfortunately the original code
was creating a list->cmp function *but* never using it.
If you look at the commit, it clearly shows that the
function listnode_add is used to insert but when you
look at that function it is a tail push.
Fixes: #6573
Namely now this ordering is preserved:
bgp as-path access-list originate-only permit ^$
bgp as-path access-list originate-only deny .*
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
---
vtysh/vtysh_config.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index abbb111f9d..2ab9dd5a9a 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -34,7 +34,7 @@ DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CONFIG_LINE, "Vtysh configuration line")
vector configvec;
-PREDECL_RBTREE_UNIQ(config_master);
+PREDECL_LIST(config_master);
struct config {
/* Configuration node name. */
@@ -72,11 +72,6 @@ static struct config *config_new(void)
return config;
}
-static int config_cmp(const struct config *c1, const struct config *c2)
-{
- return strcmp(c1->name, c2->name);
-}
-
static void config_del(struct config *config)
{
list_delete(&config->line);
@@ -84,13 +79,15 @@ static void config_del(struct config *config)
XFREE(MTYPE_VTYSH_CONFIG, config);
}
-DECLARE_RBTREE_UNIQ(config_master, struct config, rbt_item, config_cmp)
+DECLARE_LIST(config_master, struct config, rbt_item)
static struct config *config_get(int index, const char *line)
{
- struct config *config;
+ struct config *config, *config_loop;
struct config_master_head *master;
+ config = config_loop = NULL;
+
master = vector_lookup_ensure(configvec, index);
if (!master) {
@@ -99,8 +96,10 @@ static struct config *config_get(int index, const char *line)
vector_set_index(configvec, index, master);
}
- const struct config config_ref = { .name = (char *)line };
- config = config_master_find(master, &config_ref);
+ frr_each (config_master, master, config_loop) {
+ if (strcmp(config_loop->name, line) == 0)
+ config = config_loop;
+ }
if (!config) {
config = config_new();
@@ -109,7 +108,7 @@ static struct config *config_get(int index, const char *line)
config->line->cmp = (int (*)(void *, void *))line_cmp;
config->name = XSTRDUP(MTYPE_VTYSH_CONFIG_LINE, line);
config->index = index;
- config_master_add(master, config);
+ config_master_add_tail(master, config);
}
return config;
}
From 3e4d90ec556649e11954f2f56b5282f95e7e013b Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@cumulusnetworks.com>
Date: Tue, 30 Jun 2020 09:03:55 -0400
Subject: [PATCH 2/2] vtysh: Improve lookup performance
When we find the line we are interested in, stop looking.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
---
vtysh/vtysh_config.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index 2ab9dd5a9a..61bcf3b658 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -97,8 +97,10 @@ static struct config *config_get(int index, const char *line)
}
frr_each (config_master, master, config_loop) {
- if (strcmp(config_loop->name, line) == 0)
+ if (strcmp(config_loop->name, line) == 0) {
config = config_loop;
+ break;
+ }
}
if (!config) {

View File

@ -0,0 +1,835 @@
From c6a5994609deec62c8aefa1fa15c517e32575ca3 Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas.abraitis@gmail.com>
Date: Wed, 6 May 2020 17:45:31 +0300
Subject: [PATCH 1/4] tests: Remove bgp_show_ip_bgp_fqdn test
Not really relevant for now.
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
---
.../bgp_show_ip_bgp_fqdn/__init__.py | 0
.../bgp_show_ip_bgp_fqdn/r1/bgpd.conf | 5 -
.../bgp_show_ip_bgp_fqdn/r1/zebra.conf | 9 --
.../bgp_show_ip_bgp_fqdn/r2/bgpd.conf | 5 -
.../bgp_show_ip_bgp_fqdn/r2/zebra.conf | 12 --
.../bgp_show_ip_bgp_fqdn/r3/bgpd.conf | 3 -
.../bgp_show_ip_bgp_fqdn/r3/zebra.conf | 6 -
.../test_bgp_show_ip_bgp_fqdn.py | 133 ------------------
8 files changed, 173 deletions(-)
delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/__init__.py
delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf
delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf
delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf
delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf
delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/r3/bgpd.conf
delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/r3/zebra.conf
delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/__init__.py b/tests/topotests/bgp_show_ip_bgp_fqdn/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf
deleted file mode 100644
index f0df56e947..0000000000
--- a/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-router bgp 65000
- no bgp ebgp-requires-policy
- neighbor 192.168.255.2 remote-as 65001
- address-family ipv4 unicast
- redistribute connected
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf
deleted file mode 100644
index 0a283c06d5..0000000000
--- a/tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf
+++ /dev/null
@@ -1,9 +0,0 @@
-!
-interface lo
- ip address 172.16.255.254/32
-!
-interface r1-eth0
- ip address 192.168.255.1/24
-!
-ip forwarding
-!
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf
deleted file mode 100644
index 422a7345f9..0000000000
--- a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-router bgp 65001
- no bgp ebgp-requires-policy
- bgp default show-hostname
- neighbor 192.168.255.1 remote-as 65000
- neighbor 192.168.254.1 remote-as 65001
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf
deleted file mode 100644
index e9e2e4391f..0000000000
--- a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf
+++ /dev/null
@@ -1,12 +0,0 @@
-!
-interface lo
- ip address 172.16.255.253/32
-!
-interface r2-eth0
- ip address 192.168.255.2/24
-!
-interface r2-eth1
- ip address 192.168.254.2/24
-!
-ip forwarding
-!
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r3/bgpd.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r3/bgpd.conf
deleted file mode 100644
index 8fcf6a736d..0000000000
--- a/tests/topotests/bgp_show_ip_bgp_fqdn/r3/bgpd.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-router bgp 65001
- bgp default show-hostname
- neighbor 192.168.254.2 remote-as 65001
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r3/zebra.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r3/zebra.conf
deleted file mode 100644
index a8b8bc38c5..0000000000
--- a/tests/topotests/bgp_show_ip_bgp_fqdn/r3/zebra.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-!
-interface r3-eth0
- ip address 192.168.254.1/24
-!
-ip forwarding
-!
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py b/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py
deleted file mode 100644
index e8ad180935..0000000000
--- a/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/usr/bin/env python
-
-#
-# test_bgp_show_ip_bgp_fqdn.py
-# Part of NetDEF Topology Tests
-#
-# Copyright (c) 2019 by
-# Donatas Abraitis <donatas.abraitis@gmail.com>
-#
-# Permission to use, copy, modify, and/or distribute this software
-# for any purpose with or without fee is hereby granted, provided
-# that the above copyright notice and this permission notice appear
-# in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
-# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-# OF THIS SOFTWARE.
-#
-
-"""
-test_bgp_show_ip_bgp_fqdn.py:
-Test if FQND is visible in `show [ip] bgp` output if
-`bgp default show-hostname` is toggled.
-
-Topology:
-r1 <-- eBGP --> r2 <-- iBGP --> r3
-
-1. Check if both hostname and ip are added to JSON output
-for 172.16.255.254/32 on r2.
-2. Check if only ip is added to JSON output for 172.16.255.254/32 on r3.
-"""
-
-import os
-import sys
-import json
-import time
-import pytest
-import functools
-
-CWD = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(CWD, "../"))
-
-# pylint: disable=C0413
-from lib import topotest
-from lib.topogen import Topogen, TopoRouter, get_topogen
-from lib.topolog import logger
-from mininet.topo import Topo
-
-
-class TemplateTopo(Topo):
- def build(self, *_args, **_opts):
- tgen = get_topogen(self)
-
- for routern in range(1, 4):
- tgen.add_router("r{}".format(routern))
-
- switch = tgen.add_switch("s1")
- switch.add_link(tgen.gears["r1"])
- switch.add_link(tgen.gears["r2"])
-
- switch = tgen.add_switch("s2")
- switch.add_link(tgen.gears["r2"])
- switch.add_link(tgen.gears["r3"])
-
-
-def setup_module(mod):
- tgen = Topogen(TemplateTopo, mod.__name__)
- tgen.start_topology()
-
- router_list = tgen.routers()
-
- for i, (rname, router) in enumerate(router_list.iteritems(), 1):
- router.load_config(
- TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
- )
- router.load_config(
- TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
- )
-
- tgen.start_router()
-
-
-def teardown_module(mod):
- tgen = get_topogen()
- tgen.stop_topology()
-
-
-def test_bgp_show_ip_bgp_hostname():
- tgen = get_topogen()
-
- if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
-
- def _bgp_converge(router):
- output = json.loads(router.vtysh_cmd("show ip bgp 172.16.255.254/32 json"))
- expected = {"prefix": "172.16.255.254/32"}
- return topotest.json_cmp(output, expected)
-
- def _bgp_show_nexthop_hostname_and_ip(router):
- output = json.loads(router.vtysh_cmd("show ip bgp json"))
- for nh in output["routes"]["172.16.255.254/32"][0]["nexthops"]:
- if "hostname" in nh and "ip" in nh:
- return True
- return False
-
- def _bgp_show_nexthop_ip_only(router):
- output = json.loads(router.vtysh_cmd("show ip bgp json"))
- for nh in output["routes"]["172.16.255.254/32"][0]["nexthops"]:
- if "ip" in nh and not "hostname" in nh:
- return True
- return False
-
- test_func = functools.partial(_bgp_converge, tgen.gears["r2"])
- success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
-
- test_func = functools.partial(_bgp_converge, tgen.gears["r3"])
- success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
-
- assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r2"])
- assert _bgp_show_nexthop_hostname_and_ip(tgen.gears["r2"]) == True
-
- assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r3"])
- assert _bgp_show_nexthop_ip_only(tgen.gears["r3"]) == True
-
-
-if __name__ == "__main__":
- args = ["-s"] + sys.argv[1:]
- sys.exit(pytest.main(args))
From e7cc3d21452bd771a97bc46ab5a1e4853c46f944 Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas.abraitis@gmail.com>
Date: Wed, 6 May 2020 17:46:10 +0300
Subject: [PATCH 2/4] bgpd: Show the real next-hop address in addition to
hostname in `show bgp`
It's hard to cope with cases when next-hop is changed/unchanged or
peers are non-direct.
It would be better to show the hostname and nexthop IP address (both)
under `show bgp` to quickly identify the source and the real next-hop
of the route.
If `bgp default show-nexthop-hostname` is toggled the output looks like:
```
spine1-debian-9# show bgp
BGP table version is 1, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 65002
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
* 2a02:4780::/64 fe80::a00:27ff:fe09:f8a3(exit1-debian-9)
0 0 65001 ?
spine1-debian-9# show ip bgp
BGP table version is 5, local router ID is 2.2.2.2, vrf id 0
Default local pref 100, local AS 65002
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 10.255.255.0/24 192.168.0.1(exit1-debian-9)
0 0 65001 ?
```
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
---
bgpd/bgp_route.c | 161 ++++++++++++++++++++++++++++++-----------------
bgpd/bgp_vty.c | 45 +++++++++++++
bgpd/bgpd.h | 1 +
3 files changed, 149 insertions(+), 58 deletions(-)
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 7bfefde482..f033f525e5 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -7559,8 +7559,7 @@ static char *bgp_nexthop_hostname(struct peer *peer,
struct bgp_nexthop_cache *bnc)
{
if (peer->hostname
- && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME) && bnc
- && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
+ && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
return peer->hostname;
return NULL;
}
@@ -7570,6 +7569,7 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
struct bgp_path_info *path, int display, safi_t safi,
json_object *json_paths)
{
+ int len;
struct attr *attr = path->attr;
json_object *json_path = NULL;
json_object *json_nexthops = NULL;
@@ -7681,10 +7681,19 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
: "ipv6");
json_object_boolean_true_add(json_nexthop_global,
"used");
- } else
- vty_out(vty, "%s%s",
- nexthop_hostname ? nexthop_hostname : nexthop,
- vrf_id_str);
+ } else {
+ if (nexthop_hostname)
+ len = vty_out(vty, "%s(%s)%s", nexthop,
+ nexthop_hostname, vrf_id_str);
+ else
+ len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
+
+ len = 16 - len;
+ if (len < 1)
+ vty_out(vty, "\n%*s", 36, " ");
+ else
+ vty_out(vty, "%*s", len, " ");
+ }
} else if (safi == SAFI_EVPN) {
if (json_paths) {
json_nexthop_global = json_object_new_object();
@@ -7701,11 +7710,20 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
"ipv4");
json_object_boolean_true_add(json_nexthop_global,
"used");
- } else
- vty_out(vty, "%-16s%s",
- nexthop_hostname ? nexthop_hostname
- : inet_ntoa(attr->nexthop),
- vrf_id_str);
+ } else {
+ if (nexthop_hostname)
+ len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
+ nexthop_hostname, vrf_id_str);
+ else
+ len = vty_out(vty, "%pI4%s", &attr->nexthop,
+ vrf_id_str);
+
+ len = 16 - len;
+ if (len < 1)
+ vty_out(vty, "\n%*s", 36, " ");
+ else
+ vty_out(vty, "%*s", len, " ");
+ }
} else if (safi == SAFI_FLOWSPEC) {
if (attr->nexthop.s_addr != INADDR_ANY) {
if (json_paths) {
@@ -7726,10 +7744,21 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
json_nexthop_global,
"used");
} else {
- vty_out(vty, "%-16s",
- nexthop_hostname
- ? nexthop_hostname
- : inet_ntoa(attr->nexthop));
+ if (nexthop_hostname)
+ len = vty_out(vty, "%pI4(%s)%s",
+ &attr->nexthop,
+ nexthop_hostname,
+ vrf_id_str);
+ else
+ len = vty_out(vty, "%pI4%s",
+ &attr->nexthop,
+ vrf_id_str);
+
+ len = 16 - len;
+ if (len < 1)
+ vty_out(vty, "\n%*s", 36, " ");
+ else
+ vty_out(vty, "%*s", len, " ");
}
}
} else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
@@ -7749,19 +7778,23 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
json_object_boolean_true_add(json_nexthop_global,
"used");
} else {
- char buf[BUFSIZ];
+ if (nexthop_hostname)
+ len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
+ nexthop_hostname, vrf_id_str);
+ else
+ len = vty_out(vty, "%pI4%s", &attr->nexthop,
+ vrf_id_str);
- snprintf(buf, sizeof(buf), "%s%s",
- nexthop_hostname ? nexthop_hostname
- : inet_ntoa(attr->nexthop),
- vrf_id_str);
- vty_out(vty, "%-16s", buf);
+ len = 16 - len;
+ if (len < 1)
+ vty_out(vty, "\n%*s", 36, " ");
+ else
+ vty_out(vty, "%*s", len, " ");
}
}
/* IPv6 Next Hop */
else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
- int len;
char buf[BUFSIZ];
if (json_paths) {
@@ -7835,15 +7868,18 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
else
vty_out(vty, "%*s", len, " ");
} else {
- len = vty_out(
- vty, "%s%s",
- nexthop_hostname
- ? nexthop_hostname
- : inet_ntop(
- AF_INET6,
- &attr->mp_nexthop_local,
- buf, BUFSIZ),
- vrf_id_str);
+ if (nexthop_hostname)
+ len = vty_out(
+ vty, "%pI6(%s)%s",
+ &attr->mp_nexthop_local,
+ nexthop_hostname,
+ vrf_id_str);
+ else
+ len = vty_out(
+ vty, "%pI6%s",
+ &attr->mp_nexthop_local,
+ vrf_id_str);
+
len = 16 - len;
if (len < 1)
@@ -7852,15 +7888,16 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
vty_out(vty, "%*s", len, " ");
}
} else {
- len = vty_out(
- vty, "%s%s",
- nexthop_hostname
- ? nexthop_hostname
- : inet_ntop(
- AF_INET6,
- &attr->mp_nexthop_global,
- buf, BUFSIZ),
- vrf_id_str);
+ if (nexthop_hostname)
+ len = vty_out(vty, "%pI6(%s)%s",
+ &attr->mp_nexthop_global,
+ nexthop_hostname,
+ vrf_id_str);
+ else
+ len = vty_out(vty, "%pI6%s",
+ &attr->mp_nexthop_global,
+ vrf_id_str);
+
len = 16 - len;
if (len < 1)
@@ -7986,6 +8023,7 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
{
json_object *json_status = NULL;
json_object *json_net = NULL;
+ int len;
char buff[BUFSIZ];
/* Route status display. */
@@ -8079,7 +8117,6 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
inet_ntoa(attr->nexthop));
} else if (p->family == AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
- int len;
char buf[BUFSIZ];
len = vty_out(
@@ -8823,12 +8860,15 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
json_object_string_add(
json_nexthop_global, "hostname",
nexthop_hostname);
- } else
- vty_out(vty, " %s",
- nexthop_hostname
- ? nexthop_hostname
- : inet_ntoa(
- attr->mp_nexthop_global_in));
+ } else {
+ if (nexthop_hostname)
+ vty_out(vty, " %pI4(%s)",
+ &attr->mp_nexthop_global_in,
+ nexthop_hostname);
+ else
+ vty_out(vty, " %pI4",
+ &attr->mp_nexthop_global_in);
+ }
} else {
if (json_paths) {
json_object_string_add(
@@ -8839,11 +8879,15 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
json_object_string_add(
json_nexthop_global, "hostname",
nexthop_hostname);
- } else
- vty_out(vty, " %s",
- nexthop_hostname
- ? nexthop_hostname
- : inet_ntoa(attr->nexthop));
+ } else {
+ if (nexthop_hostname)
+ vty_out(vty, " %pI4(%s)",
+ &attr->nexthop,
+ nexthop_hostname);
+ else
+ vty_out(vty, " %pI4",
+ &attr->nexthop);
+ }
}
if (json_paths)
@@ -8866,12 +8910,13 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
json_object_string_add(json_nexthop_global, "scope",
"global");
} else {
- vty_out(vty, " %s",
- nexthop_hostname
- ? nexthop_hostname
- : inet_ntop(AF_INET6,
- &attr->mp_nexthop_global,
- buf, INET6_ADDRSTRLEN));
+ if (nexthop_hostname)
+ vty_out(vty, " %pI6(%s)",
+ &attr->mp_nexthop_global,
+ nexthop_hostname);
+ else
+ vty_out(vty, " %pI6",
+ &attr->mp_nexthop_global);
}
}
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 78521457fd..7f00ff3fbe 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -84,6 +84,10 @@ FRR_CFG_DEFAULT_BOOL(BGP_SHOW_HOSTNAME,
{ .val_bool = true, .match_profile = "datacenter", },
{ .val_bool = false },
)
+FRR_CFG_DEFAULT_BOOL(BGP_SHOW_NEXTHOP_HOSTNAME,
+ { .val_bool = true, .match_profile = "datacenter", },
+ { .val_bool = false },
+)
FRR_CFG_DEFAULT_BOOL(BGP_LOG_NEIGHBOR_CHANGES,
{ .val_bool = true, .match_profile = "datacenter", },
{ .val_bool = false },
@@ -422,6 +426,8 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
SET_FLAG((*bgp)->flags, BGP_FLAG_IMPORT_CHECK);
if (DFLT_BGP_SHOW_HOSTNAME)
SET_FLAG((*bgp)->flags, BGP_FLAG_SHOW_HOSTNAME);
+ if (DFLT_BGP_SHOW_NEXTHOP_HOSTNAME)
+ SET_FLAG((*bgp)->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
if (DFLT_BGP_LOG_NEIGHBOR_CHANGES)
SET_FLAG((*bgp)->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
if (DFLT_BGP_DETERMINISTIC_MED)
@@ -3100,6 +3106,32 @@ DEFUN (no_bgp_default_show_hostname,
return CMD_SUCCESS;
}
+/* Display hostname in certain command outputs */
+DEFUN (bgp_default_show_nexthop_hostname,
+ bgp_default_show_nexthop_hostname_cmd,
+ "bgp default show-nexthop-hostname",
+ "BGP specific commands\n"
+ "Configure BGP defaults\n"
+ "Show hostname for nexthop in certain command outputs\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ SET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_default_show_nexthop_hostname,
+ no_bgp_default_show_nexthop_hostname_cmd,
+ "no bgp default show-nexthop-hostname",
+ NO_STR
+ "BGP specific commands\n"
+ "Configure BGP defaults\n"
+ "Show hostname for nexthop in certain command outputs\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
+ return CMD_SUCCESS;
+}
+
/* "bgp network import-check" configuration. */
DEFUN (bgp_network_import_check,
bgp_network_import_check_cmd,
@@ -15190,6 +15222,15 @@ int bgp_config_write(struct vty *vty)
? ""
: "no ");
+ /* BGP default show-nexthop-hostname */
+ if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME)
+ != SAVE_BGP_SHOW_HOSTNAME)
+ vty_out(vty, " %sbgp default show-nexthop-hostname\n",
+ CHECK_FLAG(bgp->flags,
+ BGP_FLAG_SHOW_NEXTHOP_HOSTNAME)
+ ? ""
+ : "no ");
+
/* BGP default subgroup-pkt-queue-max. */
if (bgp->default_subgroup_pkt_queue_max
!= BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX)
@@ -15815,6 +15856,10 @@ void bgp_vty_init(void)
install_element(BGP_NODE, &bgp_default_show_hostname_cmd);
install_element(BGP_NODE, &no_bgp_default_show_hostname_cmd);
+ /* bgp default show-nexthop-hostname */
+ install_element(BGP_NODE, &bgp_default_show_nexthop_hostname_cmd);
+ install_element(BGP_NODE, &no_bgp_default_show_nexthop_hostname_cmd);
+
/* "bgp default subgroup-pkt-queue-max" commands. */
install_element(BGP_NODE, &bgp_default_subgroup_pkt_queue_max_cmd);
install_element(BGP_NODE, &no_bgp_default_subgroup_pkt_queue_max_cmd);
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 4a5772a53b..4efc068dea 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -447,6 +447,7 @@ struct bgp {
#define BGP_FLAG_SELECT_DEFER_DISABLE (1 << 23)
#define BGP_FLAG_GR_DISABLE_EOR (1 << 24)
#define BGP_FLAG_EBGP_REQUIRES_POLICY (1 << 25)
+#define BGP_FLAG_SHOW_NEXTHOP_HOSTNAME (1 << 26)
enum global_mode GLOBAL_GR_FSM[BGP_GLOBAL_GR_MODE]
[BGP_GLOBAL_GR_EVENT_CMD];
From 104dfe5258cbeb0443fa4d6577794a1e5a5dafd3 Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas.abraitis@gmail.com>
Date: Wed, 6 May 2020 17:50:04 +0300
Subject: [PATCH 3/4] bgpd: Add "hostname" in JSON output for `show bgp` family
outputs
This adds hostname regardless if `bgp default show-hostname` enabled or not.
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
---
bgpd/bgp_route.c | 40 ++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index f033f525e5..5f645fa871 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -7671,10 +7671,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
json_object_string_add(json_nexthop_global, "ip",
nexthop);
- if (nexthop_hostname)
+ if (path->peer->hostname)
json_object_string_add(json_nexthop_global,
"hostname",
- nexthop_hostname);
+ path->peer->hostname);
json_object_string_add(json_nexthop_global, "afi",
(af == AF_INET) ? "ipv4"
@@ -7701,10 +7701,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
json_object_string_add(json_nexthop_global, "ip",
inet_ntoa(attr->nexthop));
- if (nexthop_hostname)
+ if (path->peer->hostname)
json_object_string_add(json_nexthop_global,
"hostname",
- nexthop_hostname);
+ path->peer->hostname);
json_object_string_add(json_nexthop_global, "afi",
"ipv4");
@@ -7735,10 +7735,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
json_nexthop_global, "ip",
inet_ntoa(attr->nexthop));
- if (nexthop_hostname)
+ if (path->peer->hostname)
json_object_string_add(
json_nexthop_global, "hostname",
- nexthop_hostname);
+ path->peer->hostname);
json_object_boolean_true_add(
json_nexthop_global,
@@ -7768,10 +7768,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
json_object_string_add(json_nexthop_global, "ip",
inet_ntoa(attr->nexthop));
- if (nexthop_hostname)
+ if (path->peer->hostname)
json_object_string_add(json_nexthop_global,
"hostname",
- nexthop_hostname);
+ path->peer->hostname);
json_object_string_add(json_nexthop_global, "afi",
"ipv4");
@@ -7804,10 +7804,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
inet_ntop(AF_INET6, &attr->mp_nexthop_global,
buf, BUFSIZ));
- if (nexthop_hostname)
+ if (path->peer->hostname)
json_object_string_add(json_nexthop_global,
"hostname",
- nexthop_hostname);
+ path->peer->hostname);
json_object_string_add(json_nexthop_global, "afi",
"ipv6");
@@ -7826,10 +7826,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
&attr->mp_nexthop_local, buf,
BUFSIZ));
- if (nexthop_hostname)
+ if (path->peer->hostname)
json_object_string_add(
json_nexthop_ll, "hostname",
- nexthop_hostname);
+ path->peer->hostname);
json_object_string_add(json_nexthop_ll, "afi",
"ipv6");
@@ -8856,10 +8856,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
json_nexthop_global, "ip",
inet_ntoa(attr->mp_nexthop_global_in));
- if (nexthop_hostname)
+ if (path->peer->hostname)
json_object_string_add(
json_nexthop_global, "hostname",
- nexthop_hostname);
+ path->peer->hostname);
} else {
if (nexthop_hostname)
vty_out(vty, " %pI4(%s)",
@@ -8875,10 +8875,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
json_nexthop_global, "ip",
inet_ntoa(attr->nexthop));
- if (nexthop_hostname)
+ if (path->peer->hostname)
json_object_string_add(
json_nexthop_global, "hostname",
- nexthop_hostname);
+ path->peer->hostname);
} else {
if (nexthop_hostname)
vty_out(vty, " %pI4(%s)",
@@ -8900,10 +8900,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
inet_ntop(AF_INET6, &attr->mp_nexthop_global,
buf, INET6_ADDRSTRLEN));
- if (nexthop_hostname)
+ if (path->peer->hostname)
json_object_string_add(json_nexthop_global,
"hostname",
- nexthop_hostname);
+ path->peer->hostname);
json_object_string_add(json_nexthop_global, "afi",
"ipv6");
@@ -9094,10 +9094,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
inet_ntop(AF_INET6, &attr->mp_nexthop_local,
buf, INET6_ADDRSTRLEN));
- if (nexthop_hostname)
+ if (path->peer->hostname)
json_object_string_add(json_nexthop_ll,
"hostname",
- nexthop_hostname);
+ path->peer->hostname);
json_object_string_add(json_nexthop_ll, "afi", "ipv6");
json_object_string_add(json_nexthop_ll, "scope",
From 8df39282ea64e2a65a7910012627f78d080833b1 Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas.abraitis@gmail.com>
Date: Wed, 24 Jun 2020 17:26:27 +0300
Subject: [PATCH 4/4] doc: Add some words about `bgp default
show-[nexthop]-hostname`
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
---
doc/user/bgp.rst | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 36227db604..a6c29724b0 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -1366,6 +1366,19 @@ Configuring Peers
on by default or not. This command defaults to on and is not displayed.
The `no bgp default ipv4-unicast` form of the command is displayed.
+.. index:: [no] bgp default show-hostname
+.. clicmd:: [no] bgp default show-hostname
+
+ This command shows the hostname of the peer in certain BGP commands
+ outputs. It's easier to troubleshoot if you have a number of BGP peers.
+
+.. index:: [no] bgp default show-nexthop-hostname
+.. clicmd:: [no] bgp default show-nexthop-hostname
+
+ This command shows the hostname of the next-hop in certain BGP commands
+ outputs. It's easier to troubleshoot if you have a number of BGP peers
+ and a number of routes to check.
+
.. index:: [no] neighbor PEER advertisement-interval (0-600)
.. clicmd:: [no] neighbor PEER advertisement-interval (0-600)

View File

@ -0,0 +1,30 @@
From 2bbe7133eb5cb97ba4b745cd251a8615cd2bd008 Mon Sep 17 00:00:00 2001
From: Richard Wu <wutong23@baidu.com>
Date: Fri, 5 Jun 2020 17:54:57 +0800
Subject: [PATCH] bgpd: Fix the bug that BGP MRAI does not work.
Issue: bgp_process_writes will be called when the fd is writable.
And it will bgp_generate_updgrp_packets to generate the
update packets no matter MRAI is set or not.
Fix: bgp_generate_updgrp_packets thread will return without sending
any update when MRAI timer is still running.
Signed-off-by: Richard Wu <wutong23@baidu.com>
---
bgpd/bgp_packet.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 29c03f4014..6f1c033f2a 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -408,6 +408,9 @@ int bgp_generate_updgrp_packets(struct thread *thread)
if (peer->bgp->main_peers_update_hold)
return 0;
+ if (peer->t_routeadv)
+ return 0;
+
do {
s = NULL;
FOREACH_AFI_SAFI (afi, safi) {

View File

@ -1,385 +0,0 @@
From 2332428d3c80ac3d3b4e1c0bdba830b098ef440f Mon Sep 17 00:00:00 2001
From: Rafael Zalamena <rzalamena@opensourcerouting.org>
Date: Fri, 5 Jul 2019 11:07:30 -0300
Subject: [PATCH] yang: initial filter YANG model import
This model contains the description of access-list, prefix-list and
other lists used by route map and other filtering interfaces.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
---
yang/frr-filter.yang | 365 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 365 insertions(+)
create mode 100644 yang/frr-filter.yang
diff --git a/yang/frr-filter.yang b/yang/frr-filter.yang
new file mode 100644
index 0000000000..92af6aebfd
--- /dev/null
+++ b/yang/frr-filter.yang
@@ -0,0 +1,365 @@
+module frr-filter {
+ yang-version 1.1;
+ namespace "http://frrouting.org/yang/filter";
+ prefix frr-filter;
+
+ import ietf-inet-types {
+ prefix inet;
+ }
+ import ietf-yang-types {
+ prefix yang;
+ }
+
+ organization "Free Range Routing";
+ contact
+ "FRR Users List: <mailto:frog@lists.frrouting.org>
+ FRR Development List: <mailto:dev@lists.frrouting.org>";
+ description "This module defines filter settings";
+
+ revision 2019-07-04 {
+ description "Initial revision";
+ }
+
+ /*
+ * Types.
+ */
+ typedef access-list-standard {
+ description "Standard IPv4 access list (any, host or a prefix)";
+ type uint16 {
+ range "1..99 | 1300..1999";
+ }
+ }
+
+ typedef access-list-extended {
+ description
+ "Extended IPv4 access list (source / destination any, hosts or prefixes)";
+ type uint16 {
+ range "100..199 | 2000..2699";
+ }
+ }
+
+ typedef access-list-legacy {
+ description "Standard/Extended IPv4 access list";
+ type uint16 {
+ range "1..199 | 1300..2699";
+ }
+ }
+
+ typedef access-list-name {
+ description "Access list name formatting";
+ type string;
+ }
+
+ typedef access-list-sequence {
+ description "Access list sequence number";
+ type uint32 {
+ range "1..4294967295";
+ }
+ }
+
+ typedef access-list-action {
+ description "Access list return action on match";
+ type enumeration {
+ enum deny {
+ description "Deny an entry";
+ value 0;
+ }
+ enum permit {
+ description "Accept an entry";
+ value 1;
+ }
+ }
+ }
+
+ /*
+ * Configuration data.
+ */
+ container filter-list {
+ list access-list-legacy {
+ description "Access list legacy instance";
+
+ key "number sequence";
+
+ leaf number {
+ description "Access list sequence value";
+ type access-list-legacy;
+ }
+
+ leaf sequence {
+ description "Access list sequence value";
+ type access-list-sequence;
+ }
+
+ leaf action {
+ description "Access list action on match";
+ type access-list-action;
+ mandatory true;
+ }
+
+ leaf remark {
+ description "Access list remark";
+ type string;
+ }
+
+ choice value {
+ description
+ "Standard access list: value to match.
+ Extended access list: source value to match.";
+ mandatory true;
+
+ case host {
+ leaf host {
+ description "Host to match";
+ type inet:ipv4-address;
+ }
+ }
+ case network {
+ leaf network {
+ description "Network to match";
+ type inet:ipv4-prefix;
+ }
+ }
+ case any {
+ leaf any {
+ description "Match any";
+ type empty;
+ }
+ }
+ }
+
+ choice extended-value {
+ when "./sequence >= 100 and ./sequence <= 199 or
+ ./sequence >= 2000 and ./sequence <= 2699";
+ description "Destination value to match";
+
+ case destination-host {
+ leaf destination-host {
+ description "Host to match";
+ type inet:ipv4-address;
+ }
+ }
+ case destination-network {
+ leaf destination-network {
+ description "Network to match";
+ type inet:ipv4-prefix;
+ }
+ }
+ case destination-any {
+ leaf destination-any {
+ description "Match any";
+ type empty;
+ }
+ }
+ }
+ }
+
+ list access-list {
+ description "Access list instance";
+
+ key "type identifier sequence";
+
+ leaf type {
+ description "Access list content type";
+ type enumeration {
+ enum ipv4 {
+ description "Internet Protocol address version 4";
+ value 0;
+ }
+ enum ipv6 {
+ description "Internet Protocol address version 6";
+ value 1;
+ }
+ enum mac {
+ description "Media Access Control address";
+ value 2;
+ }
+
+ /*
+ * Protocol YANG models should augment the parent node to
+ * contain the routing protocol specific value. The protocol
+ * must also augment `value` leaf to include its specific
+ * values or expand the `when` statement on the existing cases.
+ */
+ enum custom {
+ description "Custom data type";
+ value 100;
+ }
+ }
+ }
+
+ leaf identifier {
+ description "Access list identifier";
+ type access-list-name;
+ }
+
+ leaf sequence {
+ description "Access list sequence value";
+ type access-list-sequence;
+ }
+
+ leaf action {
+ description "Access list action on match";
+ type access-list-action;
+ mandatory true;
+ }
+
+ leaf remark {
+ description "Access list remark";
+ type string;
+ }
+
+ choice value {
+ description "Access list value to match";
+ mandatory true;
+
+ case ipv4-prefix {
+ when "./type = 'ipv4'";
+
+ leaf ipv4-prefix {
+ description "Configure IPv4 prefix to match";
+ type inet:ipv4-prefix;
+ }
+
+ leaf ipv4-exact-match {
+ description "Exact match of prefix";
+ type boolean;
+ default false;
+ }
+ }
+ case ipv6-prefix {
+ when "./type = 'ipv6'";
+
+ leaf ipv6-prefix {
+ description "Configure IPv6 prefix to match";
+ type inet:ipv6-prefix;
+ }
+
+ leaf ipv6-exact-match {
+ description "Exact match of prefix";
+ type boolean;
+ default false;
+ }
+ }
+ case mac {
+ when "./type = 'mac'";
+
+ leaf mac {
+ description "Configure MAC address to match";
+ type yang:mac-address;
+ }
+ }
+ case any {
+ leaf any {
+ description "Match anything";
+ type empty;
+ }
+ }
+ }
+ }
+
+ list prefix-list {
+ description "Prefix list instance";
+
+ key "type name sequence";
+
+ leaf type {
+ description "Prefix list type";
+ type enumeration {
+ enum ipv4 {
+ description "Internet Protocol address version 4";
+ value 0;
+ }
+ enum ipv6 {
+ description "Internet Protocol address version 6";
+ value 1;
+ }
+ }
+ }
+
+ leaf name {
+ description "Prefix list name";
+ type access-list-name;
+ }
+
+ leaf sequence {
+ description "Access list sequence value";
+ type access-list-sequence;
+ }
+
+ leaf action {
+ description "Prefix list action on match";
+ type access-list-action;
+ mandatory true;
+ }
+
+ leaf description {
+ description "Prefix list user description";
+ type string;
+ }
+
+ choice value {
+ description "Prefix list value to match";
+ mandatory true;
+
+ case ipv4-prefix {
+ when "./type = 'ipv4'";
+
+ leaf ipv4-prefix {
+ description "Configure IPv4 prefix to match";
+ type inet:ipv4-prefix;
+ }
+
+ leaf ipv4-prefix-length-greater-or-equal {
+ description
+ "Specifies if matching prefixes with length greater than
+ or equal to value";
+ type uint8 {
+ range "0..32";
+ }
+ }
+
+ leaf ipv4-prefix-length-lesser-or-equal {
+ description
+ "Specifies if matching prefixes with length lesser than
+ or equal to value";
+ type uint8 {
+ range "0..32";
+ }
+ }
+ }
+ case ipv6-prefix {
+ when "./type = 'ipv6'";
+
+ leaf ipv6-prefix {
+ description "Configure IPv6 prefix to match";
+ type inet:ipv6-prefix;
+ }
+
+ leaf ipv6-prefix-length-greater-or-equal {
+ description
+ "Specifies if matching prefixes with length greater than
+ or equal to value";
+ type uint8 {
+ range "0..128";
+ }
+ }
+
+ leaf ipv6-prefix-length-lesser-or-equal {
+ description
+ "Specifies if matching prefixes with length lesser than
+ or equal to value";
+ type uint8 {
+ range "0..128";
+ }
+ }
+ }
+ case any {
+ leaf any {
+ description "Match anything";
+ type empty;
+ }
+ }
+ }
+ }
+ }
+}

View File

@ -1,390 +0,0 @@
--- a/dev/null 2020-04-10 18:48:03.582667900 +0300
+++ b/yang/frr-route-map.yang 2020-05-02 11:43:04.182956847 +0300
@@ -0,0 +1,387 @@
+module frr-route-map {
+ yang-version 1.1;
+ namespace "http://frrouting.org/yang/route-map";
+ prefix frr-route-map;
+
+ import ietf-inet-types {
+ prefix inet;
+ }
+ import frr-filter {
+ prefix filter;
+ }
+ import frr-interface {
+ prefix frr-interface;
+ }
+
+ organization "FRRouting";
+ contact
+ "FRR Users List: <mailto:frog@lists.frrouting.org>
+ FRR Development List: <mailto:dev@lists.frrouting.org>";
+ description "This module defines route map settings";
+
+ revision 2019-07-01 {
+ description "Initial revision";
+ }
+
+ /*
+ * Types.
+ */
+ typedef route-map-sequence {
+ description "Route map valid sequence numbers";
+ type uint16 {
+ range "1..65535";
+ }
+ }
+
+ typedef route-map-name {
+ description "Route map name format";
+ type string;
+ }
+
+ /*
+ * Operational data.
+ */
+ container lib {
+ list route-map {
+ description "Route map instance";
+
+ key "name";
+
+ leaf name {
+ description "Route map instance name";
+ type route-map-name;
+ }
+
+ list entry {
+ description "Route map entry";
+
+ key "sequence";
+
+ leaf sequence {
+ description
+ "Route map instance priority (low number means higher priority)";
+ type route-map-sequence;
+ }
+
+ leaf description {
+ description "Route map description";
+ type string;
+ }
+
+ leaf action {
+ description
+ "Route map actions: permit (executes action), deny (quits evaluation)";
+ mandatory true;
+ type enumeration {
+ enum permit {
+ description
+ "Executes configured action and permits the prefix/route
+ if the conditions matched. An alternative exit action can
+ be configured to continue processing the route map list
+ or jump to process another route map.";
+ value 0;
+ }
+ enum deny {
+ description
+ "If all conditions are met the prefix/route is denied and
+ route map processing stops.";
+ value 1;
+ }
+ }
+ }
+
+ leaf call {
+ description
+ "Call another route map before calling `exit-policy`. If the
+ called route map returns deny then this route map will also
+ return deny";
+ type route-map-name;
+ }
+
+ leaf exit-policy {
+ description "What do to after route map successful match, set and call";
+ type enumeration {
+ enum permit-or-deny {
+ description "End route map evaluation and return";
+ value 0;
+ }
+ enum next {
+ description
+ "Proceed evaluating next route map entry per sequence";
+ value 1;
+ }
+ enum goto {
+ description
+ "Go to route map entry with the provided sequence number";
+ value 2;
+ }
+ }
+ default "permit-or-deny";
+ }
+
+ leaf goto-value {
+ when "../exit-policy = 'goto'";
+ description
+ "Sequence number to jump (when using `goto` exit policy)";
+ mandatory true;
+ type route-map-sequence;
+ }
+
+ list match-condition {
+ description "Route map match conditions";
+
+ key "condition";
+
+ leaf condition {
+ description "Match condition";
+ type enumeration {
+ enum interface {
+ description "Match interface";
+ value 0;
+ }
+ enum ipv4-address-list {
+ description "Match an IPv4 access-list";
+ value 1;
+ }
+ enum ipv4-prefix-list {
+ description "Match an IPv4 prefix-list";
+ value 2;
+ }
+ enum ipv4-next-hop-list {
+ description "Match an IPv4 next-hop";
+ value 3;
+ }
+ enum ipv4-next-hop-prefix-list {
+ description "Match an IPv4 next-hop prefix list";
+ value 4;
+ }
+ enum ipv4-next-hop-type {
+ description "Match an IPv4 next-hop type";
+ value 5;
+ }
+ enum ipv6-address-list {
+ description "Match an IPv6 access-list";
+ value 6;
+ }
+ enum ipv6-prefix-list {
+ description "Match an IPv6 prefix-list";
+ value 7;
+ }
+ enum ipv6-next-hop-type {
+ description "Match an IPv6 next-hop type";
+ value 8;
+ }
+ enum metric {
+ description "Match a route metric";
+ value 9;
+ }
+ enum tag {
+ description "Match a route tag";
+ value 10;
+ }
+ /* zebra specific conditions. */
+ enum ipv4-prefix-length {
+ description "Match IPv4 prefix length";
+ value 100;
+ }
+ enum ipv6-prefix-length {
+ description "Match IPv6 prefix length";
+ value 101;
+ }
+ enum ipv4-next-hop-prefix-length {
+ description "Match next-hop prefix length";
+ value 102;
+ }
+ enum source-protocol {
+ description "Match source protocol";
+ value 103;
+ }
+ enum source-instance {
+ description "Match source protocol instance";
+ value 104;
+ }
+ }
+ }
+
+ choice condition-value {
+ description
+ "Value to match (interpretation depends on condition type)";
+ mandatory true;
+ case interface {
+ when "./condition = 'interface'";
+ leaf interface {
+ type string;
+ }
+ }
+ case access-list-num {
+ when "./condition = 'ipv4-address-list' or
+ ./condition = 'ipv4-next-hop-list'";
+ leaf access-list-num {
+ type filter:access-list-standard;
+ }
+ }
+ case access-list-num-extended {
+ when "./condition = 'ipv4-address-list' or
+ ./condition = 'ipv4-next-hop-list'";
+ leaf access-list-num-extended {
+ type filter:access-list-extended;
+ }
+ }
+ case list-name {
+ when "./condition = 'ipv4-address-list' or
+ ./condition = 'ipv4-prefix-list' or
+ ./condition = 'ipv4-next-hop-list' or
+ ./condition = 'ipv4-next-hop-prefix-list' or
+ ./condition = 'ipv6-address-list' or
+ ./condition = 'ipv6-prefix-list'";
+ leaf list-name {
+ type filter:access-list-name;
+ }
+ }
+ case ipv4-next-hop-type {
+ when "./condition = 'ipv4-next-hop-type'";
+ leaf ipv4-next-hop-type {
+ type enumeration {
+ enum blackhole {
+ value 0;
+ }
+ }
+ }
+ }
+ case ipv6-next-hop-type {
+ when "./condition = 'ipv6-next-hop-type'";
+ leaf ipv6-next-hop-type {
+ type enumeration {
+ enum blackhole {
+ value 0;
+ }
+ }
+ }
+ }
+ case metric {
+ when "./condition = 'metric'";
+ leaf metric {
+ type uint32 {
+ range "1..4294967295";
+ }
+ }
+ }
+ case tag {
+ when "./condition = 'tag'";
+ leaf tag {
+ type uint32 {
+ range "1..4294967295";
+ }
+ }
+ }
+ }
+ }
+
+ list set-action {
+ description "Route map set actions";
+
+ key "action";
+
+ leaf action {
+ description "Action to do when the route map matches";
+ type enumeration {
+ enum ipv4-next-hop {
+ description "Set IPv4 address of the next hop";
+ value 0;
+ }
+ enum ipv6-next-hop {
+ description "Set IPv6 address of the next hop";
+ value 1;
+ }
+ enum metric {
+ description "Set prefix/route metric";
+ value 2;
+ }
+ enum tag {
+ description "Set tag";
+ value 3;
+ }
+ /* zebra specific conditions. */
+ enum source {
+ description "Set source address for route";
+ value 100;
+ }
+ }
+ }
+
+ choice action-value {
+ description
+ "Value to set (interpretation depends on action-type)";
+ case ipv4-address {
+ when "./action = 'ipv4-next-hop'";
+ leaf ipv4-address {
+ description "IPv4 address";
+ type inet:ipv4-address;
+ }
+ }
+ case ipv6-address {
+ when "./action = 'ipv6-next-hop'";
+ leaf ipv6-address {
+ description "IPv6 address";
+ type inet:ipv6-address;
+ }
+ }
+ case metric {
+ when "./action = 'metric'";
+ choice metric-value {
+ description "Metric to set or use";
+ case value {
+ leaf value {
+ description "Use the following metric value";
+ type uint32 {
+ range "0..4294967295";
+ }
+ }
+ }
+ case add-metric {
+ leaf add-metric {
+ description "Add unit to metric";
+ type boolean;
+ }
+ }
+ case subtract-metric {
+ leaf subtract-metric {
+ description "Subtract unit from metric";
+ type boolean;
+ }
+ }
+ case use-round-trip-time {
+ leaf use-round-trip-time {
+ description "Use the round trip time as metric";
+ type boolean;
+ }
+ }
+ case add-round-trip-time {
+ leaf add-round-trip-time {
+ description "Add round trip time to metric";
+ type boolean;
+ }
+ }
+ case subtract-round-trip-time {
+ leaf subtract-round-trip-time {
+ description "Subtract round trip time to metric";
+ type boolean;
+ }
+ }
+ }
+ }
+ case tag {
+ when "./action = 'tag'";
+ leaf tag {
+ description "Tag value";
+ type uint32 {
+ range "0..4294967295";
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}

File diff suppressed because it is too large Load Diff

View File

@ -1,83 +0,0 @@
From bec0aa85b1f404ac9800c7524070fcf8582e82bc Mon Sep 17 00:00:00 2001
From: Rafael Zalamena <rzalamena@opensourcerouting.org>
Date: Thu, 1 Aug 2019 19:56:46 -0300
Subject: [PATCH] yang: simplify filter choice by removing cases
Based on @rwestphal feedback, lets remove `case`s where we don't expect
to add more items or items with more than one `leaf`.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
---
yang/frr-filter.yang | 48 +++++++++++++++++---------------------------
1 file changed, 18 insertions(+), 30 deletions(-)
diff --git a/yang/frr-filter.yang b/yang/frr-filter.yang
index 92af6aebfd..e79ede87b7 100644
--- a/yang/frr-filter.yang
+++ b/yang/frr-filter.yang
@@ -107,23 +107,17 @@ module frr-filter {
Extended access list: source value to match.";
mandatory true;
- case host {
- leaf host {
- description "Host to match";
- type inet:ipv4-address;
- }
+ leaf host {
+ description "Host to match";
+ type inet:ipv4-address;
}
- case network {
- leaf network {
- description "Network to match";
- type inet:ipv4-prefix;
- }
+ leaf network {
+ description "Network to match";
+ type inet:ipv4-prefix;
}
- case any {
- leaf any {
- description "Match any";
- type empty;
- }
+ leaf any {
+ description "Match any";
+ type empty;
}
}
@@ -132,23 +126,17 @@ module frr-filter {
./sequence >= 2000 and ./sequence <= 2699";
description "Destination value to match";
- case destination-host {
- leaf destination-host {
- description "Host to match";
- type inet:ipv4-address;
- }
+ leaf destination-host {
+ description "Host to match";
+ type inet:ipv4-address;
}
- case destination-network {
- leaf destination-network {
- description "Network to match";
- type inet:ipv4-prefix;
- }
+ leaf destination-network {
+ description "Network to match";
+ type inet:ipv4-prefix;
}
- case destination-any {
- leaf destination-any {
- description "Match any";
- type empty;
- }
+ leaf destination-any {
+ description "Match any";
+ type empty;
}
}
}

View File

@ -1,147 +0,0 @@
From dc397e4c0adc13982fc5d83a1afc42178708f4a5 Mon Sep 17 00:00:00 2001
From: Renato Westphal <renato@opensourcerouting.org>
Date: Fri, 3 Apr 2020 20:10:04 -0300
Subject: [PATCH] lib: consolidate flexible array hack in a single place
Old gcc versions (< 5.x) have a bug that prevents C99 flexible
arrays from working properly on shared libraries.
We already have a hack in place to work around this problem, but it
needs to be replicated in every declaration of a frr_yang_module_info
variable within libfrr. This clearly isn't a good solution if we
consider that many more libfrr YANG modules are about to come in
the future.
This commit introduces a different workaround that operates within
the northbound layer itself, such that implementers of libfrr YANG
modules won't need to worry about this problem anymore.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
---
lib/if.c | 24 ------------------------
lib/northbound.c | 7 +++++++
lib/northbound.h | 11 +++++++++++
lib/routemap_northbound.c | 25 -------------------------
4 files changed, 18 insertions(+), 49 deletions(-)
diff --git a/lib/if.c b/lib/if.c
index dabf66799d..24b103b3ff 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -1657,31 +1657,7 @@ static int lib_interface_description_destroy(enum nb_event event,
/* clang-format off */
-#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
-/* gcc versions before 5.x miscalculate the size for structs with variable
- * length arrays (they just count it as size 0)
- */
-struct frr_yang_module_info_size3 {
- /* YANG module name. */
- const char *name;
-
- /* Northbound callbacks. */
- const struct {
- /* Data path of this YANG node. */
- const char *xpath;
-
- /* Callbacks implemented for this node. */
- struct nb_callbacks cbs;
-
- /* Priority - lower priorities are processed first. */
- uint32_t priority;
- } nodes[3];
-};
-
-const struct frr_yang_module_info_size3 frr_interface_info_size3 asm("frr_interface_info") = {
-#else
const struct frr_yang_module_info frr_interface_info = {
-#endif
.name = "frr-interface",
.nodes = {
{
diff --git a/lib/northbound.c b/lib/northbound.c
index cebedcff09..85e723d7cf 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -1866,6 +1866,13 @@ static void nb_load_callbacks(const struct frr_yang_module_info *module)
struct nb_node *nb_node;
uint32_t priority;
+ if (i > YANG_MODULE_MAX_NODES) {
+ zlog_err(
+ "%s: %s.yang has more than %u nodes. Please increase YANG_MODULE_MAX_NODES to fix this problem.",
+ __func__, module->name, YANG_MODULE_MAX_NODES);
+ exit(1);
+ }
+
nb_node = nb_node_find(module->nodes[i].xpath);
if (!nb_node) {
flog_warn(EC_LIB_YANG_UNKNOWN_DATA_PATH,
diff --git a/lib/northbound.h b/lib/northbound.h
index 76a11e518c..19a2ba0865 100644
--- a/lib/northbound.h
+++ b/lib/northbound.h
@@ -403,6 +403,13 @@ struct nb_node {
/* The YANG list doesn't contain key leafs. */
#define F_NB_NODE_KEYLESS_LIST 0x02
+/*
+ * HACK: old gcc versions (< 5.x) have a bug that prevents C99 flexible arrays
+ * from working properly on shared libraries. For those compilers, use a fixed
+ * size array to work around the problem.
+ */
+#define YANG_MODULE_MAX_NODES 1024
+
struct frr_yang_module_info {
/* YANG module name. */
const char *name;
@@ -417,7 +424,11 @@ struct frr_yang_module_info {
/* Priority - lower priorities are processed first. */
uint32_t priority;
+#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
+ } nodes[YANG_MODULE_MAX_NODES + 1];
+#else
} nodes[];
+#endif
};
/* Northbound error codes. */
diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c
index 69cebbd2a1..dd4cbd7d99 100644
--- a/lib/routemap_northbound.c
+++ b/lib/routemap_northbound.c
@@ -1221,32 +1221,7 @@ lib_route_map_entry_set_action_tag_destroy(enum nb_event event,
}
/* clang-format off */
-#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
-/*
- * gcc versions before 5.x miscalculate the size for structs with variable
- * length arrays (they just count it as size 0)
- */
-struct frr_yang_module_info_sizen {
- /* YANG module name. */
- const char *name;
-
- /* Northbound callbacks. */
- const struct {
- /* Data path of this YANG node. */
- const char *xpath;
-
- /* Callbacks implemented for this node. */
- struct nb_callbacks cbs;
-
- /* Priority - lower priorities are processed first. */
- uint32_t priority;
- } nodes[28];
-};
-
-const struct frr_yang_module_info_sizen frr_route_map_info_sizen asm("frr_route_map_info") = {
-#else
const struct frr_yang_module_info frr_route_map_info = {
-#endif
.name = "frr-route-map",
.nodes = {
{

View File

@ -1,330 +0,0 @@
From 97cd849362b45ecbcb20194b5771c5ce777de6bc Mon Sep 17 00:00:00 2001
From: Renato Westphal <renato@opensourcerouting.org>
Date: Tue, 21 Apr 2020 21:27:47 -0300
Subject: [PATCH] lib: create a wrapper function for all northbound callbacks
The intention here is to keep the code more organized. These wrappers
should be used by the northbound clients only, and never directly
by any YANG backend code.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
---
lib/northbound.c | 222 +++++++++++++++++++++++-----------------
lib/northbound_grpc.cpp | 3 +-
2 files changed, 131 insertions(+), 94 deletions(-)
diff --git a/lib/northbound.c b/lib/northbound.c
index 85e723d7cf..d10e4713f5 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -62,11 +62,10 @@ static struct {
*/
static bool transaction_in_progress;
+static int nb_callback_pre_validate(const struct nb_node *nb_node,
+ const struct lyd_node *dnode);
static int nb_callback_configuration(const enum nb_event event,
struct nb_config_change *change);
-static void nb_log_callback(const enum nb_event event,
- enum nb_operation operation, const char *xpath,
- const char *value);
static struct nb_transaction *nb_transaction_new(struct nb_config *config,
struct nb_config_cbs *changes,
enum nb_client client,
@@ -609,18 +608,7 @@ static int nb_candidate_validate_code(struct nb_config *candidate,
if (!nb_node->cbs.pre_validate)
goto next;
- if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config,
- DEBUG_MODE_ALL)) {
- char xpath[XPATH_MAXLEN];
-
- yang_dnode_get_path(child, xpath,
- sizeof(xpath));
- nb_log_callback(NB_EV_VALIDATE,
- NB_OP_PRE_VALIDATE, xpath,
- NULL);
- }
-
- ret = (*nb_node->cbs.pre_validate)(child);
+ ret = nb_callback_pre_validate(nb_node, child);
if (ret != NB_OK)
return NB_ERR_VALIDATION;
@@ -791,14 +779,128 @@ int nb_running_lock_check(enum nb_client client, const void *user)
return ret;
}
-static void nb_log_callback(const enum nb_event event,
- enum nb_operation operation, const char *xpath,
- const char *value)
+static void nb_log_config_callback(const enum nb_event event,
+ enum nb_operation operation,
+ const struct lyd_node *dnode)
{
+ const char *value;
+ char xpath[XPATH_MAXLEN];
+
+ if (!DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL))
+ return;
+
+ yang_dnode_get_path(dnode, xpath, sizeof(xpath));
+ if (yang_snode_is_typeless_data(dnode->schema))
+ value = "(none)";
+ else
+ value = yang_dnode_get_string(dnode, NULL);
+
zlog_debug(
"northbound callback: event [%s] op [%s] xpath [%s] value [%s]",
nb_event_name(event), nb_operation_name(operation), xpath,
- value ? value : "(NULL)");
+ value);
+}
+
+static int nb_callback_create(const struct nb_node *nb_node,
+ enum nb_event event, const struct lyd_node *dnode,
+ union nb_resource *resource)
+{
+ nb_log_config_callback(event, NB_OP_CREATE, dnode);
+
+ return nb_node->cbs.create(event, dnode, resource);
+}
+
+static int nb_callback_modify(const struct nb_node *nb_node,
+ enum nb_event event, const struct lyd_node *dnode,
+ union nb_resource *resource)
+{
+ nb_log_config_callback(event, NB_OP_MODIFY, dnode);
+
+ return nb_node->cbs.modify(event, dnode, resource);
+}
+
+static int nb_callback_destroy(const struct nb_node *nb_node,
+ enum nb_event event,
+ const struct lyd_node *dnode)
+{
+ nb_log_config_callback(event, NB_OP_DESTROY, dnode);
+
+ return nb_node->cbs.destroy(event, dnode);
+}
+
+static int nb_callback_move(const struct nb_node *nb_node, enum nb_event event,
+ const struct lyd_node *dnode)
+{
+ nb_log_config_callback(event, NB_OP_MOVE, dnode);
+
+ return nb_node->cbs.move(event, dnode);
+}
+
+static int nb_callback_pre_validate(const struct nb_node *nb_node,
+ const struct lyd_node *dnode)
+{
+ nb_log_config_callback(NB_EV_VALIDATE, NB_OP_PRE_VALIDATE, dnode);
+
+ return nb_node->cbs.pre_validate(dnode);
+}
+
+static void nb_callback_apply_finish(const struct nb_node *nb_node,
+ const struct lyd_node *dnode)
+{
+ nb_log_config_callback(NB_EV_APPLY, NB_OP_APPLY_FINISH, dnode);
+
+ nb_node->cbs.apply_finish(dnode);
+}
+
+struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node,
+ const char *xpath,
+ const void *list_entry)
+{
+ DEBUGD(&nb_dbg_cbs_state,
+ "northbound callback (get_elem): xpath [%s] list_entry [%p]",
+ xpath, list_entry);
+
+ return nb_node->cbs.get_elem(xpath, list_entry);
+}
+
+const void *nb_callback_get_next(const struct nb_node *nb_node,
+ const void *parent_list_entry,
+ const void *list_entry)
+{
+ DEBUGD(&nb_dbg_cbs_state,
+ "northbound callback (get_next): node [%s] parent_list_entry [%p] list_entry [%p]",
+ nb_node->xpath, parent_list_entry, list_entry);
+
+ return nb_node->cbs.get_next(parent_list_entry, list_entry);
+}
+
+int nb_callback_get_keys(const struct nb_node *nb_node, const void *list_entry,
+ struct yang_list_keys *keys)
+{
+ DEBUGD(&nb_dbg_cbs_state,
+ "northbound callback (get_keys): node [%s] list_entry [%p]",
+ nb_node->xpath, list_entry);
+
+ return nb_node->cbs.get_keys(list_entry, keys);
+}
+
+const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
+ const void *parent_list_entry,
+ const struct yang_list_keys *keys)
+{
+ DEBUGD(&nb_dbg_cbs_state,
+ "northbound callback (lookup_entry): node [%s] parent_list_entry [%p]",
+ nb_node->xpath, parent_list_entry);
+
+ return nb_node->cbs.lookup_entry(parent_list_entry, keys);
+}
+
+int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
+ const struct list *input, struct list *output)
+{
+ DEBUGD(&nb_dbg_cbs_rpc, "northbound RPC: %s", xpath);
+
+ return nb_node->cbs.rpc(xpath, input, output);
}
/*
@@ -815,15 +917,6 @@ static int nb_callback_configuration(const enum nb_event event,
union nb_resource *resource;
int ret = NB_ERR;
- if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) {
- const char *value = "(none)";
-
- if (dnode && !yang_snode_is_typeless_data(dnode->schema))
- value = yang_dnode_get_string(dnode, NULL);
-
- yang_dnode_get_path(dnode, xpath, sizeof(xpath));
- nb_log_callback(event, operation, xpath, value);
- }
if (event == NB_EV_VALIDATE)
resource = NULL;
@@ -832,16 +925,16 @@ static int nb_callback_configuration(const enum nb_event event,
switch (operation) {
case NB_OP_CREATE:
- ret = (*nb_node->cbs.create)(event, dnode, resource);
+ ret = nb_callback_create(nb_node, event, dnode, resource);
break;
case NB_OP_MODIFY:
- ret = (*nb_node->cbs.modify)(event, dnode, resource);
+ ret = nb_callback_modify(nb_node, event, dnode, resource);
break;
case NB_OP_DESTROY:
- ret = (*nb_node->cbs.destroy)(event, dnode);
+ ret = nb_callback_destroy(nb_node, event, dnode);
break;
case NB_OP_MOVE:
- ret = (*nb_node->cbs.move)(event, dnode);
+ ret = nb_callback_move(nb_node, event, dnode);
break;
default:
yang_dnode_get_path(dnode, xpath, sizeof(xpath));
@@ -890,57 +983,6 @@ static int nb_callback_configuration(const enum nb_event event,
return ret;
}
-struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node,
- const char *xpath,
- const void *list_entry)
-{
- DEBUGD(&nb_dbg_cbs_state,
- "northbound callback (get_elem): xpath [%s] list_entry [%p]",
- xpath, list_entry);
-
- return nb_node->cbs.get_elem(xpath, list_entry);
-}
-
-const void *nb_callback_get_next(const struct nb_node *nb_node,
- const void *parent_list_entry,
- const void *list_entry)
-{
- DEBUGD(&nb_dbg_cbs_state,
- "northbound callback (get_next): node [%s] parent_list_entry [%p] list_entry [%p]",
- nb_node->xpath, parent_list_entry, list_entry);
-
- return nb_node->cbs.get_next(parent_list_entry, list_entry);
-}
-
-int nb_callback_get_keys(const struct nb_node *nb_node, const void *list_entry,
- struct yang_list_keys *keys)
-{
- DEBUGD(&nb_dbg_cbs_state,
- "northbound callback (get_keys): node [%s] list_entry [%p]",
- nb_node->xpath, list_entry);
-
- return nb_node->cbs.get_keys(list_entry, keys);
-}
-
-const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
- const void *parent_list_entry,
- const struct yang_list_keys *keys)
-{
- DEBUGD(&nb_dbg_cbs_state,
- "northbound callback (lookup_entry): node [%s] parent_list_entry [%p]",
- nb_node->xpath, parent_list_entry);
-
- return nb_node->cbs.lookup_entry(parent_list_entry, keys);
-}
-
-int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
- const struct list *input, struct list *output)
-{
- DEBUGD(&nb_dbg_cbs_rpc, "northbound RPC: %s", xpath);
-
- return nb_node->cbs.rpc(xpath, input, output);
-}
-
static struct nb_transaction *
nb_transaction_new(struct nb_config *config, struct nb_config_cbs *changes,
enum nb_client client, const void *user, const char *comment)
@@ -1058,7 +1100,6 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)
{
struct nb_config_cbs cbs;
struct nb_config_cb *cb;
- char xpath[XPATH_MAXLEN];
/* Initialize tree of 'apply_finish' callbacks. */
RB_INIT(nb_config_cbs, &cbs);
@@ -1075,6 +1116,8 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)
* be called though).
*/
if (change->cb.operation == NB_OP_DESTROY) {
+ char xpath[XPATH_MAXLEN];
+
dnode = dnode->parent;
if (!dnode)
break;
@@ -1111,15 +1154,8 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)
}
/* Call the 'apply_finish' callbacks, sorted by their priorities. */
- RB_FOREACH (cb, nb_config_cbs, &cbs) {
- if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) {
- yang_dnode_get_path(cb->dnode, xpath, sizeof(xpath));
- nb_log_callback(NB_EV_APPLY, NB_OP_APPLY_FINISH, xpath,
- NULL);
- }
-
- (*cb->nb_node->cbs.apply_finish)(cb->dnode);
- }
+ RB_FOREACH (cb, nb_config_cbs, &cbs)
+ nb_callback_apply_finish(cb->nb_node, cb->dnode);
/* Release memory. */
while (!RB_EMPTY(nb_config_cbs, &cbs)) {
diff --git a/lib/northbound_grpc.cpp b/lib/northbound_grpc.cpp
index b195f1aeca..66bf05c1ab 100644
--- a/lib/northbound_grpc.cpp
+++ b/lib/northbound_grpc.cpp
@@ -545,7 +545,8 @@ class NorthboundImpl final : public frr::Northbound::Service
}
// Execute callback registered for this XPath.
- if (nb_node->cbs.rpc(xpath, input_list, output_list) != NB_OK) {
+ if (nb_callback_rpc(nb_node, xpath, input_list, output_list)
+ != NB_OK) {
flog_warn(EC_LIB_NB_CB_RPC,
"%s: rpc callback failed: %s", __func__,
xpath);

View File

@ -1,14 +0,0 @@
--- a/lib/northbound.h
+++ b/lib/northbound.h
@@ -504,11 +504,7 @@ struct frr_yang_module_info {
/* Priority - lower priorities are processed first. */
uint32_t priority;
-#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
} nodes[YANG_MODULE_MAX_NODES + 1];
-#else
- } nodes[];
-#endif
};
/* Northbound error codes. */