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)
{
struct bgp_nexthop_cache_head *tree = NULL;
struct bgp_nexthop_cache *bnc;
struct bgp_nexthop_cache *bnc_nhc, *bnc_import;
struct bgp *bgp;
struct zapi_route nhr;
afi_t afi;
@ -685,22 +685,38 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
}
afi = family2afi(nhr.prefix.family);
if (command == ZEBRA_NEXTHOP_UPDATE)
tree = &bgp->nexthop_cache_table[afi];
else if (command == ZEBRA_IMPORT_CHECK_UPDATE)
tree = &bgp->import_check_table[afi];
tree = &bgp->nexthop_cache_table[afi];
bnc = bnc_find(tree, &nhr.prefix, nhr.srte_color);
if (!bnc) {
bnc_nhc = bnc_find(tree, &nhr.prefix, nhr.srte_color);
if (!bnc_nhc) {
if (BGP_DEBUG(nht, NHT))
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);
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
* 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
* a more efficient and elegant way.
*/
if (nhr.srte_color == 0) {
if (nhr.srte_color == 0 && bnc_nhc) {
struct bgp_nexthop_cache *bnc_iter;
frr_each (bgp_nexthop_cache, &bgp->nexthop_cache_table[afi],
bnc_iter) {
if (!prefix_same(&bnc->prefix, &bnc_iter->prefix)
if (!prefix_same(&bnc_import->prefix, &bnc_iter->prefix)
|| bnc_iter->srte_color == 0
|| CHECK_FLAG(bnc_iter->flags, BGP_NEXTHOP_VALID))
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)
{
bool exact_match = false;
bool resolve_via_default = false;
int ret;
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",
__func__);
}
if ((command == ZEBRA_NEXTHOP_REGISTER
|| command == ZEBRA_IMPORT_ROUTE_REGISTER)
&& (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)
|| CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH)))
exact_match = true;
if (command == ZEBRA_NEXTHOP_REGISTER) {
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
exact_match = true;
if (CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
resolve_via_default = true;
}
if (BGP_DEBUG(zebra, ZEBRA))
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);
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 */
if (ret == ZCLIENT_SEND_FAILURE)
flog_warn(EC_BGP_ZEBRA_SEND,
"sendmsg_nexthop: zclient_send_message() failed");
if ((command == ZEBRA_NEXTHOP_REGISTER)
|| (command == ZEBRA_IMPORT_ROUTE_REGISTER))
if (command == ZEBRA_NEXTHOP_REGISTER)
SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
else if ((command == ZEBRA_NEXTHOP_UNREGISTER)
|| (command == ZEBRA_IMPORT_ROUTE_UNREGISTER))
else if (command == ZEBRA_NEXTHOP_UNREGISTER)
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
return;
}
@ -910,10 +926,7 @@ static void register_zebra_rnh(struct bgp_nexthop_cache *bnc,
return;
}
if (is_bgp_import_route)
sendmsg_zebra_rnh(bnc, ZEBRA_IMPORT_ROUTE_REGISTER);
else
sendmsg_zebra_rnh(bnc, ZEBRA_NEXTHOP_REGISTER);
sendmsg_zebra_rnh(bnc, ZEBRA_NEXTHOP_REGISTER);
}
/**
@ -935,10 +948,7 @@ static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc,
return;
}
if (is_bgp_import_route)
sendmsg_zebra_rnh(bnc, ZEBRA_IMPORT_ROUTE_UNREGISTER);
else
sendmsg_zebra_rnh(bnc, ZEBRA_NEXTHOP_UNREGISTER);
sendmsg_zebra_rnh(bnc, ZEBRA_NEXTHOP_UNREGISTER);
}
/**

View File

@ -112,12 +112,6 @@ static int bgp_read_nexthop_update(ZAPI_CALLBACK_ARGS)
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
* would in turn cause BGP to initiate or turn off IPv6 RAs on this
* 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_del = zebra_read_route;
zclient->nexthop_update = bgp_read_nexthop_update;
zclient->import_check_update = bgp_read_import_check_update;
zclient->fec_update = bgp_read_fec_update;
zclient->local_es_add = bgp_zebra_process_local_es_add;
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_DELETE),
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_DEREGISTER),
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,
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;
s = zclient->obuf;
stream_reset(s);
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_putc(s, p->prefixlen);
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));
STREAM_GETL(s, nhr->message);
STREAM_GETW(s, nhr->safi);
STREAM_GETW(s, nhr->prefix.family);
STREAM_GETC(s, nhr->prefix.prefixlen);
switch (nhr->prefix.family) {
@ -4016,13 +4019,6 @@ static int zclient_read(struct thread *thread)
(*zclient->nexthop_update)(command, zclient, length,
vrf_id);
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:
if (zclient->bfd_dest_replay)
(*zclient->bfd_dest_replay)(command, zclient, length,

View File

@ -126,9 +126,6 @@ typedef enum {
ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
ZEBRA_INTERFACE_NBR_ADDRESS_DELETE,
ZEBRA_INTERFACE_BFD_DEST_UPDATE,
ZEBRA_IMPORT_ROUTE_REGISTER,
ZEBRA_IMPORT_ROUTE_UNREGISTER,
ZEBRA_IMPORT_CHECK_UPDATE,
ZEBRA_BFD_DEST_REGISTER,
ZEBRA_BFD_DEST_DEREGISTER,
ZEBRA_BFD_DEST_UPDATE,
@ -362,7 +359,6 @@ struct zclient {
int (*interface_nbr_address_delete)(ZAPI_CALLBACK_ARGS);
int (*interface_vrf_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 (*redistribute_route_add)(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 *);
extern enum zclient_send_status
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,
uint32_t api_flags, uint32_t api_message);
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;
if (unreg)
command = ZEBRA_IMPORT_ROUTE_UNREGISTER;
command = ZEBRA_NEXTHOP_UNREGISTER;
else
command = ZEBRA_IMPORT_ROUTE_REGISTER;
command = ZEBRA_NEXTHOP_REGISTER;
if (IS_OSPF6_DEBUG_ZEBRA(SEND))
zlog_debug("%s: sending cmd %s for %pFX (vrf %u)", __func__,
zserv_command_string(command), &prefix,
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)
flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_send_rnh() failed",
__func__);
@ -720,7 +721,7 @@ void ospf6_zebra_init(struct thread_master *master)
ospf6_zebra_if_address_update_delete;
zclient->redistribute_route_add = 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_element(VIEW_NODE, &show_ospf6_zebra_cmd);

View File

@ -478,7 +478,7 @@ void pbr_send_rnh(struct nexthop *nhop, bool reg)
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) {
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;
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)
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;
if (!import) {
command = ZEBRA_NEXTHOP_REGISTER;
command = ZEBRA_NEXTHOP_REGISTER;
if (!watch)
command = ZEBRA_NEXTHOP_UNREGISTER;
} else {
command = ZEBRA_IMPORT_ROUTE_REGISTER;
if (!watch)
command = ZEBRA_NEXTHOP_UNREGISTER;
if (!watch)
command = ZEBRA_IMPORT_ROUTE_UNREGISTER;
}
if (zclient_send_rnh(zclient, command, p, connected, vrf_id)
if (zclient_send_rnh(zclient, command, p, connected, false, vrf_id)
== ZCLIENT_SEND_FAILURE)
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->route_notify_owner = route_notify_owner;
zclient->nexthop_update = sharp_nexthop_update;
zclient->import_check_update = sharp_nexthop_update;
zclient->nhg_notify_owner = nhg_notify_owner;
zclient->zebra_buffer_write_ready = sharp_zclient_buffer_ready;
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);
}
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)
zlog_warn("%s: Failure to send nexthop to zebra", __func__);
}

View File

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

View File

@ -1164,13 +1164,6 @@ int zsend_zebra_srv6_locator_delete(struct zserv *client,
/* 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 */
static void zread_rnh_register(ZAPI_HANDLER_ARGS)
{
@ -1178,17 +1171,17 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
struct stream *s;
struct prefix p;
unsigned short l = 0;
uint8_t flags = 0;
uint16_t type = cmd2type[hdr->command];
uint8_t connected = 0;
uint8_t resolve_via_default;
bool exist;
bool flag_changed = false;
uint8_t orig_flags;
safi_t safi;
if (IS_ZEBRA_DEBUG_NHT)
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,
(type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route",
zvrf->vrf->vrf_id);
s = msg;
@ -1197,10 +1190,12 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
client->nh_reg_time = monotime(NULL);
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_GETC(s, p.prefixlen);
l += 4;
l += 7;
if (p.family == AF_INET) {
client->v4_nh_watch_add_cnt++;
if (p.prefixlen > IPV4_MAX_BITLEN) {
@ -1228,37 +1223,29 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
p.family);
return;
}
rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type, &exist);
rnh = zebra_add_rnh(&p, zvrf_id(zvrf), &exist);
if (!rnh)
return;
orig_flags = rnh->flags;
if (type == RNH_NEXTHOP_TYPE) {
if (flags
&& !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
else if (!flags
&& CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
} else if (type == RNH_IMPORT_CHECK_TYPE) {
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 (connected && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
else if (!connected
&& CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
if (resolve_via_default)
SET_FLAG(rnh->flags, ZEBRA_NHT_RESOLVE_VIA_DEFAULT);
if (orig_flags != rnh->flags)
flag_changed = true;
/* Anything not AF_INET/INET6 has been filtered out above */
if (!exist || flag_changed)
zebra_evaluate_rnh(zvrf, family2afi(p.family), 1, type,
&p);
zebra_evaluate_rnh(zvrf, family2afi(p.family), 1, &p,
safi);
zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf));
zebra_add_rnh_client(rnh, client, zvrf_id(zvrf));
}
stream_failure:
@ -1272,7 +1259,7 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
struct stream *s;
struct prefix p;
unsigned short l = 0;
uint16_t type = cmd2type[hdr->command];
safi_t safi;
if (IS_ZEBRA_DEBUG_NHT)
zlog_debug(
@ -1283,15 +1270,19 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
s = msg;
while (l < hdr->length) {
uint8_t flags;
uint8_t ignore;
STREAM_GETC(s, flags);
if (flags != 0)
STREAM_GETC(s, ignore);
if (ignore != 0)
goto stream_failure;
STREAM_GETC(s, ignore);
if (ignore != 0)
goto stream_failure;
STREAM_GETW(s, safi);
STREAM_GETW(s, p.family);
STREAM_GETC(s, p.prefixlen);
l += 4;
l += 7;
if (p.family == AF_INET) {
client->v4_nh_watch_rem_cnt++;
if (p.prefixlen > IPV4_MAX_BITLEN) {
@ -1319,10 +1310,10 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
p.family);
return;
}
rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), type);
rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), safi);
if (rnh) {
client->nh_dereg_time = monotime(NULL);
zebra_remove_rnh_client(rnh, client, type);
zebra_remove_rnh_client(rnh, client);
}
}
stream_failure:
@ -3683,8 +3674,6 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_HELLO] = zread_hello,
[ZEBRA_NEXTHOP_REGISTER] = zread_rnh_register,
[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_REGISTER] = zebra_ptm_bfd_dst_register,
[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)
zlog_debug(
"%s(%u):%pRN has Nexthop(%pFX) Type: %s depending on it, evaluating %u:%u",
zvrf_name(zvrf), zvrf_id(zvrf),
rn, p, rnh_type2str(rnh->type), seq,
rnh->seqno);
"%s(%u):%pRN has Nexthop(%pFX) depending on it, evaluating %u:%u",
zvrf_name(zvrf), zvrf_id(zvrf), rn, p,
seq, rnh->seqno);
/*
* 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;
zebra_evaluate_rnh(zvrf, family2afi(p->family), 0,
rnh->type, p);
zebra_evaluate_rnh(zvrf, family2afi(p->family), 0, p,
rnh->safi);
}
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,
enum rnh_type type)
safi_t safi)
{
struct zebra_vrf *zvrf;
struct route_table *t = NULL;
zvrf = zebra_vrf_lookup_by_id(vrfid);
if (zvrf)
switch (type) {
case RNH_NEXTHOP_TYPE:
if (zvrf) {
if (safi == SAFI_UNICAST)
t = zvrf->rnh_table[afi];
break;
case RNH_IMPORT_CHECK_TYPE:
t = zvrf->import_check_table[afi];
break;
}
else if (safi == SAFI_MULTICAST)
t = zvrf->rnh_table_multicast[afi];
}
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)
{
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;
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)
{
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;
rib_dest_t *dest;
@ -135,27 +132,28 @@ static void zebra_rnh_store_in_routing_table(struct rnh *rnh)
route_unlock_node(rn);
}
struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, enum rnh_type type,
bool *exists)
struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, bool *exists)
{
struct route_table *table;
struct route_node *rn;
struct rnh *rnh = NULL;
afi_t afi = family2afi(p->family);
safi_t safi = SAFI_UNICAST;
if (IS_ZEBRA_DEBUG_NHT) {
struct vrf *vrf = vrf_lookup_by_id(vrfid);
zlog_debug("%s(%u): Add RNH %pFX type %s", VRF_LOGNAME(vrf),
vrfid, p, rnh_type2str(type));
zlog_debug("%s(%u): Add RNH %pFX for safi: %u",
VRF_LOGNAME(vrf), vrfid, p, safi);
}
table = get_rnh_table(vrfid, afi, type);
table = get_rnh_table(vrfid, afi, safi);
if (!table) {
struct vrf *vrf = vrf_lookup_by_id(vrfid);
flog_warn(EC_ZEBRA_RNH_NO_TABLE,
"%s(%u): Add RNH %pFX type %s - table not found",
VRF_LOGNAME(vrf), vrfid, p, rnh_type2str(type));
"%s(%u): Add RNH %pFX - table not found",
VRF_LOGNAME(vrf), vrfid, p);
*exists = false;
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->client_list = list_new();
rnh->vrf_id = vrfid;
rnh->type = type;
rnh->seqno = 0;
rnh->afi = afi;
rnh->safi = safi;
rnh->zebra_pseudowire_list = list_new();
route_lock_node(rn);
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);
}
struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid,
enum rnh_type type)
struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, safi_t safi)
{
struct route_table *table;
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)
return NULL;
@ -228,7 +225,7 @@ void zebra_free_rnh(struct rnh *rnh)
list_delete(&rnh->zebra_pseudowire_list);
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) {
struct route_node *rern;
@ -247,7 +244,7 @@ void zebra_free_rnh(struct 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;
@ -261,8 +258,8 @@ static void zebra_delete_rnh(struct rnh *rnh, enum rnh_type type)
if (IS_ZEBRA_DEBUG_NHT) {
struct vrf *vrf = vrf_lookup_by_id(rnh->vrf_id);
zlog_debug("%s(%u): Del RNH %pRN type %s", VRF_LOGNAME(vrf),
rnh->vrf_id, rnh->node, rnh_type2str(type));
zlog_debug("%s(%u): Del RNH %pRN", VRF_LOGNAME(vrf),
rnh->vrf_id, rnh->node);
}
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.
*/
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) {
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,
zebra_route_string(client->proto), rnh->node,
rnh_type2str(type));
zebra_route_string(client->proto), rnh->node);
}
if (!listnode_lookup(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,
* 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,
enum rnh_type type)
void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client)
{
if (IS_ZEBRA_DEBUG_NHT) {
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),
vrf->vrf_id, rnh->node, rnh_type2str(type));
vrf->vrf_id, rnh->node);
}
listnode_delete(rnh->client_list, client);
zebra_delete_rnh(rnh, type);
zebra_delete_rnh(rnh);
}
/* 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;
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)
return;
if (!listnode_lookup(rnh->zebra_pseudowire_list, pw)) {
listnode_add(rnh->zebra_pseudowire_list, pw);
pw->rnh = rnh;
zebra_evaluate_rnh(zvrf, family2afi(pw->af), 1,
RNH_NEXTHOP_TYPE, &nh);
zebra_evaluate_rnh(zvrf, family2afi(pw->af), 1, &nh,
SAFI_UNICAST);
} else
*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);
pw->rnh = NULL;
zebra_delete_rnh(rnh, RNH_NEXTHOP_TYPE);
zebra_delete_rnh(rnh);
}
/* 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);
}
/*
* 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.
*/
@ -580,8 +470,7 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi,
zebra_route_string(client->proto));
}
zebra_send_rnh_update(rnh, client, RNH_NEXTHOP_TYPE,
zvrf->vrf->vrf_id, 0);
zebra_send_rnh_update(rnh, client, zvrf->vrf->vrf_id, 0);
}
if (re)
@ -676,7 +565,7 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
*prn = NULL;
route_table = zvrf->table[afi][SAFI_UNICAST];
route_table = zvrf->table[afi][rnh->safi];
if (!route_table)
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
*/
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)
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;
}
@ -823,26 +716,22 @@ static void zebra_rnh_eval_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
/* Evaluate one tracked entry */
static void zebra_rnh_evaluate_entry(struct zebra_vrf *zvrf, afi_t afi,
int force, enum rnh_type type,
struct route_node *nrn)
int force, struct route_node *nrn)
{
struct rnh *rnh;
struct route_entry *re;
struct route_node *prn;
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,
rnh_type2str(type), force ? "(force)" : "");
force ? "(force)" : "");
}
rnh = nrn->info;
/* Identify route entry (RE) resolving this tracked entry. */
if (type == RNH_IMPORT_CHECK_TYPE)
re = zebra_rnh_resolve_import_entry(zvrf, afi, nrn, rnh, &prn);
else
re = zebra_rnh_resolve_nexthop_entry(zvrf, afi, nrn, rnh, &prn);
re = zebra_rnh_resolve_nexthop_entry(zvrf, afi, nrn, rnh, &prn);
/* If the entry cannot be resolved and that is also the existing state,
* there is nothing further to do.
@ -851,12 +740,7 @@ static void zebra_rnh_evaluate_entry(struct zebra_vrf *zvrf, afi_t afi,
return;
/* Process based on type of entry. */
if (type == RNH_IMPORT_CHECK_TYPE)
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);
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.
*/
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 route_entry *re;
@ -878,12 +762,7 @@ static void zebra_rnh_clear_nhc_flag(struct zebra_vrf *zvrf, afi_t afi,
rnh = nrn->info;
/* Identify route entry (RIB) resolving this tracked entry. */
if (type == RNH_IMPORT_CHECK_TYPE)
re = zebra_rnh_resolve_import_entry(zvrf, afi, nrn, rnh,
&prn);
else
re = zebra_rnh_resolve_nexthop_entry(zvrf, afi, nrn, rnh,
&prn);
re = zebra_rnh_resolve_nexthop_entry(zvrf, afi, nrn, rnh, &prn);
if (re)
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.
*/
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_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
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. */
nrn = route_node_lookup(rnh_table, p);
if (nrn && nrn->info)
zebra_rnh_evaluate_entry(zvrf, afi, force, type, nrn);
zebra_rnh_evaluate_entry(zvrf, afi, force, nrn);
if (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);
while (nrn) {
if (nrn->info)
zebra_rnh_evaluate_entry(zvrf, afi, force, type,
nrn);
zebra_rnh_evaluate_entry(zvrf, afi, force, nrn);
nrn = route_next(nrn); /* this will also unlock nrn */
}
nrn = route_top(rnh_table);
while (nrn) {
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 */
}
}
}
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_node *rn;
table = get_rnh_table(vrfid, afi, type);
table = get_rnh_table(vrfid, afi, SAFI_UNICAST);
if (!table) {
if (IS_ZEBRA_DEBUG_NHT)
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,
enum rnh_type type, vrf_id_t vrf_id,
uint32_t srte_color)
vrf_id_t vrf_id, uint32_t srte_color)
{
struct stream *s = NULL;
struct route_entry *re;
@ -1282,8 +1159,6 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client,
struct route_node *rn;
int ret;
uint32_t message = 0;
int cmd = (type == RNH_IMPORT_CHECK_TYPE) ? ZEBRA_IMPORT_CHECK_UPDATE
: ZEBRA_NEXTHOP_UPDATE;
rn = rnh->node;
re = rnh->state;
@ -1291,13 +1166,14 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client,
/* Get output stream. */
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. */
if (srte_color)
SET_FLAG(message, ZAPI_MESSAGE_SRTE);
stream_putl(s, message);
stream_putw(s, rnh->safi);
stream_putw(s, rn->p.family);
switch (rn->p.family) {
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,
struct zserv *client, enum rnh_type type)
struct zserv *client)
{
struct route_table *ntable;
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) {
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
zlog_debug(
"%s(%u): Client %s RNH cleanup for family %s type %s",
VRF_LOGNAME(vrf), vrf_id,
zebra_route_string(client->proto), afi2str(afi),
rnh_type2str(type));
zlog_debug("%s(%u): Client %s RNH cleanup for family %s",
VRF_LOGNAME(vrf), vrf_id,
zebra_route_string(client->proto), afi2str(afi));
}
ntable = get_rnh_table(vrf_id, afi, type);
ntable = get_rnh_table(vrf_id, afi, SAFI_UNICAST);
if (!ntable) {
zlog_debug("cleanup_rnh_client: rnh table not found");
return -1;
@ -1471,7 +1345,7 @@ static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi,
continue;
rnh = nrn->info;
zebra_remove_rnh_client(rnh, client, type);
zebra_remove_rnh_client(rnh, client);
}
return 1;
}
@ -1485,14 +1359,9 @@ static int zebra_client_cleanup_rnh(struct zserv *client)
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
zvrf = vrf->info;
if (zvrf) {
zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP, client,
RNH_NEXTHOP_TYPE);
zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP6, 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);
zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP, client);
zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP6,
client);
}
}

View File

@ -31,36 +31,22 @@ extern "C" {
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,
enum rnh_type type, bool *exists);
bool *exists);
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_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,
enum rnh_type type, vrf_id_t vrf_id,
uint32_t srte_color);
vrf_id_t vrf_id, uint32_t srte_color);
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_remove_rnh_client(struct rnh *rnh, struct zserv *client,
enum rnh_type type);
extern void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client);
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,
enum rnh_type type, struct prefix *p);
struct prefix *p);
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));
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;
}
@ -340,8 +340,7 @@ static int ip_nht_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype,
zvrf->vrf->vrf_id, rtype);
NHT_RM_MAP(zvrf, afi, rtype) = NULL;
zebra_evaluate_rnh(zvrf, AFI_IP, 1, RNH_NEXTHOP_TYPE,
NULL);
zebra_evaluate_rnh(zvrf, AFI_IP, 1, NULL, SAFI_UNICAST);
}
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;
zebra_evaluate_rnh(
zvrf, AFI_IP, 1,
RNH_NEXTHOP_TYPE, NULL);
zvrf, AFI_IP, 1, NULL,
SAFI_UNICAST);
}
}
}
@ -1620,8 +1619,8 @@ static void zebra_nht_rm_update(const char *rmap)
afi_ipv6 = 1;
zebra_evaluate_rnh(
zvrf, AFI_IP, 1,
RNH_NEXTHOP_TYPE, NULL);
zvrf, AFI_IP, 1, 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);
stream_putl(s, message);
stream_putw(s, SAFI_UNICAST);
switch (policy->endpoint.ipa_type) {
case IPADDR_V4:
stream_putw(s, AF_INET);
@ -196,7 +197,7 @@ static void zebra_sr_policy_notify_update(struct zebra_sr_policy *policy)
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)
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);
else
/* Fallback to the IGP shortest path. */
zebra_send_rnh_update(rnh, client, RNH_NEXTHOP_TYPE,
zvrf_id(zvrf), policy->color);
zebra_send_rnh_update(rnh, client, zvrf_id(zvrf),
policy->color);
}
}

View File

@ -158,7 +158,7 @@ static int zebra_vrf_enable(struct vrf *vrf)
table = route_table_init();
table->cleanup = zebra_rnhtable_node_cleanup;
zvrf->import_check_table[afi] = table;
zvrf->rnh_table_multicast[afi] = table;
}
/* 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++) {
route_table_finish(zvrf->rnh_table[afi]);
zvrf->rnh_table[afi] = NULL;
route_table_finish(zvrf->import_check_table[afi]);
zvrf->import_check_table[afi] = NULL;
route_table_finish(zvrf->rnh_table_multicast[afi]);
zvrf->rnh_table_multicast[afi] = NULL;
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; 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])
route_table_finish(zvrf->rnh_table[afi]);
if (zvrf->import_check_table[afi])
route_table_finish(zvrf->import_check_table[afi]);
if (zvrf->rnh_table_multicast[afi])
route_table_finish(zvrf->rnh_table[afi]);
}
otable = otable_pop(&zvrf->other_tables);

View File

@ -78,9 +78,7 @@ struct zebra_vrf {
/* Recursive Nexthop table */
struct route_table *rnh_table[AFI_MAX];
/* Import check table (used mostly by BGP */
struct route_table *import_check_table[AFI_MAX];
struct route_table *rnh_table_multicast[AFI_MAX];
struct otable_head other_tables;
@ -183,8 +181,8 @@ struct zebra_vrf {
struct rtadv rtadv;
#endif /* HAVE_RTADV */
int zebra_rnh_ip_default_route;
int zebra_rnh_ipv6_default_route;
bool zebra_rnh_ip_default_route;
bool zebra_rnh_ipv6_default_route;
};
#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

View File

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