]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib,zebra,sharpd: add code for backup proto-NHs but disabled
authorStephen Worley <sworley@cumulusnetworks.com>
Fri, 25 Sep 2020 17:48:21 +0000 (13:48 -0400)
committerStephen Worley <sworley@cumulusnetworks.com>
Mon, 28 Sep 2020 16:41:00 +0000 (12:41 -0400)
Add the zapi code for encoding/decoding of backup nexthops for when
we are ready for it, but disable it for now so that we revert
to the old way with them.

When zebra gets a proto-NHG with a backup in it, we early fail and
tell the upper level proto. In this case sharpd. Sharpd then reverts
to the old way of installation with the route.

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
lib/zclient.c
lib/zclient.h
sharpd/sharp_nht.c
sharpd/sharp_zebra.c
sharpd/sharp_zebra.h
zebra/zapi_msg.c
zebra/zebra_nhg.c

index 13eba4c7901b99cbc9240ae009a0e605e1fc304c..b7d240b4e88e6f4a57e304c617a21b61e816c1e8 100644 (file)
@@ -1017,9 +1017,10 @@ done:
        return ret;
 }
 
-static int zapi_nhg_encode(struct stream *s, uint16_t proto, int cmd,
-                          struct zapi_nhg *api_nhg)
+int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)
 {
+       int i;
+
        if (cmd != ZEBRA_NHG_DEL && cmd != ZEBRA_NHG_ADD) {
                flog_err(EC_LIB_ZAPI_ENCODE,
                         "%s: Specified zapi NHG command (%d) doesn't exist\n",
@@ -1030,17 +1031,26 @@ static int zapi_nhg_encode(struct stream *s, uint16_t proto, int cmd,
        stream_reset(s);
        zclient_create_header(s, cmd, VRF_DEFAULT);
 
-       stream_putw(s, proto);
+       stream_putw(s, api_nhg->proto);
        stream_putl(s, api_nhg->id);
 
        if (cmd == ZEBRA_NHG_ADD) {
+               /* Nexthops */
                zapi_nexthop_group_sort(api_nhg->nexthops,
                                        api_nhg->nexthop_num);
 
                stream_putw(s, api_nhg->nexthop_num);
 
-               for (int i = 0; i < api_nhg->nexthop_num; i++)
+               for (i = 0; i < api_nhg->nexthop_num; i++)
                        zapi_nexthop_encode(s, &api_nhg->nexthops[i], 0, 0);
+
+               /* Backup nexthops */
+
+               stream_putw(s, api_nhg->backup_nexthop_num);
+
+               for (i = 0; i < api_nhg->backup_nexthop_num; i++)
+                       zapi_nexthop_encode(s, &api_nhg->backup_nexthops[i], 0,
+                                           0);
        }
 
        stream_putw_at(s, 0, stream_get_endp(s));
@@ -1050,8 +1060,9 @@ static int zapi_nhg_encode(struct stream *s, uint16_t proto, int cmd,
 
 int zclient_nhg_send(struct zclient *zclient, int cmd, struct zapi_nhg *api_nhg)
 {
-       if (zapi_nhg_encode(zclient->obuf, zclient->redist_default, cmd,
-                           api_nhg))
+       api_nhg->proto = zclient->redist_default;
+
+       if (zapi_nhg_encode(zclient->obuf, cmd, api_nhg))
                return -1;
 
        return zclient_send_message(zclient);
index b41f291554d5fbaa19885dd4500a52829fe07269..959a101395842644d805541357ad626760b7063b 100644 (file)
@@ -442,9 +442,14 @@ struct zapi_nexthop {
  * ZAPI Nexthop Group. For use with protocol creation of nexthop groups.
  */
 struct zapi_nhg {
+       uint16_t proto;
        uint32_t id;
+
        uint16_t nexthop_num;
        struct zapi_nexthop nexthops[MULTIPATH_NUM];
+
+       uint16_t backup_nexthop_num;
+       struct zapi_nexthop backup_nexthops[MULTIPATH_NUM];
 };
 
 /*
@@ -907,6 +912,9 @@ bool zapi_ipset_notify_decode(struct stream *s,
                              uint32_t *unique,
                             enum zapi_ipset_notify_owner *note);
 
+
+extern int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg);
+extern int zapi_nhg_decode(struct stream *s, int cmd, struct zapi_nhg *api_nhg);
 extern int zclient_nhg_send(struct zclient *zclient, int cmd,
                            struct zapi_nhg *api_nhg);
 
index 9f3155272083f349a402ac54521a139f1306e34b..5b3fe2583ee693c1843d79456b93d55b49fecc42 100644 (file)
@@ -133,11 +133,15 @@ static void sharp_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd *nhgc,
 {
        struct sharp_nhg lookup;
        struct sharp_nhg *snhg;
+       struct nexthop_group_cmd *bnhgc = NULL;
 
        strlcpy(lookup.name, nhgc->name, sizeof(lookup.name));
        snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
 
-       nhg_add(snhg->id, &nhgc->nhg);
+       if (nhgc->backup_list_name[0])
+               bnhgc = nhgc_find(nhgc->backup_list_name);
+
+       nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL));
 }
 
 static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc,
@@ -145,11 +149,15 @@ static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc,
 {
        struct sharp_nhg lookup;
        struct sharp_nhg *snhg;
+       struct nexthop_group_cmd *bnhgc = NULL;
 
        strlcpy(lookup.name, nhgc->name, sizeof(lookup.name));
        snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
 
-       nhg_add(snhg->id, &nhgc->nhg);
+       if (nhgc->backup_list_name[0])
+               bnhgc = nhgc_find(nhgc->backup_list_name);
+
+       nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL));
 }
 
 static void sharp_nhgroup_delete_cb(const char *name)
index 50129c2363f4eb8f03a1937af69159995bf6e364..d167e8e277b1e63c10b64638273b663e3b6d3da9 100644 (file)
@@ -357,7 +357,8 @@ 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)
+void nhg_add(uint32_t id, const struct nexthop_group *nhg,
+            const struct nexthop_group *backup_nhg)
 {
        struct zapi_nhg api_nhg = {};
        struct zapi_nexthop *api_nh;
@@ -378,6 +379,22 @@ void nhg_add(uint32_t id, const struct nexthop_group *nhg)
                api_nhg.nexthop_num++;
        }
 
+       if (backup_nhg) {
+               for (ALL_NEXTHOPS_PTR(backup_nhg, nh)) {
+                       if (api_nhg.backup_nexthop_num >= MULTIPATH_NUM) {
+                               zlog_warn(
+                                       "%s: number of backup nexthops greater than max multipath size, truncating",
+                                       __func__);
+                               break;
+                       }
+                       api_nh = &api_nhg.backup_nexthops
+                                         [api_nhg.backup_nexthop_num];
+
+                       zapi_backup_nexthop_from_nexthop(api_nh, nh);
+                       api_nhg.backup_nexthop_num++;
+               }
+       }
+
        zclient_nhg_send(zclient, ZEBRA_NHG_ADD, &api_nhg);
 }
 
index 69d7343cc477dc2dba9725955476dd16c95b8a2d..4a767ababf20833dd29596c2221f627617de2339 100644 (file)
@@ -29,7 +29,8 @@ 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_add(uint32_t id, const struct nexthop_group *nhg,
+                   const struct nexthop_group *backup_nhg);
 extern void nhg_del(uint32_t id);
 extern void route_add(const struct prefix *p, vrf_id_t, uint8_t instance,
                      uint32_t nhgid, const struct nexthop_group *nhg,
index 7ed3a41ae1f09826ec38881a6fb3619a6a96d80f..1d8c5c7cc0b541be0dd23d05342d2a4e8bbb5970 100644 (file)
@@ -1732,84 +1732,134 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
        return true;
 }
 
+int zapi_nhg_decode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)
+{
+       uint16_t i;
+       struct zapi_nexthop *znh;
+
+       STREAM_GETW(s, api_nhg->proto);
+       STREAM_GETL(s, api_nhg->id);
+
+       if (cmd == ZEBRA_NHG_DEL)
+               goto done;
+
+       /* Nexthops */
+       STREAM_GETW(s, api_nhg->nexthop_num);
+
+       if (zserv_nexthop_num_warn(__func__, NULL, api_nhg->nexthop_num))
+               return -1;
+
+       if (api_nhg->nexthop_num <= 0) {
+               flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
+                         "%s: No nexthops sent", __func__);
+               return -1;
+       }
+
+       for (i = 0; i < api_nhg->nexthop_num; i++) {
+               znh = &((api_nhg->nexthops)[i]);
+
+               if (zapi_nexthop_decode(s, znh, 0, 0) != 0) {
+                       flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
+                                 "%s: Nexthop creation failed", __func__);
+                       return -1;
+               }
+       }
+
+       /* Backup Nexthops */
+       STREAM_GETW(s, api_nhg->backup_nexthop_num);
+
+       if (zserv_nexthop_num_warn(__func__, NULL, api_nhg->backup_nexthop_num))
+               return -1;
+
+       for (i = 0; i < api_nhg->backup_nexthop_num; i++) {
+               znh = &((api_nhg->backup_nexthops)[i]);
+
+               if (zapi_nexthop_decode(s, znh, 0, 0) != 0) {
+                       flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
+                                 "%s: Backup Nexthop creation failed",
+                                 __func__);
+                       return -1;
+               }
+       }
+
+done:
+       return 0;
+
+stream_failure:
+       flog_warn(
+               EC_ZEBRA_NEXTHOP_CREATION_FAILED,
+               "%s: Nexthop Group decode failed with some sort of stream read failure",
+               __func__);
+       return -1;
+}
+
 static void zread_nhg_del(ZAPI_HANDLER_ARGS)
 {
-       struct stream *s = msg;
-       uint32_t id;
-       uint16_t proto;
+       struct stream *s;
+       struct zapi_nhg api_nhg = {};
        struct nhg_hash_entry *nhe;
 
-       STREAM_GETW(s, proto);
-       STREAM_GETL(s, id);
+       s = msg;
+       if (zapi_nhg_decode(s, hdr->command, &api_nhg) < 0) {
+               if (IS_ZEBRA_DEBUG_RECV)
+                       zlog_debug("%s: Unable to decode zapi_nhg sent",
+                                  __func__);
+               return;
+       }
 
        /*
         * Delete the received nhg id
         */
 
-       nhe = zebra_nhg_proto_del(id, proto);
+       nhe = zebra_nhg_proto_del(api_nhg.id, api_nhg.proto);
 
        if (nhe) {
                zebra_nhg_decrement_ref(nhe);
-               nhg_notify(proto, client->instance, id, ZAPI_NHG_REMOVED);
+               nhg_notify(api_nhg.proto, client->instance, api_nhg.id,
+                          ZAPI_NHG_REMOVED);
        } else
-               nhg_notify(proto, client->instance, id, ZAPI_NHG_REMOVE_FAIL);
-
-       return;
-
-stream_failure:
-       flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
-                 "%s: Nexthop group deletion failed", __func__);
-       return;
+               nhg_notify(api_nhg.proto, client->instance, api_nhg.id,
+                          ZAPI_NHG_REMOVE_FAIL);
 }
 
 static void zread_nhg_add(ZAPI_HANDLER_ARGS)
 {
        struct stream *s;
-       uint32_t id;
-       size_t nhops, i;
-       struct zapi_nexthop zapi_nexthops[MULTIPATH_NUM];
+       struct zapi_nhg api_nhg = {};
        struct nexthop_group *nhg = NULL;
-       uint16_t proto;
+       struct nhg_backup_info *bnhg = NULL;
        struct nhg_hash_entry *nhe;
 
        s = msg;
-
-       STREAM_GETW(s, proto);
-       STREAM_GETL(s, id);
-       STREAM_GETW(s, nhops);
-
-       if (zserv_nexthop_num_warn(__func__, NULL, nhops))
-               return;
-
-       if (nhops <= 0) {
-               flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
-                         "%s: No nexthops sent", __func__);
+       if (zapi_nhg_decode(s, hdr->command, &api_nhg) < 0) {
+               if (IS_ZEBRA_DEBUG_RECV)
+                       zlog_debug("%s: Unable to decode zapi_nhg sent",
+                                  __func__);
                return;
        }
 
-       for (i = 0; i < nhops; i++) {
-               struct zapi_nexthop *znh = &zapi_nexthops[i];
+       if ((!zapi_read_nexthops(client, NULL, api_nhg.nexthops, 0, 0,
+                                api_nhg.nexthop_num,
+                                api_nhg.backup_nexthop_num, &nhg, NULL))
+           || (!zapi_read_nexthops(client, NULL, api_nhg.backup_nexthops, 0, 0,
+                                   api_nhg.backup_nexthop_num,
+                                   api_nhg.backup_nexthop_num, NULL, &bnhg))) {
 
-               if (zapi_nexthop_decode(s, znh, 0, 0) != 0) {
-                       flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
-                                 "%s: Nexthop creation failed", __func__);
-                       return;
-               }
-       }
-
-       if (!zapi_read_nexthops(client, NULL, zapi_nexthops, 0, 0, nhops, 0,
-                               &nhg, NULL)) {
                flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
                          "%s: Nexthop Group Creation failed", __func__);
+
+               nexthop_group_delete(&nhg);
+               zebra_nhg_backup_free(&bnhg);
                return;
        }
 
        /*
         * Create the nhg
         */
-       nhe = zebra_nhg_proto_add(id, proto, nhg, 0);
+       nhe = zebra_nhg_proto_add(api_nhg.id, api_nhg.proto, nhg, 0);
 
        nexthop_group_delete(&nhg);
+       zebra_nhg_backup_free(&bnhg);
 
        /*
         * TODO:
@@ -1818,18 +1868,11 @@ static void zread_nhg_add(ZAPI_HANDLER_ARGS)
         * Resolution is going to need some more work.
         */
        if (nhe)
-               nhg_notify(proto, client->instance, id, ZAPI_NHG_INSTALLED);
+               nhg_notify(api_nhg.proto, client->instance, api_nhg.id,
+                          ZAPI_NHG_INSTALLED);
        else
-               nhg_notify(proto, client->instance, id, ZAPI_NHG_FAIL_INSTALL);
-
-       return;
-
-stream_failure:
-       flog_warn(
-               EC_ZEBRA_NEXTHOP_CREATION_FAILED,
-               "%s: Nexthop Group creation failed with some sort of stream read failure",
-               __func__);
-       return;
+               nhg_notify(api_nhg.proto, client->instance, api_nhg.id,
+                          ZAPI_NHG_FAIL_INSTALL);
 }
 
 static void zread_route_add(ZAPI_HANDLER_ARGS)
@@ -1911,6 +1954,9 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
                                       api.flags, api.message,
                                       api.backup_nexthop_num,
                                       api.backup_nexthop_num, NULL, &bnhg))) {
+
+               nexthop_group_delete(&ng);
+               zebra_nhg_backup_free(&bnhg);
                XFREE(MTYPE_RE, re);
                return;
        }
index 1ed7ff00e5fe042f8f2811a508d50953493986cf..6aa9ba0ebc95eed4efd9d0da46541b9740759223 100644 (file)
@@ -2759,6 +2759,14 @@ struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type,
         * Once resolution is figured out, we won't need this!
         */
        for (ALL_NEXTHOPS_PTR(nhg, newhop)) {
+               if (CHECK_FLAG(newhop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
+                       if (IS_ZEBRA_DEBUG_NHG)
+                               zlog_debug(
+                                       "%s: id %u, backup nexthops not supported",
+                                       __func__, id);
+                       return NULL;
+               }
+
                if (newhop->type == NEXTHOP_TYPE_BLACKHOLE) {
                        if (IS_ZEBRA_DEBUG_NHG)
                                zlog_debug(