Merge pull request #14834 from opensourcerouting/zclient-nexthop-update

*: move common NHT update decoding bits into lib/
This commit is contained in:
Donald Sharp 2023-11-21 10:56:47 -05:00 committed by GitHub
commit 01af05fbd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 143 additions and 182 deletions

View File

@ -897,52 +897,44 @@ void bgp_nht_interface_events(struct peer *peer)
bnc->ifindex_ipv6_ll, NULL); bnc->ifindex_ipv6_ll, NULL);
} }
void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id) void bgp_nexthop_update(struct vrf *vrf, struct prefix *match,
struct zapi_route *nhr)
{ {
struct bgp_nexthop_cache_head *tree = NULL; struct bgp_nexthop_cache_head *tree = NULL;
struct bgp_nexthop_cache *bnc_nhc, *bnc_import; struct bgp_nexthop_cache *bnc_nhc, *bnc_import;
struct bgp *bgp; struct bgp *bgp;
struct prefix match;
struct zapi_route nhr;
afi_t afi; afi_t afi;
bgp = bgp_lookup_by_vrf_id(vrf_id); if (!vrf->info) {
if (!bgp) { flog_err(EC_BGP_NH_UPD,
flog_err( "parse nexthop update: instance not found for vrf_id %u",
EC_BGP_NH_UPD, vrf->vrf_id);
"parse nexthop update: instance not found for vrf_id %u",
vrf_id);
return; return;
} }
if (!zapi_nexthop_update_decode(zclient->ibuf, &match, &nhr)) { bgp = (struct bgp *)vrf->info;
zlog_err("%s[%s]: Failure to decode nexthop update", __func__, afi = family2afi(match->family);
bgp->name_pretty);
return;
}
afi = family2afi(match.family);
tree = &bgp->nexthop_cache_table[afi]; tree = &bgp->nexthop_cache_table[afi];
bnc_nhc = bnc_find(tree, &match, nhr.srte_color, 0); bnc_nhc = bnc_find(tree, match, nhr->srte_color, 0);
if (!bnc_nhc) { if (!bnc_nhc) {
if (BGP_DEBUG(nht, NHT)) if (BGP_DEBUG(nht, NHT))
zlog_debug( zlog_debug("parse nexthop update %pFX(%u)(%s): bnc info not found for nexthop cache",
"parse nexthop update %pFX(%u)(%s): bnc info not found for nexthop cache", &nhr->prefix, nhr->srte_color,
&nhr.prefix, nhr.srte_color, bgp->name_pretty); bgp->name_pretty);
} else } else
bgp_process_nexthop_update(bnc_nhc, &nhr, false); bgp_process_nexthop_update(bnc_nhc, nhr, false);
tree = &bgp->import_check_table[afi]; tree = &bgp->import_check_table[afi];
bnc_import = bnc_find(tree, &match, nhr.srte_color, 0); bnc_import = bnc_find(tree, match, nhr->srte_color, 0);
if (!bnc_import) { if (!bnc_import) {
if (BGP_DEBUG(nht, NHT)) if (BGP_DEBUG(nht, NHT))
zlog_debug( zlog_debug("parse nexthop update %pFX(%u)(%s): bnc info not found for import check",
"parse nexthop update %pFX(%u)(%s): bnc info not found for import check", &nhr->prefix, nhr->srte_color,
&nhr.prefix, nhr.srte_color, bgp->name_pretty); bgp->name_pretty);
} else } else
bgp_process_nexthop_update(bnc_import, &nhr, true); bgp_process_nexthop_update(bnc_import, nhr, true);
/* /*
* HACK: if any BGP route is dependant on an SR-policy that doesn't * HACK: if any BGP route is dependant on an SR-policy that doesn't
@ -955,7 +947,7 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
* which should provide a better infrastructure to solve this issue in * which should provide a better infrastructure to solve this issue in
* a more efficient and elegant way. * a more efficient and elegant way.
*/ */
if (nhr.srte_color == 0 && bnc_nhc) { if (nhr->srte_color == 0 && bnc_nhc) {
struct bgp_nexthop_cache *bnc_iter; struct bgp_nexthop_cache *bnc_iter;
frr_each (bgp_nexthop_cache, &bgp->nexthop_cache_table[afi], frr_each (bgp_nexthop_cache, &bgp->nexthop_cache_table[afi],
@ -965,7 +957,7 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
CHECK_FLAG(bnc_iter->flags, BGP_NEXTHOP_VALID)) CHECK_FLAG(bnc_iter->flags, BGP_NEXTHOP_VALID))
continue; continue;
bgp_process_nexthop_update(bnc_iter, &nhr, false); bgp_process_nexthop_update(bnc_iter, nhr, false);
} }
} }
} }

View File

@ -7,9 +7,10 @@
#define _BGP_NHT_H #define _BGP_NHT_H
/** /**
* bgp_parse_nexthop_update() - parse a nexthop update message from Zebra. * bgp_nexthop_update() - process a nexthop update message from Zebra.
*/ */
extern void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id); extern void bgp_nexthop_update(struct vrf *vrf, struct prefix *match,
struct zapi_route *nhr);
/** /**
* bgp_find_or_add_nexthop() - lookup the nexthop cache table for the bnc * bgp_find_or_add_nexthop() - lookup the nexthop cache table for the bnc

View File

@ -100,13 +100,6 @@ static int bgp_router_id_update(ZAPI_CALLBACK_ARGS)
return 0; return 0;
} }
/* Nexthop update message from zebra. */
static int bgp_read_nexthop_update(ZAPI_CALLBACK_ARGS)
{
bgp_parse_nexthop_update(cmd, vrf_id);
return 0;
}
/* Set or clear interface on which unnumbered neighbor is configured. This /* Set or clear interface on which unnumbered neighbor is configured. This
* would in turn cause BGP to initiate or turn off IPv6 RAs on this * would in turn cause BGP to initiate or turn off IPv6 RAs on this
* interface. * interface.
@ -3332,7 +3325,6 @@ static zclient_handler *const bgp_handlers[] = {
[ZEBRA_INTERFACE_NBR_ADDRESS_DELETE] = bgp_interface_nbr_address_delete, [ZEBRA_INTERFACE_NBR_ADDRESS_DELETE] = bgp_interface_nbr_address_delete,
[ZEBRA_REDISTRIBUTE_ROUTE_ADD] = zebra_read_route, [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = zebra_read_route,
[ZEBRA_REDISTRIBUTE_ROUTE_DEL] = zebra_read_route, [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = zebra_read_route,
[ZEBRA_NEXTHOP_UPDATE] = bgp_read_nexthop_update,
[ZEBRA_FEC_UPDATE] = bgp_read_fec_update, [ZEBRA_FEC_UPDATE] = bgp_read_fec_update,
[ZEBRA_LOCAL_ES_ADD] = bgp_zebra_process_local_es_add, [ZEBRA_LOCAL_ES_ADD] = bgp_zebra_process_local_es_add,
[ZEBRA_LOCAL_ES_DEL] = bgp_zebra_process_local_es_del, [ZEBRA_LOCAL_ES_DEL] = bgp_zebra_process_local_es_del,
@ -3454,6 +3446,7 @@ void bgp_zebra_init(struct event_loop *master, unsigned short instance)
zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs); zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs);
zclient->zebra_connected = bgp_zebra_connected; zclient->zebra_connected = bgp_zebra_connected;
zclient->zebra_capabilities = bgp_zebra_capabilities; zclient->zebra_capabilities = bgp_zebra_capabilities;
zclient->nexthop_update = bgp_nexthop_update;
zclient->instance = instance; zclient->instance = instance;
/* Initialize special zclient for synchronous message exchanges. */ /* Initialize special zclient for synchronous message exchanges. */

View File

@ -2269,8 +2269,8 @@ const char *zapi_nexthop2str(const struct zapi_nexthop *znh, char *buf,
/* /*
* Decode the nexthop-tracking update message * Decode the nexthop-tracking update message
*/ */
bool zapi_nexthop_update_decode(struct stream *s, struct prefix *match, static bool zapi_nexthop_update_decode(struct stream *s, struct prefix *match,
struct zapi_route *nhr) struct zapi_route *nhr)
{ {
uint32_t i; uint32_t i;
@ -4298,6 +4298,28 @@ stream_failure:
return -1; return -1;
} }
static int zclient_nexthop_update(ZAPI_CALLBACK_ARGS)
{
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct prefix match;
struct zapi_route route;
if (!vrf) {
zlog_warn("nexthop update for unknown VRF ID %u", vrf_id);
return 0;
}
if (!zapi_nexthop_update_decode(zclient->ibuf, &match, &route)) {
zlog_err("failed to decode nexthop update");
return -1;
}
if (zclient->nexthop_update)
zclient->nexthop_update(vrf, &match, &route);
return 0;
}
static zclient_handler *const lib_handlers[] = { static zclient_handler *const lib_handlers[] = {
/* fundamentals */ /* fundamentals */
[ZEBRA_CAPABILITIES] = zclient_capability_decode, [ZEBRA_CAPABILITIES] = zclient_capability_decode,
@ -4311,6 +4333,9 @@ static zclient_handler *const lib_handlers[] = {
[ZEBRA_INTERFACE_UP] = zclient_interface_up, [ZEBRA_INTERFACE_UP] = zclient_interface_up,
[ZEBRA_INTERFACE_DOWN] = zclient_interface_down, [ZEBRA_INTERFACE_DOWN] = zclient_interface_down,
/* NHT pre-decode */
[ZEBRA_NEXTHOP_UPDATE] = zclient_nexthop_update,
/* BFD */ /* BFD */
[ZEBRA_BFD_DEST_REPLAY] = zclient_bfd_session_replay, [ZEBRA_BFD_DEST_REPLAY] = zclient_bfd_session_replay,
[ZEBRA_INTERFACE_BFD_DEST_UPDATE] = zclient_bfd_session_update, [ZEBRA_INTERFACE_BFD_DEST_UPDATE] = zclient_bfd_session_update,

View File

@ -293,6 +293,8 @@ struct zapi_cap {
typedef int (zclient_handler)(ZAPI_CALLBACK_ARGS); typedef int (zclient_handler)(ZAPI_CALLBACK_ARGS);
/* clang-format on */ /* clang-format on */
struct zapi_route;
/* Structure for the zebra client. */ /* Structure for the zebra client. */
struct zclient { struct zclient {
/* The thread master we schedule ourselves on */ /* The thread master we schedule ourselves on */
@ -348,6 +350,19 @@ struct zclient {
void (*zebra_connected)(struct zclient *); void (*zebra_connected)(struct zclient *);
void (*zebra_capabilities)(struct zclient_capabilities *cap); void (*zebra_capabilities)(struct zclient_capabilities *cap);
/*
* 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.
*/
void (*nexthop_update)(struct vrf *vrf, struct prefix *match,
struct zapi_route *nhr);
int (*handle_error)(enum zebra_error_types error); int (*handle_error)(enum zebra_error_types error);
/* /*
@ -1123,18 +1138,6 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
const struct nexthop *nh); const struct nexthop *nh);
int zapi_backup_nexthop_from_nexthop(struct zapi_nexthop *znh, int zapi_backup_nexthop_from_nexthop(struct zapi_nexthop *znh,
const struct nexthop *nh); const struct nexthop *nh);
/*
* 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, const char *zapi_nexthop2str(const struct zapi_nexthop *znh, char *buf,
int bufsize); int bufsize);

View File

@ -147,30 +147,22 @@ void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg)
__func__); __func__);
} }
static int ospf6_zebra_import_check_update(ZAPI_CALLBACK_ARGS) static void ospf6_zebra_import_check_update(struct vrf *vrf,
struct prefix *matched,
struct zapi_route *nhr)
{ {
struct ospf6 *ospf6; struct ospf6 *ospf6;
struct zapi_route nhr;
struct prefix matched;
ospf6 = ospf6_lookup_by_vrf_id(vrf_id); ospf6 = (struct ospf6 *)vrf->info;
if (ospf6 == NULL || !IS_OSPF6_ASBR(ospf6)) if (ospf6 == NULL || !IS_OSPF6_ASBR(ospf6))
return 0; return;
if (!zapi_nexthop_update_decode(zclient->ibuf, &matched, &nhr)) { if (matched->family != AF_INET6 || matched->prefixlen != 0 ||
zlog_err("%s[%u]: Failure to decode route", __func__, nhr->type == ZEBRA_ROUTE_OSPF6)
ospf6->vrf_id); return;
return -1;
}
if (matched.family != AF_INET6 || matched.prefixlen != 0 || ospf6->nssa_default_import_check.status = !!nhr->nexthop_num;
nhr.type == ZEBRA_ROUTE_OSPF6)
return 0;
ospf6->nssa_default_import_check.status = !!nhr.nexthop_num;
ospf6_abr_nssa_type_7_defaults(ospf6); ospf6_abr_nssa_type_7_defaults(ospf6);
return 0;
} }
static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS) static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS)
@ -763,7 +755,6 @@ static zclient_handler *const ospf6_handlers[] = {
[ZEBRA_INTERFACE_ADDRESS_DELETE] = ospf6_zebra_if_address_update_delete, [ZEBRA_INTERFACE_ADDRESS_DELETE] = ospf6_zebra_if_address_update_delete,
[ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ospf6_zebra_read_route, [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ospf6_zebra_read_route,
[ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf6_zebra_read_route, [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf6_zebra_read_route,
[ZEBRA_NEXTHOP_UPDATE] = ospf6_zebra_import_check_update,
}; };
void ospf6_zebra_init(struct event_loop *master) void ospf6_zebra_init(struct event_loop *master)
@ -773,6 +764,7 @@ void ospf6_zebra_init(struct event_loop *master)
array_size(ospf6_handlers)); array_size(ospf6_handlers));
zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs); zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs);
zclient->zebra_connected = ospf6_zebra_connected; zclient->zebra_connected = ospf6_zebra_connected;
zclient->nexthop_update = ospf6_zebra_import_check_update;
/* Install command element for zebra node. */ /* Install command element for zebra node. */
install_element(VIEW_NODE, &show_ospf6_zebra_cmd); install_element(VIEW_NODE, &show_ospf6_zebra_cmd);

View File

@ -1487,30 +1487,20 @@ void ospf_zebra_import_default_route(struct ospf *ospf, bool unreg)
__func__); __func__);
} }
static int ospf_zebra_import_check_update(ZAPI_CALLBACK_ARGS) static void ospf_zebra_import_check_update(struct vrf *vrf, struct prefix *match,
struct zapi_route *nhr)
{ {
struct ospf *ospf; struct ospf *ospf = vrf->info;
struct zapi_route nhr;
struct prefix matched;
ospf = ospf_lookup_by_vrf_id(vrf_id);
if (ospf == NULL || !IS_OSPF_ASBR(ospf)) if (ospf == NULL || !IS_OSPF_ASBR(ospf))
return 0; return;
if (!zapi_nexthop_update_decode(zclient->ibuf, &matched, &nhr)) { if (match->family != AF_INET || match->prefixlen != 0 ||
zlog_err("%s[%u]: Failure to decode route", __func__, nhr->type == ZEBRA_ROUTE_OSPF)
ospf->vrf_id); return;
return -1;
}
if (matched.family != AF_INET || matched.prefixlen != 0 || ospf->nssa_default_import_check.status = !!nhr->nexthop_num;
nhr.type == ZEBRA_ROUTE_OSPF)
return 0;
ospf->nssa_default_import_check.status = !!nhr.nexthop_num;
ospf_abr_nssa_type7_defaults(ospf); ospf_abr_nssa_type7_defaults(ospf);
return 0;
} }
int ospf_distribute_list_out_set(struct ospf *ospf, int type, const char *name) int ospf_distribute_list_out_set(struct ospf *ospf, int type, const char *name)
@ -2183,7 +2173,6 @@ static zclient_handler *const ospf_handlers[] = {
[ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ospf_zebra_read_route, [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ospf_zebra_read_route,
[ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf_zebra_read_route, [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf_zebra_read_route,
[ZEBRA_NEXTHOP_UPDATE] = ospf_zebra_import_check_update,
[ZEBRA_OPAQUE_MESSAGE] = ospf_opaque_msg_handler, [ZEBRA_OPAQUE_MESSAGE] = ospf_opaque_msg_handler,
@ -2197,6 +2186,7 @@ void ospf_zebra_init(struct event_loop *master, unsigned short instance)
array_size(ospf_handlers)); array_size(ospf_handlers));
zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs); zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs);
zclient->zebra_connected = ospf_zebra_connected; zclient->zebra_connected = ospf_zebra_connected;
zclient->nexthop_update = ospf_zebra_import_check_update;
/* Initialize special zclient for synchronous message exchanges. */ /* Initialize special zclient for synchronous message exchanges. */
struct zclient_options options = zclient_options_default; struct zclient_options options = zclient_options_default;

View File

@ -364,38 +364,30 @@ void route_delete(struct pbr_nexthop_group_cache *pnhgc, afi_t afi)
} }
} }
static int pbr_zebra_nexthop_update(ZAPI_CALLBACK_ARGS) static void pbr_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched,
struct zapi_route *nhr)
{ {
struct zapi_route nhr;
struct prefix matched;
uint32_t i; uint32_t i;
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)) { if (DEBUG_MODE_CHECK(&pbr_dbg_zebra, DEBUG_MODE_ALL)) {
DEBUGD(&pbr_dbg_zebra, DEBUGD(&pbr_dbg_zebra,
"%s: Received Nexthop update: %pFX against %pFX", "%s: Received Nexthop update: %pFX against %pFX",
__func__, &matched, &nhr.prefix); __func__, matched, &nhr->prefix);
DEBUGD(&pbr_dbg_zebra, "%s: (Nexthops(%u)", __func__, DEBUGD(&pbr_dbg_zebra, "%s: (Nexthops(%u)", __func__,
nhr.nexthop_num); nhr->nexthop_num);
for (i = 0; i < nhr.nexthop_num; i++) { for (i = 0; i < nhr->nexthop_num; i++) {
DEBUGD(&pbr_dbg_zebra, DEBUGD(&pbr_dbg_zebra,
"%s: Type: %d: vrf: %d, ifindex: %d gate: %pI4", "%s: Type: %d: vrf: %d, ifindex: %d gate: %pI4",
__func__, nhr.nexthops[i].type, __func__, nhr->nexthops[i].type,
nhr.nexthops[i].vrf_id, nhr.nexthops[i].ifindex, nhr->nexthops[i].vrf_id, nhr->nexthops[i].ifindex,
&nhr.nexthops[i].gate.ipv4); &nhr->nexthops[i].gate.ipv4);
} }
} }
nhr.prefix = matched; nhr->prefix = *matched;
pbr_nht_nexthop_update(&nhr); pbr_nht_nexthop_update(nhr);
return 1;
} }
extern struct zebra_privs_t pbr_privs; extern struct zebra_privs_t pbr_privs;
@ -405,7 +397,6 @@ static zclient_handler *const pbr_handlers[] = {
[ZEBRA_INTERFACE_ADDRESS_DELETE] = interface_address_delete, [ZEBRA_INTERFACE_ADDRESS_DELETE] = interface_address_delete,
[ZEBRA_ROUTE_NOTIFY_OWNER] = route_notify_owner, [ZEBRA_ROUTE_NOTIFY_OWNER] = route_notify_owner,
[ZEBRA_RULE_NOTIFY_OWNER] = rule_notify_owner, [ZEBRA_RULE_NOTIFY_OWNER] = rule_notify_owner,
[ZEBRA_NEXTHOP_UPDATE] = pbr_zebra_nexthop_update,
}; };
void pbr_zebra_init(void) void pbr_zebra_init(void)
@ -417,6 +408,7 @@ void pbr_zebra_init(void)
zclient_init(zclient, ZEBRA_ROUTE_PBR, 0, &pbr_privs); zclient_init(zclient, ZEBRA_ROUTE_PBR, 0, &pbr_privs);
zclient->zebra_connected = zebra_connected; zclient->zebra_connected = zebra_connected;
zclient->nexthop_update = pbr_zebra_nexthop_update;
} }
void pbr_zebra_destroy(void) void pbr_zebra_destroy(void)

View File

@ -723,7 +723,8 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
/* This API is used to parse Registered address nexthop update coming from Zebra /* This API is used to parse Registered address nexthop update coming from Zebra
*/ */
int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS) void pim_nexthop_update(struct vrf *vrf, struct prefix *match,
struct zapi_route *nhr)
{ {
struct nexthop *nexthop; struct nexthop *nexthop;
struct nexthop *nhlist_head = NULL; struct nexthop *nhlist_head = NULL;
@ -732,38 +733,27 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
struct pim_rpf rpf; struct pim_rpf rpf;
struct pim_nexthop_cache *pnc = NULL; struct pim_nexthop_cache *pnc = NULL;
struct interface *ifp = NULL; struct interface *ifp = NULL;
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct pim_instance *pim; struct pim_instance *pim;
struct zapi_route nhr;
struct prefix match;
if (!vrf)
return 0;
pim = vrf->info; pim = vrf->info;
if (!zapi_nexthop_update_decode(zclient->ibuf, &match, &nhr)) { rpf.rpf_addr = pim_addr_from_prefix(match);
zlog_err("%s: Decode of nexthop update from zebra failed",
__func__);
return 0;
}
rpf.rpf_addr = pim_addr_from_prefix(&match);
pnc = pim_nexthop_cache_find(pim, &rpf); pnc = pim_nexthop_cache_find(pim, &rpf);
if (!pnc) { if (!pnc) {
if (PIM_DEBUG_PIM_NHT) if (PIM_DEBUG_PIM_NHT)
zlog_debug( zlog_debug(
"%s: Skipping NHT update, addr %pPA is not in local cached DB.", "%s: Skipping NHT update, addr %pPA is not in local cached DB.",
__func__, &rpf.rpf_addr); __func__, &rpf.rpf_addr);
return 0; return;
} }
pnc->last_update = pim_time_monotonic_usec(); pnc->last_update = pim_time_monotonic_usec();
if (nhr.nexthop_num) { if (nhr->nexthop_num) {
pnc->nexthop_num = 0; pnc->nexthop_num = 0;
for (i = 0; i < nhr.nexthop_num; i++) { for (i = 0; i < nhr->nexthop_num; i++) {
nexthop = nexthop_from_zapi_nexthop(&nhr.nexthops[i]); nexthop = nexthop_from_zapi_nexthop(&nhr->nexthops[i]);
switch (nexthop->type) { switch (nexthop->type) {
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
/* /*
@ -842,11 +832,11 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
#else #else
pim_addr nhaddr = nexthop->gate.ipv6; pim_addr nhaddr = nexthop->gate.ipv6;
#endif #endif
zlog_debug( zlog_debug("%s: NHT addr %pFX(%s) %d-nhop via %pPA(%s) type %d distance:%u metric:%u ",
"%s: NHT addr %pFX(%s) %d-nhop via %pPA(%s) type %d distance:%u metric:%u ", __func__, match, pim->vrf->name,
__func__, &match, pim->vrf->name, i + 1, i + 1, &nhaddr, ifp->name,
&nhaddr, ifp->name, nexthop->type, nexthop->type, nhr->distance,
nhr.distance, nhr.metric); nhr->metric);
} }
if (!ifp->info) { if (!ifp->info) {
@ -887,23 +877,22 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
pnc->nexthop = nhlist_head; pnc->nexthop = nhlist_head;
if (pnc->nexthop_num) { if (pnc->nexthop_num) {
pnc->flags |= PIM_NEXTHOP_VALID; pnc->flags |= PIM_NEXTHOP_VALID;
pnc->distance = nhr.distance; pnc->distance = nhr->distance;
pnc->metric = nhr.metric; pnc->metric = nhr->metric;
} }
} else { } else {
pnc->flags &= ~PIM_NEXTHOP_VALID; pnc->flags &= ~PIM_NEXTHOP_VALID;
pnc->nexthop_num = nhr.nexthop_num; pnc->nexthop_num = nhr->nexthop_num;
nexthops_free(pnc->nexthop); nexthops_free(pnc->nexthop);
pnc->nexthop = NULL; pnc->nexthop = NULL;
} }
SET_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED); SET_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED);
if (PIM_DEBUG_PIM_NHT) if (PIM_DEBUG_PIM_NHT)
zlog_debug( zlog_debug("%s: NHT Update for %pFX(%s) num_nh %d num_pim_nh %d vrf:%u up %ld rp %d",
"%s: NHT Update for %pFX(%s) num_nh %d num_pim_nh %d vrf:%u up %ld rp %d", __func__, match, pim->vrf->name, nhr->nexthop_num,
__func__, &match, pim->vrf->name, nhr.nexthop_num, pnc->nexthop_num, vrf->vrf_id,
pnc->nexthop_num, vrf_id, pnc->upstream_hash->count, pnc->upstream_hash->count, listcount(pnc->rp_list));
listcount(pnc->rp_list));
pim_rpf_set_refresh_time(pim); pim_rpf_set_refresh_time(pim);
@ -911,8 +900,6 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
pim_update_rp_nh(pim, pnc); pim_update_rp_nh(pim, pnc);
if (pnc->upstream_hash->count) if (pnc->upstream_hash->count)
pim_update_upstream_nh(pim, pnc); pim_update_upstream_nh(pim, pnc);
return 0;
} }
int pim_ecmp_nexthop_lookup(struct pim_instance *pim, int pim_ecmp_nexthop_lookup(struct pim_instance *pim,

View File

@ -45,7 +45,8 @@ struct pnc_hash_walk_data {
struct interface *ifp; struct interface *ifp;
}; };
int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS); void pim_nexthop_update(struct vrf *vrf, struct prefix *match,
struct zapi_route *nhr);
int pim_find_or_track_nexthop(struct pim_instance *pim, pim_addr addr, int pim_find_or_track_nexthop(struct pim_instance *pim, pim_addr addr,
struct pim_upstream *up, struct rp_info *rp, struct pim_upstream *up, struct rp_info *rp,
struct pim_nexthop_cache *out_pnc); struct pim_nexthop_cache *out_pnc);

View File

@ -428,7 +428,6 @@ static zclient_handler *const pim_handlers[] = {
[ZEBRA_INTERFACE_ADDRESS_ADD] = pim_zebra_if_address_add, [ZEBRA_INTERFACE_ADDRESS_ADD] = pim_zebra_if_address_add,
[ZEBRA_INTERFACE_ADDRESS_DELETE] = pim_zebra_if_address_del, [ZEBRA_INTERFACE_ADDRESS_DELETE] = pim_zebra_if_address_del,
[ZEBRA_NEXTHOP_UPDATE] = pim_parse_nexthop_update,
[ZEBRA_ROUTER_ID_UPDATE] = pim_router_id_update_zebra, [ZEBRA_ROUTER_ID_UPDATE] = pim_router_id_update_zebra,
#if PIM_IPV == 4 #if PIM_IPV == 4
@ -449,6 +448,7 @@ void pim_zebra_init(void)
zclient->zebra_capabilities = pim_zebra_capabilities; zclient->zebra_capabilities = pim_zebra_capabilities;
zclient->zebra_connected = pim_zebra_connected; zclient->zebra_connected = pim_zebra_connected;
zclient->nexthop_update = pim_nexthop_update;
zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs); zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs);
if (PIM_DEBUG_PIM_TRACE) { if (PIM_DEBUG_PIM_TRACE) {

View File

@ -666,27 +666,20 @@ static int sharp_debug_nexthops(struct zapi_route *api)
return i; return i;
} }
static int sharp_nexthop_update(ZAPI_CALLBACK_ARGS)
static void sharp_nexthop_update(struct vrf *vrf, struct prefix *matched,
struct zapi_route *nhr)
{ {
struct sharp_nh_tracker *nht; struct sharp_nh_tracker *nht;
struct zapi_route nhr;
struct prefix matched;
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 actual match: %pFX metric: %u", zlog_debug("Received update for %pFX actual match: %pFX metric: %u",
&matched, &nhr.prefix, nhr.metric); matched, &nhr->prefix, nhr->metric);
nht = sharp_nh_tracker_get(&matched); nht = sharp_nh_tracker_get(matched);
nht->nhop_num = nhr.nexthop_num; nht->nhop_num = nhr->nexthop_num;
nht->updates++; nht->updates++;
sharp_debug_nexthops(&nhr); sharp_debug_nexthops(nhr);
return 0;
} }
static int sharp_redistribute_route(ZAPI_CALLBACK_ARGS) static int sharp_redistribute_route(ZAPI_CALLBACK_ARGS)
@ -1063,7 +1056,6 @@ static zclient_handler *const sharp_handlers[] = {
[ZEBRA_INTERFACE_ADDRESS_ADD] = interface_address_add, [ZEBRA_INTERFACE_ADDRESS_ADD] = interface_address_add,
[ZEBRA_INTERFACE_ADDRESS_DELETE] = interface_address_delete, [ZEBRA_INTERFACE_ADDRESS_DELETE] = interface_address_delete,
[ZEBRA_ROUTE_NOTIFY_OWNER] = route_notify_owner, [ZEBRA_ROUTE_NOTIFY_OWNER] = route_notify_owner,
[ZEBRA_NEXTHOP_UPDATE] = sharp_nexthop_update,
[ZEBRA_NHG_NOTIFY_OWNER] = nhg_notify_owner, [ZEBRA_NHG_NOTIFY_OWNER] = nhg_notify_owner,
[ZEBRA_REDISTRIBUTE_ROUTE_ADD] = sharp_redistribute_route, [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = sharp_redistribute_route,
[ZEBRA_REDISTRIBUTE_ROUTE_DEL] = sharp_redistribute_route, [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = sharp_redistribute_route,
@ -1088,6 +1080,7 @@ void sharp_zebra_init(void)
zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs); zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs);
zclient->zebra_connected = zebra_connected; zclient->zebra_connected = zebra_connected;
zclient->zebra_buffer_write_ready = sharp_zclient_buffer_ready; zclient->zebra_buffer_write_ready = sharp_zclient_buffer_ready;
zclient->nexthop_update = sharp_nexthop_update;
} }
void sharp_zebra_terminate(void) void sharp_zebra_terminate(void)

View File

@ -186,48 +186,40 @@ static_nexthop_is_local(vrf_id_t vrfid, struct prefix *addr, int family)
} }
return false; return false;
} }
static int static_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)
static void static_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched,
struct zapi_route *nhr)
{ {
struct static_nht_data *nhtd, lookup; struct static_nht_data *nhtd, lookup;
struct zapi_route nhr;
struct prefix matched;
afi_t afi = AFI_IP; afi_t afi = AFI_IP;
if (!zapi_nexthop_update_decode(zclient->ibuf, &matched, &nhr)) {
zlog_err("Failure to decode nexthop update message");
return 1;
}
if (zclient->bfd_integration) if (zclient->bfd_integration)
bfd_nht_update(&matched, &nhr); bfd_nht_update(matched, nhr);
if (matched.family == AF_INET6) if (matched->family == AF_INET6)
afi = AFI_IP6; afi = AFI_IP6;
if (nhr.type == ZEBRA_ROUTE_CONNECT) { if (nhr->type == ZEBRA_ROUTE_CONNECT) {
if (static_nexthop_is_local(vrf_id, &matched, if (static_nexthop_is_local(vrf->vrf_id, matched,
nhr.prefix.family)) nhr->prefix.family))
nhr.nexthop_num = 0; nhr->nexthop_num = 0;
} }
memset(&lookup, 0, sizeof(lookup)); memset(&lookup, 0, sizeof(lookup));
lookup.nh = matched; lookup.nh = *matched;
lookup.nh_vrf_id = vrf_id; lookup.nh_vrf_id = vrf->vrf_id;
lookup.safi = nhr.safi; lookup.safi = nhr->safi;
nhtd = static_nht_hash_find(static_nht_hash, &lookup); nhtd = static_nht_hash_find(static_nht_hash, &lookup);
if (nhtd) { if (nhtd) {
nhtd->nh_num = nhr.nexthop_num; nhtd->nh_num = nhr->nexthop_num;
static_nht_reset_start(&matched, afi, nhr.safi, static_nht_reset_start(matched, afi, nhr->safi, nhtd->nh_vrf_id);
nhtd->nh_vrf_id); static_nht_update(NULL, matched, nhr->nexthop_num, afi,
static_nht_update(NULL, &matched, nhr.nexthop_num, afi, nhr->safi, nhtd->nh_vrf_id);
nhr.safi, nhtd->nh_vrf_id);
} else } else
zlog_err("No nhtd?"); zlog_err("No nhtd?");
return 1;
} }
static void static_zebra_capabilities(struct zclient_capabilities *cap) static void static_zebra_capabilities(struct zclient_capabilities *cap)
@ -535,7 +527,6 @@ static zclient_handler *const static_handlers[] = {
[ZEBRA_INTERFACE_ADDRESS_ADD] = interface_address_add, [ZEBRA_INTERFACE_ADDRESS_ADD] = interface_address_add,
[ZEBRA_INTERFACE_ADDRESS_DELETE] = interface_address_delete, [ZEBRA_INTERFACE_ADDRESS_DELETE] = interface_address_delete,
[ZEBRA_ROUTE_NOTIFY_OWNER] = route_notify_owner, [ZEBRA_ROUTE_NOTIFY_OWNER] = route_notify_owner,
[ZEBRA_NEXTHOP_UPDATE] = static_zebra_nexthop_update,
}; };
void static_zebra_init(void) void static_zebra_init(void)
@ -553,6 +544,7 @@ void static_zebra_init(void)
zclient_init(zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs); zclient_init(zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs);
zclient->zebra_capabilities = static_zebra_capabilities; zclient->zebra_capabilities = static_zebra_capabilities;
zclient->zebra_connected = zebra_connected; zclient->zebra_connected = zebra_connected;
zclient->nexthop_update = static_zebra_nexthop_update;
static_nht_hash_init(static_nht_hash); static_nht_hash_init(static_nht_hash);
static_bfd_initialize(zclient, master); static_bfd_initialize(zclient, master);