]> git.puffer.fish Git - mirror/frr.git/commitdiff
sharpd: support backup nexthops
authorMark Stapp <mjs@voltanet.io>
Fri, 15 Nov 2019 21:33:34 +0000 (16:33 -0500)
committerMark Stapp <mjs@voltanet.io>
Fri, 27 Mar 2020 13:39:14 +0000 (09:39 -0400)
Add cli and zapi support for backup nexthops for sharpd routes.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
lib/zclient.c
sharpd/sharp_globals.h
sharpd/sharp_vty.c
sharpd/sharp_zebra.c
sharpd/sharp_zebra.h

index 55b8d29a4d8ecc75ac9beb1569c4056ed0e9b3eb..d380267a708c50385be3b841b53a60acd66a1d9f 100644 (file)
@@ -1500,6 +1500,7 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
 
        znh->type = nh->type;
        znh->vrf_id = nh->vrf_id;
+       znh->weight = nh->weight;
        znh->ifindex = nh->ifindex;
        znh->gate = nh->gate;
 
index 4e5c933667acd367b501f029fe1aae0457b4c100..8eba57f4ddeca820194447628beaafc562711c99 100644 (file)
@@ -28,9 +28,11 @@ struct sharp_routes {
        /* The original prefix for route installation */
        struct prefix orig_prefix;
 
-       /* The nexthop group we are using for installation */
+       /* The nexthop info we are using for installation */
        struct nexthop nhop;
+       struct nexthop backup_nhop;
        struct nexthop_group nhop_group;
+       struct nexthop_group backup_nhop_group;
 
        uint32_t total_routes;
        uint32_t installed_routes;
index aa3d85624bf5c49b62f1a05dce01701b61ef3455..8a787c8e831fb0bb0ff4da57ab9eb8516e51bba9 100644 (file)
@@ -162,7 +162,12 @@ DEFPY (install_routes_data_dump,
 
 DEFPY (install_routes,
        install_routes_cmd,
-       "sharp install routes [vrf NAME$vrf_name] <A.B.C.D$start4|X:X::X:X$start6> <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|nexthop-group NHGNAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]",
+       "sharp install routes [vrf NAME$vrf_name]\
+         <A.B.C.D$start4|X:X::X:X$start6>\
+         <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|\
+          nexthop-group NHGNAME$nexthop_group>\
+         [backup$backup <A.B.C.D$backup_nexthop4|X:X::X:X$backup_nexthop6>] \
+         (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]",
        "Sharp routing Protocol\n"
        "install some routes\n"
        "Routes to install\n"
@@ -175,6 +180,9 @@ DEFPY (install_routes,
        "V6 Nexthop address to use\n"
        "Nexthop-Group to use\n"
        "The Name of the nexthop-group\n"
+       "Backup nexthop to use(Can be an IPv4 or IPv6 address)\n"
+       "Backup V4 Nexthop address to use\n"
+       "Backup V6 Nexthop address to use\n"
        "How many to create\n"
        "Instance to use\n"
        "Instance\n"
@@ -197,6 +205,8 @@ DEFPY (install_routes,
        memset(&sg.r.orig_prefix, 0, sizeof(sg.r.orig_prefix));
        memset(&sg.r.nhop, 0, sizeof(sg.r.nhop));
        memset(&sg.r.nhop_group, 0, sizeof(sg.r.nhop_group));
+       memset(&sg.r.backup_nhop, 0, sizeof(sg.r.nhop));
+       memset(&sg.r.backup_nhop_group, 0, sizeof(sg.r.nhop_group));
 
        if (start4.s_addr != 0) {
                prefix.family = AF_INET;
@@ -219,6 +229,12 @@ DEFPY (install_routes,
                return CMD_WARNING;
        }
 
+       /* Explicit backup not available with named nexthop-group */
+       if (backup && nexthop_group) {
+               vty_out(vty, "%% Invalid: cannot specify both nexthop-group and backup\n");
+               return CMD_WARNING;
+       }
+
        if (nexthop_group) {
                struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group);
                if (!nhgc) {
@@ -229,6 +245,22 @@ DEFPY (install_routes,
                }
 
                sg.r.nhop_group.nexthop = nhgc->nhg.nexthop;
+
+               /* Use group's backup nexthop info if present */
+               if (nhgc->backup_list_name[0]) {
+                       struct nexthop_group_cmd *bnhgc =
+                               nhgc_find(nhgc->backup_list_name);
+
+                       if (!bnhgc) {
+                               vty_out(vty, "%% Backup group %s not found for group %s\n",
+                                       nhgc->backup_list_name,
+                                       nhgc->name);
+                               return CMD_WARNING;
+                       }
+
+                       sg.r.backup_nhop.vrf_id = vrf->vrf_id;
+                       sg.r.backup_nhop_group.nexthop = bnhgc->nhg.nexthop;
+               }
        } else {
                if (nexthop4.s_addr != INADDR_ANY) {
                        sg.r.nhop.gate.ipv4 = nexthop4;
@@ -242,11 +274,30 @@ DEFPY (install_routes,
                sg.r.nhop_group.nexthop = &sg.r.nhop;
        }
 
+       /* Use single backup nexthop if specified */
+       if (backup) {
+               /* Set flag and index in primary nexthop */
+               SET_FLAG(sg.r.nhop.flags, NEXTHOP_FLAG_HAS_BACKUP);
+               sg.r.nhop.backup_idx = 0;
+
+               if (backup_nexthop4.s_addr != INADDR_ANY) {
+                       sg.r.backup_nhop.gate.ipv4 = backup_nexthop4;
+                       sg.r.backup_nhop.type = NEXTHOP_TYPE_IPV4;
+               } else {
+                       sg.r.backup_nhop.gate.ipv6 = backup_nexthop6;
+                       sg.r.backup_nhop.type = NEXTHOP_TYPE_IPV6;
+               }
+
+               sg.r.backup_nhop.vrf_id = vrf->vrf_id;
+               sg.r.backup_nhop_group.nexthop = &sg.r.backup_nhop;
+       }
+
        sg.r.inst = instance;
        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, rts);
+       sharp_install_routes_helper(&prefix, sg.r.vrf_id, sg.r.inst,
+                                   &sg.r.nhop_group, &sg.r.backup_nhop_group,
+                                   rts);
 
        return CMD_SUCCESS;
 }
index 258a0a06dd07f4a53d11bc6cb32e3e97eaa6e31b..e1bd6f57226433420f61a71cc0578516f8af1b14 100644 (file)
@@ -143,7 +143,9 @@ int sharp_install_lsps_helper(bool install_p, const struct prefix *p,
 }
 
 void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
-                                uint8_t instance, struct nexthop_group *nhg,
+                                uint8_t instance,
+                                const struct nexthop_group *nhg,
+                                const struct nexthop_group *backup_nhg,
                                 uint32_t routes)
 {
        uint32_t temp, i;
@@ -157,9 +159,13 @@ void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
        } else
                temp = ntohl(p->u.val32[3]);
 
+       /* Only use backup route/nexthops if present */
+       if (backup_nhg && (backup_nhg->nexthop == NULL))
+               backup_nhg = NULL;
+
        monotime(&sg.r.t_start);
        for (i = 0; i < routes; i++) {
-               route_add(p, vrf_id, (uint8_t)instance, nhg);
+               route_add(p, vrf_id, (uint8_t)instance, nhg, backup_nhg);
                if (v4)
                        p->u.prefix4.s_addr = htonl(++temp);
                else
@@ -209,6 +215,7 @@ static void handle_repeated(bool installed)
                sg.r.installed_routes = 0;
                sharp_install_routes_helper(&p, sg.r.vrf_id, sg.r.inst,
                                            &sg.r.nhop_group,
+                                           &sg.r.backup_nhop_group,
                                            sg.r.total_routes);
        }
 }
@@ -276,8 +283,9 @@ 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 route_add(struct prefix *p, vrf_id_t vrf_id,
-              uint8_t instance, struct nexthop_group *nhg)
+void route_add(const struct prefix *p, vrf_id_t vrf_id,
+              uint8_t instance, const struct nexthop_group *nhg,
+              const struct nexthop_group *backup_nhg)
 {
        struct zapi_route api;
        struct zapi_nexthop *api_nh;
@@ -298,10 +306,27 @@ void route_add(struct prefix *p, vrf_id_t vrf_id,
                api_nh = &api.nexthops[i];
 
                zapi_nexthop_from_nexthop(api_nh, nh);
+
                i++;
        }
        api.nexthop_num = i;
 
+       /* Include backup nexthops, if present */
+       if (backup_nhg && backup_nhg->nexthop) {
+               SET_FLAG(api.message, ZAPI_MESSAGE_BACKUP_NEXTHOPS);
+
+               i = 0;
+               for (ALL_NEXTHOPS_PTR(backup_nhg, nh)) {
+                       api_nh = &api.backup_nexthops[i];
+
+                       zapi_backup_nexthop_from_nexthop(api_nh, nh);
+
+                       i++;
+               }
+
+               api.backup_nexthop_num = i;
+       }
+
        zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
 }
 
index c995d557af4e3bbefb349436e4ab608562fdc303..926bff676be36d76b5f6c435db09aa937647bbec 100644 (file)
 extern void sharp_zebra_init(void);
 
 extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label);
-extern void route_add(struct prefix *p, vrf_id_t, uint8_t instance,
-                     struct nexthop_group *nhg);
+extern void route_add(const struct prefix *p, vrf_id_t, uint8_t instance,
+                     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,
-                                       struct nexthop_group *nhg,
+                                       const struct nexthop_group *nhg,
+                                       const struct nexthop_group *backup_nhg,
                                        uint32_t routes);
 extern void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id,
                                       uint8_t instance, uint32_t routes);