From: Maria Matejka Date: Wed, 18 Jun 2025 07:12:54 +0000 (+0200) Subject: some conceptual updates X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d4b1de28ff83bbdc4637631521e7a82648760d8;p=thirdparty%2Fbird.git some conceptual updates - the proto_attrs (i would rather name it route context because it's not actually protocol attributes but more like additional context for the route processing) needs to be a global attribute because it has to be accessible from the best route selection algorithm - we can't easily add an attribute to BGP and even that MPLS label stack is an abomination -> all the attribute numbers are public and reserved by IANA; this is not the problem in BIRD 3 ... so also the flags were quite bonkers - we shouldn't per-use the pointer argument for adata to point somewhere else, that argument is reinterpreted as adata and behaves _very_ weirdly - named the global attribute "route_context" but if you look at nest/rt-attr.c diff, that get_generic_attr() routine should also call ->format() routine (and we should find a way how to neatly write the whole attribute out to CLI) - moved rte_better and rte_recalculate to that attribute; not finished but from the diff you should be able to infer how to continue - kinda rule: if you write very long calls including typecasting, there is often a better way to do that, see bgp_get_route_context() --- diff --git a/nest/protocol.h b/nest/protocol.h index 68da8fd9e..5e276b5fc 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -238,8 +238,6 @@ struct proto { * rte_remove Called whenever a rte is removed from the routing table. */ - int (*rte_recalculate)(struct rtable *, struct network *, struct rte *, struct rte *, struct rte *); - int (*rte_better)(struct rte *, struct rte *); int (*rte_mergable)(struct rte *, struct rte *); struct rte * (*rte_modify)(struct rte *, struct linpool *); void (*rte_insert)(struct network *, struct rte *); diff --git a/nest/route.h b/nest/route.h index 41940fb92..92b4287f4 100644 --- a/nest/route.h +++ b/nest/route.h @@ -539,6 +539,7 @@ const char *ea_custom_name(uint ea); #define EA_MPLS_POLICY EA_CODE(PROTOCOL_NONE, 2) #define EA_MPLS_CLASS EA_CODE(PROTOCOL_NONE, 3) #define EA_ASPA_PROVIDERS EA_CODE(PROTOCOL_NONE, 4) +#define EA_ROUTE_CONTEXT EA_CODE(PROTOCOL_NONE, 5) #define EA_CODE_MASK 0xffff #define EA_CUSTOM_BIT 0x8000 @@ -561,7 +562,6 @@ const char *ea_custom_name(uint ea); #define EAF_TYPE_STRING 0x16 /* Text string */ #define EAF_EMBEDDED 0x01 /* Data stored in eattr.u.data (part of type spec) */ #define EAF_VAR_LENGTH 0x02 /* Attribute length is variable (part of type spec) */ -#define EAF_PROTO_ATTR_PTR 0x18 /* Pointer to bgp_proto_attributes */ typedef struct adata { uint length; /* Length of data */ @@ -691,6 +691,19 @@ ea_set_attr_data(ea_list **to, struct linpool *pool, uint id, uint flags, uint t ea_set_attr(to, pool, id, flags, type, (uintptr_t) a); } +struct rte_context { + uint proto_class; /* Actually enum protocol_class but we can't refer to it here */ + uint (*format)(const struct rte_context *, byte *buf); + int (*rte_recalculate)(const struct rte_context *, struct rtable *, struct network *, struct rte *, struct rte *, struct rte *); + int (*rte_better)(const struct rte_context *, struct rte *, struct rte *); +}; + +struct rte_ctx_adata { + adata ad; + struct rte_context *ctx; +}; + +const struct rte_context *rte_get_context(const rte *r); #define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*MPLS_MAX_LABEL_STACK) diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 7c49af174..b6dd11c64 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -852,6 +852,19 @@ get_generic_attr(const eattr *a, byte **buf, int buflen) *buf += int_set_format(a->u.ptr, ISF_NUMBERS, -1, *buf, end - *buf); return GA_FULL; + case EA_ROUTE_CONTEXT: + { + struct rte_ctx_adata *rcad = SKIP_BACK(struct rte_ctx_adata, ad, a->u.ptr); + if (!rcad->ctx->format) + return GA_HIDDEN; + + *buf += bsprintf(*buf, "route_context"); + *(*buf)++ = ':'; + *(*buf)++ = ' '; + *buf += rcad->ctx->format(rcad->ctx, *buf); + return GA_FULL; + } + default: return GA_UNKNOWN; } diff --git a/nest/rt-table.c b/nest/rt-table.c index 1be8a381d..73f1b60a6 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -558,8 +558,6 @@ rte_cow_rta(rte *r, linpool *lp) static int /* Actually better or at least as good as */ rte_better(rte *new, rte *old) { - int (*better)(rte *, rte *); - if (!rte_is_valid(old)) return 1; if (!rte_is_valid(new)) @@ -578,8 +576,11 @@ rte_better(rte *new, rte *old) */ return new->src->proto->proto > old->src->proto->proto; } - if (better = new->src->proto->rte_better) - return better(new, old); + + const struct rte_context *ctx = rte_get_context(new); + if (ctx && ctx->rte_better) + return ctx->rte_better(ctx, new, old); + return 0; } @@ -1319,10 +1320,11 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src) /* If routes are not sorted, find the best route and move it on the first position. There are several optimized cases. */ - if (src->proto->rte_recalculate && src->proto->rte_recalculate(table, net, new, old, old_best)) + const struct rte_context *ctx = rte_get_context(new); + if (ctx && ctx->rte_recalculate && ctx->rte_recalculate(ctx, table, net, new, old, old_best)) goto do_recalculate; - if (new && rte_better(new, old_best)) + if (new && rte_better(new, old_best)) { /* The first case - the new route is cleary optimal, we link it at the first position */ @@ -2692,8 +2694,9 @@ rt_next_hop_update_net(rtable *tab, net *n) /* Call a pre-comparison hook */ /* Not really an efficient way to compute this */ - if (e->src->proto->rte_recalculate) - e->src->proto->rte_recalculate(tab, n, new, e, NULL); + const struct rte_context *ctx = rte_get_context(e); + if (ctx && ctx->rte_recalculate) + ctx->rte_recalculate(ctx, tab, n, new, e, NULL); if (e != old_best) rte_free_quick(e); @@ -3495,6 +3498,17 @@ rt_get_igp_metric(rte *rt) return IGP_METRIC_UNKNOWN; } +const struct rte_context * +rte_get_context(const rte *r) +{ + if (r == NULL) + return NULL; + const eattr *a = ea_find(r->attrs->eattrs, EA_ROUTE_CONTEXT); + const adata *ad = a ? a->u.ptr : NULL; + const struct rte_ctx_adata *rca = ad ? SKIP_BACK(const struct rte_ctx_adata, ad, ad) : NULL; + return rca ? rca->ctx : NULL; +} + static int rt_update_hostentry(rtable *tab, struct hostentry *he) { diff --git a/proto/babel/babel.c b/proto/babel/babel.c index cc9bc7647..638bacfc1 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -2502,7 +2502,7 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net, } static int -babel_rte_better(struct rte *new, struct rte *old) +babel_rte_better(const struct rte_context *ctx UNUSED, struct rte *new, struct rte *old) { uint new_metric = ea_get_int(new->attrs->eattrs, EA_BABEL_METRIC, BABEL_INFINITY); uint old_metric = ea_get_int(old->attrs->eattrs, EA_BABEL_METRIC, BABEL_INFINITY); @@ -2547,9 +2547,11 @@ babel_init(struct proto_config *CF) P->if_notify = babel_if_notify; P->rt_notify = babel_rt_notify; P->preexport = babel_preexport; - P->rte_better = babel_rte_better; P->rte_igp_metric = babel_rte_igp_metric; + p->rte_ctx.proto_class = PROTOCOL_BABEL; + p->rte_ctx.rte_better = babel_rte_better; + return P; } diff --git a/proto/babel/babel.h b/proto/babel/babel.h index 7e070f2db..878241efc 100644 --- a/proto/babel/babel.h +++ b/proto/babel/babel.h @@ -180,6 +180,8 @@ struct babel_iface_config { struct babel_proto { struct proto p; + struct rte_context rte_ctx; + timer *timer; struct fib ip4_rtable; struct fib ip6_rtable; diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 52c54ef2e..e9851cc62 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -451,6 +451,9 @@ bgp_decode_as_path(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte int as_length = s->as4_session ? 4 : 2; int as_sets = s->allow_as_sets; struct bgp_proto_attributes *proto_attrs = s->proto_attrs; + if (!proto_attrs) + return; + int as_confed = proto_attrs->confederation && proto_attrs->is_interior; char err[128]; @@ -959,18 +962,6 @@ bgp_encode_mpls_label_stack(struct bgp_write_state *s, eattr *a, byte *buf UNUSE return 0; } -static int -bgp_encode_proto_attrs(struct bgp_write_state *s UNUSED, eattr *a UNUSED, byte *buf UNUSED, uint size UNUSED) -{ - return 0; -} - -static void -bgp_decode_proto_attrs(struct bgp_parse_state *s UNUSED, uint code UNUSED, uint flags UNUSED, byte *data UNUSED, uint len UNUSED, ea_list **to UNUSED) -{ - return; -} - static void bgp_decode_mpls_label_stack(struct bgp_parse_state *s, uint code UNUSED, uint flags UNUSED, byte *data UNUSED, uint len UNUSED, ea_list **to UNUSED) { @@ -1151,13 +1142,6 @@ static const struct bgp_attr_desc bgp_attr_table[] = { .encode = bgp_encode_u32, .decode = bgp_decode_otc, }, - [BA_PROTO_ATTRS] = { - .name = "bgp proto attrs", - .type = EAF_PROTO_ATTR_PTR, - .flags = BAF_OPERATIONAL, - .encode = bgp_encode_proto_attrs, - .decode = bgp_decode_proto_attrs, - }, [BA_MPLS_LABEL_STACK] = { .name = "mpls_label_stack", .type = EAF_TYPE_INT_SET, @@ -2007,7 +1991,7 @@ bgp_get_neighbor(rte *r) return as; /* If AS_PATH is not defined, we treat rte as locally originated */ - struct bgp_proto_attributes *p = (struct bgp_proto_attributes *) ea_find(r->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_PROTO_ATTRS))->u.ptr; + struct bgp_proto_attributes *p = (struct bgp_proto_attributes *) ea_find(r->attrs->eattrs, EA_ROUTE_CONTEXT)->u.ptr; return p->confederation ?: p->local_as; } @@ -2035,10 +2019,13 @@ rte_stale(rte *r) } int -bgp_rte_better(rte *new, rte *old) +bgp_rte_better(const struct rte_context *ctx, rte *new, rte *old) { - struct bgp_proto_attributes *new_bgp = (struct bgp_proto_attributes *) ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_PROTO_ATTRS))->u.ptr; - struct bgp_proto_attributes *old_bgp = (struct bgp_proto_attributes *) ea_find(old->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_PROTO_ATTRS))->u.ptr; + const struct bgp_proto_attributes *new_bgp = SKIP_BACK(const struct bgp_proto_attributes, bgp_rte_ctx, ctx); + const struct bgp_proto_attributes *old_bgp = bgp_get_route_context(old); + + ASSERT_DIE(old_bgp); /* This means that old is actually really a bgp route */ + eattr *x, *y; u32 n, o; @@ -2182,8 +2169,8 @@ bgp_rte_better(rte *new, rte *old) int bgp_rte_mergable(rte *pri, rte *sec) { - struct bgp_proto_attributes *pri_bgp = (struct bgp_proto_attributes *) ea_find(pri->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_PROTO_ATTRS))->u.ptr; - struct bgp_proto_attributes *sec_bgp = (struct bgp_proto_attributes *) ea_find(sec->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_PROTO_ATTRS))->u.ptr; + struct bgp_proto_attributes *pri_bgp = (struct bgp_proto_attributes *) ea_find(pri->attrs->eattrs, EA_ROUTE_CONTEXT)->u.ptr; + struct bgp_proto_attributes *sec_bgp = (struct bgp_proto_attributes *) ea_find(sec->attrs->eattrs, EA_ROUTE_CONTEXT)->u.ptr; eattr *x, *y; u32 p, s; @@ -2265,14 +2252,14 @@ same_group(rte *r, u32 lpref, u32 lasn) } static inline int -use_deterministic_med(rte *r) +use_deterministic_med(const rte *r) { - struct bgp_proto_attributes *pa = (struct bgp_proto_attributes *) ea_find(r->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_PROTO_ATTRS))->u.ptr; - return (pa->routes_proto == BGP_ROUTE) && pa->deterministic_med; + const struct bgp_proto_attributes *pa = bgp_get_route_context(r); + return pa && pa->deterministic_med; } int -bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best) +bgp_rte_recalculate(const struct rte_context *ctx, rtable *table, net *net, rte *new, rte *old, rte *old_best) { rte *r, *s; rte *key = new ? new : old; @@ -2316,8 +2303,8 @@ bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best) if (new && old && !same_group(old, lpref, lasn)) { int i1, i2; - i1 = bgp_rte_recalculate(table, net, NULL, old, old_best); - i2 = bgp_rte_recalculate(table, net, new, NULL, old_best); + i1 = bgp_rte_recalculate(ctx, table, net, NULL, old, old_best); + i2 = bgp_rte_recalculate(ctx, table, net, new, NULL, old_best); return i1 || i2; } @@ -2337,7 +2324,7 @@ bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best) old->pflags |= BGP_REF_SUPPRESSED; /* The fast case - replace not best with worse (or remove not best) */ - if (old_suppressed && !(new && bgp_rte_better(new, old))) + if (old_suppressed && !(new && bgp_rte_better(ctx, new, old))) return 0; } @@ -2347,7 +2334,7 @@ bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best) if (use_deterministic_med(s) && same_group(s, lpref, lasn)) { s->pflags |= BGP_REF_SUPPRESSED; - if (!r || bgp_rte_better(s, r)) + if (!r || bgp_rte_better(ctx, s, r)) r = s; } diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 84c273f41..ad6eca42f 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -2252,14 +2252,15 @@ bgp_init(struct proto_config *CF) P->reload_routes = bgp_reload_routes; P->feed_begin = bgp_feed_begin; P->feed_end = bgp_feed_end; - P->rte_better = bgp_rte_better; P->rte_mergable = bgp_rte_mergable; - P->rte_recalculate = cf->deterministic_med ? bgp_rte_recalculate : NULL; P->rte_modify = bgp_rte_modify_stale; P->rte_igp_metric = bgp_rte_igp_metric; + p->proto_attrs.bgp_rte_ctx.proto_class = PROTOCOL_BGP; + p->proto_attrs.bgp_rte_ctx.rte_better = bgp_rte_better; + p->proto_attrs.bgp_rte_ctx.rte_recalculate = cf->deterministic_med ? bgp_rte_recalculate : NULL; + p->cf = cf; - p->routes_proto = BGP_ROUTE; p->is_internal = (cf->local_as == cf->remote_as); p->is_interior = p->is_internal || cf->confederation_member; p->rs_client = cf->rs_client; diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 14f9f8f3b..e33f2dd2d 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -359,12 +359,8 @@ struct bgp_conn { uint hold_time, keepalive_time, send_hold_time; /* Times calculated from my and neighbor's requirements */ }; -enum route_proto { - BGP_ROUTE = 1, -}; - -#define BGP_PROTO_ATTRIBUTES \ - enum route_proto routes_proto; /* protocol enum (pointer to bgp_proto_attributes is given to route eattrs) */ \ +#define BGP_ROUTE_CONTEXT \ + struct rte_context bgp_rte_ctx; /* Type common header */ \ u32 local_as, remote_as; \ ip_addr local_ip, remote_ip; \ u32 local_id; /* BGP identifier of this router */ \ @@ -378,7 +374,7 @@ enum route_proto { /* from conf */ \ BGP_ROUTE_ATTRIBUTES\ -struct bgp_proto_attributes { BGP_PROTO_ATTRIBUTES }; +struct bgp_proto_attributes { BGP_ROUTE_CONTEXT }; struct bgp_proto { struct proto p; @@ -386,7 +382,7 @@ struct bgp_proto { const char *hostname; /* Hostname for this BGP protocol */ union { struct bgp_proto_attributes proto_attrs; - struct { BGP_PROTO_ATTRIBUTES; }; + struct { BGP_ROUTE_CONTEXT; }; }; u32 public_as; /* Externally visible ASN (local_as or confederation id) */ u8 start_state; /* Substates that partitions BS_START */ @@ -682,6 +678,14 @@ rte_resolvable(rte *rt) /* attrs.c */ +static inline const struct bgp_proto_attributes * +bgp_get_route_context(const rte *r) +{ + const struct rte_context *ctx = rte_get_context(r); + return (ctx && (ctx->proto_class == PROTOCOL_BGP)) ? + SKIP_BACK(struct bgp_proto_attributes, bgp_rte_ctx, ctx) : NULL; +} + static inline eattr * bgp_find_attr(ea_list *attrs, uint code) { @@ -729,9 +733,9 @@ void bgp_init_prefix_table(struct bgp_channel *c); void bgp_free_prefix_table(struct bgp_channel *c); void bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *bp); -int bgp_rte_better(struct rte *, struct rte *); +int bgp_rte_better(const struct rte_context *, struct rte *, struct rte *); int bgp_rte_mergable(rte *pri, rte *sec); -int bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best); +int bgp_rte_recalculate(const struct rte_context *, rtable *table, net *net, rte *new, rte *old, rte *old_best); struct rte *bgp_rte_modify_stale(struct rte *r, struct linpool *pool); u32 bgp_rte_igp_metric(struct rte *); void bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old); @@ -790,7 +794,6 @@ byte *bgp_create_end_mark_(struct bgp_channel *c, byte *buf); #define BAF_TRANSITIVE 0x40 #define BAF_PARTIAL 0x20 #define BAF_EXT_LEN 0x10 -#define BAF_OPERATIONAL 0x100 #define BAF_DECODE_FLAGS 0x0100 /* Private flag - attribute flags are handled by the decode hook */ @@ -812,7 +815,6 @@ byte *bgp_create_end_mark_(struct bgp_channel *c, byte *buf); #define BA_AIGP 0x1a /* RFC 7311 */ #define BA_LARGE_COMMUNITY 0x20 /* RFC 8092 */ #define BA_ONLY_TO_CUSTOMER 0x23 /* RFC 9234 */ -#define BA_PROTO_ATTRS 0x24 /* BGP_PROTO_ATTRIBUTES */ /* Bird's private internal BGP attributes */ #define BA_MPLS_LABEL_STACK 0xfe /* MPLS label stack transfer attribute */ diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 5b4cda16b..35a79bc32 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -2861,7 +2861,10 @@ bgp_parse_update(struct bgp_parse_state *s, byte *pkt, uint len, ea_list **ea) else *ea = NULL; - bgp_set_attr_ptr(ea, s->pool, BA_PROTO_ATTRS, 0, (adata*) s->proto_attrs); + struct rte_ctx_adata *rcad = lp_allocz(s->pool, sizeof *rcad); + rcad->ad.length = sizeof *rcad - sizeof rcad->ad; + rcad->ctx = &s->proto_attrs->bgp_rte_ctx; + ea_set_attr_ptr(ea, s->pool, EA_ROUTE_CONTEXT, 0, EAF_TYPE_OPAQUE, &rcad->ad); /* Check for End-of-RIB marker */ if (!s->attr_len && !s->ip_unreach_len && !s->ip_reach_len) diff --git a/proto/l3vpn/l3vpn.c b/proto/l3vpn/l3vpn.c index bd5fbdaf0..c6f7df954 100644 --- a/proto/l3vpn/l3vpn.c +++ b/proto/l3vpn/l3vpn.c @@ -311,7 +311,7 @@ l3vpn_metric(rte *e) } static int -l3vpn_rte_better(rte *new, rte *old) +l3vpn_rte_better(const struct rte_context * rtx UNUSED, rte *new, rte *old) { /* This is hack, we should have full BGP-style comparison */ return l3vpn_metric(new) < l3vpn_metric(old); @@ -360,7 +360,7 @@ l3vpn_init(struct proto_config *CF) P->rt_notify = l3vpn_rt_notify; P->preexport = l3vpn_preexport; P->reload_routes = l3vpn_reload_routes; - P->rte_better = l3vpn_rte_better; + p->rte_ctx.rte_better = l3vpn_rte_better; return P; } diff --git a/proto/l3vpn/l3vpn.h b/proto/l3vpn/l3vpn.h index 1cce28faa..bd57bf774 100644 --- a/proto/l3vpn/l3vpn.h +++ b/proto/l3vpn/l3vpn.h @@ -20,6 +20,7 @@ struct l3vpn_config { struct l3vpn_proto { struct proto p; + struct rte_context rte_ctx; struct channel *ip4_channel; struct channel *ip6_channel; struct channel *vpn4_channel; diff --git a/proto/mrt/mrt_load.h b/proto/mrt/mrt_load.h index 64391cc4a..0bddb526b 100644 --- a/proto/mrt/mrt_load.h +++ b/proto/mrt/mrt_load.h @@ -31,7 +31,7 @@ struct mrtload_proto { struct proto p; union { struct rte_class_config rte_class; - struct { BGP_PROTO_ATTRIBUTES }; + struct { BGP_ROUTE_CONTEXT }; }; struct mrt_table_dump_state *table_dump; diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index da29e6c4e..c105bbb20 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -109,7 +109,7 @@ static int ospf_preexport(struct channel *P, rte *new); static void ospf_reload_routes(struct channel *C); -static int ospf_rte_better(struct rte *new, struct rte *old); +static int ospf_rte_better(const struct rte_context * rcx UNUSED, struct rte *new, struct rte *old); static u32 ospf_rte_igp_metric(struct rte *rt); static void ospf_disp(timer *timer); @@ -375,15 +375,16 @@ ospf_init(struct proto_config *CF) P->reload_routes = ospf_reload_routes; P->feed_begin = ospf_feed_begin; P->feed_end = ospf_feed_end; - P->rte_better = ospf_rte_better; P->rte_igp_metric = ospf_rte_igp_metric; + struct ospf_proto *p = (void *) P; + p->rte_ctx.rte_better = ospf_rte_better; return P; } /* If new is better return 1 */ static int -ospf_rte_better(struct rte *new, struct rte *old) +ospf_rte_better(const struct rte_context * rcx UNUSED, struct rte *new, struct rte *old) { u32 new_metric1 = ea_get_int(new->attrs->eattrs, EA_OSPF_METRIC1, LSINFINITY); diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 4949f173f..7ba608b4a 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -213,6 +213,7 @@ struct ospf_iface_patt struct ospf_proto { struct proto p; + struct rte_context rte_ctx; timer *disp_timer; /* OSPF proto dispatcher */ uint tick; struct top_graph *gr; /* LSA graph */ diff --git a/proto/rip/rip.c b/proto/rip/rip.c index b70b6e8ec..a863a7660 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -1112,7 +1112,7 @@ rip_rte_igp_metric(struct rte *rt) } static int -rip_rte_better(struct rte *new, struct rte *old) +rip_rte_better(const struct rte_context * rtx UNUSED, struct rte *new, struct rte *old) { return rip_rte_igp_metric(new) < rip_rte_igp_metric(old); } @@ -1138,8 +1138,9 @@ rip_init(struct proto_config *CF) P->rt_notify = rip_rt_notify; P->neigh_notify = rip_neigh_notify; P->reload_routes = rip_reload_routes; - P->rte_better = rip_rte_better; P->rte_igp_metric = rip_rte_igp_metric; + struct rip_proto *p = (void *) P; + p->rte_ctx.rte_better = rip_rte_better; return P; } diff --git a/proto/rip/rip.h b/proto/rip/rip.h index f8713c4a7..eda07777c 100644 --- a/proto/rip/rip.h +++ b/proto/rip/rip.h @@ -90,6 +90,7 @@ struct rip_iface_config struct rip_proto { struct proto p; + struct rte_context rte_ctx; struct fib rtable; /* Internal routing table */ list iface_list; /* List of interfaces (struct rip_iface) */ slab *rte_slab; /* Slab for internal routes (struct rip_rte) */ diff --git a/proto/static/static.c b/proto/static/static.c index 65fdb701d..85b6c17d6 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -478,7 +478,7 @@ static_reload_routes(struct channel *C) } static int -static_rte_better(rte *new, rte *old) +static_rte_better(const struct rte_context * rtx UNUSED, rte *new, rte *old) { u32 n = ea_get_int(new->attrs->eattrs, EA_GEN_IGP_METRIC, IGP_METRIC_UNKNOWN); u32 o = ea_get_int(old->attrs->eattrs, EA_GEN_IGP_METRIC, IGP_METRIC_UNKNOWN); @@ -544,7 +544,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_ctx.rte_better = static_rte_better; P->rte_mergable = static_rte_mergable; if (cf->igp_table_ip4) diff --git a/proto/static/static.h b/proto/static/static.h index edd2dc228..a71a04acc 100644 --- a/proto/static/static.h +++ b/proto/static/static.h @@ -24,6 +24,7 @@ struct static_config { struct static_proto { struct proto p; + struct rte_context rte_ctx; struct event *event; /* Event for announcing updated routes */ BUFFER_(struct static_route *) marked; /* Routes marked for reannouncement */ int marked_all; /* All routes are marked */