diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2023-08-22 15:28:05 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2023-08-22 15:28:05 +0200 |
commit | 5121101136cb80151a9361c63dc4822afeb44eef (patch) | |
tree | 2bcf923fe58bf38386ee4693882d5a09e9a40648 /nest | |
parent | d2dbe854631813eae9fbf3e264ced4460ea4c432 (diff) | |
parent | 4558adabfbbe3696156d20767168010d6238f434 (diff) |
Merge branch 'bmp'
Diffstat (limited to 'nest')
-rw-r--r-- | nest/proto.c | 6 | ||||
-rw-r--r-- | nest/protocol.h | 7 | ||||
-rw-r--r-- | nest/rt-table.c | 71 |
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; |