summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2022-03-12 23:22:11 +0100
committerGitHub <noreply@github.com>2022-03-12 23:22:11 +0100
commitf2cd9263544622d1a4e7aec75e2cd8b8343c0894 (patch)
tree298e5f1e9c7272fe3d1eb4f89b8898743c5a62f3
parentef58d790d968fc348c1e46350efd3245a8a3f9e4 (diff)
parentbb14bbeab09ef245611dc9b1cbf9e24824605ba8 (diff)
Merge pull request #10784 from FRRouting/mergify/bp/stable/8.2/pr-10783
-rw-r--r--bgpd/bgp_nht.c9
-rw-r--r--lib/zclient.c19
-rw-r--r--lib/zclient.h12
-rw-r--r--ospf6d/ospf6_zebra.c7
-rw-r--r--pbrd/pbr_zebra.c9
-rw-r--r--pimd/pim_nht.c13
-rw-r--r--sharpd/sharp_zebra.c9
-rw-r--r--staticd/static_zebra.c15
-rw-r--r--zebra/rib.h3
-rw-r--r--zebra/zebra_rnh.c26
-rw-r--r--zebra/zebra_srte.c12
11 files changed, 101 insertions, 33 deletions
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 19ae137208..eb3366d337 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -667,6 +667,7 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
struct bgp_nexthop_cache_head *tree = NULL;
struct bgp_nexthop_cache *bnc_nhc, *bnc_import;
struct bgp *bgp;
+ struct prefix match;
struct zapi_route nhr;
afi_t afi;
@@ -679,16 +680,16 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
return;
}
- if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
+ if (!zapi_nexthop_update_decode(zclient->ibuf, &match, &nhr)) {
zlog_err("%s[%s]: Failure to decode nexthop update", __func__,
bgp->name_pretty);
return;
}
- afi = family2afi(nhr.prefix.family);
+ afi = family2afi(match.family);
tree = &bgp->nexthop_cache_table[afi];
- bnc_nhc = bnc_find(tree, &nhr.prefix, nhr.srte_color);
+ bnc_nhc = bnc_find(tree, &match, nhr.srte_color);
if (!bnc_nhc) {
if (BGP_DEBUG(nht, NHT))
zlog_debug(
@@ -699,7 +700,7 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
tree = &bgp->import_check_table[afi];
- bnc_import = bnc_find(tree, &nhr.prefix, nhr.srte_color);
+ bnc_import = bnc_find(tree, &match, nhr.srte_color);
if (!bnc_import) {
if (BGP_DEBUG(nht, NHT))
zlog_debug(
diff --git a/lib/zclient.c b/lib/zclient.c
index ab2dd09896..445837017a 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -1924,7 +1924,8 @@ const char *zapi_nexthop2str(const struct zapi_nexthop *znh, char *buf,
/*
* Decode the nexthop-tracking update message
*/
-bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
+bool zapi_nexthop_update_decode(struct stream *s, struct prefix *match,
+ struct zapi_route *nhr)
{
uint32_t i;
@@ -1932,6 +1933,22 @@ bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
STREAM_GETL(s, nhr->message);
STREAM_GETW(s, nhr->safi);
+ STREAM_GETW(s, match->family);
+ STREAM_GETC(s, match->prefixlen);
+ /*
+ * What we got told to match against
+ */
+ switch (match->family) {
+ case AF_INET:
+ STREAM_GET(&match->u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
+ break;
+ case AF_INET6:
+ STREAM_GET(&match->u.prefix6, s, IPV6_MAX_BYTELEN);
+ break;
+ }
+ /*
+ * What we matched against
+ */
STREAM_GETW(s, nhr->prefix.family);
STREAM_GETC(s, nhr->prefix.prefixlen);
switch (nhr->prefix.family) {
diff --git a/lib/zclient.h b/lib/zclient.h
index ca62b1afeb..092754f602 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -1111,7 +1111,17 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
const struct nexthop *nh);
int zapi_backup_nexthop_from_nexthop(struct zapi_nexthop *znh,
const struct nexthop *nh);
-extern bool zapi_nexthop_update_decode(struct stream *s,
+/*
+ * match -> is the prefix that the calling daemon asked to be matched
+ * against.
+ * nhr->prefix -> is the actual prefix that was matched against in the
+ * rib itself.
+ *
+ * This distinction is made because a LPM can be made if there is a
+ * covering route. This way the upper level protocol can make a decision
+ * point about whether or not it wants to use the match or not.
+ */
+extern bool zapi_nexthop_update_decode(struct stream *s, struct prefix *match,
struct zapi_route *nhr);
const char *zapi_nexthop2str(const struct zapi_nexthop *znh, char *buf,
int bufsize);
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 82d280811b..af5c54c920 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -166,19 +166,20 @@ static int ospf6_zebra_import_check_update(ZAPI_CALLBACK_ARGS)
{
struct ospf6 *ospf6;
struct zapi_route nhr;
+ struct prefix matched;
ospf6 = ospf6_lookup_by_vrf_id(vrf_id);
if (ospf6 == NULL || !IS_OSPF6_ASBR(ospf6))
return 0;
- if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
+ if (!zapi_nexthop_update_decode(zclient->ibuf, &matched, &nhr)) {
zlog_err("%s[%u]: Failure to decode route", __func__,
ospf6->vrf_id);
return -1;
}
- if (nhr.prefix.family != AF_INET6 || nhr.prefix.prefixlen != 0
- || nhr.type == ZEBRA_ROUTE_OSPF6)
+ if (matched.family != AF_INET6 || matched.prefixlen != 0 ||
+ nhr.type == ZEBRA_ROUTE_OSPF6)
return 0;
ospf6->nssa_default_import_check.status = !!nhr.nexthop_num;
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index b480d4072e..f992588729 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -399,17 +399,19 @@ void route_delete(struct pbr_nexthop_group_cache *pnhgc, afi_t afi)
static int pbr_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)
{
struct zapi_route nhr;
+ struct prefix matched;
uint32_t i;
- if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
+ if (!zapi_nexthop_update_decode(zclient->ibuf, &matched, &nhr)) {
zlog_err("Failure to decode Nexthop update message");
return 0;
}
if (DEBUG_MODE_CHECK(&pbr_dbg_zebra, DEBUG_MODE_ALL)) {
- DEBUGD(&pbr_dbg_zebra, "%s: Received Nexthop update: %pFX",
- __func__, &nhr.prefix);
+ DEBUGD(&pbr_dbg_zebra,
+ "%s: Received Nexthop update: %pFX against %pFX",
+ __func__, &matched, &nhr.prefix);
DEBUGD(&pbr_dbg_zebra, "%s: (Nexthops(%u)", __func__,
nhr.nexthop_num);
@@ -423,6 +425,7 @@ static int pbr_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)
}
}
+ nhr.prefix = matched;
pbr_nht_nexthop_update(&nhr);
return 1;
}
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 94a624e2c4..2a780bd339 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -728,19 +728,20 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct pim_instance *pim;
struct zapi_route nhr;
+ struct prefix match;
if (!vrf)
return 0;
pim = vrf->info;
- if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
+ if (!zapi_nexthop_update_decode(zclient->ibuf, &match, &nhr)) {
zlog_err("%s: Decode of nexthop update from zebra failed",
__func__);
return 0;
}
if (cmd == ZEBRA_NEXTHOP_UPDATE) {
- prefix_copy(&rpf.rpf_addr, &nhr.prefix);
+ prefix_copy(&rpf.rpf_addr, &match);
pnc = pim_nexthop_cache_find(pim, &rpf);
if (!pnc) {
if (PIM_DEBUG_PIM_NHT)
@@ -819,9 +820,9 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
if (PIM_DEBUG_PIM_NHT)
zlog_debug(
"%s: NHT addr %pFX(%s) %d-nhop via %pI4(%s) type %d distance:%u metric:%u ",
- __func__, &nhr.prefix, pim->vrf->name,
- i + 1, &nexthop->gate.ipv4,
- ifp->name, nexthop->type, nhr.distance,
+ __func__, &match, pim->vrf->name, i + 1,
+ &nexthop->gate.ipv4, ifp->name,
+ nexthop->type, nhr.distance,
nhr.metric);
if (!ifp->info) {
@@ -875,7 +876,7 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
if (PIM_DEBUG_PIM_NHT)
zlog_debug(
"%s: NHT Update for %pFX(%s) num_nh %d num_pim_nh %d vrf:%u up %ld rp %d",
- __func__, &nhr.prefix, pim->vrf->name, nhr.nexthop_num,
+ __func__, &match, pim->vrf->name, nhr.nexthop_num,
pnc->nexthop_num, vrf_id, pnc->upstream_hash->count,
listcount(pnc->rp_list));
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index 8c9f0c2784..20aec292aa 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -680,16 +680,17 @@ static int sharp_nexthop_update(ZAPI_CALLBACK_ARGS)
{
struct sharp_nh_tracker *nht;
struct zapi_route nhr;
+ struct prefix matched;
- if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
+ if (!zapi_nexthop_update_decode(zclient->ibuf, &matched, &nhr)) {
zlog_err("%s: Decode of update failed", __func__);
return 0;
}
- zlog_debug("Received update for %pFX metric: %u", &nhr.prefix,
- nhr.metric);
+ zlog_debug("Received update for %pFX actual match: %pFX metric: %u",
+ &matched, &nhr.prefix, nhr.metric);
- nht = sharp_nh_tracker_get(&nhr.prefix);
+ nht = sharp_nh_tracker_get(&matched);
nht->nhop_num = nhr.nexthop_num;
nht->updates++;
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index ca0c8c4a1c..c661ad198f 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -169,24 +169,25 @@ static int static_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)
{
struct static_nht_data *nhtd, lookup;
struct zapi_route nhr;
+ struct prefix matched;
afi_t afi = AFI_IP;
- if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
+ if (!zapi_nexthop_update_decode(zclient->ibuf, &matched, &nhr)) {
zlog_err("Failure to decode nexthop update message");
return 1;
}
- if (nhr.prefix.family == AF_INET6)
+ if (matched.family == AF_INET6)
afi = AFI_IP6;
if (nhr.type == ZEBRA_ROUTE_CONNECT) {
- if (static_nexthop_is_local(vrf_id, &nhr.prefix,
- nhr.prefix.family))
+ if (static_nexthop_is_local(vrf_id, &matched,
+ nhr.prefix.family))
nhr.nexthop_num = 0;
}
memset(&lookup, 0, sizeof(lookup));
- lookup.nh = &nhr.prefix;
+ lookup.nh = &matched;
lookup.nh_vrf_id = vrf_id;
nhtd = hash_lookup(static_nht_hash, &lookup);
@@ -194,8 +195,8 @@ static int static_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)
if (nhtd) {
nhtd->nh_num = nhr.nexthop_num;
- static_nht_reset_start(&nhr.prefix, afi, nhtd->nh_vrf_id);
- static_nht_update(NULL, &nhr.prefix, nhr.nexthop_num, afi,
+ static_nht_reset_start(&matched, afi, nhtd->nh_vrf_id);
+ static_nht_update(NULL, &matched, nhr.nexthop_num, afi,
nhtd->nh_vrf_id);
} else
zlog_err("No nhtd?");
diff --git a/zebra/rib.h b/zebra/rib.h
index d5aec5d4c1..9ec8259e4d 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -54,8 +54,7 @@ struct rnh {
#define ZEBRA_NHT_CONNECTED 0x1
#define ZEBRA_NHT_DELETED 0x2
-#define ZEBRA_NHT_EXACT_MATCH 0x4
-#define ZEBRA_NHT_RESOLVE_VIA_DEFAULT 0x8
+#define ZEBRA_NHT_RESOLVE_VIA_DEFAULT 0x4
/* VRF identifier. */
vrf_id_t vrf_id;
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index f5faaab71b..af2b6a1171 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -1173,15 +1173,17 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client,
SET_FLAG(message, ZAPI_MESSAGE_SRTE);
stream_putl(s, message);
+ /*
+ * Put what we were told to match against
+ */
stream_putw(s, rnh->safi);
stream_putw(s, rn->p.family);
+ stream_putc(s, rn->p.prefixlen);
switch (rn->p.family) {
case AF_INET:
- stream_putc(s, rn->p.prefixlen);
stream_put_in_addr(s, &rn->p.u.prefix4);
break;
case AF_INET6:
- stream_putc(s, rn->p.prefixlen);
stream_put(s, &rn->p.u.prefix6, IPV6_MAX_BYTELEN);
break;
default:
@@ -1190,6 +1192,26 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client,
__func__, rn->p.family);
goto failure;
}
+
+ /*
+ * What we matched against
+ */
+ stream_putw(s, rnh->resolved_route.family);
+ stream_putc(s, rnh->resolved_route.prefixlen);
+ switch (rnh->resolved_route.family) {
+ case AF_INET:
+ stream_put_in_addr(s, &rnh->resolved_route.u.prefix4);
+ break;
+ case AF_INET6:
+ stream_put(s, &rnh->resolved_route.u.prefix6, IPV6_MAX_BYTELEN);
+ break;
+ default:
+ flog_err(EC_ZEBRA_RNH_UNKNOWN_FAMILY,
+ "%s: Unknown family (%d) notification attempted",
+ __func__, rn->p.family);
+ goto failure;
+ }
+
if (srte_color)
stream_putl(s, srte_color);
diff --git a/zebra/zebra_srte.c b/zebra/zebra_srte.c
index 7933ef66b1..c0f18dd091 100644
--- a/zebra/zebra_srte.c
+++ b/zebra/zebra_srte.c
@@ -117,16 +117,28 @@ static int zebra_sr_policy_notify_update_client(struct zebra_sr_policy *policy,
stream_putl(s, message);
stream_putw(s, SAFI_UNICAST);
+ /*
+ * The prefix is copied twice because the ZEBRA_NEXTHOP_UPDATE
+ * code was modified to send back both the matched against
+ * as well as the actual matched. There does not appear to
+ * be an equivalent here so just send the same thing twice.
+ */
switch (policy->endpoint.ipa_type) {
case IPADDR_V4:
stream_putw(s, AF_INET);
stream_putc(s, IPV4_MAX_BITLEN);
stream_put_in_addr(s, &policy->endpoint.ipaddr_v4);
+ stream_putw(s, AF_INET);
+ stream_putc(s, IPV4_MAX_BITLEN);
+ stream_put_in_addr(s, &policy->endpoint.ipaddr_v4);
break;
case IPADDR_V6:
stream_putw(s, AF_INET6);
stream_putc(s, IPV6_MAX_BITLEN);
stream_put(s, &policy->endpoint.ipaddr_v6, IPV6_MAX_BYTELEN);
+ stream_putw(s, AF_INET6);
+ stream_putc(s, IPV6_MAX_BITLEN);
+ stream_put(s, &policy->endpoint.ipaddr_v6, IPV6_MAX_BYTELEN);
break;
default:
flog_warn(EC_LIB_DEVELOPMENT,