diff --git a/sharpd/sharp_nht.c b/sharpd/sharp_nht.c index 731d58e560..4c32dc279d 100644 --- a/sharpd/sharp_nht.c +++ b/sharpd/sharp_nht.c @@ -78,6 +78,8 @@ struct sharp_nhg { uint32_t id; char name[256]; + + bool installed; }; static uint32_t nhg_id; @@ -99,6 +101,22 @@ static int sharp_nhg_compare_func(const struct sharp_nhg *a, DECLARE_RBTREE_UNIQ(sharp_nhg_rb, struct sharp_nhg, mylistitem, sharp_nhg_compare_func); +static struct sharp_nhg *sharp_nhgroup_find_id(uint32_t id) +{ + struct sharp_nhg *lookup; + + /* Yea its just a for loop, I don't want add complexity + * to sharpd with another RB tree for just IDs + */ + + frr_each(sharp_nhg_rb, &nhg_head, lookup) { + if (lookup->id == id) + return lookup; + } + + return NULL; +} + static void sharp_nhgroup_add_cb(const char *name) { struct sharp_nhg *snhg; @@ -166,6 +184,32 @@ uint32_t sharp_nhgroup_get_id(const char *name) return snhg->id; } +void sharp_nhgroup_id_set_installed(uint32_t id, bool installed) +{ + struct sharp_nhg *snhg; + + snhg = sharp_nhgroup_find_id(id); + if (!snhg) { + zlog_debug("%s: nhg %u not found", __func__, id); + return; + } + + snhg->installed = installed; +} + +bool sharp_nhgroup_id_is_installed(uint32_t id) +{ + struct sharp_nhg *snhg; + + snhg = sharp_nhgroup_find_id(id); + if (!snhg) { + zlog_debug("%s: nhg %u not found", __func__, id); + return false; + } + + return snhg->installed; +} + void sharp_nhgroup_init(void) { sharp_nhg_rb_init(&nhg_head); diff --git a/sharpd/sharp_nht.h b/sharpd/sharp_nht.h index 27c0104583..da33502878 100644 --- a/sharpd/sharp_nht.h +++ b/sharpd/sharp_nht.h @@ -37,5 +37,8 @@ extern struct sharp_nh_tracker *sharp_nh_tracker_get(struct prefix *p); extern void sharp_nh_tracker_dump(struct vty *vty); extern uint32_t sharp_nhgroup_get_id(const char *name); +extern void sharp_nhgroup_id_set_installed(uint32_t id, bool installed); +extern bool sharp_nhgroup_id_is_installed(uint32_t id); + extern void sharp_nhgroup_init(void); #endif diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index 8e357f96c9..6be1176db5 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -403,7 +403,8 @@ void route_add(const struct prefix *p, vrf_id_t vrf_id, SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - if (nhgid) { + /* Only send via ID if nhgroup has been successfully installed */ + if (nhgid && sharp_nhgroup_id_is_installed(nhgid)) { SET_FLAG(api.message, ZAPI_MESSAGE_NHG); api.nhgid = nhgid; } else { @@ -700,6 +701,33 @@ void sharp_zebra_send_arp(const struct interface *ifp, const struct prefix *p) zclient_send_neigh_discovery_req(zclient, ifp, p); } +static int nhg_notify_owner(ZAPI_CALLBACK_ARGS) +{ + enum zapi_nhg_notify_owner note; + uint32_t id; + + if (!zapi_nhg_notify_decode(zclient->ibuf, &id, ¬e)) + return -1; + + switch (note) { + case ZAPI_NHG_INSTALLED: + sharp_nhgroup_id_set_installed(id, true); + zlog_debug("Installed nhg %u", id); + break; + case ZAPI_NHG_FAIL_INSTALL: + zlog_debug("Failed install of nhg %u", id); + break; + case ZAPI_NHG_REMOVED: + zlog_debug("Removed nhg %u", id); + break; + case ZAPI_NHG_REMOVE_FAIL: + zlog_debug("Failed removal of nhg %u", id); + break; + } + + return 0; +} + void sharp_zebra_init(void) { struct zclient_options opt = {.receive_notify = true}; @@ -716,6 +744,7 @@ void sharp_zebra_init(void) 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->redistribute_route_add = sharp_redistribute_route; zclient->redistribute_route_del = sharp_redistribute_route;