]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_rib.c
tools: config clang-format to allow aligned macros
[mirror_frr.git] / zebra / zebra_rib.c
index 014b5126b5b3f82b9ab5558f66e220ef464fe1c0..adcaf640445fa3dc8b70df06e7dc2d7f35f2f0ae 100644 (file)
@@ -18,7 +18,7 @@
 #include "sockunion.h"
 #include "srcdest_table.h"
 #include "table.h"
-#include "event.h"
+#include "frrevent.h"
 #include "vrf.h"
 #include "workqueue.h"
 #include "nexthop_group_private.h"
@@ -64,7 +64,12 @@ DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason),
 DEFINE_HOOK(rib_shutdown, (struct route_node * rn), (rn));
 
 
-/* Meta Q's specific names */
+/*
+ * Meta Q's specific names
+ *
+ * If you add something here ensure that you
+ * change MQ_SIZE as well over in rib.h
+ */
 enum meta_queue_indexes {
        META_QUEUE_NHG,
        META_QUEUE_EVPN,
@@ -76,6 +81,7 @@ enum meta_queue_indexes {
        META_QUEUE_NOTBGP,
        META_QUEUE_BGP,
        META_QUEUE_OTHER,
+       META_QUEUE_GR_RUN,
 };
 
 /* Each route type's string and default distance value. */
@@ -250,6 +256,8 @@ static const char *subqueue2str(enum meta_queue_indexes index)
                return "BGP Routes";
        case META_QUEUE_OTHER:
                return "Other Routes";
+       case META_QUEUE_GR_RUN:
+               return "Graceful Restart";
        }
 
        return "Unknown";
@@ -632,7 +640,7 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re,
 {
        struct nexthop *nexthop;
        struct rib_table_info *info = srcdest_rnode_table_info(rn);
-       struct zebra_vrf *zvrf = vrf_info_lookup(re->vrf_id);
+       struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
        const struct prefix *p, *src_p;
        enum zebra_dplane_result ret;
 
@@ -715,7 +723,7 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re)
 {
        struct nexthop *nexthop;
        struct rib_table_info *info = srcdest_rnode_table_info(rn);
-       struct zebra_vrf *zvrf = vrf_info_lookup(re->vrf_id);
+       struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(re->vrf_id);
 
        if (info->safi != SAFI_UNICAST) {
                UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
@@ -1410,7 +1418,7 @@ static void rib_process(struct route_node *rn)
 static void zebra_rib_evaluate_mpls(struct route_node *rn)
 {
        rib_dest_t *dest = rib_dest_from_rnode(rn);
-       struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT);
+       struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
 
        if (!dest)
                return;
@@ -1898,7 +1906,7 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
        struct rib_table_info *info;
        bool rt_delete = false;
 
-       zvrf = vrf_info_lookup(dplane_ctx_get_vrf(ctx));
+       zvrf = zebra_vrf_lookup_by_id(dplane_ctx_get_vrf(ctx));
        vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx));
 
        /* Locate rn and re(s) from ctx */
@@ -2566,7 +2574,7 @@ static void process_subq_early_label(struct listnode *lnode)
        if (!w)
                return;
 
-       zvrf = vrf_info_lookup(w->vrf_id);
+       zvrf = zebra_vrf_lookup_by_id(w->vrf_id);
        if (!zvrf) {
                XFREE(MTYPE_WQ_WRAPPER, w);
                return;
@@ -3089,6 +3097,23 @@ static void process_subq_early_route(struct listnode *lnode)
                process_subq_early_route_add(ere);
 }
 
+struct meta_q_gr_run {
+       afi_t afi;
+       vrf_id_t vrf_id;
+       uint8_t proto;
+       uint8_t instance;
+};
+
+static void process_subq_gr_run(struct listnode *lnode)
+{
+       struct meta_q_gr_run *gr_run = listgetdata(lnode);
+
+       zebra_gr_process_client(gr_run->afi, gr_run->vrf_id, gr_run->proto,
+                               gr_run->instance);
+
+       XFREE(MTYPE_WQ_WRAPPER, gr_run);
+}
+
 /*
  * Examine the specified subqueue; process one entry and return 1 if
  * there is a node, return 0 otherwise.
@@ -3122,6 +3147,9 @@ static unsigned int process_subq(struct list *subq,
        case META_QUEUE_OTHER:
                process_subq_route(lnode, qindex);
                break;
+       case META_QUEUE_GR_RUN:
+               process_subq_gr_run(lnode);
+               break;
        }
 
        list_delete_node(subq, lnode);
@@ -3727,6 +3755,23 @@ static void early_route_meta_queue_free(struct meta_queue *mq, struct list *l,
        }
 }
 
+static void rib_meta_queue_gr_run_free(struct meta_queue *mq, struct list *l,
+                                      struct zebra_vrf *zvrf)
+{
+       struct meta_q_gr_run *gr_run;
+       struct listnode *node, *nnode;
+
+       for (ALL_LIST_ELEMENTS(l, node, nnode, gr_run)) {
+               if (zvrf && zvrf->vrf->vrf_id != gr_run->vrf_id)
+                       continue;
+
+               XFREE(MTYPE_WQ_WRAPPER, gr_run);
+               node->data = NULL;
+               list_delete_node(l, node);
+               mq->size--;
+       }
+}
+
 void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf)
 {
        enum meta_queue_indexes i;
@@ -3754,6 +3799,9 @@ void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf)
                case META_QUEUE_OTHER:
                        rib_meta_queue_free(mq, mq->subq[i], zvrf);
                        break;
+               case META_QUEUE_GR_RUN:
+                       rib_meta_queue_gr_run_free(mq, mq->subq[i], zvrf);
+                       break;
                }
                if (!zvrf)
                        list_delete(&mq->subq[i]);
@@ -4094,6 +4142,17 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
        zlog_debug("%s: dump complete", straddr);
 }
 
+static int rib_meta_queue_gr_run_add(struct meta_queue *mq, void *data)
+{
+       listnode_add(mq->subq[META_QUEUE_GR_RUN], data);
+       mq->size++;
+
+       if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+               zlog_debug("Graceful Run adding");
+
+       return 0;
+}
+
 static int rib_meta_queue_early_route_add(struct meta_queue *mq, void *data)
 {
        struct zebra_early_route *ere = data;
@@ -4110,6 +4169,20 @@ static int rib_meta_queue_early_route_add(struct meta_queue *mq, void *data)
        return 0;
 }
 
+int rib_add_gr_run(afi_t afi, vrf_id_t vrf_id, uint8_t proto, uint8_t instance)
+{
+       struct meta_q_gr_run *gr_run;
+
+       gr_run = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(*gr_run));
+
+       gr_run->afi = afi;
+       gr_run->proto = proto;
+       gr_run->vrf_id = vrf_id;
+       gr_run->instance = instance;
+
+       return mq_add_handler(gr_run, rib_meta_queue_gr_run_add);
+}
+
 struct route_entry *zebra_rib_route_entry_new(vrf_id_t vrf_id, int type,
                                              uint8_t instance, uint32_t flags,
                                              uint32_t nhe_id,
@@ -4410,6 +4483,22 @@ static void rib_update_handler(struct event *thread)
  */
 static struct event *t_rib_update_threads[RIB_UPDATE_MAX];
 
+void rib_update_finish(void)
+{
+       int i;
+
+       for (i = RIB_UPDATE_KERNEL; i < RIB_UPDATE_MAX; i++) {
+               if (event_is_scheduled(t_rib_update_threads[i])) {
+                       struct rib_update_ctx *ctx;
+
+                       ctx = EVENT_ARG(t_rib_update_threads[i]);
+
+                       rib_update_ctx_fini(&ctx);
+                       EVENT_OFF(t_rib_update_threads[i]);
+               }
+       }
+}
+
 /* Schedule a RIB update event for all vrfs */
 void rib_update(enum rib_update_event event)
 {
@@ -4418,6 +4507,9 @@ void rib_update(enum rib_update_event event)
        if (event_is_scheduled(t_rib_update_threads[event]))
                return;
 
+       if (zebra_router_in_shutdown())
+               return;
+
        ctx = rib_update_ctx_init(0, event);
 
        event_add_event(zrouter.master, rib_update_handler, ctx, 0,