summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sharpd/sharp_nht.c44
-rw-r--r--sharpd/sharp_nht.h3
-rw-r--r--sharpd/sharp_zebra.c31
3 files changed, 77 insertions, 1 deletions
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, &note))
+ 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;