]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_rib.c
zebra: delay default vrf name after vrf initialization
[mirror_frr.git] / zebra / zebra_rib.c
index b89d2851185911f2473507cc55eadfe7e34ae0ae..828539252732166570af5970fd31135c58a703db 100644 (file)
@@ -38,6 +38,7 @@
 #include "vrf.h"
 #include "workqueue.h"
 
+#include "zebra/zebra_router.h"
 #include "zebra/connected.h"
 #include "zebra/debug.h"
 #include "zebra/interface.h"
@@ -60,7 +61,7 @@
  */
 static pthread_mutex_t dplane_mutex;
 static struct thread *t_dplane;
-static struct dplane_ctx_q_s rib_dplane_q;
+static struct dplane_ctx_q rib_dplane_q;
 
 DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason),
            (rn, reason))
@@ -357,8 +358,6 @@ static void nexthop_set_resolved(afi_t afi, const struct nexthop *newhop,
                if (newhop->ifindex) {
                        resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
                        resolved_hop->ifindex = newhop->ifindex;
-                       if (newhop->flags & NEXTHOP_FLAG_ONLINK)
-                               resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
                }
                break;
        case NEXTHOP_TYPE_IPV6:
@@ -397,6 +396,9 @@ static void nexthop_set_resolved(afi_t afi, const struct nexthop *newhop,
                break;
        }
 
+       if (newhop->flags & NEXTHOP_FLAG_ONLINK)
+               resolved_hop->flags |= NEXTHOP_FLAG_ONLINK;
+
        /* Copy labels of the resolved route */
        if (newhop->nh_label)
                nexthop_add_labels(resolved_hop, newhop->nh_label_type,
@@ -1092,75 +1094,6 @@ int zebra_rib_labeled_unicast(struct route_entry *re)
        return 1;
 }
 
-void kernel_route_rib_pass_fail(struct route_node *rn, const struct prefix *p,
-                               struct route_entry *re,
-                               enum zebra_dplane_status res)
-{
-       struct nexthop *nexthop;
-       char buf[PREFIX_STRLEN];
-       rib_dest_t *dest;
-
-       dest = rib_dest_from_rnode(rn);
-
-       switch (res) {
-       case ZEBRA_DPLANE_INSTALL_SUCCESS:
-               dest->selected_fib = re;
-               for (ALL_NEXTHOPS(re->ng, nexthop)) {
-                       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
-                               continue;
-
-                       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
-                               SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
-                       else
-                               UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
-               }
-               zsend_route_notify_owner(re, p, ZAPI_ROUTE_INSTALLED);
-               break;
-       case ZEBRA_DPLANE_INSTALL_FAILURE:
-               /*
-                * I am not sure this is the right thing to do here
-                * but the code always set selected_fib before
-                * this assignment was moved here.
-                */
-               dest->selected_fib = re;
-
-               zsend_route_notify_owner(re, p, ZAPI_ROUTE_FAIL_INSTALL);
-               flog_err(EC_ZEBRA_DP_INSTALL_FAIL,
-                        "%u:%s: Route install failed", re->vrf_id,
-                        prefix2str(p, buf, sizeof(buf)));
-               break;
-       case ZEBRA_DPLANE_DELETE_SUCCESS:
-               /*
-                * The case where selected_fib is not re is
-                * when we have received a system route
-                * that is overriding our installed route
-                * as such we should leave the selected_fib
-                * pointer alone
-                */
-               if (dest->selected_fib == re)
-                       dest->selected_fib = NULL;
-               for (ALL_NEXTHOPS(re->ng, nexthop))
-                       UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
-
-               zsend_route_notify_owner(re, p, ZAPI_ROUTE_REMOVED);
-               break;
-       case ZEBRA_DPLANE_DELETE_FAILURE:
-               /*
-                * Should we set this to NULL if the
-                * delete fails?
-                */
-               dest->selected_fib = NULL;
-               flog_err(EC_ZEBRA_DP_DELETE_FAIL,
-                        "%u:%s: Route Deletion failure", re->vrf_id,
-                        prefix2str(p, buf, sizeof(buf)));
-
-               zsend_route_notify_owner(re, p, ZAPI_ROUTE_REMOVE_FAIL);
-               break;
-       case ZEBRA_DPLANE_STATUS_NONE:
-               break;
-       }
-}
-
 /* Update flag indicates whether this is a "replace" or not. Currently, this
  * is only used for IPv4.
  */
@@ -1887,7 +1820,8 @@ static void rib_process(struct route_node *rn)
  * Utility to match route with dplane context data
  */
 static bool rib_route_match_ctx(const struct route_entry *re,
-                               const dplane_ctx_h ctx, bool is_update)
+                               const struct zebra_dplane_ctx *ctx,
+                               bool is_update)
 {
        bool result = false;
 
@@ -1941,17 +1875,16 @@ done:
 }
 
 /*
- * TODO - WIP version of route-update processing after async dataplane
- * update.
+ * Route-update results processing after async dataplane update.
  */
-static void rib_process_after(dplane_ctx_h ctx)
+static void rib_process_after(struct zebra_dplane_ctx *ctx)
 {
        struct route_table *table = NULL;
        struct zebra_vrf *zvrf = NULL;
        struct route_node *rn = NULL;
        struct route_entry *re = NULL, *old_re = NULL, *rib;
        bool is_update = false;
-       struct nexthop *nexthop;
+       struct nexthop *nexthop, *ctx_nexthop;
        char dest_str[PREFIX_STRLEN] = "";
        enum dplane_op_e op;
        enum zebra_dplane_result status;
@@ -2000,9 +1933,9 @@ static void rib_process_after(dplane_ctx_h ctx)
        status = dplane_ctx_get_status(ctx);
 
        if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
-               zlog_debug("%u:%s Processing dplane ctx %p, op %s result %d",
+               zlog_debug("%u:%s Processing dplane ctx %p, op %s result %s",
                           dplane_ctx_get_vrf(ctx), dest_str, ctx,
-                          dplane_op2str(op), status);
+                          dplane_op2str(op), dplane_res2str(status));
        }
 
        if (op == DPLANE_OP_ROUTE_DELETE) {
@@ -2090,19 +2023,34 @@ static void rib_process_after(dplane_ctx_h ctx)
        }
 
        if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) {
-               /* Set nexthop FIB flags */
-               for (ALL_NEXTHOPS(re->ng, nexthop)) {
+               /* Update zebra nexthop FIB flag for each
+                * nexthop that was installed.
+                */
+               for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), ctx_nexthop)) {
+
+                       for (ALL_NEXTHOPS(re->ng, nexthop)) {
+                               if (nexthop_same(ctx_nexthop, nexthop))
+                                       break;
+                       }
+
+                       if (nexthop == NULL)
+                               continue;
+
                        if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
                                continue;
 
-                       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+                       if (CHECK_FLAG(ctx_nexthop->flags,
+                                      NEXTHOP_FLAG_FIB))
                                SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                        else
                                UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                }
 
-               if (zvrf)
+               if (zvrf) {
                        zvrf->installs++;
+                       /* Set flag for nexthop tracking processing */
+                       zvrf->flags |= ZEBRA_VRF_RIB_SCHEDULED;
+               }
 
                /* Redistribute */
                /* TODO -- still calling the redist api using the route_entries,
@@ -2179,9 +2127,9 @@ static unsigned int process_subq(struct list *subq, uint8_t qindex)
 }
 
 /*
- * All meta queues have been processed. Trigger next-hop evaluation.
+ * Perform next-hop tracking processing after RIB updates.
  */
-static void meta_queue_process_complete(struct work_queue *dummy)
+static void do_nht_processing(void)
 {
        struct vrf *vrf;
        struct zebra_vrf *zvrf;
@@ -2196,6 +2144,10 @@ static void meta_queue_process_complete(struct work_queue *dummy)
                if (zvrf == NULL || !(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED))
                        continue;
 
+               if (IS_ZEBRA_DEBUG_RIB_DETAILED || IS_ZEBRA_DEBUG_NHT)
+                       zlog_debug("NHT processing check for zvrf %s",
+                                  zvrf_name(zvrf));
+
                zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED;
                zebra_evaluate_rnh(zvrf, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL);
                zebra_evaluate_rnh(zvrf, AF_INET, 0, RNH_IMPORT_CHECK_TYPE,
@@ -2217,6 +2169,14 @@ static void meta_queue_process_complete(struct work_queue *dummy)
        }
 }
 
+/*
+ * All meta queues have been processed. Trigger next-hop evaluation.
+ */
+static void meta_queue_process_complete(struct work_queue *dummy)
+{
+       do_nht_processing();
+}
+
 /* Dispatch the meta queue by picking, processing and unlocking the next RN from
  * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and
  * data
@@ -2226,6 +2186,22 @@ static wq_item_status meta_queue_process(struct work_queue *dummy, void *data)
 {
        struct meta_queue *mq = data;
        unsigned i;
+       uint32_t queue_len, queue_limit;
+
+       /* Ensure there's room for more dataplane updates */
+       queue_limit = dplane_get_in_queue_limit();
+       queue_len = dplane_get_in_queue_len();
+       if (queue_len > queue_limit) {
+               if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+                       zlog_debug("rib queue: dplane queue len %u, limit %u, retrying",
+                                  queue_len, queue_limit);
+
+               /* Ensure that the meta-queue is actually enqueued */
+               if (work_queue_empty(zebrad.ribq))
+                       work_queue_add(zebrad.ribq, zebrad.mq);
+
+               return WQ_QUEUE_BLOCKED;
+       }
 
        for (i = 0; i < MQ_SIZE; i++)
                if (process_subq(mq->subq[i], i)) {
@@ -3205,7 +3181,7 @@ void rib_sweep_route(void)
                rib_sweep_table(zvrf->table[AFI_IP6][SAFI_UNICAST]);
        }
 
-       zebra_ns_sweep_route();
+       zebra_router_sweep_route();
 }
 
 /* Remove specific by protocol routes from 'table'. */
@@ -3247,7 +3223,7 @@ unsigned long rib_score_proto(uint8_t proto, unsigned short instance)
                                         proto, instance,
                                         zvrf->table[AFI_IP6][SAFI_UNICAST]);
 
-       cnt += zebra_ns_score_proto(proto, instance);
+       cnt += zebra_router_score_proto(proto, instance);
 
        return cnt;
 }
@@ -3271,8 +3247,10 @@ void rib_close_table(struct route_table *table)
                        if (info->safi == SAFI_UNICAST)
                                hook_call(rib_update, rn, NULL);
 
-                       if (!RIB_SYSTEM_ROUTE(dest->selected_fib))
+                       if (!RIB_SYSTEM_ROUTE(dest->selected_fib)) {
                                rib_uninstall_kernel(rn, dest->selected_fib);
+                               dest->selected_fib = NULL;
+                       }
                }
        }
 }
@@ -3282,7 +3260,7 @@ void rib_close_table(struct route_table *table)
  */
 static int rib_process_dplane_results(struct thread *thread)
 {
-       dplane_ctx_h ctx;
+       struct zebra_dplane_ctx *ctx;
 
        do {
                /* Take lock controlling queue of results */
@@ -3300,15 +3278,18 @@ static int rib_process_dplane_results(struct thread *thread)
 
        } while (1);
 
+       /* Check for nexthop tracking processing after finishing with results */
+       do_nht_processing();
+
        return 0;
 }
 
 /*
  * Results are returned from the dataplane subsystem, in the context of
- * the dataplane thread. We enqueue the results here for processing by
+ * the dataplane pthread. We enqueue the results here for processing by
  * the main thread later.
  */
-static int rib_dplane_results(dplane_ctx_h ctx)
+static int rib_dplane_results(const struct zebra_dplane_ctx *ctx)
 {
        /* Take lock controlling queue of results */
        pthread_mutex_lock(&dplane_mutex);