]> git.proxmox.com Git - mirror_frr.git/commitdiff
sharpd: add abilty to send a nhg to zebra
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 29 Apr 2020 16:32:53 +0000 (12:32 -0400)
committerStephen Worley <sworley@cumulusnetworks.com>
Mon, 28 Sep 2020 16:40:59 +0000 (12:40 -0400)
Modify the sharpd program to have the ability to pass down
a NHG and then operate on it for route installation.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
sharpd/sharp_globals.h
sharpd/sharp_main.c
sharpd/sharp_nht.c
sharpd/sharp_nht.h
sharpd/sharp_vty.c
sharpd/sharp_zebra.c
sharpd/sharp_zebra.h

index 8eba57f4ddeca820194447628beaafc562711c99..0bd47454a9250c254d490db553c27ee9edbf983c 100644 (file)
@@ -31,6 +31,7 @@ struct sharp_routes {
        /* The nexthop info we are using for installation */
        struct nexthop nhop;
        struct nexthop backup_nhop;
+       uint32_t nhgid;
        struct nexthop_group nhop_group;
        struct nexthop_group backup_nhop_group;
 
index ccf34b10dd1b46874478664039da350f2b75bea1..4cd92c7f3d72688f9f87d169a8587e71446cab3c 100644 (file)
@@ -47,6 +47,7 @@
 #include "sharp_zebra.h"
 #include "sharp_vty.h"
 #include "sharp_globals.h"
+#include "sharp_nht.h"
 
 DEFINE_MGROUP(SHARPD, "sharpd")
 
@@ -164,7 +165,7 @@ int main(int argc, char **argv, char **envp)
 
        sharp_global_init();
 
-       nexthop_group_init(NULL, NULL, NULL, NULL);
+       sharp_nhgroup_init();
        vrf_init(NULL, NULL, NULL, NULL, NULL);
 
        sharp_zebra_init();
index 174f1868639bd1c3be5957190e023b284ed8861c..414879290014be672cec07fe4a160f788fb4a108 100644 (file)
 #include "nexthop.h"
 #include "nexthop_group.h"
 #include "vty.h"
+#include "typesafe.h"
+#include "zclient.h"
 
 #include "sharp_nht.h"
 #include "sharp_globals.h"
+#include "sharp_zebra.h"
 
 DEFINE_MTYPE_STATIC(SHARPD, NH_TRACKER, "Nexthop Tracker")
+DEFINE_MTYPE_STATIC(SHARPD, NHG, "Nexthop Group")
 
 struct sharp_nh_tracker *sharp_nh_tracker_get(struct prefix *p)
 {
@@ -65,3 +69,109 @@ void sharp_nh_tracker_dump(struct vty *vty)
                        nht->updates);
        }
 }
+
+PREDECL_RBTREE_UNIQ(sharp_nhg_rb);
+
+struct sharp_nhg {
+       struct sharp_nhg_rb_item mylistitem;
+
+       uint32_t id;
+
+       char name[256];
+};
+
+static uint32_t nhg_id;
+
+static uint32_t sharp_get_next_nhid(void)
+{
+       zlog_debug("Id assigned: %u", nhg_id + 1);
+       return nhg_id++;
+}
+
+struct sharp_nhg_rb_head nhg_head;
+
+static int sharp_nhg_compare_func(const struct sharp_nhg *a,
+                                 const struct sharp_nhg *b)
+{
+       return strncmp(a->name, b->name, strlen(a->name));
+}
+
+DECLARE_RBTREE_UNIQ(sharp_nhg_rb, struct sharp_nhg, mylistitem,
+                   sharp_nhg_compare_func);
+
+static void sharp_nhgroup_add_cb(const char *name)
+{
+       struct sharp_nhg *snhg;
+
+       snhg = XCALLOC(MTYPE_NHG, sizeof(*snhg));
+       snhg->id = sharp_get_next_nhid();
+       strncpy(snhg->name, name, sizeof(snhg->name));
+
+       sharp_nhg_rb_add(&nhg_head, snhg);
+       return;
+}
+
+static void sharp_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd *nhgc,
+                                        const struct nexthop *nhop)
+{
+       struct sharp_nhg lookup;
+       struct sharp_nhg *snhg;
+
+       strncpy(lookup.name, nhgc->name, sizeof(lookup.name));
+       snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
+
+       nhg_add(snhg->id, &nhgc->nhg);
+       return;
+}
+
+static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc,
+                                        const struct nexthop *nhop)
+{
+       struct sharp_nhg lookup;
+       struct sharp_nhg *snhg;
+
+       strncpy(lookup.name, nhgc->name, sizeof(lookup.name));
+       snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
+
+       nhg_add(snhg->id, &nhgc->nhg);
+       return;
+}
+
+static void sharp_nhgroup_delete_cb(const char *name)
+{
+       struct sharp_nhg lookup;
+       struct sharp_nhg *snhg;
+
+       strncpy(lookup.name, name, sizeof(lookup.name));
+       snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
+       if (!snhg)
+               return;
+
+       nhg_del(snhg->id);
+       sharp_nhg_rb_del(&nhg_head, snhg);
+       XFREE(MTYPE_NHG, snhg);
+       return;
+}
+
+uint32_t sharp_nhgroup_get_id(const char *name)
+{
+       struct sharp_nhg lookup;
+       struct sharp_nhg *snhg;
+
+       strncpy(lookup.name, name, sizeof(lookup.name));
+       snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
+       if (!snhg)
+               return 0;
+
+       return snhg->id;
+}
+
+void sharp_nhgroup_init(void)
+{
+       sharp_nhg_rb_init(&nhg_head);
+       nhg_id = zclient_get_nhg_start(ZEBRA_ROUTE_SHARP);
+
+       nexthop_group_init(sharp_nhgroup_add_cb, sharp_nhgroup_add_nexthop_cb,
+                          sharp_nhgroup_del_nexthop_cb,
+                          sharp_nhgroup_delete_cb);
+}
index 0b00774a81b19371f7642b034f188a656b68901b..27c010458354bfe227cee9272db7363e8136abab 100644 (file)
@@ -35,4 +35,7 @@ struct sharp_nh_tracker {
 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_init(void);
 #endif
index d390ea81925352b507906d3d9c6cda0bb322cc20..2903588c1355b2a5670d604772f880a76bcb4ee3 100644 (file)
@@ -192,6 +192,7 @@ DEFPY (install_routes,
        struct vrf *vrf;
        struct prefix prefix;
        uint32_t rts;
+       uint32_t nhgid = 0;
 
        sg.r.total_routes = routes;
        sg.r.installed_routes = 0;
@@ -244,6 +245,8 @@ DEFPY (install_routes,
                        return CMD_WARNING;
                }
 
+               nhgid = sharp_nhgroup_get_id(nexthop_group);
+               sg.r.nhgid = nhgid;
                sg.r.nhop_group.nexthop = nhgc->nhg.nexthop;
 
                /* Use group's backup nexthop info if present */
@@ -297,8 +300,8 @@ DEFPY (install_routes,
        sg.r.vrf_id = vrf->vrf_id;
        rts = routes;
        sharp_install_routes_helper(&prefix, sg.r.vrf_id, sg.r.inst,
-                                   &sg.r.nhop_group, &sg.r.backup_nhop_group,
-                                   rts);
+                                   nhgid, &sg.r.nhop_group,
+                                   &sg.r.backup_nhop_group, rts);
 
        return CMD_SUCCESS;
 }
index 08f5a07b7e91ed06892654c6e89bce67916ee979..8e357f96c9980d1b6e6cbd15461a6c554b07e382 100644 (file)
@@ -217,7 +217,7 @@ int sharp_install_lsps_helper(bool install_p, bool update_p,
 }
 
 void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
-                                uint8_t instance,
+                                uint8_t instance, uint32_t nhgid,
                                 const struct nexthop_group *nhg,
                                 const struct nexthop_group *backup_nhg,
                                 uint32_t routes)
@@ -239,7 +239,7 @@ void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
 
        monotime(&sg.r.t_start);
        for (i = 0; i < routes; i++) {
-               route_add(p, vrf_id, (uint8_t)instance, nhg, backup_nhg);
+               route_add(p, vrf_id, (uint8_t)instance, nhgid, nhg, backup_nhg);
                if (v4)
                        p->u.prefix4.s_addr = htonl(++temp);
                else
@@ -288,6 +288,7 @@ static void handle_repeated(bool installed)
        if (!installed) {
                sg.r.installed_routes = 0;
                sharp_install_routes_helper(&p, sg.r.vrf_id, sg.r.inst,
+                                           sg.r.nhgid,
                                            &sg.r.nhop_group,
                                            &sg.r.backup_nhop_group,
                                            sg.r.total_routes);
@@ -357,8 +358,34 @@ void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label)
        zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP);
 }
 
+void nhg_add(uint32_t id, const struct nexthop_group *nhg)
+{
+       struct zapi_nexthop nh_array[MULTIPATH_NUM];
+       struct zapi_nexthop *api_nh;
+       uint16_t nexthop_num = 0;
+       struct nexthop *nh;
+
+       for (ALL_NEXTHOPS_PTR(nhg, nh)) {
+               api_nh = &nh_array[nexthop_num];
+
+               zapi_nexthop_from_nexthop(api_nh, nh);
+               nexthop_num++;
+       }
+
+       zclient_nhg_add(zclient, id, nexthop_num, nh_array);
+
+       zclient_send_message(zclient);
+}
+
+void nhg_del(uint32_t id)
+{
+       zclient_nhg_del(zclient, id);
+       zclient_send_message(zclient);
+}
+
 void route_add(const struct prefix *p, vrf_id_t vrf_id,
-              uint8_t instance, const struct nexthop_group *nhg,
+              uint8_t instance, uint32_t nhgid,
+              const struct nexthop_group *nhg,
               const struct nexthop_group *backup_nhg)
 {
        struct zapi_route api;
@@ -376,14 +403,19 @@ 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);
 
-       for (ALL_NEXTHOPS_PTR(nhg, nh)) {
-               api_nh = &api.nexthops[i];
+       if (nhgid) {
+               SET_FLAG(api.message, ZAPI_MESSAGE_NHG);
+               api.nhgid = nhgid;
+       } else {
+               for (ALL_NEXTHOPS_PTR(nhg, nh)) {
+                       api_nh = &api.nexthops[i];
 
-               zapi_nexthop_from_nexthop(api_nh, nh);
+                       zapi_nexthop_from_nexthop(api_nh, nh);
 
-               i++;
+                       i++;
+               }
+               api.nexthop_num = i;
        }
-       api.nexthop_num = i;
 
        /* Include backup nexthops, if present */
        if (backup_nhg && backup_nhg->nexthop) {
index 0a44fa694f6c1111c0d7ed60d430ddd233d3f91b..69d7343cc477dc2dba9725955476dd16c95b8a2d 100644 (file)
@@ -29,15 +29,17 @@ int sharp_zclient_create(uint32_t session_id);
 int sharp_zclient_delete(uint32_t session_id);
 
 extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label);
+extern void nhg_add(uint32_t id, const struct nexthop_group *nhg);
+extern void nhg_del(uint32_t id);
 extern void route_add(const struct prefix *p, vrf_id_t, uint8_t instance,
-                     const struct nexthop_group *nhg,
+                     uint32_t nhgid, const struct nexthop_group *nhg,
                      const struct nexthop_group *backup_nhg);
 extern void route_delete(struct prefix *p, vrf_id_t vrf_id, uint8_t instance);
 extern void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id,
                                      bool import, bool watch, bool connected);
 
 extern void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
-                                       uint8_t instance,
+                                       uint8_t instance, uint32_t nhgid,
                                        const struct nexthop_group *nhg,
                                        const struct nexthop_group *backup_nhg,
                                        uint32_t routes);