Merge pull request #9676 from donaldsharp/import_register

This commit is contained in:
David Lamparter 2021-10-13 22:28:03 +02:00 committed by GitHub
commit c5726f0314
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 205 additions and 386 deletions

View File

@ -664,7 +664,7 @@ void bgp_nht_interface_events(struct peer *peer)
void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id) void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
{ {
struct bgp_nexthop_cache_head *tree = NULL; struct bgp_nexthop_cache_head *tree = NULL;
struct bgp_nexthop_cache *bnc; struct bgp_nexthop_cache *bnc_nhc, *bnc_import;
struct bgp *bgp; struct bgp *bgp;
struct zapi_route nhr; struct zapi_route nhr;
afi_t afi; afi_t afi;
@ -685,22 +685,38 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
} }
afi = family2afi(nhr.prefix.family); afi = family2afi(nhr.prefix.family);
if (command == ZEBRA_NEXTHOP_UPDATE) tree = &bgp->nexthop_cache_table[afi];
tree = &bgp->nexthop_cache_table[afi];
else if (command == ZEBRA_IMPORT_CHECK_UPDATE)
tree = &bgp->import_check_table[afi];
bnc = bnc_find(tree, &nhr.prefix, nhr.srte_color); bnc_nhc = bnc_find(tree, &nhr.prefix, nhr.srte_color);
if (!bnc) { 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", "parse nexthop update(%pFX(%u)(%s)): bnc info not found for nexthop cache",
&nhr.prefix, nhr.srte_color, bgp->name_pretty);
} else
bgp_process_nexthop_update(bnc_nhc, &nhr);
tree = &bgp->import_check_table[afi];
bnc_import = bnc_find(tree, &nhr.prefix, nhr.srte_color);
if (!bnc_import) {
if (BGP_DEBUG(nht, NHT))
zlog_debug(
"parse nexthop update(%pFX(%u)(%s)): bnc info not found for import check",
&nhr.prefix, nhr.srte_color, bgp->name_pretty); &nhr.prefix, nhr.srte_color, bgp->name_pretty);
return; return;
} else {
if (nhr.type == ZEBRA_ROUTE_BGP
|| !prefix_same(&bnc_import->prefix, &nhr.prefix)) {
if (BGP_DEBUG(nht, NHT))
zlog_debug(
"%s: Import Check does not resolve to the same prefix for %pFX received %pFX",
__func__, &bnc_import->prefix, &nhr.prefix);
return;
}
bgp_process_nexthop_update(bnc_import, &nhr);
} }
bgp_process_nexthop_update(bnc, &nhr);
/* /*
* 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
* exist, zebra will never send NH updates relative to that policy. In * exist, zebra will never send NH updates relative to that policy. In
@ -712,12 +728,12 @@ 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) { 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],
bnc_iter) { bnc_iter) {
if (!prefix_same(&bnc->prefix, &bnc_iter->prefix) if (!prefix_same(&bnc_import->prefix, &bnc_iter->prefix)
|| bnc_iter->srte_color == 0 || bnc_iter->srte_color == 0
|| CHECK_FLAG(bnc_iter->flags, BGP_NEXTHOP_VALID)) || CHECK_FLAG(bnc_iter->flags, BGP_NEXTHOP_VALID))
continue; continue;
@ -843,6 +859,7 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command) static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
{ {
bool exact_match = false; bool exact_match = false;
bool resolve_via_default = false;
int ret; int ret;
if (!zclient) if (!zclient)
@ -863,11 +880,12 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
"%s: We have not connected yet, cannot send nexthops", "%s: We have not connected yet, cannot send nexthops",
__func__); __func__);
} }
if ((command == ZEBRA_NEXTHOP_REGISTER if (command == ZEBRA_NEXTHOP_REGISTER) {
|| command == ZEBRA_IMPORT_ROUTE_REGISTER) if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
&& (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED) exact_match = true;
|| CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))) if (CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
exact_match = true; resolve_via_default = true;
}
if (BGP_DEBUG(zebra, ZEBRA)) if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: sending cmd %s for %pFX (vrf %s)", __func__, zlog_debug("%s: sending cmd %s for %pFX (vrf %s)", __func__,
@ -875,17 +893,15 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
bnc->bgp->name_pretty); bnc->bgp->name_pretty);
ret = zclient_send_rnh(zclient, command, &bnc->prefix, exact_match, ret = zclient_send_rnh(zclient, command, &bnc->prefix, exact_match,
bnc->bgp->vrf_id); resolve_via_default, bnc->bgp->vrf_id);
/* TBD: handle the failure */ /* TBD: handle the failure */
if (ret == ZCLIENT_SEND_FAILURE) if (ret == ZCLIENT_SEND_FAILURE)
flog_warn(EC_BGP_ZEBRA_SEND, flog_warn(EC_BGP_ZEBRA_SEND,
"sendmsg_nexthop: zclient_send_message() failed"); "sendmsg_nexthop: zclient_send_message() failed");
if ((command == ZEBRA_NEXTHOP_REGISTER) if (command == ZEBRA_NEXTHOP_REGISTER)
|| (command == ZEBRA_IMPORT_ROUTE_REGISTER))
SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED); SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
else if ((command == ZEBRA_NEXTHOP_UNREGISTER) else if (command == ZEBRA_NEXTHOP_UNREGISTER)
|| (command == ZEBRA_IMPORT_ROUTE_UNREGISTER))
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED); UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
return; return;
} }
@ -910,10 +926,7 @@ static void register_zebra_rnh(struct bgp_nexthop_cache *bnc,
return; return;
} }
if (is_bgp_import_route) sendmsg_zebra_rnh(bnc, ZEBRA_NEXTHOP_REGISTER);
sendmsg_zebra_rnh(bnc, ZEBRA_IMPORT_ROUTE_REGISTER);
else
sendmsg_zebra_rnh(bnc, ZEBRA_NEXTHOP_REGISTER);
} }
/** /**
@ -935,10 +948,7 @@ static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
return; return;
} }
if (is_bgp_import_route) sendmsg_zebra_rnh(bnc, ZEBRA_NEXTHOP_UNREGISTER);
sendmsg_zebra_rnh(bnc, ZEBRA_IMPORT_ROUTE_UNREGISTER);
else
sendmsg_zebra_rnh(bnc, ZEBRA_NEXTHOP_UNREGISTER);
} }
/** /**

View File

@ -112,12 +112,6 @@ static int bgp_read_nexthop_update(ZAPI_CALLBACK_ARGS)
return 0; return 0;
} }
static int bgp_read_import_check_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.
@ -3217,7 +3211,6 @@ void bgp_zebra_init(struct thread_master *master, unsigned short instance)
zclient->redistribute_route_add = zebra_read_route; zclient->redistribute_route_add = zebra_read_route;
zclient->redistribute_route_del = zebra_read_route; zclient->redistribute_route_del = zebra_read_route;
zclient->nexthop_update = bgp_read_nexthop_update; zclient->nexthop_update = bgp_read_nexthop_update;
zclient->import_check_update = bgp_read_import_check_update;
zclient->fec_update = bgp_read_fec_update; zclient->fec_update = bgp_read_fec_update;
zclient->local_es_add = bgp_zebra_process_local_es_add; zclient->local_es_add = bgp_zebra_process_local_es_add;
zclient->local_es_del = bgp_zebra_process_local_es_del; zclient->local_es_del = bgp_zebra_process_local_es_del;

View File

@ -355,9 +355,6 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_INTERFACE_NBR_ADDRESS_ADD), DESC_ENTRY(ZEBRA_INTERFACE_NBR_ADDRESS_ADD),
DESC_ENTRY(ZEBRA_INTERFACE_NBR_ADDRESS_DELETE), DESC_ENTRY(ZEBRA_INTERFACE_NBR_ADDRESS_DELETE),
DESC_ENTRY(ZEBRA_INTERFACE_BFD_DEST_UPDATE), DESC_ENTRY(ZEBRA_INTERFACE_BFD_DEST_UPDATE),
DESC_ENTRY(ZEBRA_IMPORT_ROUTE_REGISTER),
DESC_ENTRY(ZEBRA_IMPORT_ROUTE_UNREGISTER),
DESC_ENTRY(ZEBRA_IMPORT_CHECK_UPDATE),
DESC_ENTRY(ZEBRA_BFD_DEST_REGISTER), DESC_ENTRY(ZEBRA_BFD_DEST_REGISTER),
DESC_ENTRY(ZEBRA_BFD_DEST_DEREGISTER), DESC_ENTRY(ZEBRA_BFD_DEST_DEREGISTER),
DESC_ENTRY(ZEBRA_BFD_DEST_UPDATE), DESC_ENTRY(ZEBRA_BFD_DEST_UPDATE),

View File

@ -765,15 +765,17 @@ static int zclient_connect(struct thread *t)
enum zclient_send_status zclient_send_rnh(struct zclient *zclient, int command, enum zclient_send_status zclient_send_rnh(struct zclient *zclient, int command,
const struct prefix *p, const struct prefix *p,
bool exact_match, vrf_id_t vrf_id) bool connected,
bool resolve_via_def, vrf_id_t vrf_id)
{ {
struct stream *s; struct stream *s;
s = zclient->obuf; s = zclient->obuf;
stream_reset(s); stream_reset(s);
zclient_create_header(s, command, vrf_id); zclient_create_header(s, command, vrf_id);
stream_putc(s, (exact_match) ? 1 : 0); stream_putc(s, (connected) ? 1 : 0);
stream_putc(s, (resolve_via_def) ? 1 : 0);
stream_putw(s, SAFI_UNICAST);
stream_putw(s, PREFIX_FAMILY(p)); stream_putw(s, PREFIX_FAMILY(p));
stream_putc(s, p->prefixlen); stream_putc(s, p->prefixlen);
switch (PREFIX_FAMILY(p)) { switch (PREFIX_FAMILY(p)) {
@ -1925,6 +1927,7 @@ bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
memset(nhr, 0, sizeof(*nhr)); memset(nhr, 0, sizeof(*nhr));
STREAM_GETL(s, nhr->message); STREAM_GETL(s, nhr->message);
STREAM_GETW(s, nhr->safi);
STREAM_GETW(s, nhr->prefix.family); STREAM_GETW(s, nhr->prefix.family);
STREAM_GETC(s, nhr->prefix.prefixlen); STREAM_GETC(s, nhr->prefix.prefixlen);
switch (nhr->prefix.family) { switch (nhr->prefix.family) {
@ -4016,13 +4019,6 @@ static int zclient_read(struct thread *thread)
(*zclient->nexthop_update)(command, zclient, length, (*zclient->nexthop_update)(command, zclient, length,
vrf_id); vrf_id);
break; break;
case ZEBRA_IMPORT_CHECK_UPDATE:
if (zclient_debug)
zlog_debug("zclient rcvd import check update");
if (zclient->import_check_update)
(*zclient->import_check_update)(command, zclient,
length, vrf_id);
break;
case ZEBRA_BFD_DEST_REPLAY: case ZEBRA_BFD_DEST_REPLAY:
if (zclient->bfd_dest_replay) if (zclient->bfd_dest_replay)
(*zclient->bfd_dest_replay)(command, zclient, length, (*zclient->bfd_dest_replay)(command, zclient, length,

View File

@ -126,9 +126,6 @@ typedef enum {
ZEBRA_INTERFACE_NBR_ADDRESS_ADD, ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, ZEBRA_INTERFACE_NBR_ADDRESS_DELETE,
ZEBRA_INTERFACE_BFD_DEST_UPDATE, ZEBRA_INTERFACE_BFD_DEST_UPDATE,
ZEBRA_IMPORT_ROUTE_REGISTER,
ZEBRA_IMPORT_ROUTE_UNREGISTER,
ZEBRA_IMPORT_CHECK_UPDATE,
ZEBRA_BFD_DEST_REGISTER, ZEBRA_BFD_DEST_REGISTER,
ZEBRA_BFD_DEST_DEREGISTER, ZEBRA_BFD_DEST_DEREGISTER,
ZEBRA_BFD_DEST_UPDATE, ZEBRA_BFD_DEST_UPDATE,
@ -362,7 +359,6 @@ struct zclient {
int (*interface_nbr_address_delete)(ZAPI_CALLBACK_ARGS); int (*interface_nbr_address_delete)(ZAPI_CALLBACK_ARGS);
int (*interface_vrf_update)(ZAPI_CALLBACK_ARGS); int (*interface_vrf_update)(ZAPI_CALLBACK_ARGS);
int (*nexthop_update)(ZAPI_CALLBACK_ARGS); int (*nexthop_update)(ZAPI_CALLBACK_ARGS);
int (*import_check_update)(ZAPI_CALLBACK_ARGS);
int (*bfd_dest_replay)(ZAPI_CALLBACK_ARGS); int (*bfd_dest_replay)(ZAPI_CALLBACK_ARGS);
int (*redistribute_route_add)(ZAPI_CALLBACK_ARGS); int (*redistribute_route_add)(ZAPI_CALLBACK_ARGS);
int (*redistribute_route_del)(ZAPI_CALLBACK_ARGS); int (*redistribute_route_del)(ZAPI_CALLBACK_ARGS);
@ -1107,7 +1103,7 @@ extern enum zclient_send_status zclient_route_send(uint8_t, struct zclient *,
struct zapi_route *); struct zapi_route *);
extern enum zclient_send_status extern enum zclient_send_status
zclient_send_rnh(struct zclient *zclient, int command, const struct prefix *p, zclient_send_rnh(struct zclient *zclient, int command, const struct prefix *p,
bool exact_match, vrf_id_t vrf_id); bool connected, bool resolve_via_default, vrf_id_t vrf_id);
int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh, int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
uint32_t api_flags, uint32_t api_message); uint32_t api_flags, uint32_t api_message);
extern int zapi_route_encode(uint8_t, struct stream *, struct zapi_route *); extern int zapi_route_encode(uint8_t, struct stream *, struct zapi_route *);

View File

@ -145,16 +145,17 @@ void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg)
prefix.prefixlen = 0; prefix.prefixlen = 0;
if (unreg) if (unreg)
command = ZEBRA_IMPORT_ROUTE_UNREGISTER; command = ZEBRA_NEXTHOP_UNREGISTER;
else else
command = ZEBRA_IMPORT_ROUTE_REGISTER; command = ZEBRA_NEXTHOP_REGISTER;
if (IS_OSPF6_DEBUG_ZEBRA(SEND)) if (IS_OSPF6_DEBUG_ZEBRA(SEND))
zlog_debug("%s: sending cmd %s for %pFX (vrf %u)", __func__, zlog_debug("%s: sending cmd %s for %pFX (vrf %u)", __func__,
zserv_command_string(command), &prefix, zserv_command_string(command), &prefix,
ospf6->vrf_id); ospf6->vrf_id);
if (zclient_send_rnh(zclient, command, &prefix, true, ospf6->vrf_id) if (zclient_send_rnh(zclient, command, &prefix, false, true,
ospf6->vrf_id)
== ZCLIENT_SEND_FAILURE) == ZCLIENT_SEND_FAILURE)
flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_send_rnh() failed", flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_send_rnh() failed",
__func__); __func__);
@ -720,7 +721,7 @@ void ospf6_zebra_init(struct thread_master *master)
ospf6_zebra_if_address_update_delete; ospf6_zebra_if_address_update_delete;
zclient->redistribute_route_add = ospf6_zebra_read_route; zclient->redistribute_route_add = ospf6_zebra_read_route;
zclient->redistribute_route_del = ospf6_zebra_read_route; zclient->redistribute_route_del = ospf6_zebra_read_route;
zclient->import_check_update = ospf6_zebra_import_check_update; 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

@ -478,7 +478,7 @@ void pbr_send_rnh(struct nexthop *nhop, bool reg)
break; break;
} }
if (zclient_send_rnh(zclient, command, &p, false, nhop->vrf_id) if (zclient_send_rnh(zclient, command, &p, false, false, nhop->vrf_id)
== ZCLIENT_SEND_FAILURE) { == ZCLIENT_SEND_FAILURE) {
zlog_warn("%s: Failure to send nexthop to zebra", __func__); zlog_warn("%s: Failure to send nexthop to zebra", __func__);
} }

View File

@ -54,7 +54,8 @@ void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient,
int ret; int ret;
p = &(pnc->rpf.rpf_addr); p = &(pnc->rpf.rpf_addr);
ret = zclient_send_rnh(zclient, command, p, false, pim->vrf->vrf_id); ret = zclient_send_rnh(zclient, command, p, false, false,
pim->vrf->vrf_id);
if (ret == ZCLIENT_SEND_FAILURE) if (ret == ZCLIENT_SEND_FAILURE)
zlog_warn("sendmsg_nexthop: zclient_send_message() failed"); zlog_warn("sendmsg_nexthop: zclient_send_message() failed");

View File

@ -626,19 +626,12 @@ void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id, bool import,
{ {
int command; int command;
if (!import) { command = ZEBRA_NEXTHOP_REGISTER;
command = ZEBRA_NEXTHOP_REGISTER;
if (!watch) if (!watch)
command = ZEBRA_NEXTHOP_UNREGISTER; command = ZEBRA_NEXTHOP_UNREGISTER;
} else {
command = ZEBRA_IMPORT_ROUTE_REGISTER;
if (!watch) if (zclient_send_rnh(zclient, command, p, connected, false, vrf_id)
command = ZEBRA_IMPORT_ROUTE_UNREGISTER;
}
if (zclient_send_rnh(zclient, command, p, connected, vrf_id)
== ZCLIENT_SEND_FAILURE) == ZCLIENT_SEND_FAILURE)
zlog_warn("%s: Failure to send nexthop to zebra", __func__); zlog_warn("%s: Failure to send nexthop to zebra", __func__);
} }
@ -984,7 +977,6 @@ void sharp_zebra_init(void)
zclient->interface_address_delete = interface_address_delete; zclient->interface_address_delete = interface_address_delete;
zclient->route_notify_owner = route_notify_owner; zclient->route_notify_owner = route_notify_owner;
zclient->nexthop_update = sharp_nexthop_update; zclient->nexthop_update = sharp_nexthop_update;
zclient->import_check_update = sharp_nexthop_update;
zclient->nhg_notify_owner = nhg_notify_owner; zclient->nhg_notify_owner = nhg_notify_owner;
zclient->zebra_buffer_write_ready = sharp_zclient_buffer_ready; zclient->zebra_buffer_write_ready = sharp_zclient_buffer_ready;
zclient->redistribute_route_add = sharp_redistribute_route; zclient->redistribute_route_add = sharp_redistribute_route;

View File

@ -332,7 +332,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
static_nht_hash_free(nhtd); static_nht_hash_free(nhtd);
} }
if (zclient_send_rnh(zclient, cmd, &p, false, nh->nh_vrf_id) if (zclient_send_rnh(zclient, cmd, &p, false, false, nh->nh_vrf_id)
== ZCLIENT_SEND_FAILURE) == ZCLIENT_SEND_FAILURE)
zlog_warn("%s: Failure to send nexthop to zebra", __func__); zlog_warn("%s: Failure to send nexthop to zebra", __func__);
} }

View File

@ -46,24 +46,22 @@ DECLARE_MGROUP(ZEBRA);
DECLARE_MTYPE(RE); DECLARE_MTYPE(RE);
enum rnh_type { RNH_NEXTHOP_TYPE, RNH_IMPORT_CHECK_TYPE };
PREDECL_LIST(rnh_list); PREDECL_LIST(rnh_list);
/* Nexthop structure. */ /* Nexthop structure. */
struct rnh { struct rnh {
uint8_t flags; uint8_t flags;
#define ZEBRA_NHT_CONNECTED 0x1 #define ZEBRA_NHT_CONNECTED 0x1
#define ZEBRA_NHT_DELETED 0x2 #define ZEBRA_NHT_DELETED 0x2
#define ZEBRA_NHT_EXACT_MATCH 0x4 #define ZEBRA_NHT_EXACT_MATCH 0x4
#define ZEBRA_NHT_RESOLVE_VIA_DEFAULT 0x8
/* VRF identifier. */ /* VRF identifier. */
vrf_id_t vrf_id; vrf_id_t vrf_id;
afi_t afi; afi_t afi;
safi_t safi;
enum rnh_type type;
uint32_t seqno; uint32_t seqno;

View File

@ -1164,13 +1164,6 @@ int zsend_zebra_srv6_locator_delete(struct zserv *client,
/* Inbound message handling ------------------------------------------------ */ /* Inbound message handling ------------------------------------------------ */
const int cmd2type[] = {
[ZEBRA_NEXTHOP_REGISTER] = RNH_NEXTHOP_TYPE,
[ZEBRA_NEXTHOP_UNREGISTER] = RNH_NEXTHOP_TYPE,
[ZEBRA_IMPORT_ROUTE_REGISTER] = RNH_IMPORT_CHECK_TYPE,
[ZEBRA_IMPORT_ROUTE_UNREGISTER] = RNH_IMPORT_CHECK_TYPE,
};
/* Nexthop register */ /* Nexthop register */
static void zread_rnh_register(ZAPI_HANDLER_ARGS) static void zread_rnh_register(ZAPI_HANDLER_ARGS)
{ {
@ -1178,17 +1171,17 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
struct stream *s; struct stream *s;
struct prefix p; struct prefix p;
unsigned short l = 0; unsigned short l = 0;
uint8_t flags = 0; uint8_t connected = 0;
uint16_t type = cmd2type[hdr->command]; uint8_t resolve_via_default;
bool exist; bool exist;
bool flag_changed = false; bool flag_changed = false;
uint8_t orig_flags; uint8_t orig_flags;
safi_t safi;
if (IS_ZEBRA_DEBUG_NHT) if (IS_ZEBRA_DEBUG_NHT)
zlog_debug( zlog_debug(
"rnh_register msg from client %s: hdr->length=%d, type=%s vrf=%u", "rnh_register msg from client %s: hdr->length=%d vrf=%u",
zebra_route_string(client->proto), hdr->length, zebra_route_string(client->proto), hdr->length,
(type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route",
zvrf->vrf->vrf_id); zvrf->vrf->vrf_id);
s = msg; s = msg;
@ -1197,10 +1190,12 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
client->nh_reg_time = monotime(NULL); client->nh_reg_time = monotime(NULL);
while (l < hdr->length) { while (l < hdr->length) {
STREAM_GETC(s, flags); STREAM_GETC(s, connected);
STREAM_GETC(s, resolve_via_default);
STREAM_GETW(s, safi);
STREAM_GETW(s, p.family); STREAM_GETW(s, p.family);
STREAM_GETC(s, p.prefixlen); STREAM_GETC(s, p.prefixlen);
l += 4; l += 7;
if (p.family == AF_INET) { if (p.family == AF_INET) {
client->v4_nh_watch_add_cnt++; client->v4_nh_watch_add_cnt++;
if (p.prefixlen > IPV4_MAX_BITLEN) { if (p.prefixlen > IPV4_MAX_BITLEN) {
@ -1228,37 +1223,29 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
p.family); p.family);
return; return;
} }
rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type, &exist); rnh = zebra_add_rnh(&p, zvrf_id(zvrf), &exist);
if (!rnh) if (!rnh)
return; return;
orig_flags = rnh->flags; orig_flags = rnh->flags;
if (type == RNH_NEXTHOP_TYPE) { if (connected && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
if (flags SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
&& !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) else if (!connected
SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
else if (!flags UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
&& CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); if (resolve_via_default)
} else if (type == RNH_IMPORT_CHECK_TYPE) { SET_FLAG(rnh->flags, ZEBRA_NHT_RESOLVE_VIA_DEFAULT);
if (flags
&& !CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH))
SET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
else if (!flags
&& CHECK_FLAG(rnh->flags,
ZEBRA_NHT_EXACT_MATCH))
UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
}
if (orig_flags != rnh->flags) if (orig_flags != rnh->flags)
flag_changed = true; flag_changed = true;
/* Anything not AF_INET/INET6 has been filtered out above */ /* Anything not AF_INET/INET6 has been filtered out above */
if (!exist || flag_changed) if (!exist || flag_changed)
zebra_evaluate_rnh(zvrf, family2afi(p.family), 1, type, zebra_evaluate_rnh(zvrf, family2afi(p.family), 1, &p,
&p); safi);
zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf)); zebra_add_rnh_client(rnh, client, zvrf_id(zvrf));
} }
stream_failure: stream_failure:
@ -1272,7 +1259,7 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
struct stream *s; struct stream *s;
struct prefix p; struct prefix p;
unsigned short l = 0; unsigned short l = 0;
uint16_t type = cmd2type[hdr->command]; safi_t safi;
if (IS_ZEBRA_DEBUG_NHT) if (IS_ZEBRA_DEBUG_NHT)
zlog_debug( zlog_debug(
@ -1283,15 +1270,19 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
s = msg; s = msg;
while (l < hdr->length) { while (l < hdr->length) {
uint8_t flags; uint8_t ignore;
STREAM_GETC(s, flags); STREAM_GETC(s, ignore);
if (flags != 0) if (ignore != 0)
goto stream_failure;
STREAM_GETC(s, ignore);
if (ignore != 0)
goto stream_failure; goto stream_failure;
STREAM_GETW(s, safi);
STREAM_GETW(s, p.family); STREAM_GETW(s, p.family);
STREAM_GETC(s, p.prefixlen); STREAM_GETC(s, p.prefixlen);
l += 4; l += 7;
if (p.family == AF_INET) { if (p.family == AF_INET) {
client->v4_nh_watch_rem_cnt++; client->v4_nh_watch_rem_cnt++;
if (p.prefixlen > IPV4_MAX_BITLEN) { if (p.prefixlen > IPV4_MAX_BITLEN) {
@ -1319,10 +1310,10 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
p.family); p.family);
return; return;
} }
rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), type); rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), safi);
if (rnh) { if (rnh) {
client->nh_dereg_time = monotime(NULL); client->nh_dereg_time = monotime(NULL);
zebra_remove_rnh_client(rnh, client, type); zebra_remove_rnh_client(rnh, client);
} }
} }
stream_failure: stream_failure:
@ -3683,8 +3674,6 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_HELLO] = zread_hello, [ZEBRA_HELLO] = zread_hello,
[ZEBRA_NEXTHOP_REGISTER] = zread_rnh_register, [ZEBRA_NEXTHOP_REGISTER] = zread_rnh_register,
[ZEBRA_NEXTHOP_UNREGISTER] = zread_rnh_unregister, [ZEBRA_NEXTHOP_UNREGISTER] = zread_rnh_unregister,
[ZEBRA_IMPORT_ROUTE_REGISTER] = zread_rnh_register,
[ZEBRA_IMPORT_ROUTE_UNREGISTER] = zread_rnh_unregister,
[ZEBRA_BFD_DEST_UPDATE] = zebra_ptm_bfd_dst_register, [ZEBRA_BFD_DEST_UPDATE] = zebra_ptm_bfd_dst_register,
[ZEBRA_BFD_DEST_REGISTER] = zebra_ptm_bfd_dst_register, [ZEBRA_BFD_DEST_REGISTER] = zebra_ptm_bfd_dst_register,
[ZEBRA_BFD_DEST_DEREGISTER] = zebra_ptm_bfd_dst_deregister, [ZEBRA_BFD_DEST_DEREGISTER] = zebra_ptm_bfd_dst_deregister,

View File

@ -730,10 +730,9 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq)
if (IS_ZEBRA_DEBUG_NHT_DETAILED) if (IS_ZEBRA_DEBUG_NHT_DETAILED)
zlog_debug( zlog_debug(
"%s(%u):%pRN has Nexthop(%pFX) Type: %s depending on it, evaluating %u:%u", "%s(%u):%pRN has Nexthop(%pFX) depending on it, evaluating %u:%u",
zvrf_name(zvrf), zvrf_id(zvrf), zvrf_name(zvrf), zvrf_id(zvrf), rn, p,
rn, p, rnh_type2str(rnh->type), seq, seq, rnh->seqno);
rnh->seqno);
/* /*
* If we have evaluated this node on this pass * If we have evaluated this node on this pass
@ -755,8 +754,8 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq)
} }
rnh->seqno = seq; rnh->seqno = seq;
zebra_evaluate_rnh(zvrf, family2afi(p->family), 0, zebra_evaluate_rnh(zvrf, family2afi(p->family), 0, p,
rnh->type, p); rnh->safi);
} }
rn = rn->parent; rn = rn->parent;

View File

@ -71,21 +71,18 @@ void zebra_rnh_init(void)
} }
static inline struct route_table *get_rnh_table(vrf_id_t vrfid, afi_t afi, static inline struct route_table *get_rnh_table(vrf_id_t vrfid, afi_t afi,
enum rnh_type type) safi_t safi)
{ {
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
struct route_table *t = NULL; struct route_table *t = NULL;
zvrf = zebra_vrf_lookup_by_id(vrfid); zvrf = zebra_vrf_lookup_by_id(vrfid);
if (zvrf) if (zvrf) {
switch (type) { if (safi == SAFI_UNICAST)
case RNH_NEXTHOP_TYPE:
t = zvrf->rnh_table[afi]; t = zvrf->rnh_table[afi];
break; else if (safi == SAFI_MULTICAST)
case RNH_IMPORT_CHECK_TYPE: t = zvrf->rnh_table_multicast[afi];
t = zvrf->import_check_table[afi]; }
break;
}
return t; return t;
} }
@ -93,7 +90,7 @@ static inline struct route_table *get_rnh_table(vrf_id_t vrfid, afi_t afi,
static void zebra_rnh_remove_from_routing_table(struct rnh *rnh) static void zebra_rnh_remove_from_routing_table(struct rnh *rnh)
{ {
struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id); struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id);
struct route_table *table = zvrf->table[rnh->afi][SAFI_UNICAST]; struct route_table *table = zvrf->table[rnh->afi][rnh->safi];
struct route_node *rn; struct route_node *rn;
rib_dest_t *dest; rib_dest_t *dest;
@ -117,7 +114,7 @@ static void zebra_rnh_remove_from_routing_table(struct rnh *rnh)
static void zebra_rnh_store_in_routing_table(struct rnh *rnh) static void zebra_rnh_store_in_routing_table(struct rnh *rnh)
{ {
struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id); struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id);
struct route_table *table = zvrf->table[rnh->afi][SAFI_UNICAST]; struct route_table *table = zvrf->table[rnh->afi][rnh->safi];
struct route_node *rn; struct route_node *rn;
rib_dest_t *dest; rib_dest_t *dest;
@ -135,27 +132,28 @@ static void zebra_rnh_store_in_routing_table(struct rnh *rnh)
route_unlock_node(rn); route_unlock_node(rn);
} }
struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, enum rnh_type type, struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, bool *exists)
bool *exists)
{ {
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
struct rnh *rnh = NULL; struct rnh *rnh = NULL;
afi_t afi = family2afi(p->family); afi_t afi = family2afi(p->family);
safi_t safi = SAFI_UNICAST;
if (IS_ZEBRA_DEBUG_NHT) { if (IS_ZEBRA_DEBUG_NHT) {
struct vrf *vrf = vrf_lookup_by_id(vrfid); struct vrf *vrf = vrf_lookup_by_id(vrfid);
zlog_debug("%s(%u): Add RNH %pFX type %s", VRF_LOGNAME(vrf), zlog_debug("%s(%u): Add RNH %pFX for safi: %u",
vrfid, p, rnh_type2str(type)); VRF_LOGNAME(vrf), vrfid, p, safi);
} }
table = get_rnh_table(vrfid, afi, type);
table = get_rnh_table(vrfid, afi, safi);
if (!table) { if (!table) {
struct vrf *vrf = vrf_lookup_by_id(vrfid); struct vrf *vrf = vrf_lookup_by_id(vrfid);
flog_warn(EC_ZEBRA_RNH_NO_TABLE, flog_warn(EC_ZEBRA_RNH_NO_TABLE,
"%s(%u): Add RNH %pFX type %s - table not found", "%s(%u): Add RNH %pFX - table not found",
VRF_LOGNAME(vrf), vrfid, p, rnh_type2str(type)); VRF_LOGNAME(vrf), vrfid, p);
*exists = false; *exists = false;
return NULL; return NULL;
} }
@ -178,9 +176,9 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, enum rnh_type type,
rnh->resolved_route.family = p->family; rnh->resolved_route.family = p->family;
rnh->client_list = list_new(); rnh->client_list = list_new();
rnh->vrf_id = vrfid; rnh->vrf_id = vrfid;
rnh->type = type;
rnh->seqno = 0; rnh->seqno = 0;
rnh->afi = afi; rnh->afi = afi;
rnh->safi = safi;
rnh->zebra_pseudowire_list = list_new(); rnh->zebra_pseudowire_list = list_new();
route_lock_node(rn); route_lock_node(rn);
rn->info = rnh; rn->info = rnh;
@ -195,13 +193,12 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, enum rnh_type type,
return (rn->info); return (rn->info);
} }
struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, safi_t safi)
enum rnh_type type)
{ {
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
table = get_rnh_table(vrfid, family2afi(PREFIX_FAMILY(p)), type); table = get_rnh_table(vrfid, family2afi(PREFIX_FAMILY(p)), safi);
if (!table) if (!table)
return NULL; return NULL;
@ -228,7 +225,7 @@ void zebra_free_rnh(struct rnh *rnh)
list_delete(&rnh->zebra_pseudowire_list); list_delete(&rnh->zebra_pseudowire_list);
zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id); zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id);
table = zvrf->table[family2afi(rnh->resolved_route.family)][SAFI_UNICAST]; table = zvrf->table[family2afi(rnh->resolved_route.family)][rnh->safi];
if (table) { if (table) {
struct route_node *rern; struct route_node *rern;
@ -247,7 +244,7 @@ void zebra_free_rnh(struct rnh *rnh)
XFREE(MTYPE_RNH, rnh); XFREE(MTYPE_RNH, rnh);
} }
static void zebra_delete_rnh(struct rnh *rnh, enum rnh_type type) static void zebra_delete_rnh(struct rnh *rnh)
{ {
struct route_node *rn; struct route_node *rn;
@ -261,8 +258,8 @@ static void zebra_delete_rnh(struct rnh *rnh, enum rnh_type type)
if (IS_ZEBRA_DEBUG_NHT) { if (IS_ZEBRA_DEBUG_NHT) {
struct vrf *vrf = vrf_lookup_by_id(rnh->vrf_id); struct vrf *vrf = vrf_lookup_by_id(rnh->vrf_id);
zlog_debug("%s(%u): Del RNH %pRN type %s", VRF_LOGNAME(vrf), zlog_debug("%s(%u): Del RNH %pRN", VRF_LOGNAME(vrf),
rnh->vrf_id, rnh->node, rnh_type2str(type)); rnh->vrf_id, rnh->node);
} }
zebra_free_rnh(rnh); zebra_free_rnh(rnh);
@ -279,15 +276,14 @@ static void zebra_delete_rnh(struct rnh *rnh, enum rnh_type type)
* and as such it will have a resolved rnh. * and as such it will have a resolved rnh.
*/ */
void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client,
enum rnh_type type, vrf_id_t vrf_id) vrf_id_t vrf_id)
{ {
if (IS_ZEBRA_DEBUG_NHT) { if (IS_ZEBRA_DEBUG_NHT) {
struct vrf *vrf = vrf_lookup_by_id(vrf_id); struct vrf *vrf = vrf_lookup_by_id(vrf_id);
zlog_debug("%s(%u): Client %s registers for RNH %pRN type %s", zlog_debug("%s(%u): Client %s registers for RNH %pRN",
VRF_LOGNAME(vrf), vrf_id, VRF_LOGNAME(vrf), vrf_id,
zebra_route_string(client->proto), rnh->node, zebra_route_string(client->proto), rnh->node);
rnh_type2str(type));
} }
if (!listnode_lookup(rnh->client_list, client)) if (!listnode_lookup(rnh->client_list, client))
listnode_add(rnh->client_list, client); listnode_add(rnh->client_list, client);
@ -296,21 +292,20 @@ void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client,
* We always need to respond with known information, * We always need to respond with known information,
* currently multiple daemons expect this behavior * currently multiple daemons expect this behavior
*/ */
zebra_send_rnh_update(rnh, client, type, vrf_id, 0); zebra_send_rnh_update(rnh, client, vrf_id, 0);
} }
void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client, void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client)
enum rnh_type type)
{ {
if (IS_ZEBRA_DEBUG_NHT) { if (IS_ZEBRA_DEBUG_NHT) {
struct vrf *vrf = vrf_lookup_by_id(rnh->vrf_id); struct vrf *vrf = vrf_lookup_by_id(rnh->vrf_id);
zlog_debug("Client %s unregisters for RNH %s(%u)%pRN type %s", zlog_debug("Client %s unregisters for RNH %s(%u)%pRN",
zebra_route_string(client->proto), VRF_LOGNAME(vrf), zebra_route_string(client->proto), VRF_LOGNAME(vrf),
vrf->vrf_id, rnh->node, rnh_type2str(type)); vrf->vrf_id, rnh->node);
} }
listnode_delete(rnh->client_list, client); listnode_delete(rnh->client_list, client);
zebra_delete_rnh(rnh, type); zebra_delete_rnh(rnh);
} }
/* XXX move this utility function elsewhere? */ /* XXX move this utility function elsewhere? */
@ -350,15 +345,15 @@ void zebra_register_rnh_pseudowire(vrf_id_t vrf_id, struct zebra_pw *pw,
return; return;
addr2hostprefix(pw->af, &pw->nexthop, &nh); addr2hostprefix(pw->af, &pw->nexthop, &nh);
rnh = zebra_add_rnh(&nh, vrf_id, RNH_NEXTHOP_TYPE, &exists); rnh = zebra_add_rnh(&nh, vrf_id, &exists);
if (!rnh) if (!rnh)
return; return;
if (!listnode_lookup(rnh->zebra_pseudowire_list, pw)) { if (!listnode_lookup(rnh->zebra_pseudowire_list, pw)) {
listnode_add(rnh->zebra_pseudowire_list, pw); listnode_add(rnh->zebra_pseudowire_list, pw);
pw->rnh = rnh; pw->rnh = rnh;
zebra_evaluate_rnh(zvrf, family2afi(pw->af), 1, zebra_evaluate_rnh(zvrf, family2afi(pw->af), 1, &nh,
RNH_NEXTHOP_TYPE, &nh); SAFI_UNICAST);
} else } else
*nht_exists = true; *nht_exists = true;
} }
@ -374,7 +369,7 @@ void zebra_deregister_rnh_pseudowire(vrf_id_t vrf_id, struct zebra_pw *pw)
listnode_delete(rnh->zebra_pseudowire_list, pw); listnode_delete(rnh->zebra_pseudowire_list, pw);
pw->rnh = NULL; pw->rnh = NULL;
zebra_delete_rnh(rnh, RNH_NEXTHOP_TYPE); zebra_delete_rnh(rnh);
} }
/* Clear the NEXTHOP_FLAG_RNH_FILTERED flags on all nexthops /* Clear the NEXTHOP_FLAG_RNH_FILTERED flags on all nexthops
@ -418,111 +413,6 @@ static int zebra_rnh_apply_nht_rmap(afi_t afi, struct zebra_vrf *zvrf,
return (at_least_one); return (at_least_one);
} }
/*
* Determine appropriate route (RE entry) resolving a tracked BGP route
* for BGP route for import.
*/
static struct route_entry *
zebra_rnh_resolve_import_entry(struct zebra_vrf *zvrf, afi_t afi,
struct route_node *nrn, struct rnh *rnh,
struct route_node **prn)
{
struct route_table *route_table;
struct route_node *rn;
struct route_entry *re;
*prn = NULL;
route_table = zvrf->table[afi][SAFI_UNICAST];
if (!route_table) // unexpected
return NULL;
rn = route_node_match(route_table, &nrn->p);
if (!rn)
return NULL;
/* Unlock route node - we don't need to lock when walking the tree. */
route_unlock_node(rn);
if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH)
&& !prefix_same(&nrn->p, &rn->p))
return NULL;
if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
zlog_debug("%s: %s(%u):%pRN Resolved Import Entry to %pRN",
__func__, VRF_LOGNAME(zvrf->vrf), rnh->vrf_id,
rnh->node, rn);
}
/* Identify appropriate route entry. */
RNODE_FOREACH_RE (rn, re) {
if (!CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)
&& CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)
&& !CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED)
&& (re->type != ZEBRA_ROUTE_BGP))
break;
}
if (re)
*prn = rn;
if (!re && IS_ZEBRA_DEBUG_NHT_DETAILED)
zlog_debug(" Rejected due to removed or is a bgp route");
return re;
}
/*
* See if a tracked route entry for import (by BGP) has undergone any
* change, and if so, notify the client.
*/
static void zebra_rnh_eval_import_check_entry(struct zebra_vrf *zvrf, afi_t afi,
int force, struct route_node *nrn,
struct rnh *rnh,
struct route_node *prn,
struct route_entry *re)
{
int state_changed = 0;
struct zserv *client;
struct listnode *node;
zebra_rnh_remove_from_routing_table(rnh);
if (prn) {
prefix_copy(&rnh->resolved_route, &prn->p);
} else {
int family = rnh->resolved_route.family;
memset(&rnh->resolved_route.family, 0, sizeof(struct prefix));
rnh->resolved_route.family = family;
}
zebra_rnh_store_in_routing_table(rnh);
if (re && (rnh->state == NULL)) {
if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
state_changed = 1;
} else if (!re && (rnh->state != NULL))
state_changed = 1;
if (compare_state(re, rnh->state)) {
copy_state(rnh, re, nrn);
state_changed = 1;
}
if (state_changed || force) {
if (IS_ZEBRA_DEBUG_NHT)
zlog_debug("%s(%u):%pRN: Route import check %s %s",
VRF_LOGNAME(zvrf->vrf), zvrf->vrf->vrf_id,
nrn, rnh->state ? "passed" : "failed",
state_changed ? "(state changed)" : "");
/* state changed, notify clients */
for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) {
zebra_send_rnh_update(rnh, client,
RNH_IMPORT_CHECK_TYPE,
zvrf->vrf->vrf_id, 0);
}
}
}
/* /*
* Notify clients registered for this nexthop about a change. * Notify clients registered for this nexthop about a change.
*/ */
@ -580,8 +470,7 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi,
zebra_route_string(client->proto)); zebra_route_string(client->proto));
} }
zebra_send_rnh_update(rnh, client, RNH_NEXTHOP_TYPE, zebra_send_rnh_update(rnh, client, zvrf->vrf->vrf_id, 0);
zvrf->vrf->vrf_id, 0);
} }
if (re) if (re)
@ -676,7 +565,7 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
*prn = NULL; *prn = NULL;
route_table = zvrf->table[afi][SAFI_UNICAST]; route_table = zvrf->table[afi][rnh->safi];
if (!route_table) if (!route_table)
return NULL; return NULL;
@ -700,10 +589,14 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
* match route to be exact if so specified * match route to be exact if so specified
*/ */
if (is_default_prefix(&rn->p) if (is_default_prefix(&rn->p)
&& !rnh_resolve_via_default(zvrf, rn->p.family)) { && (!CHECK_FLAG(rnh->flags, ZEBRA_NHT_RESOLVE_VIA_DEFAULT)
&& !rnh_resolve_via_default(zvrf, rn->p.family))) {
if (IS_ZEBRA_DEBUG_NHT_DETAILED) if (IS_ZEBRA_DEBUG_NHT_DETAILED)
zlog_debug( zlog_debug(
" Not allowed to resolve through default prefix"); " Not allowed to resolve through default prefix: rnh->resolve_via_default: %u",
CHECK_FLAG(
rnh->flags,
ZEBRA_NHT_RESOLVE_VIA_DEFAULT));
return NULL; return NULL;
} }
@ -823,26 +716,22 @@ static void zebra_rnh_eval_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
/* Evaluate one tracked entry */ /* Evaluate one tracked entry */
static void zebra_rnh_evaluate_entry(struct zebra_vrf *zvrf, afi_t afi, static void zebra_rnh_evaluate_entry(struct zebra_vrf *zvrf, afi_t afi,
int force, enum rnh_type type, int force, struct route_node *nrn)
struct route_node *nrn)
{ {
struct rnh *rnh; struct rnh *rnh;
struct route_entry *re; struct route_entry *re;
struct route_node *prn; struct route_node *prn;
if (IS_ZEBRA_DEBUG_NHT) { if (IS_ZEBRA_DEBUG_NHT) {
zlog_debug("%s(%u):%pRN: Evaluate RNH, type %s %s", zlog_debug("%s(%u):%pRN: Evaluate RNH, %s",
VRF_LOGNAME(zvrf->vrf), zvrf->vrf->vrf_id, nrn, VRF_LOGNAME(zvrf->vrf), zvrf->vrf->vrf_id, nrn,
rnh_type2str(type), force ? "(force)" : ""); force ? "(force)" : "");
} }
rnh = nrn->info; rnh = nrn->info;
/* Identify route entry (RE) resolving this tracked entry. */ /* Identify route entry (RE) resolving this tracked entry. */
if (type == RNH_IMPORT_CHECK_TYPE) re = zebra_rnh_resolve_nexthop_entry(zvrf, afi, nrn, rnh, &prn);
re = zebra_rnh_resolve_import_entry(zvrf, afi, nrn, rnh, &prn);
else
re = zebra_rnh_resolve_nexthop_entry(zvrf, afi, nrn, rnh, &prn);
/* If the entry cannot be resolved and that is also the existing state, /* If the entry cannot be resolved and that is also the existing state,
* there is nothing further to do. * there is nothing further to do.
@ -851,12 +740,7 @@ static void zebra_rnh_evaluate_entry(struct zebra_vrf *zvrf, afi_t afi,
return; return;
/* Process based on type of entry. */ /* Process based on type of entry. */
if (type == RNH_IMPORT_CHECK_TYPE) zebra_rnh_eval_nexthop_entry(zvrf, afi, force, nrn, rnh, prn, re);
zebra_rnh_eval_import_check_entry(zvrf, afi, force, nrn, rnh,
prn, re);
else
zebra_rnh_eval_nexthop_entry(zvrf, afi, force, nrn, rnh, prn,
re);
} }
/* /*
@ -869,7 +753,7 @@ static void zebra_rnh_evaluate_entry(struct zebra_vrf *zvrf, afi_t afi,
* covers multiple nexthops we are interested in. * covers multiple nexthops we are interested in.
*/ */
static void zebra_rnh_clear_nhc_flag(struct zebra_vrf *zvrf, afi_t afi, static void zebra_rnh_clear_nhc_flag(struct zebra_vrf *zvrf, afi_t afi,
enum rnh_type type, struct route_node *nrn) struct route_node *nrn)
{ {
struct rnh *rnh; struct rnh *rnh;
struct route_entry *re; struct route_entry *re;
@ -878,12 +762,7 @@ static void zebra_rnh_clear_nhc_flag(struct zebra_vrf *zvrf, afi_t afi,
rnh = nrn->info; rnh = nrn->info;
/* Identify route entry (RIB) resolving this tracked entry. */ /* Identify route entry (RIB) resolving this tracked entry. */
if (type == RNH_IMPORT_CHECK_TYPE) re = zebra_rnh_resolve_nexthop_entry(zvrf, afi, nrn, rnh, &prn);
re = zebra_rnh_resolve_import_entry(zvrf, afi, nrn, rnh,
&prn);
else
re = zebra_rnh_resolve_nexthop_entry(zvrf, afi, nrn, rnh,
&prn);
if (re) if (re)
UNSET_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED); UNSET_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED);
@ -893,12 +772,12 @@ static void zebra_rnh_clear_nhc_flag(struct zebra_vrf *zvrf, afi_t afi,
* of a particular VRF and address-family or a specific prefix. * of a particular VRF and address-family or a specific prefix.
*/ */
void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force, void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force,
enum rnh_type type, struct prefix *p) struct prefix *p, safi_t safi)
{ {
struct route_table *rnh_table; struct route_table *rnh_table;
struct route_node *nrn; struct route_node *nrn;
rnh_table = get_rnh_table(zvrf->vrf->vrf_id, afi, type); rnh_table = get_rnh_table(zvrf->vrf->vrf_id, afi, safi);
if (!rnh_table) // unexpected if (!rnh_table) // unexpected
return; return;
@ -906,7 +785,7 @@ void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force,
/* Evaluating a specific entry, make sure it exists. */ /* Evaluating a specific entry, make sure it exists. */
nrn = route_node_lookup(rnh_table, p); nrn = route_node_lookup(rnh_table, p);
if (nrn && nrn->info) if (nrn && nrn->info)
zebra_rnh_evaluate_entry(zvrf, afi, force, type, nrn); zebra_rnh_evaluate_entry(zvrf, afi, force, nrn);
if (nrn) if (nrn)
route_unlock_node(nrn); route_unlock_node(nrn);
@ -915,26 +794,25 @@ void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force,
nrn = route_top(rnh_table); nrn = route_top(rnh_table);
while (nrn) { while (nrn) {
if (nrn->info) if (nrn->info)
zebra_rnh_evaluate_entry(zvrf, afi, force, type, zebra_rnh_evaluate_entry(zvrf, afi, force, nrn);
nrn);
nrn = route_next(nrn); /* this will also unlock nrn */ nrn = route_next(nrn); /* this will also unlock nrn */
} }
nrn = route_top(rnh_table); nrn = route_top(rnh_table);
while (nrn) { while (nrn) {
if (nrn->info) if (nrn->info)
zebra_rnh_clear_nhc_flag(zvrf, afi, type, nrn); zebra_rnh_clear_nhc_flag(zvrf, afi, nrn);
nrn = route_next(nrn); /* this will also unlock nrn */ nrn = route_next(nrn); /* this will also unlock nrn */
} }
} }
} }
void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty, void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty,
enum rnh_type type, struct prefix *p) struct prefix *p)
{ {
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
table = get_rnh_table(vrfid, afi, type); table = get_rnh_table(vrfid, afi, SAFI_UNICAST);
if (!table) { if (!table) {
if (IS_ZEBRA_DEBUG_NHT) if (IS_ZEBRA_DEBUG_NHT)
zlog_debug("print_rnhs: rnh table not found"); zlog_debug("print_rnhs: rnh table not found");
@ -1271,8 +1149,7 @@ static bool compare_state(struct route_entry *r1,
} }
int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client, int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client,
enum rnh_type type, vrf_id_t vrf_id, vrf_id_t vrf_id, uint32_t srte_color)
uint32_t srte_color)
{ {
struct stream *s = NULL; struct stream *s = NULL;
struct route_entry *re; struct route_entry *re;
@ -1282,8 +1159,6 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client,
struct route_node *rn; struct route_node *rn;
int ret; int ret;
uint32_t message = 0; uint32_t message = 0;
int cmd = (type == RNH_IMPORT_CHECK_TYPE) ? ZEBRA_IMPORT_CHECK_UPDATE
: ZEBRA_NEXTHOP_UPDATE;
rn = rnh->node; rn = rnh->node;
re = rnh->state; re = rnh->state;
@ -1291,13 +1166,14 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client,
/* Get output stream. */ /* Get output stream. */
s = stream_new(ZEBRA_MAX_PACKET_SIZ); s = stream_new(ZEBRA_MAX_PACKET_SIZ);
zclient_create_header(s, cmd, vrf_id); zclient_create_header(s, ZEBRA_NEXTHOP_UPDATE, vrf_id);
/* Message flags. */ /* Message flags. */
if (srte_color) if (srte_color)
SET_FLAG(message, ZAPI_MESSAGE_SRTE); SET_FLAG(message, ZAPI_MESSAGE_SRTE);
stream_putl(s, message); stream_putl(s, message);
stream_putw(s, rnh->safi);
stream_putw(s, rn->p.family); stream_putw(s, rn->p.family);
switch (rn->p.family) { switch (rn->p.family) {
case AF_INET: case AF_INET:
@ -1444,7 +1320,7 @@ static void print_rnh(struct route_node *rn, struct vty *vty)
} }
static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi, static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi,
struct zserv *client, enum rnh_type type) struct zserv *client)
{ {
struct route_table *ntable; struct route_table *ntable;
struct route_node *nrn; struct route_node *nrn;
@ -1453,14 +1329,12 @@ static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi,
if (IS_ZEBRA_DEBUG_NHT) { if (IS_ZEBRA_DEBUG_NHT) {
struct vrf *vrf = vrf_lookup_by_id(vrf_id); struct vrf *vrf = vrf_lookup_by_id(vrf_id);
zlog_debug( zlog_debug("%s(%u): Client %s RNH cleanup for family %s",
"%s(%u): Client %s RNH cleanup for family %s type %s", VRF_LOGNAME(vrf), vrf_id,
VRF_LOGNAME(vrf), vrf_id, zebra_route_string(client->proto), afi2str(afi));
zebra_route_string(client->proto), afi2str(afi),
rnh_type2str(type));
} }
ntable = get_rnh_table(vrf_id, afi, type); ntable = get_rnh_table(vrf_id, afi, SAFI_UNICAST);
if (!ntable) { if (!ntable) {
zlog_debug("cleanup_rnh_client: rnh table not found"); zlog_debug("cleanup_rnh_client: rnh table not found");
return -1; return -1;
@ -1471,7 +1345,7 @@ static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi,
continue; continue;
rnh = nrn->info; rnh = nrn->info;
zebra_remove_rnh_client(rnh, client, type); zebra_remove_rnh_client(rnh, client);
} }
return 1; return 1;
} }
@ -1485,14 +1359,9 @@ static int zebra_client_cleanup_rnh(struct zserv *client)
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
zvrf = vrf->info; zvrf = vrf->info;
if (zvrf) { if (zvrf) {
zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP, client, zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP, client);
RNH_NEXTHOP_TYPE); zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP6,
zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP6, client, client);
RNH_NEXTHOP_TYPE);
zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP, client,
RNH_IMPORT_CHECK_TYPE);
zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP6, client,
RNH_IMPORT_CHECK_TYPE);
} }
} }

View File

@ -31,36 +31,22 @@ extern "C" {
extern void zebra_rnh_init(void); extern void zebra_rnh_init(void);
static inline const char *rnh_type2str(enum rnh_type type)
{
switch (type) {
case RNH_NEXTHOP_TYPE:
return "Nexthop";
case RNH_IMPORT_CHECK_TYPE:
return "Import";
}
return "ERROR";
}
extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid,
enum rnh_type type, bool *exists); bool *exists);
extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid,
enum rnh_type type); safi_t safi);
extern void zebra_free_rnh(struct rnh *rnh); extern void zebra_free_rnh(struct rnh *rnh);
extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client,
enum rnh_type type, vrf_id_t vrfid); vrf_id_t vrfid);
extern int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client, extern int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client,
enum rnh_type type, vrf_id_t vrf_id, vrf_id_t vrf_id, uint32_t srte_color);
uint32_t srte_color);
extern void zebra_register_rnh_pseudowire(vrf_id_t, struct zebra_pw *, bool *); extern void zebra_register_rnh_pseudowire(vrf_id_t, struct zebra_pw *, bool *);
extern void zebra_deregister_rnh_pseudowire(vrf_id_t, struct zebra_pw *); extern void zebra_deregister_rnh_pseudowire(vrf_id_t, struct zebra_pw *);
extern void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client, extern void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client);
enum rnh_type type);
extern void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force, extern void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force,
enum rnh_type type, struct prefix *p); struct prefix *p, safi_t safi);
extern void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty, extern void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty,
enum rnh_type type, struct prefix *p); struct prefix *p);
extern int rnh_resolve_via_default(struct zebra_vrf *zvrf, int family); extern int rnh_resolve_via_default(struct zebra_vrf *zvrf, int family);

View File

@ -319,7 +319,7 @@ static int ip_nht_rm_add(struct zebra_vrf *zvrf, const char *rmap, int rtype,
route_map_counter_increment(NHT_RM_MAP(zvrf, afi, rtype)); route_map_counter_increment(NHT_RM_MAP(zvrf, afi, rtype));
if (NHT_RM_MAP(zvrf, afi, rtype)) if (NHT_RM_MAP(zvrf, afi, rtype))
zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, NULL); zebra_evaluate_rnh(zvrf, AFI_IP, 1, NULL, SAFI_UNICAST);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -340,8 +340,7 @@ static int ip_nht_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype,
zvrf->vrf->vrf_id, rtype); zvrf->vrf->vrf_id, rtype);
NHT_RM_MAP(zvrf, afi, rtype) = NULL; NHT_RM_MAP(zvrf, afi, rtype) = NULL;
zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE, zebra_evaluate_rnh(zvrf, AFI_IP, 1, NULL, SAFI_UNICAST);
NULL);
} }
XFREE(MTYPE_ROUTE_MAP_NAME, NHT_RM_NAME(zvrf, afi, rtype)); XFREE(MTYPE_ROUTE_MAP_NAME, NHT_RM_NAME(zvrf, afi, rtype));
} }
@ -1589,8 +1588,8 @@ static void zebra_nht_rm_update(const char *rmap)
afi_ip = 1; afi_ip = 1;
zebra_evaluate_rnh( zebra_evaluate_rnh(
zvrf, AFI_IP, 1, zvrf, AFI_IP, 1, NULL,
RNH_NEXTHOP_TYPE, NULL); SAFI_UNICAST);
} }
} }
} }
@ -1620,8 +1619,8 @@ static void zebra_nht_rm_update(const char *rmap)
afi_ipv6 = 1; afi_ipv6 = 1;
zebra_evaluate_rnh( zebra_evaluate_rnh(
zvrf, AFI_IP, 1, zvrf, AFI_IP, 1, NULL,
RNH_NEXTHOP_TYPE, NULL); SAFI_UNICAST);
} }
} }
} }

View File

@ -116,6 +116,7 @@ static int zebra_sr_policy_notify_update_client(struct zebra_sr_policy *policy,
SET_FLAG(message, ZAPI_MESSAGE_SRTE); SET_FLAG(message, ZAPI_MESSAGE_SRTE);
stream_putl(s, message); stream_putl(s, message);
stream_putw(s, SAFI_UNICAST);
switch (policy->endpoint.ipa_type) { switch (policy->endpoint.ipa_type) {
case IPADDR_V4: case IPADDR_V4:
stream_putw(s, AF_INET); stream_putw(s, AF_INET);
@ -196,7 +197,7 @@ static void zebra_sr_policy_notify_update(struct zebra_sr_policy *policy)
exit(1); exit(1);
} }
rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), RNH_NEXTHOP_TYPE); rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), SAFI_UNICAST);
if (!rnh) if (!rnh)
return; return;
@ -205,8 +206,8 @@ static void zebra_sr_policy_notify_update(struct zebra_sr_policy *policy)
zebra_sr_policy_notify_update_client(policy, client); zebra_sr_policy_notify_update_client(policy, client);
else else
/* Fallback to the IGP shortest path. */ /* Fallback to the IGP shortest path. */
zebra_send_rnh_update(rnh, client, RNH_NEXTHOP_TYPE, zebra_send_rnh_update(rnh, client, zvrf_id(zvrf),
zvrf_id(zvrf), policy->color); policy->color);
} }
} }

View File

@ -158,7 +158,7 @@ static int zebra_vrf_enable(struct vrf *vrf)
table = route_table_init(); table = route_table_init();
table->cleanup = zebra_rnhtable_node_cleanup; table->cleanup = zebra_rnhtable_node_cleanup;
zvrf->import_check_table[afi] = table; zvrf->rnh_table_multicast[afi] = table;
} }
/* Kick off any VxLAN-EVPN processing. */ /* Kick off any VxLAN-EVPN processing. */
@ -203,8 +203,8 @@ static int zebra_vrf_disable(struct vrf *vrf)
for (afi = AFI_IP; afi <= AFI_IP6; afi++) { for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
route_table_finish(zvrf->rnh_table[afi]); route_table_finish(zvrf->rnh_table[afi]);
zvrf->rnh_table[afi] = NULL; zvrf->rnh_table[afi] = NULL;
route_table_finish(zvrf->import_check_table[afi]); route_table_finish(zvrf->rnh_table_multicast[afi]);
zvrf->import_check_table[afi] = NULL; zvrf->rnh_table_multicast[afi] = NULL;
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
rib_close_table(zvrf->table[afi][safi]); rib_close_table(zvrf->table[afi][safi]);
@ -305,8 +305,8 @@ static int zebra_vrf_delete(struct vrf *vrf)
if (zvrf->rnh_table[afi]) if (zvrf->rnh_table[afi])
route_table_finish(zvrf->rnh_table[afi]); route_table_finish(zvrf->rnh_table[afi]);
if (zvrf->import_check_table[afi]) if (zvrf->rnh_table_multicast[afi])
route_table_finish(zvrf->import_check_table[afi]); route_table_finish(zvrf->rnh_table[afi]);
} }
otable = otable_pop(&zvrf->other_tables); otable = otable_pop(&zvrf->other_tables);

View File

@ -78,9 +78,7 @@ struct zebra_vrf {
/* Recursive Nexthop table */ /* Recursive Nexthop table */
struct route_table *rnh_table[AFI_MAX]; struct route_table *rnh_table[AFI_MAX];
struct route_table *rnh_table_multicast[AFI_MAX];
/* Import check table (used mostly by BGP */
struct route_table *import_check_table[AFI_MAX];
struct otable_head other_tables; struct otable_head other_tables;
@ -183,8 +181,8 @@ struct zebra_vrf {
struct rtadv rtadv; struct rtadv rtadv;
#endif /* HAVE_RTADV */ #endif /* HAVE_RTADV */
int zebra_rnh_ip_default_route; bool zebra_rnh_ip_default_route;
int zebra_rnh_ipv6_default_route; bool zebra_rnh_ipv6_default_route;
}; };
#define PROTO_RM_NAME(zvrf, afi, rtype) zvrf->proto_rm[afi][rtype].name #define PROTO_RM_NAME(zvrf, afi, rtype) zvrf->proto_rm[afi][rtype].name
#define NHT_RM_NAME(zvrf, afi, rtype) zvrf->nht_rm[afi][rtype].name #define NHT_RM_NAME(zvrf, afi, rtype) zvrf->nht_rm[afi][rtype].name

View File

@ -1332,12 +1332,6 @@ DEFPY (show_ip_nht,
afi_t afi = ipv4 ? AFI_IP : AFI_IP6; afi_t afi = ipv4 ? AFI_IP : AFI_IP6;
vrf_id_t vrf_id = VRF_DEFAULT; vrf_id_t vrf_id = VRF_DEFAULT;
struct prefix prefix, *p = NULL; struct prefix prefix, *p = NULL;
enum rnh_type rtype;
if (strcmp(type, "nht") == 0)
rtype = RNH_NEXTHOP_TYPE;
else
rtype = RNH_IMPORT_CHECK_TYPE;
if (vrf_all) { if (vrf_all) {
struct vrf *vrf; struct vrf *vrf;
@ -1347,7 +1341,7 @@ DEFPY (show_ip_nht,
if ((zvrf = vrf->info) != NULL) { if ((zvrf = vrf->info) != NULL) {
vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf)); vty_out(vty, "\nVRF %s:\n", zvrf_name(zvrf));
zebra_print_rnh_table(zvrf_id(zvrf), afi, vty, zebra_print_rnh_table(zvrf_id(zvrf), afi, vty,
rtype, NULL); NULL);
} }
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -1361,7 +1355,7 @@ DEFPY (show_ip_nht,
return CMD_WARNING; return CMD_WARNING;
} }
zebra_print_rnh_table(vrf_id, afi, vty, rtype, p); zebra_print_rnh_table(vrf_id, afi, vty, p);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -1380,9 +1374,9 @@ DEFUN (ip_nht_default_route,
if (zvrf->zebra_rnh_ip_default_route) if (zvrf->zebra_rnh_ip_default_route)
return CMD_SUCCESS; return CMD_SUCCESS;
zvrf->zebra_rnh_ip_default_route = 1; zvrf->zebra_rnh_ip_default_route = true;
zebra_evaluate_rnh(zvrf, AFI_IP, 0, RNH_NEXTHOP_TYPE, NULL); zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -1719,8 +1713,8 @@ DEFUN (no_ip_nht_default_route,
if (!zvrf->zebra_rnh_ip_default_route) if (!zvrf->zebra_rnh_ip_default_route)
return CMD_SUCCESS; return CMD_SUCCESS;
zvrf->zebra_rnh_ip_default_route = 0; zvrf->zebra_rnh_ip_default_route = false;
zebra_evaluate_rnh(zvrf, AFI_IP, 0, RNH_NEXTHOP_TYPE, NULL); zebra_evaluate_rnh(zvrf, AFI_IP, 0, NULL, SAFI_UNICAST);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -1739,8 +1733,8 @@ DEFUN (ipv6_nht_default_route,
if (zvrf->zebra_rnh_ipv6_default_route) if (zvrf->zebra_rnh_ipv6_default_route)
return CMD_SUCCESS; return CMD_SUCCESS;
zvrf->zebra_rnh_ipv6_default_route = 1; zvrf->zebra_rnh_ipv6_default_route = true;
zebra_evaluate_rnh(zvrf, AFI_IP6, 0, RNH_NEXTHOP_TYPE, NULL); zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -1760,8 +1754,8 @@ DEFUN (no_ipv6_nht_default_route,
if (!zvrf->zebra_rnh_ipv6_default_route) if (!zvrf->zebra_rnh_ipv6_default_route)
return CMD_SUCCESS; return CMD_SUCCESS;
zvrf->zebra_rnh_ipv6_default_route = 0; zvrf->zebra_rnh_ipv6_default_route = false;
zebra_evaluate_rnh(zvrf, AFI_IP6, 0, RNH_NEXTHOP_TYPE, NULL); zebra_evaluate_rnh(zvrf, AFI_IP6, 0, NULL, SAFI_UNICAST);
return CMD_SUCCESS; return CMD_SUCCESS;
} }