#define _BIRD_ROUTE_H_
#include "lib/lists.h"
+#include "lib/tlists.h"
#include "lib/bitmap.h"
#include "lib/resource.h"
#include "lib/net.h"
list imports; /* Registered route importers */
struct rt_exporter exporter; /* Exporter API structure */
+ TLIST_STRUCT_DEF(rt_flowspec_link, struct rt_flowspec_link) flowspec_links; /* Links serving flowspec reload */
struct hmap id_map;
struct hostcache *hostcache;
struct rt_export_request req; /* Notifier */
};
-struct rt_flowspec_link {
- rtable *src;
- rtable *dst;
- u32 uc;
- struct rt_export_request req;
-};
-
#define rte_update channel_rte_import
/**
* rte_update - enter a new update to a routing table
tm_start_in(tab->prune_timer, gc_period, tab->loop);
}
+#define TLIST_PREFIX rt_flowspec_link
+#define TLIST_TYPE struct rt_flowspec_link
+#define TLIST_ITEM n
+#define TLIST_WANT_WALK
+#define TLIST_WANT_ADD_TAIL
+#define TLIST_DEFINED_BEFORE
+
+struct rt_flowspec_link {
+ TLIST_DEFAULT_NODE;
+ rtable *src;
+ rtable *dst;
+ u32 uc;
+ struct rt_export_request req;
+};
+
+#include "lib/tlists.h"
+
static void
rt_flowspec_export_one(struct rt_export_request *req, const net_addr *net, struct rt_pending_export *first)
static struct rt_flowspec_link *
rt_flowspec_find_link(struct rtable_private *src, rtable *dst)
{
- struct rt_export_hook *hook; node *n;
- WALK_LIST2(hook, n, src->exporter.hooks, n)
- switch (atomic_load_explicit(&hook->export_state, memory_order_acquire))
- {
- case TES_HUNGRY:
- case TES_FEEDING:
- case TES_READY:
- if (hook->req->export_one == rt_flowspec_export_one)
- {
- struct rt_flowspec_link *ln = SKIP_BACK(struct rt_flowspec_link, req, hook->req);
- if (ln->dst == dst)
- return ln;
- }
- }
+ WALK_TLIST(rt_flowspec_link, ln, &src->flowspec_links)
+ if (ln->dst == dst && ln->req.hook)
+ switch (atomic_load_explicit(&ln->req.hook->export_state, memory_order_acquire))
+ {
+ case TES_HUNGRY:
+ case TES_FEEDING:
+ case TES_READY:
+ return ln;
+ }
return NULL;
}
.log_state_change = rt_flowspec_log_state_change,
.export_one = rt_flowspec_export_one,
};
+ rt_flowspec_link_add_tail(&src->flowspec_links, ln);
rt_table_export_start_locked(src, &ln->req);
ASSERT(ln && (ln->uc > 0));
if (!--ln->uc)
+ {
+ rt_flowspec_link_rem_node(&t->flowspec_links, ln);
rt_stop_export(&ln->req, rt_flowspec_link_stopped);
+ }
}
birdloop_leave(dst->loop);