]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
some conceptual updates
authorMaria Matejka <mq@ucw.cz>
Wed, 18 Jun 2025 07:12:54 +0000 (09:12 +0200)
committerKaterina Kubecova <katerina.kubecova@nic.cz>
Thu, 19 Jun 2025 15:22:05 +0000 (17:22 +0200)
- 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()

19 files changed:
nest/protocol.h
nest/route.h
nest/rt-attr.c
nest/rt-table.c
proto/babel/babel.c
proto/babel/babel.h
proto/bgp/attrs.c
proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/packets.c
proto/l3vpn/l3vpn.c
proto/l3vpn/l3vpn.h
proto/mrt/mrt_load.h
proto/ospf/ospf.c
proto/ospf/ospf.h
proto/rip/rip.c
proto/rip/rip.h
proto/static/static.c
proto/static/static.h

index 68da8fd9ee7aaf7c927129873aaa95ba882f5c74..5e276b5fc285b8636c324984e7de399ae81e6d2c 100644 (file)
@@ -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 *);
index 41940fb922b619597cd8b654789acef7984dac8e..92b4287f453ee47216ca1d78ca1aad4a62419b0b 100644 (file)
@@ -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)
 
index 7c49af17474607c3d0fa9dd180aa6369b8ca6eaf..b6dd11c6442732aa8ff4536e3a3ef53d387cd9d9 100644 (file)
@@ -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;
   }
index 1be8a381d1591220b76551b4d578f6c95416ea11..73f1b60a6be4a2fba7e42bf464b43aa66d6f2eb0 100644 (file)
@@ -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)
 {
index cc9bc7647eed114b438eb836a9cd7ceac00ea0e5..638bacfc1118c46e5624c857a5b952a18a448924 100644 (file)
@@ -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;
 }
 
index 7e070f2dbb5f08ffecdec57329de3da9c1fae315..878241efc968353c2cb1e7abc83d18293367aced 100644 (file)
@@ -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;
index 52c54ef2e2c50d0a415fdbfa4a5556020429094e..e9851cc62f779aa0ba97ce6d585d4fb2ca1fa5e0 100644 (file)
@@ -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;
     }
 
index 84c273f410e167c7580df72052c3138aac43d7b2..ad6eca42f0d4a8d1c1c17c1249a1b7a8cdb7b475 100644 (file)
@@ -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;
index 14f9f8f3be846389032da332fb09490c1f8c7c79..e33f2dd2d4002d07ea1eca94cacf5318184b129f 100644 (file)
@@ -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 */
index 5b4cda16b8ff395b652b0d19707337b43b554dc6..35a79bc32d49e0ce6196e796c1b163942559b7d7 100644 (file)
@@ -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)
index bd5fbdaf00a43cb61cb9c92a62b8e016cc946b82..c6f7df954297a3a437e9b2aca9ecd9081140153d 100644 (file)
@@ -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;
 }
index 1cce28faacd84cd509fc4e36c0ab7747a2dde209..bd57bf77422d94eba1e00bf3aeba2000b0852292 100644 (file)
@@ -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;
index 64391cc4a1fb484183c110e1ccc1df826acd84c1..0bddb526b127cc37af6e3a42f4843f554db8e5f7 100644 (file)
@@ -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;
index da29e6c4e70fe75012f039ee9370b080bab90038..c105bbb208eb40bc018cb70094dc96287461b944 100644 (file)
 
 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);
 
index 4949f173f8fbbf38069c0603fea05410b3021066..7ba608b4a22d87558a2bb0ee465fe439effc1114 100644 (file)
@@ -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 */
index b70b6e8ec9c80c6997c1a047a57bff38bccab953..a863a76609ce3a846b8404198fbcb77ef0100266 100644 (file)
@@ -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;
 }
index f8713c4a76c72890ccb439ef25d84d2acecd83b9..eda07777c0a34f6d6709986ee8fac19d220ff70c 100644 (file)
@@ -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) */
index 65fdb701d0f1debcf72b08deacd20e549f7693ca..85b6c17d6a737820d1edd178617ac39b3d71bf71 100644 (file)
@@ -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)
index edd2dc228eb165a0f390d7d97253adbfec08ea07..a71a04acc12e8f43d6dc2cd1c51cf3088e66f885 100644 (file)
@@ -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 */