mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 20:51:17 +00:00
zebra: When registering a nexthop, we do not always need to re-eval
The code prior to this change, was allowing clients to register for nexthop tracking. Then zebra would look up the rnh and send to that particular client any known data. Additionally zebra was blindly re-evaluating the rnh for every registration. This leads to interesting behavior in that all people registered for that nexthop will get callbacks even if nothing changes. Modify the code to know if we have evaluated the rnh or not and if so limit the re-evaluation to when absolutely necessary This is of particular importance to do because of nht callbacks for protocols cause those protocols to do not insignificant work and as more protocols are registering for nht callbacks we will cause more work than is necessary. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
9b8c3903bd
commit
1d30d1f4a8
@ -1022,6 +1022,7 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
|
||||
unsigned short l = 0;
|
||||
uint8_t flags = 0;
|
||||
uint16_t type = cmd2type[hdr->command];
|
||||
bool exist;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_NHT)
|
||||
zlog_debug(
|
||||
@ -1064,7 +1065,10 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
|
||||
p.family);
|
||||
return;
|
||||
}
|
||||
rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type);
|
||||
rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type, &exist);
|
||||
if (!rnh)
|
||||
return;
|
||||
|
||||
if (type == RNH_NEXTHOP_TYPE) {
|
||||
if (flags
|
||||
&& !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
|
||||
@ -1084,7 +1088,9 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
|
||||
|
||||
zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf));
|
||||
/* Anything not AF_INET/INET6 has been filtered out above */
|
||||
zebra_evaluate_rnh(zvrf_id(zvrf), p.family, 1, type, &p);
|
||||
if (!exist)
|
||||
zebra_evaluate_rnh(zvrf_id(zvrf), p.family, 1, type,
|
||||
&p);
|
||||
}
|
||||
|
||||
stream_failure:
|
||||
|
@ -103,7 +103,8 @@ char *rnh_str(struct rnh *rnh, char *buf, int size)
|
||||
return buf;
|
||||
}
|
||||
|
||||
struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type)
|
||||
struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type,
|
||||
bool *exists)
|
||||
{
|
||||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
@ -119,6 +120,7 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type)
|
||||
prefix2str(p, buf, sizeof(buf));
|
||||
zlog_warn("%u: Add RNH %s type %d - table not found", vrfid,
|
||||
buf, type);
|
||||
exists = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -136,7 +138,9 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type)
|
||||
route_lock_node(rn);
|
||||
rn->info = rnh;
|
||||
rnh->node = rn;
|
||||
}
|
||||
*exists = false;
|
||||
} else
|
||||
*exists = true;
|
||||
|
||||
route_unlock_node(rn);
|
||||
return (rn->info);
|
||||
@ -190,6 +194,14 @@ void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type)
|
||||
route_unlock_node(rn);
|
||||
}
|
||||
|
||||
/*
|
||||
* This code will send to the registering client
|
||||
* the looked up rnh.
|
||||
* For a rnh that was created, there is no data
|
||||
* so it will send an empty nexthop group
|
||||
* If rnh exists then we know it has been evaluated
|
||||
* and as such it will have a resolved rnh.
|
||||
*/
|
||||
void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client,
|
||||
rnh_type_t type, vrf_id_t vrf_id)
|
||||
{
|
||||
@ -201,8 +213,7 @@ void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client,
|
||||
}
|
||||
if (!listnode_lookup(rnh->client_list, client)) {
|
||||
listnode_add(rnh->client_list, client);
|
||||
send_client(rnh, client, type,
|
||||
vrf_id); // Pending: check if its needed
|
||||
send_client(rnh, client, type, vrf_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,9 +258,10 @@ void zebra_register_rnh_pseudowire(vrf_id_t vrf_id, struct zebra_pw *pw)
|
||||
{
|
||||
struct prefix nh;
|
||||
struct rnh *rnh;
|
||||
bool exists;
|
||||
|
||||
addr2hostprefix(pw->af, &pw->nexthop, &nh);
|
||||
rnh = zebra_add_rnh(&nh, vrf_id, RNH_NEXTHOP_TYPE);
|
||||
rnh = zebra_add_rnh(&nh, vrf_id, RNH_NEXTHOP_TYPE, &exists);
|
||||
if (rnh && !listnode_lookup(rnh->zebra_pseudowire_list, pw)) {
|
||||
listnode_add(rnh->zebra_pseudowire_list, pw);
|
||||
pw->rnh = rnh;
|
||||
|
@ -68,7 +68,7 @@ static inline int rnh_resolve_via_default(int family)
|
||||
}
|
||||
|
||||
extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid,
|
||||
rnh_type_t type);
|
||||
rnh_type_t type, bool *exists);
|
||||
extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid,
|
||||
rnh_type_t type);
|
||||
extern void zebra_free_rnh(struct rnh *rnh);
|
||||
|
Loading…
Reference in New Issue
Block a user