summaryrefslogtreecommitdiff
path: root/proto/static/static.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto/static/static.c')
-rw-r--r--proto/static/static.c78
1 files changed, 41 insertions, 37 deletions
diff --git a/proto/static/static.c b/proto/static/static.c
index 2789c1bb..d89ca8b0 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -52,14 +52,18 @@ static linpool *static_lp;
static inline struct rte_src * static_get_source(struct static_proto *p, uint i)
{ return i ? rt_get_source(&p->p, i) : p->p.main_source; }
+static inline void static_free_source(struct rte_src *src, uint i)
+{ if (i) rt_unlock_source(src); }
+
static void
static_announce_rte(struct static_proto *p, struct static_route *r)
{
+ struct rte_src *src;
rta *a = allocz(RTA_MAX_SIZE);
- a->src = static_get_source(p, r->index);
a->source = RTS_STATIC;
a->scope = SCOPE_UNIVERSE;
a->dest = r->dest;
+ a->pref = p->p.main_channel->preference;
if (r->dest == RTD_UNICAST)
{
@@ -94,7 +98,7 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
if (r->dest == RTDX_RECURSIVE)
{
rtable *tab = ipa_is_ip4(r->via) ? p->igp_table_ip4 : p->igp_table_ip6;
- rta_set_recursive_next_hop(p->p.main_channel->table, a, tab, r->via, IPA_NONE, r->mls);
+ rta_set_recursive_next_hop(p->p.main_channel->table, a, tab, r->via, IPA_NONE, r->mls, static_lp);
}
/* Already announced */
@@ -102,24 +106,16 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
return;
/* We skip rta_lookup() here */
- rte *e = rte_get_temp(a);
- e->pflags = 0;
+ src = static_get_source(p, r->index);
+ rte e0 = { .attrs = a, .src = src, .net = r->net, }, *e = &e0;
+ /* Evaluate the filter */
if (r->cmds)
- {
- /* Create a temporary table node */
- e->net = alloca(sizeof(net) + r->net->length);
- memset(e->net, 0, sizeof(net) + r->net->length);
- net_copy(e->net->n.addr, r->net);
+ f_eval_rte(r->cmds, e, static_lp);
- /* Evaluate the filter */
- f_eval_rte(r->cmds, &e, static_lp);
+ rte_update(p->p.main_channel, r->net, e, src);
+ static_free_source(src, r->index);
- /* Remove the temporary node */
- e->net = NULL;
- }
-
- rte_update2(p->p.main_channel, r->net, e, a->src);
r->state = SRS_CLEAN;
if (r->cmds)
@@ -131,7 +127,9 @@ withdraw:
if (r->state == SRS_DOWN)
return;
- rte_update2(p->p.main_channel, r->net, NULL, a->src);
+ src = static_get_source(p, r->index);
+ rte_update(p->p.main_channel, r->net, NULL, src);
+ static_free_source(src, r->index);
r->state = SRS_DOWN;
}
@@ -208,7 +206,7 @@ static_update_bfd(struct static_proto *p, struct static_route *r)
// ip_addr local = ipa_nonzero(r->local) ? r->local : nb->ifa->ip;
r->bfd_req = bfd_request_session(p->p.pool, r->via, nb->ifa->ip,
nb->iface, p->p.vrf,
- static_bfd_notify, r, NULL);
+ static_bfd_notify, r, birdloop_event_list(p->p.loop), NULL);
}
if (!bfd_up && r->bfd_req)
@@ -297,7 +295,11 @@ static void
static_remove_rte(struct static_proto *p, struct static_route *r)
{
if (r->state)
- rte_update2(p->p.main_channel, r->net, NULL, static_get_source(p, r->index));
+ {
+ struct rte_src *src = static_get_source(p, r->index);
+ rte_update(p->p.main_channel, r->net, NULL, src);
+ static_free_source(src, r->index);
+ }
static_reset_rte(p, r);
}
@@ -454,6 +456,8 @@ static_postconfig(struct proto_config *CF)
static_index_routes(cf);
}
+static struct rte_owner_class static_rte_owner_class;
+
static struct proto *
static_init(struct proto_config *CF)
{
@@ -465,8 +469,7 @@ static_init(struct proto_config *CF)
P->neigh_notify = static_neigh_notify;
P->reload_routes = static_reload_routes;
- P->rte_better = static_rte_better;
- P->rte_mergable = static_rte_mergable;
+ P->sources.class = &static_rte_owner_class;
if (cf->igp_table_ip4)
p->igp_table_ip4 = cf->igp_table_ip4->table;
@@ -488,10 +491,12 @@ static_start(struct proto *P)
static_lp = lp_new(&root_pool, LP_GOOD_SIZE(1024));
if (p->igp_table_ip4)
- rt_lock_table(p->igp_table_ip4);
+ RT_LOCKED(p->igp_table_ip4, t)
+ rt_lock_table(t);
if (p->igp_table_ip6)
- rt_lock_table(p->igp_table_ip6);
+ RT_LOCKED(p->igp_table_ip6, t)
+ rt_lock_table(t);
p->event = ev_new_init(p->p.pool, static_announce_marked, p);
@@ -517,19 +522,15 @@ static_shutdown(struct proto *P)
WALK_LIST(r, cf->routes)
static_reset_rte(p, r);
- return PS_DOWN;
-}
-
-static void
-static_cleanup(struct proto *P)
-{
- struct static_proto *p = (void *) P;
-
if (p->igp_table_ip4)
- rt_unlock_table(p->igp_table_ip4);
+ RT_LOCKED(p->igp_table_ip4, t)
+ rt_unlock_table(t);
if (p->igp_table_ip6)
- rt_unlock_table(p->igp_table_ip6);
+ RT_LOCKED(p->igp_table_ip6, t)
+ rt_unlock_table(t);
+
+ return PS_DOWN;
}
static void
@@ -721,9 +722,9 @@ static_get_route_info(rte *rte, byte *buf)
{
eattr *a = ea_find(rte->attrs->eattrs, EA_GEN_IGP_METRIC);
if (a)
- buf += bsprintf(buf, " (%d/%u)", rte->pref, a->u.data);
+ buf += bsprintf(buf, " (%d/%u)", rte->attrs->pref, a->u.data);
else
- buf += bsprintf(buf, " (%d)", rte->pref);
+ buf += bsprintf(buf, " (%d)", rte->attrs->pref);
}
static void
@@ -773,6 +774,11 @@ static_show(struct proto *P)
static_show_rt(r);
}
+static struct rte_owner_class static_rte_owner_class = {
+ .get_route_info = static_get_route_info,
+ .rte_better = static_rte_better,
+ .rte_mergable = static_rte_mergable,
+};
struct protocol proto_static = {
.name = "Static",
@@ -787,8 +793,6 @@ struct protocol proto_static = {
.dump = static_dump,
.start = static_start,
.shutdown = static_shutdown,
- .cleanup = static_cleanup,
.reconfigure = static_reconfigure,
.copy_config = static_copy_config,
- .get_route_info = static_get_route_info,
};