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:
parent
9441e45176
commit
8c0d17cf5d
17 changed files with 1518 additions and 6424 deletions
|
@ -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:= \
|
||||
|
|
|
@ -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;
|
83
net/frr/patches/001-bgpd_Some_backports.patch
Normal file
83
net/frr/patches/001-bgpd_Some_backports.patch
Normal 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;
|
|
@ -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
|
|
@ -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);
|
|
@ -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]
|
||||
|
|
@ -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");
|
||||
}
|
120
net/frr/patches/005-vtysh_fixes.patch
Normal file
120
net/frr/patches/005-vtysh_fixes.patch
Normal 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) {
|
835
net/frr/patches/006-bgpd_how_the_real_next_hop_address.patch
Normal file
835
net/frr/patches/006-bgpd_how_the_real_next_hop_address.patch
Normal 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)
|
||||
|
30
net/frr/patches/007-bgpd_Fix_the_bug_BGP_MRAI.patch
Normal file
30
net/frr/patches/007-bgpd_Fix_the_bug_BGP_MRAI.patch
Normal 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) {
|
|
@ -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;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 = {
|
||||
{
|
|
@ -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);
|
|
@ -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. */
|
Loading…
Reference in a new issue