summaryrefslogtreecommitdiff
path: root/zebra/zebra_rib.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_rib.c')
-rw-r--r--zebra/zebra_rib.c125
1 files changed, 107 insertions, 18 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 6c499b77d7..32cfa4d04c 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -18,7 +18,7 @@
#include "sockunion.h"
#include "srcdest_table.h"
#include "table.h"
-#include "thread.h"
+#include "frrevent.h"
#include "vrf.h"
#include "workqueue.h"
#include "nexthop_group_private.h"
@@ -56,7 +56,7 @@ DEFINE_MTYPE_STATIC(ZEBRA, WQ_WRAPPER, "WQ wrapper");
* Event, list, and mutex for delivery of dataplane results
*/
static pthread_mutex_t dplane_mutex;
-static struct thread *t_dplane;
+static struct event *t_dplane;
static struct dplane_ctx_list_head rib_dplane_q;
DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason),
@@ -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,20 @@ 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);
+ }
+}
+
void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf)
{
enum meta_queue_indexes i;
@@ -3754,6 +3796,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 +4139,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 +4166,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,
@@ -4393,11 +4463,11 @@ static void rib_update_ctx_fini(struct rib_update_ctx **ctx)
XFREE(MTYPE_RIB_UPDATE_CTX, *ctx);
}
-static void rib_update_handler(struct thread *thread)
+static void rib_update_handler(struct event *thread)
{
struct rib_update_ctx *ctx;
- ctx = THREAD_ARG(thread);
+ ctx = EVENT_ARG(thread);
rib_update_handle_vrf_all(ctx->event, ZEBRA_ROUTE_ALL);
@@ -4408,20 +4478,39 @@ static void rib_update_handler(struct thread *thread)
* Thread list to ensure we don't schedule a ton of events
* if interfaces are flapping for instance.
*/
-static struct thread *t_rib_update_threads[RIB_UPDATE_MAX];
+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)
{
struct rib_update_ctx *ctx;
- if (thread_is_scheduled(t_rib_update_threads[event]))
+ if (event_is_scheduled(t_rib_update_threads[event]))
+ return;
+
+ if (zebra_router_in_shutdown())
return;
ctx = rib_update_ctx_init(0, event);
- thread_add_event(zrouter.master, rib_update_handler, ctx, 0,
- &t_rib_update_threads[event]);
+ event_add_event(zrouter.master, rib_update_handler, ctx, 0,
+ &t_rib_update_threads[event]);
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("%s: Scheduled VRF (ALL), event %s", __func__,
@@ -4494,7 +4583,7 @@ void rib_sweep_table(struct route_table *table)
}
/* Sweep all RIB tables. */
-void rib_sweep_route(struct thread *t)
+void rib_sweep_route(struct event *t)
{
struct vrf *vrf;
struct zebra_vrf *zvrf;
@@ -4606,7 +4695,7 @@ static void handle_pw_result(struct zebra_dplane_ctx *ctx)
* Handle results from the dataplane system. Dequeue update context
* structs, dispatch to appropriate internal handlers.
*/
-static void rib_process_dplane_results(struct thread *thread)
+static void rib_process_dplane_results(struct event *thread)
{
struct zebra_dplane_ctx *ctx;
struct dplane_ctx_list_head ctxlist;
@@ -4793,8 +4882,8 @@ static int rib_dplane_results(struct dplane_ctx_list_head *ctxlist)
}
/* Ensure event is signalled to zebra main pthread */
- thread_add_event(zrouter.master, rib_process_dplane_results, NULL, 0,
- &t_dplane);
+ event_add_event(zrouter.master, rib_process_dplane_results, NULL, 0,
+ &t_dplane);
return 0;
}