]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Fix pass back of data from dplane through fpm pipe
authorDonald Sharp <sharpd@nvidia.com>
Thu, 30 Jan 2025 13:57:57 +0000 (08:57 -0500)
committerDonald Sharp <sharpd@nvidia.com>
Fri, 31 Jan 2025 20:05:40 +0000 (15:05 -0500)
A recent code change 29122bc9b8d5317f6f486f9fe61a92a854948cc5
changed the passing of data up the fpm from passing the
tableid and vrf to the sonic expected tableid contains
the vrfid.  This violates the assumptions in the code
that the netlink message passes up the tableid as the
tableid.  Additionally this code change did not modify
the rib_find_rn_from_ctx to actually properly decode
what could be passed up.  Let's just fix this and let
Sonic carry the patch as appropriate for themselves
since they are not the only users of dplane_fpm_nl.c

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
zebra/dplane_fpm_nl.c
zebra/zebra_rib.c

index b8dbabb60dd8005984f05efdbba1030177a0ffda..a65bae95c42130a752edbd83929cbd377285154c 100644 (file)
@@ -587,7 +587,6 @@ static void fpm_read(struct event *t)
        struct zebra_dplane_ctx *ctx;
        size_t available_bytes;
        size_t hdr_available_bytes;
-       int ival;
 
        /* Let's ignore the input at the moment. */
        rv = stream_read_try(fnc->ibuf, fnc->socket,
@@ -724,12 +723,18 @@ static void fpm_read(struct event *t)
                                              NULL);
 
                        if (netlink_route_notify_read_ctx(hdr, 0, ctx) >= 0) {
-                               /* In the FPM encoding, the vrfid is present */
-                               ival = dplane_ctx_get_table(ctx);
-                               dplane_ctx_set_vrf(ctx, ival);
-                               dplane_ctx_set_table(ctx,
-                                                    ZEBRA_ROUTE_TABLE_UNKNOWN);
-
+                               /*
+                                * Receiving back a netlink message from
+                                * the fpm.  Currently the netlink messages
+                                * do not have a way to specify the vrf
+                                * so it must be unknown.  I'm looking
+                                * at you sonic.  If you are reading this
+                                * and wondering why it's not working
+                                * you must extend your patch to translate
+                                * the tableid to the vrfid and set the
+                                * tableid to 0 in order for this to work.
+                                */
+                               dplane_ctx_set_vrf(ctx, VRF_UNKNOWN);
                                dplane_provider_enqueue_to_zebra(ctx);
                        } else {
                                /*
index 2881192eb77e3f2b8eb4ed4e36c892c1a65fafb5..a1c8cd305956095c0c7f5dcb173f5b4d25a85f2f 100644 (file)
@@ -1891,20 +1891,18 @@ struct route_node *rib_find_rn_from_ctx(const struct zebra_dplane_ctx *ctx)
        struct route_table *table = NULL;
        struct route_node *rn = NULL;
        const struct prefix *dest_pfx, *src_pfx;
+       uint32_t tableid = dplane_ctx_get_table(ctx);
+       vrf_id_t vrf_id = dplane_ctx_get_vrf(ctx);
 
        /* Locate rn and re(s) from ctx */
+       table = zebra_vrf_lookup_table_with_table_id(dplane_ctx_get_afi(ctx),
+                                                    dplane_ctx_get_safi(ctx), vrf_id, tableid);
 
-       table = zebra_vrf_lookup_table_with_table_id(
-               dplane_ctx_get_afi(ctx), dplane_ctx_get_safi(ctx),
-               dplane_ctx_get_vrf(ctx), dplane_ctx_get_table(ctx));
        if (table == NULL) {
                if (IS_ZEBRA_DEBUG_DPLANE) {
-                       zlog_debug(
-                               "Failed to find route for ctx: no table for afi %d, safi %d, vrf %s(%u)",
-                               dplane_ctx_get_afi(ctx),
-                               dplane_ctx_get_safi(ctx),
-                               vrf_id_to_name(dplane_ctx_get_vrf(ctx)),
-                               dplane_ctx_get_vrf(ctx));
+                       zlog_debug("Failed to find route for ctx: no table for afi %d, safi %d, vrf %s(%u) table %u",
+                                  dplane_ctx_get_afi(ctx), dplane_ctx_get_safi(ctx),
+                                  vrf_id_to_name(vrf_id), vrf_id, tableid);
                }
                goto done;
        }
@@ -2214,26 +2212,13 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
 {
        struct route_node *rn = NULL;
        struct route_entry *re = NULL;
-       struct vrf *vrf;
+       struct vrf *vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx));
        struct nexthop *nexthop;
        rib_dest_t *dest;
        bool fib_changed = false;
        bool debug_p = IS_ZEBRA_DEBUG_DPLANE | IS_ZEBRA_DEBUG_RIB;
        int start_count, end_count;
-       vrf_id_t vrf_id;
-       int tableid;
-
-       /* Locate vrf and route table - we must have one or the other */
-       tableid = dplane_ctx_get_table(ctx);
-       vrf_id = dplane_ctx_get_vrf(ctx);
-       if (vrf_id == VRF_UNKNOWN)
-               vrf_id = zebra_vrf_lookup_by_table(tableid,
-                                                  dplane_ctx_get_ns_id(ctx));
-       else if (tableid == ZEBRA_ROUTE_TABLE_UNKNOWN)
-               tableid = zebra_vrf_lookup_tableid(vrf_id,
-                                                  dplane_ctx_get_ns_id(ctx));
-
-       vrf = vrf_lookup_by_id(vrf_id);
+       uint32_t tableid = dplane_ctx_get_table(ctx);
 
        /* Locate rn and re(s) from ctx */
        rn = rib_find_rn_from_ctx(ctx);
@@ -4862,6 +4847,33 @@ void rib_close_table(struct route_table *table)
        }
 }
 
+/*
+ * The context sent up from the dplane may be a context
+ * that has been generated by the zebra master pthread
+ * or it may be a context generated from a event in
+ * either the kernel dplane code or the fpm dplane
+ * code.  In which case the tableid and vrfid may
+ * not be fully known and we have to figure it out
+ * when the context hits the master pthread.
+ * since this is the *starter* spot for that let
+ * us do a bit of work on each one to see if any
+ * massaging is needed
+ */
+static inline void zebra_rib_translate_ctx_from_dplane(struct zebra_dplane_ctx *ctx)
+{
+       uint32_t tableid = dplane_ctx_get_table(ctx);
+       vrf_id_t vrfid = dplane_ctx_get_vrf(ctx);
+       uint32_t nsid = dplane_ctx_get_ns_id(ctx);
+       enum dplane_op_e op = dplane_ctx_get_op(ctx);
+
+       if (vrfid == VRF_UNKNOWN)
+               dplane_ctx_set_vrf(ctx, zebra_vrf_lookup_by_table(tableid, nsid));
+       else if ((op == DPLANE_OP_ROUTE_INSTALL || op == DPLANE_OP_ROUTE_UPDATE ||
+                 op == DPLANE_OP_ROUTE_DELETE) &&
+                tableid == ZEBRA_ROUTE_TABLE_UNKNOWN)
+               dplane_ctx_set_table(ctx, zebra_vrf_lookup_tableid(vrfid, nsid));
+}
+
 /*
  * Handle results from the dataplane system. Dequeue update context
  * structs, dispatch to appropriate internal handlers.
@@ -4921,6 +4933,8 @@ static void rib_process_dplane_results(struct event *thread)
                }
 
                while (ctx) {
+                       zebra_rib_translate_ctx_from_dplane(ctx);
+
 #ifdef HAVE_SCRIPTING
                        if (ret == 0)
                                frrscript_call(fs,