]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: update pw dataplane info
authorMark Stapp <mjs@voltanet.io>
Fri, 4 Jun 2021 17:15:50 +0000 (13:15 -0400)
committermergify-bot <noreply@mergify.io>
Sat, 24 Jul 2021 17:17:00 +0000 (17:17 +0000)
Include the complete set of primary and backup nexthops from
the resolving route for a pseudowire. Add accessors for that
info. Modify the logic that creates the fib set of pw nexthops
so that only installed, labelled nexthops are included.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
(cherry picked from commit 072b487b8f1b07829ccc547627ef7a0aa84ab289)

zebra/zebra_dplane.c
zebra/zebra_dplane.h

index a8df0c56ceb369405e4c20083dfbe8c8852be84b..a5d672987d3382177ed3c504f95aa629257f9e3d 100644 (file)
@@ -157,12 +157,17 @@ struct dplane_pw_info {
        int af;
        int status;
        uint32_t flags;
+       uint32_t nhg_id;
        union g_addr dest;
        mpls_label_t local_label;
        mpls_label_t remote_label;
 
-       /* Nexthops */
-       struct nexthop_group nhg;
+       /* Nexthops that are valid and installed */
+       struct nexthop_group fib_nhg;
+
+       /* Primary and backup nexthop sets, copied from the resolving route. */
+       struct nexthop_group primary_nhg;
+       struct nexthop_group backup_nhg;
 
        union pw_protocol_fields fields;
 };
@@ -664,11 +669,21 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx)
        case DPLANE_OP_PW_INSTALL:
        case DPLANE_OP_PW_UNINSTALL:
                /* Free allocated nexthops */
-               if (ctx->u.pw.nhg.nexthop) {
+               if (ctx->u.pw.fib_nhg.nexthop) {
                        /* This deals with recursive nexthops too */
-                       nexthops_free(ctx->u.pw.nhg.nexthop);
+                       nexthops_free(ctx->u.pw.fib_nhg.nexthop);
+
+                       ctx->u.pw.fib_nhg.nexthop = NULL;
+               }
+               if (ctx->u.pw.primary_nhg.nexthop) {
+                       nexthops_free(ctx->u.pw.primary_nhg.nexthop);
+
+                       ctx->u.pw.primary_nhg.nexthop = NULL;
+               }
+               if (ctx->u.pw.backup_nhg.nexthop) {
+                       nexthops_free(ctx->u.pw.backup_nhg.nexthop);
 
-                       ctx->u.pw.nhg.nexthop = NULL;
+                       ctx->u.pw.backup_nhg.nexthop = NULL;
                }
                break;
 
@@ -1630,7 +1645,23 @@ dplane_ctx_get_pw_nhg(const struct zebra_dplane_ctx *ctx)
 {
        DPLANE_CTX_VALID(ctx);
 
-       return &(ctx->u.pw.nhg);
+       return &(ctx->u.pw.fib_nhg);
+}
+
+const struct nexthop_group *
+dplane_ctx_get_pw_primary_nhg(const struct zebra_dplane_ctx *ctx)
+{
+       DPLANE_CTX_VALID(ctx);
+
+       return &(ctx->u.pw.primary_nhg);
+}
+
+const struct nexthop_group *
+dplane_ctx_get_pw_backup_nhg(const struct zebra_dplane_ctx *ctx)
+{
+       DPLANE_CTX_VALID(ctx);
+
+       return &(ctx->u.pw.backup_nhg);
 }
 
 /* Accessors for interface information */
@@ -2461,12 +2492,14 @@ static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx,
                              enum dplane_op_e op,
                              struct zebra_pw *pw)
 {
+       int ret = EINVAL;
        struct prefix p;
        afi_t afi;
        struct route_table *table;
        struct route_node *rn;
        struct route_entry *re;
        const struct nexthop_group *nhg;
+       struct nexthop *nh, *newnh, *last_nh;
 
        if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
                zlog_debug("init dplane ctx %s: pw '%s', loc %u, rem %u",
@@ -2509,31 +2542,83 @@ static int dplane_ctx_pw_init(struct zebra_dplane_ctx *ctx,
 
        afi = (pw->af == AF_INET) ? AFI_IP : AFI_IP6;
        table = zebra_vrf_table(afi, SAFI_UNICAST, pw->vrf_id);
-       if (table) {
-               rn = route_node_match(table, &p);
-               if (rn) {
-                       RNODE_FOREACH_RE(rn, re) {
-                               if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
-                                       break;
+       if (table == NULL)
+               goto done;
+
+       rn = route_node_match(table, &p);
+       if (rn == NULL)
+               goto done;
+
+       re = NULL;
+       RNODE_FOREACH_RE(rn, re) {
+               if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
+                       break;
+       }
+
+       if (re) {
+               /* We'll capture a 'fib' list of nexthops that meet our
+                * criteria: installed, and labelled.
+                */
+               nhg = rib_get_fib_nhg(re);
+               last_nh = NULL;
+
+               if (nhg && nhg->nexthop) {
+                       for (ALL_NEXTHOPS_PTR(nhg, nh)) {
+                               if (!CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE)
+                                   || CHECK_FLAG(nh->flags,
+                                                 NEXTHOP_FLAG_RECURSIVE)
+                                   || nh->nh_label == NULL)
+                                       continue;
+
+                               newnh = nexthop_dup(nh, NULL);
+
+                               if (last_nh)
+                                       NEXTHOP_APPEND(last_nh, newnh);
+                               else
+                                       ctx->u.pw.fib_nhg.nexthop = newnh;
+                               last_nh = newnh;
                        }
+               }
 
-                       if (re) {
-                               nhg = rib_get_fib_nhg(re);
-                               if (nhg && nhg->nexthop)
-                                       copy_nexthops(&(ctx->u.pw.nhg.nexthop),
-                                                     nhg->nexthop, NULL);
-
-                               /* Include any installed backup nexthops */
-                               nhg = rib_get_fib_backup_nhg(re);
-                               if (nhg && nhg->nexthop)
-                                       copy_nexthops(&(ctx->u.pw.nhg.nexthop),
-                                                     nhg->nexthop, NULL);
+               /* Include any installed backup nexthops also. */
+               nhg = rib_get_fib_backup_nhg(re);
+               if (nhg && nhg->nexthop) {
+                       for (ALL_NEXTHOPS_PTR(nhg, nh)) {
+                               if (!CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE)
+                                   || CHECK_FLAG(nh->flags,
+                                                 NEXTHOP_FLAG_RECURSIVE)
+                                   || nh->nh_label == NULL)
+                                       continue;
+
+                               newnh = nexthop_dup(nh, NULL);
+
+                               if (last_nh)
+                                       NEXTHOP_APPEND(last_nh, newnh);
+                               else
+                                       ctx->u.pw.fib_nhg.nexthop = newnh;
+                               last_nh = newnh;
                        }
-                       route_unlock_node(rn);
+               }
+
+               /* Copy primary nexthops; recursive info is included too */
+               assert(re->nhe != NULL); /* SA warning */
+               copy_nexthops(&(ctx->u.pw.primary_nhg.nexthop),
+                             re->nhe->nhg.nexthop, NULL);
+               ctx->u.pw.nhg_id = re->nhe->id;
+
+               /* Copy backup nexthop info, if present */
+               if (re->nhe->backup_info && re->nhe->backup_info->nhe) {
+                       copy_nexthops(&(ctx->u.pw.backup_nhg.nexthop),
+                                     re->nhe->backup_info->nhe->nhg.nexthop,
+                                     NULL);
                }
        }
+       route_unlock_node(rn);
 
-       return AOK;
+       ret = AOK;
+
+done:
+       return ret;
 }
 
 /**
index 3a8536dda50b81e7e3114c676cd7181ee8f25bad..e091655a48ebe1335c01f229d77a6f77bfb84383 100644 (file)
@@ -437,6 +437,10 @@ const union pw_protocol_fields *dplane_ctx_get_pw_proto(
        const struct zebra_dplane_ctx *ctx);
 const struct nexthop_group *dplane_ctx_get_pw_nhg(
        const struct zebra_dplane_ctx *ctx);
+const struct nexthop_group *
+dplane_ctx_get_pw_primary_nhg(const struct zebra_dplane_ctx *ctx);
+const struct nexthop_group *
+dplane_ctx_get_pw_backup_nhg(const struct zebra_dplane_ctx *ctx);
 
 /* Accessors for interface information */
 uint32_t dplane_ctx_get_intf_metric(const struct zebra_dplane_ctx *ctx);