summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2023-08-22 15:28:05 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2023-08-22 15:28:05 +0200
commit5121101136cb80151a9361c63dc4822afeb44eef (patch)
tree2bcf923fe58bf38386ee4693882d5a09e9a40648 /nest
parentd2dbe854631813eae9fbf3e264ced4460ea4c432 (diff)
parent4558adabfbbe3696156d20767168010d6238f434 (diff)
Merge branch 'bmp'
Diffstat (limited to 'nest')
-rw-r--r--nest/proto.c6
-rw-r--r--nest/protocol.h7
-rw-r--r--nest/rt-table.c71
3 files changed, 47 insertions, 37 deletions
diff --git a/nest/proto.c b/nest/proto.c
index 885a0b75..a5325705 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -179,6 +179,7 @@ proto_add_channel(struct proto *p, struct channel_config *cf)
c->merge_limit = cf->merge_limit;
c->in_keep_filtered = cf->in_keep_filtered;
c->rpki_reload = cf->rpki_reload;
+ c->bmp_hack = cf->bmp_hack;
c->channel_state = CS_DOWN;
c->export_state = ES_DOWN;
@@ -523,7 +524,7 @@ channel_setup_in_table(struct channel *c)
cf->addr_type = c->net_type;
cf->internal = 1;
- c->in_table = rt_setup(c->proto->pool, cf);
+ c->in_table = cf->table = rt_setup(c->proto->pool, cf);
c->reload_event = ev_new_init(c->proto->pool, channel_reload_loop, c);
}
@@ -574,7 +575,8 @@ channel_do_up(struct channel *c)
static void
channel_do_flush(struct channel *c)
{
- rt_schedule_prune(c->table);
+ if (!c->bmp_hack)
+ rt_schedule_prune(c->table);
c->gr_wait = 0;
if (c->gr_lock)
diff --git a/nest/protocol.h b/nest/protocol.h
index da6d434e..dad0b781 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -214,7 +214,6 @@ struct proto {
void (*if_notify)(struct proto *, unsigned flags, struct iface *i);
void (*ifa_notify)(struct proto *, unsigned flags, struct ifa *a);
void (*rt_notify)(struct proto *, struct channel *, struct network *net, struct rte *new, struct rte *old);
- void (*rte_update_in_notify)(struct channel *, const net_addr *, const struct rte *, const struct rte_src *);
void (*neigh_notify)(struct neighbor *neigh);
int (*preexport)(struct channel *, struct rte *rt);
void (*reload_routes)(struct channel *);
@@ -477,7 +476,8 @@ struct channel_class {
#endif
};
-extern struct channel_class channel_bgp;
+extern const struct channel_class channel_basic;
+extern const struct channel_class channel_bgp;
struct channel_config {
node n;
@@ -500,6 +500,7 @@ struct channel_config {
u8 merge_limit; /* Maximal number of nexthops for RA_MERGED */
u8 in_keep_filtered; /* Routes rejected in import filter are kept */
u8 rpki_reload; /* RPKI changes trigger channel reload */
+ u8 bmp_hack; /* No flush */
};
struct channel {
@@ -552,6 +553,7 @@ struct channel {
u8 reload_pending; /* Reloading and another reload is scheduled */
u8 refeed_pending; /* Refeeding and another refeed is scheduled */
u8 rpki_reload; /* RPKI changes trigger channel reload */
+ u8 bmp_hack; /* No flush */
struct rtable *out_table; /* Internal table for exported routes */
@@ -620,6 +622,7 @@ static inline struct channel_config *proto_cf_main_channel(struct proto_config *
struct channel *proto_find_channel_by_table(struct proto *p, struct rtable *t);
struct channel *proto_find_channel_by_name(struct proto *p, const char *n);
struct channel *proto_add_channel(struct proto *p, struct channel_config *cf);
+void proto_remove_channel(struct proto *p, struct channel *c);
int proto_configure_channel(struct proto *p, struct channel **c, struct channel_config *cf);
void channel_set_state(struct channel *c, uint state);
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 2b065032..23c4bbb2 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -2148,11 +2148,11 @@ rt_setup(pool *pp, struct rtable_config *cf)
init_list(&t->flowspec_links);
init_list(&t->subscribers);
+ hmap_init(&t->id_map, p, 1024);
+ hmap_set(&t->id_map, 0);
+
if (!(t->internal = cf->internal))
{
- hmap_init(&t->id_map, p, 1024);
- hmap_set(&t->id_map, 0);
-
t->rt_event = ev_new_init(p, rt_event, t);
t->prune_timer = tm_new_init(p, rt_prune_timer, t, 0, 0);
t->last_rt_change = t->gc_time = current_time();
@@ -3096,9 +3096,6 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
{
old->flags &= ~(REF_STALE | REF_DISCARD | REF_MODIFY);
- if (c->proto->rte_update_in_notify)
- c->proto->rte_update_in_notify(c, n, old, src);
-
return 1;
}
@@ -3111,28 +3108,15 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
/* Remove the old rte */
*pos = old->next;
- rte_free_quick(old);
tab->rt_count--;
-
break;
}
- if (!new)
- {
- if (!old)
- goto drop_withdraw;
-
- if (!net->routes)
- fib_delete(&tab->fib, net);
-
- if (c->proto->rte_update_in_notify)
- c->proto->rte_update_in_notify(c, n, NULL, src);
-
- return 1;
- }
+ if (!old && !new)
+ goto drop_withdraw;
struct channel_limit *l = &c->rx_limit;
- if (l->action && !old)
+ if (l->action && !old && new)
{
if (tab->rt_count >= l->limit)
channel_notify_limit(c, l, PLD_RX, tab->rt_count);
@@ -3147,18 +3131,39 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
}
}
- /* Insert the new rte */
- rte *e = rte_do_cow(new);
- e->flags |= REF_COW;
- e->net = net;
- e->sender = c;
- e->lastmod = current_time();
- e->next = *pos;
- *pos = e;
- tab->rt_count++;
+ if (new)
+ {
+ /* Insert the new rte */
+ rte *e = rte_do_cow(new);
+ e->flags |= REF_COW;
+ e->net = net;
+ e->sender = c;
+ e->lastmod = current_time();
+ e->next = *pos;
+ *pos = new = e;
+ tab->rt_count++;
- if (c->proto->rte_update_in_notify)
- c->proto->rte_update_in_notify(c, n, e, src);
+ if (!old)
+ {
+ new->id = hmap_first_zero(&tab->id_map);
+ hmap_set(&tab->id_map, new->id);
+ }
+ else
+ new->id = old->id;
+ }
+
+ rte_announce(tab, RA_ANY, net, new, old, NULL, NULL);
+
+ if (old)
+ {
+ if (!new)
+ hmap_clear(&tab->id_map, old->id);
+
+ rte_free_quick(old);
+ }
+
+ if (!net->routes)
+ fib_delete(&tab->fib, net);
return 1;