From: Maria Matejka Date: Tue, 31 May 2022 10:51:34 +0000 (+0200) Subject: Merge commit '4fe9881d625f10e44109a649e369a413bd98de71' into haugesund X-Git-Tag: v3.0-alpha1~171^2~49 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ea109ce3e3474dd10d7592c44d2371b794f5c867;p=thirdparty%2Fbird.git Merge commit '4fe9881d625f10e44109a649e369a413bd98de71' into haugesund --- ea109ce3e3474dd10d7592c44d2371b794f5c867 diff --cc lib/route.h index 1ade1a817,3ce8021dc..613df0c38 --- a/lib/route.h +++ b/lib/route.h @@@ -329,13 -328,9 +330,9 @@@ extern struct ea_class ea_gen_from /* Source: An old method to devise the route source protocol and kind. * To be superseded in a near future by something more informative. */ extern struct ea_class ea_gen_source; -static inline u32 rt_get_source_attr(rte *rt) +static inline u32 rt_get_source_attr(const rte *rt) { return ea_get_int(rt->attrs->eattrs, &ea_gen_source, 0); } - /* MPLS labels: Use with a recursive nexthop specification - * to add additional labels to the resolved nexthop */ - extern struct ea_class ea_mpls_labels; - /* Next hop: For now, stored as adata */ extern struct ea_class ea_gen_nexthop; diff --cc nest/rt-table.c index d43305c99,d98f33e4d..8677c177d --- a/nest/rt-table.c +++ b/nest/rt-table.c @@@ -121,45 -121,11 +121,47 @@@ static void rt_free_hostcache(rtable *t static void rt_notify_hostcache(rtable *tab, net *net); static void rt_update_hostcache(rtable *tab); static void rt_next_hop_update(rtable *tab); ++static inline void rt_next_hop_resolve_rte(rte *r); static inline void rt_prune_table(rtable *tab); static inline void rt_schedule_notify(rtable *tab); static void rt_flowspec_notify(rtable *tab, net *net); -static inline rte *rt_next_hop_update_rte(rtable *tab, rte *old); +static void rt_feed_channel(void *); + +const char *rt_import_state_name_array[TIS_MAX] = { + [TIS_DOWN] = "DOWN", + [TIS_UP] = "UP", + [TIS_STOP] = "STOP", + [TIS_FLUSHING] = "FLUSHING", + [TIS_WAITING] = "WAITING", + [TIS_CLEARED] = "CLEARED", +}; + +const char *rt_export_state_name_array[TES_MAX] = { + [TES_DOWN] = "DOWN", + [TES_HUNGRY] = "HUNGRY", + [TES_FEEDING] = "FEEDING", + [TES_READY] = "READY", + [TES_STOP] = "STOP" +}; + +const char *rt_import_state_name(u8 state) +{ + if (state >= TIS_MAX) + return "!! INVALID !!"; + else + return rt_import_state_name_array[state]; +} + +const char *rt_export_state_name(u8 state) +{ + if (state >= TES_MAX) + return "!! INVALID !!"; + else + return rt_export_state_name_array[state]; +} + - ++static inline struct rte_storage *rt_next_hop_update_rte(rtable *tab, net *n, rte *old); + static struct hostentry *rt_get_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep); static void net_init_with_trie(struct fib *f, void *N) @@@ -1550,60 -1573,91 +1552,65 @@@ rte_update_direct(struct channel *c, co rte_update_lock(); if (new) { - /* Create a temporary table node */ - nn = alloca(sizeof(net) + n->length); - memset(nn, 0, sizeof(net) + n->length); - net_copy(nn->n.addr, n); - - new->net = nn; - new->sender = c; - - stats->imp_updates_received++; - if (filter == FILTER_REJECT) - { - stats->imp_updates_filtered++; - rte_trace_in(D_FILTERS, c, new, "filtered out"); + new->net = n; - if (! c->in_keep_filtered) - goto drop; + int fr; - /* new is a private copy, i could modify it */ - new->flags |= REF_FILTERED; - } - else if (filter) + stats->updates_received++; - if (!rte_validate(c, new)) - { - channel_rte_trace_in(D_FILTERS, c, new, "invalid"); - stats->updates_invalid++; - new = NULL; - } - else if ((filter == FILTER_REJECT) || ++ if ((filter == FILTER_REJECT) || + ((fr = f_run(filter, new, 0)) > F_ACCEPT)) { - int fr = f_run(filter, &new, 0); - if (fr > F_ACCEPT) - { - stats->imp_updates_filtered++; - rte_trace_in(D_FILTERS, c, new, "filtered out"); - - if (! c->in_keep_filtered) - goto drop; + stats->updates_filtered++; + channel_rte_trace_in(D_FILTERS, c, new, "filtered out"); + if (c->in_keep_filtered) new->flags |= REF_FILTERED; - } + else + new = NULL; } + - rte *new_resolved = rt_next_hop_update_rte(c->table, new); - if (new_resolved) - { - rte_free(new); - new = new_resolved; - } ++ if (new) ++ rt_next_hop_resolve_rte(new); + - /* After all checks, updates and filters have been done, - * validate the route */ - if (!rte_validate(new)) ++ if (new && !rte_validate(c, new)) + { - rte_trace_in(D_FILTERS, c, new, "invalid"); - stats->imp_updates_invalid++; - goto drop; ++ channel_rte_trace_in(D_FILTERS, c, new, "invalid"); ++ stats->updates_invalid++; ++ new = NULL; + } + - if (!rta_is_cached(new->attrs)) /* Need to copy attributes */ - new->attrs = rta_lookup(new->attrs); - new->flags |= REF_COW; - - /* Use the actual struct network, not the dummy one */ - nn = net_get(c->table, n); - new->net = nn; } else - { - stats->imp_withdraws_received++; - - if (!(nn = net_find(c->table, n)) || !src) - { - stats->imp_withdraws_ignored++; - rte_update_unlock(); - return; - } - } + stats->withdraws_received++; - recalc: - /* And recalculate the best route */ - rte_recalculate(c, nn, new, src); + rte_import(&c->in_req, n, new, src); rte_update_unlock(); - return; +} - drop: - rte_free(new); - new = NULL; - if (nn = net_find(c->table, n)) - goto recalc; +void +rte_import(struct rt_import_request *req, const net_addr *n, rte *new, struct rte_src *src) +{ + struct rt_import_hook *hook = req->hook; + if (!hook) + return; - rte_update_unlock(); + net *nn; + if (new) + { + /* Use the actual struct network, not the dummy one */ + nn = net_get(hook->table, n); + new->net = nn->n.addr; + new->sender = hook; + } + else if (!(nn = net_find(hook->table, n))) + { + req->hook->stats.withdraws_ignored++; + return; + } + + /* And recalculate the best route */ + rte_recalculate(hook, nn, new, src); } /* Independent call to rte_announce(), used from next hop @@@ -2598,45 -2508,48 +2620,65 @@@ rta_apply_hostentry(rta *a, struct host &ea_gen_nexthop, 0, &new->ad)); } - static inline int + static inline struct hostentry_adata * rta_next_hop_outdated(rta *a) { - struct hostentry *he = a->hostentry; + eattr *heea = ea_find(a->eattrs, &ea_gen_hostentry); + if (!heea) + return NULL; - if (!he) - return 0; + struct hostentry_adata *head = (struct hostentry_adata *) heea->u.ptr; - if (!he->src) - return a->dest != RTD_UNREACHABLE; + if (!head->he->src) + return (a->dest != RTD_UNREACHABLE) ? head : NULL; - eattr *he_nh_ea = ea_find(he->src->eattrs, &ea_gen_nexthop); + eattr *he_nh_ea = ea_find(head->he->src->eattrs, &ea_gen_nexthop); eattr *a_nh_ea = ea_find(a->eattrs, &ea_gen_nexthop); - return (a->dest != he->dest) || - (ea_get_int(a->eattrs, &ea_gen_igp_metric, IGP_METRIC_UNKNOWN) != he->igp_metric) || - (!he->nexthop_linkable) || - (!he_nh_ea != !a_nh_ea) || - (he_nh_ea && a_nh_ea && !adata_same(he_nh_ea->u.ptr, a_nh_ea->u.ptr)); + return ((a->dest != head->he->dest) || + (ea_get_int(a->eattrs, &ea_gen_igp_metric, IGP_METRIC_UNKNOWN) != head->he->igp_metric) || + (!head->he->nexthop_linkable) || + (!he_nh_ea != !a_nh_ea) || + (he_nh_ea && a_nh_ea && !adata_same(he_nh_ea->u.ptr, a_nh_ea->u.ptr))) + ? head : NULL; } -static inline rte * -rt_next_hop_update_rte(rtable *tab UNUSED, rte *old) +static inline struct rte_storage * +rt_next_hop_update_rte(rtable *tab, net *n, rte *old) { - if (!rta_next_hop_outdated(old->attrs)) + struct hostentry_adata *head = rta_next_hop_outdated(old->attrs); + if (!head) return NULL; - rta *a = alloca(RTA_MAX_SIZE); - memcpy(a, old->attrs, rta_size(old->attrs)); - - rta_apply_hostentry(a, old->attrs->hostentry); - a->cached = 0; + rta a = *old->attrs; + a.cached = 0; + rta_apply_hostentry(&a, head); - rte *e = sl_alloc(rte_slab); - memcpy(e, old, sizeof(rte)); - e->attrs = rta_lookup(&a); - rt_lock_source(e->src); + rte e0 = *old; - e0.attrs = a; ++ e0.attrs = &a; - return e; + return rte_store(&e0, n, tab); } ++static inline void ++rt_next_hop_resolve_rte(rte *r) ++{ ++ eattr *heea = ea_find(r->attrs->eattrs, &ea_gen_hostentry); ++ if (!heea) ++ return; ++ ++ struct hostentry_adata *head = (struct hostentry_adata *) heea->u.ptr; ++ ++ if (r->attrs->cached) ++ { ++ rta *a = tmp_alloc(RTA_MAX_SIZE); ++ *a = *r->attrs; ++ a->cached = 0; ++ r->attrs = a; ++ } ++ ++ rta_apply_hostentry(r->attrs, head); ++} #ifdef CONFIG_BGP @@@ -3581,11 -3533,11 +3623,11 @@@ rt_update_hostentry(rtable *tab, struc net *n = net_route(tab, &he_addr); if (n) { - rte *e = n->routes; - rta *a = e->attrs; + struct rte_storage *e = n->routes; + rta *a = e->rte.attrs; pxlen = n->n.addr->pxlen; - if (a->hostentry) + if (ea_find(a->eattrs, &ea_gen_hostentry)) { /* Recursive route should not depend on another recursive route */ log(L_WARN "Next hop address %I resolvable through recursive route for %N", diff --cc proto/pipe/pipe.c index b99df434f,e458a238b..e122d7715 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@@ -62,18 -75,26 +62,19 @@@ pipe_rt_notify(struct proto *P, struct memcpy(a, new->attrs, rta_size(new->attrs)); a->cached = 0; - a->hostentry = NULL; + ea_unset_attr(&a->eattrs, 0, &ea_gen_hostentry); + - e = rte_get_temp(a, src); - e->pflags = new->pflags; -#ifdef CONFIG_BGP - /* Hack to cleanup cached value */ - if (e->src->proto->proto == &proto_bgp) - e->pflags &= ~(BGP_REF_STALE | BGP_REF_NOT_STALE); -#endif + rte e0 = { + .attrs = a, + .src = new->src, + .generation = new->generation + 1, + }; + + rte_update(dst, n, &e0, new->src); } else - { - e = NULL; - src = old->src; - } - - src_ch->table->pipe_busy = 1; - rte_update2(dst, n->n.addr, e, src); - src_ch->table->pipe_busy = 0; + rte_update(dst, n, NULL, old->src); } static int