Merge commit '60880b539b8886f76961125d89a265c6e1112b7a' into haugesund
This commit is contained in:
commit
19e727a248
12 changed files with 41 additions and 293 deletions
|
@ -75,16 +75,6 @@ int reconfigure(struct proto *p, struct proto_config *c)
|
||||||
void dump(struct proto *p)
|
void dump(struct proto *p)
|
||||||
{ DUMMY; }
|
{ DUMMY; }
|
||||||
|
|
||||||
/**
|
|
||||||
* dump_attrs - dump protocol-dependent attributes
|
|
||||||
* @e: a route entry
|
|
||||||
*
|
|
||||||
* This hook dumps all attributes in the &rte which belong to this
|
|
||||||
* protocol to the debug output.
|
|
||||||
*/
|
|
||||||
void dump_attrs(rte *e)
|
|
||||||
{ DUMMY; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* start - request instance startup
|
* start - request instance startup
|
||||||
* @p: protocol instance
|
* @p: protocol instance
|
||||||
|
@ -227,36 +217,6 @@ void rt_notify(struct proto *p, net *net, rte *new, rte *old, ea_list *attrs)
|
||||||
void neigh_notify(neighbor *neigh)
|
void neigh_notify(neighbor *neigh)
|
||||||
{ DUMMY; }
|
{ DUMMY; }
|
||||||
|
|
||||||
/**
|
|
||||||
* make_tmp_attrs - convert embedded attributes to temporary ones
|
|
||||||
* @e: route entry
|
|
||||||
* @pool: linear pool to allocate attribute memory in
|
|
||||||
*
|
|
||||||
* This hook is called by the routing table functions if they need
|
|
||||||
* to convert the protocol attributes embedded directly in the &rte
|
|
||||||
* to temporary extended attributes in order to distribute them
|
|
||||||
* to other protocols or to filters. make_tmp_attrs() creates
|
|
||||||
* an &ea_list in the linear pool @pool, fills it with values of the
|
|
||||||
* temporary attributes and returns a pointer to it.
|
|
||||||
*/
|
|
||||||
ea_list *make_tmp_attrs(rte *e, struct linpool *pool)
|
|
||||||
{ DUMMY; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* store_tmp_attrs - convert temporary attributes to embedded ones
|
|
||||||
* @e: route entry
|
|
||||||
* @attrs: temporary attributes to be converted
|
|
||||||
*
|
|
||||||
* This hook is an exact opposite of make_tmp_attrs() -- it takes
|
|
||||||
* a list of extended attributes and converts them to attributes
|
|
||||||
* embedded in the &rte corresponding to this protocol.
|
|
||||||
*
|
|
||||||
* You must be prepared for any of the attributes being missing
|
|
||||||
* from the list and use default values instead.
|
|
||||||
*/
|
|
||||||
void store_tmp_attrs(rte *e, ea_list *attrs)
|
|
||||||
{ DUMMY; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* preexport - pre-filtering decisions before route export
|
* preexport - pre-filtering decisions before route export
|
||||||
* @p: protocol instance the route is going to be exported to
|
* @p: protocol instance the route is going to be exported to
|
||||||
|
|
|
@ -74,7 +74,6 @@ struct protocol {
|
||||||
struct proto * (*init)(struct proto_config *); /* Create new instance */
|
struct proto * (*init)(struct proto_config *); /* Create new instance */
|
||||||
int (*reconfigure)(struct proto *, struct proto_config *); /* Try to reconfigure instance, returns success */
|
int (*reconfigure)(struct proto *, struct proto_config *); /* Try to reconfigure instance, returns success */
|
||||||
void (*dump)(struct proto *); /* Debugging dump */
|
void (*dump)(struct proto *); /* Debugging dump */
|
||||||
void (*dump_attrs)(struct rte *); /* Dump protocol-dependent attributes */
|
|
||||||
int (*start)(struct proto *); /* Start the instance */
|
int (*start)(struct proto *); /* Start the instance */
|
||||||
int (*shutdown)(struct proto *); /* Stop the instance */
|
int (*shutdown)(struct proto *); /* Stop the instance */
|
||||||
void (*cleanup)(struct proto *); /* Called after shutdown when protocol became hungry/down */
|
void (*cleanup)(struct proto *); /* Called after shutdown when protocol became hungry/down */
|
||||||
|
@ -198,8 +197,6 @@ struct proto {
|
||||||
* ifa_notify Notify protocol about interface address changes.
|
* ifa_notify Notify protocol about interface address changes.
|
||||||
* rt_notify Notify protocol about routing table updates.
|
* rt_notify Notify protocol about routing table updates.
|
||||||
* neigh_notify Notify protocol about neighbor cache events.
|
* neigh_notify Notify protocol about neighbor cache events.
|
||||||
* make_tmp_attrs Add attributes to rta from from private attrs stored in rte. The route and rta MUST NOT be cached.
|
|
||||||
* store_tmp_attrs Store private attrs back to rte and undef added attributes. The route and rta MUST NOT be cached.
|
|
||||||
* preexport Called as the first step of the route exporting process.
|
* preexport Called as the first step of the route exporting process.
|
||||||
* It can decide whether the route shall be exported:
|
* It can decide whether the route shall be exported:
|
||||||
* -1 = reject,
|
* -1 = reject,
|
||||||
|
@ -216,8 +213,6 @@ struct proto {
|
||||||
void (*ifa_notify)(struct proto *, unsigned flags, struct ifa *a);
|
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 (*rt_notify)(struct proto *, struct channel *, struct network *net, struct rte *new, struct rte *old);
|
||||||
void (*neigh_notify)(struct neighbor *neigh);
|
void (*neigh_notify)(struct neighbor *neigh);
|
||||||
void (*make_tmp_attrs)(struct rte *rt, struct linpool *pool);
|
|
||||||
void (*store_tmp_attrs)(struct rte *rt, struct linpool *pool);
|
|
||||||
int (*preexport)(struct proto *, struct rte *rt);
|
int (*preexport)(struct proto *, struct rte *rt);
|
||||||
void (*reload_routes)(struct channel *);
|
void (*reload_routes)(struct channel *);
|
||||||
void (*feed_begin)(struct channel *, int initial);
|
void (*feed_begin)(struct channel *, int initial);
|
||||||
|
@ -236,7 +231,6 @@ struct proto {
|
||||||
|
|
||||||
int (*rte_recalculate)(struct rtable *, struct network *, struct rte *, struct rte *, struct rte *);
|
int (*rte_recalculate)(struct rtable *, struct network *, struct rte *, struct rte *, struct rte *);
|
||||||
int (*rte_better)(struct rte *, struct rte *);
|
int (*rte_better)(struct rte *, struct rte *);
|
||||||
int (*rte_same)(struct rte *, struct rte *);
|
|
||||||
int (*rte_mergable)(struct rte *, struct rte *);
|
int (*rte_mergable)(struct rte *, struct rte *);
|
||||||
struct rte * (*rte_modify)(struct rte *, struct linpool *);
|
struct rte * (*rte_modify)(struct rte *, struct linpool *);
|
||||||
void (*rte_insert)(struct network *, struct rte *);
|
void (*rte_insert)(struct network *, struct rte *);
|
||||||
|
@ -471,7 +465,6 @@ struct channel_class {
|
||||||
|
|
||||||
|
|
||||||
void (*dump)(struct proto *); /* Debugging dump */
|
void (*dump)(struct proto *); /* Debugging dump */
|
||||||
void (*dump_attrs)(struct rte *); /* Dump protocol-dependent attributes */
|
|
||||||
|
|
||||||
void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
|
void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
|
||||||
void (*get_route_info)(struct rte *, byte *buf); /* Get route information (for `show route' command) */
|
void (*get_route_info)(struct rte *, byte *buf); /* Get route information (for `show route' command) */
|
||||||
|
|
14
nest/route.h
14
nest/route.h
|
@ -262,14 +262,6 @@ typedef struct rte {
|
||||||
byte flags; /* Flags (REF_...) */
|
byte flags; /* Flags (REF_...) */
|
||||||
byte pflags; /* Protocol-specific flags */
|
byte pflags; /* Protocol-specific flags */
|
||||||
btime lastmod; /* Last modified */
|
btime lastmod; /* Last modified */
|
||||||
union { /* Protocol-dependent data (metrics etc.) */
|
|
||||||
#ifdef CONFIG_BGP
|
|
||||||
struct {
|
|
||||||
u8 suppressed; /* Used for deterministic MED comparison */
|
|
||||||
s8 stale; /* Route is LLGR_STALE, -1 if unknown */
|
|
||||||
} bgp;
|
|
||||||
#endif
|
|
||||||
} u;
|
|
||||||
} rte;
|
} rte;
|
||||||
|
|
||||||
#define REF_COW 1 /* Copy this rte on write */
|
#define REF_COW 1 /* Copy this rte on write */
|
||||||
|
@ -337,10 +329,6 @@ void rte_free(rte *);
|
||||||
rte *rte_do_cow(rte *);
|
rte *rte_do_cow(rte *);
|
||||||
static inline rte * rte_cow(rte *r) { return (r->flags & REF_COW) ? rte_do_cow(r) : r; }
|
static inline rte * rte_cow(rte *r) { return (r->flags & REF_COW) ? rte_do_cow(r) : r; }
|
||||||
rte *rte_cow_rta(rte *r, linpool *lp);
|
rte *rte_cow_rta(rte *r, linpool *lp);
|
||||||
void rte_init_tmp_attrs(struct rte *r, linpool *lp, uint max);
|
|
||||||
void rte_make_tmp_attr(struct rte *r, uint id, uint type, uintptr_t val);
|
|
||||||
void rte_make_tmp_attrs(struct rte **r, struct linpool *pool, struct rta **old_attrs);
|
|
||||||
uintptr_t rte_store_tmp_attr(struct rte *r, uint id);
|
|
||||||
void rt_dump(rtable *);
|
void rt_dump(rtable *);
|
||||||
void rt_dump_all(void);
|
void rt_dump_all(void);
|
||||||
int rt_feed_channel(struct channel *c);
|
int rt_feed_channel(struct channel *c);
|
||||||
|
@ -525,7 +513,6 @@ typedef struct eattr {
|
||||||
#define EA_CODE(proto,id) (((proto) << 8) | (id))
|
#define EA_CODE(proto,id) (((proto) << 8) | (id))
|
||||||
#define EA_ID(ea) ((ea) & 0xff)
|
#define EA_ID(ea) ((ea) & 0xff)
|
||||||
#define EA_PROTO(ea) ((ea) >> 8)
|
#define EA_PROTO(ea) ((ea) >> 8)
|
||||||
#define EA_ID_FLAG(ea) (1 << EA_ID(ea))
|
|
||||||
#define EA_CUSTOM(id) ((id) | EA_CUSTOM_BIT)
|
#define EA_CUSTOM(id) ((id) | EA_CUSTOM_BIT)
|
||||||
#define EA_IS_CUSTOM(ea) ((ea) & EA_CUSTOM_BIT)
|
#define EA_IS_CUSTOM(ea) ((ea) & EA_CUSTOM_BIT)
|
||||||
#define EA_CUSTOM_ID(ea) ((ea) & ~EA_CUSTOM_BIT)
|
#define EA_CUSTOM_ID(ea) ((ea) & ~EA_CUSTOM_BIT)
|
||||||
|
@ -587,7 +574,6 @@ typedef struct ea_list {
|
||||||
#define EALF_SORTED 1 /* Attributes are sorted by code */
|
#define EALF_SORTED 1 /* Attributes are sorted by code */
|
||||||
#define EALF_BISECT 2 /* Use interval bisection for searching */
|
#define EALF_BISECT 2 /* Use interval bisection for searching */
|
||||||
#define EALF_CACHED 4 /* Attributes belonging to cached rta */
|
#define EALF_CACHED 4 /* Attributes belonging to cached rta */
|
||||||
#define EALF_TEMP 8 /* Temporary ea_list added by make_tmp_attrs hooks */
|
|
||||||
|
|
||||||
struct rte_src *rt_find_source(struct proto *p, u32 id);
|
struct rte_src *rt_find_source(struct proto *p, u32 id);
|
||||||
struct rte_src *rt_get_source(struct proto *p, u32 id);
|
struct rte_src *rt_get_source(struct proto *p, u32 id);
|
||||||
|
|
|
@ -127,7 +127,6 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ee = e;
|
ee = e;
|
||||||
rte_make_tmp_attrs(&e, c->show_pool, NULL);
|
|
||||||
|
|
||||||
/* Export channel is down, do not try to export routes to it */
|
/* Export channel is down, do not try to export routes to it */
|
||||||
if (ec && (ec->export_state == ES_DOWN))
|
if (ec && (ec->export_state == ES_DOWN))
|
||||||
|
|
197
nest/rt-table.c
197
nest/rt-table.c
|
@ -642,175 +642,6 @@ rte_free_quick(rte *e)
|
||||||
sl_free(rte_slab, e);
|
sl_free(rte_slab, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* rte_init_tmp_attrs - initialize temporary ea_list for route
|
|
||||||
* @r: route entry to be modified
|
|
||||||
* @lp: linpool from which to allocate attributes
|
|
||||||
* @max: maximum number of added temporary attribus
|
|
||||||
*
|
|
||||||
* This function is supposed to be called from make_tmp_attrs() and
|
|
||||||
* store_tmp_attrs() hooks before rte_make_tmp_attr() / rte_store_tmp_attr()
|
|
||||||
* functions. It allocates &ea_list with length for @max items for temporary
|
|
||||||
* attributes and puts it on top of eattrs stack.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
rte_init_tmp_attrs(rte *r, linpool *lp, uint max)
|
|
||||||
{
|
|
||||||
struct ea_list *e = lp_alloc(lp, sizeof(struct ea_list) + max * sizeof(eattr));
|
|
||||||
|
|
||||||
e->next = r->attrs->eattrs;
|
|
||||||
e->flags = EALF_SORTED | EALF_TEMP;
|
|
||||||
e->count = 0;
|
|
||||||
|
|
||||||
r->attrs->eattrs = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* rte_make_tmp_attr - make temporary eattr from private route fields
|
|
||||||
* @r: route entry to be modified
|
|
||||||
* @id: attribute ID
|
|
||||||
* @type: attribute type
|
|
||||||
* @val: attribute value (u32 or adata ptr)
|
|
||||||
*
|
|
||||||
* This function is supposed to be called from make_tmp_attrs() hook for
|
|
||||||
* each temporary attribute, after temporary &ea_list was initialized by
|
|
||||||
* rte_init_tmp_attrs(). It checks whether temporary attribute is supposed to
|
|
||||||
* be defined (based on route pflags) and if so then it fills &eattr field in
|
|
||||||
* preallocated temporary &ea_list on top of route @r eattrs stack.
|
|
||||||
*
|
|
||||||
* Note that it may require free &eattr in temporary &ea_list, so it must not be
|
|
||||||
* called more times than @max argument of rte_init_tmp_attrs().
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
rte_make_tmp_attr(rte *r, uint id, uint type, uintptr_t val)
|
|
||||||
{
|
|
||||||
if (r->pflags & EA_ID_FLAG(id))
|
|
||||||
{
|
|
||||||
ea_list *e = r->attrs->eattrs;
|
|
||||||
eattr *a = &e->attrs[e->count++];
|
|
||||||
a->id = id;
|
|
||||||
a->type = type;
|
|
||||||
a->flags = 0;
|
|
||||||
|
|
||||||
if (type & EAF_EMBEDDED)
|
|
||||||
a->u.data = (u32) val;
|
|
||||||
else
|
|
||||||
a->u.ptr = (struct adata *) val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* rte_store_tmp_attr - store temporary eattr to private route fields
|
|
||||||
* @r: route entry to be modified
|
|
||||||
* @id: attribute ID
|
|
||||||
*
|
|
||||||
* This function is supposed to be called from store_tmp_attrs() hook for
|
|
||||||
* each temporary attribute, after temporary &ea_list was initialized by
|
|
||||||
* rte_init_tmp_attrs(). It checks whether temporary attribute is defined in
|
|
||||||
* route @r eattrs stack, updates route pflags accordingly, undefines it by
|
|
||||||
* filling &eattr field in preallocated temporary &ea_list on top of the eattrs
|
|
||||||
* stack, and returns the value. Caller is supposed to store it in the
|
|
||||||
* appropriate private field.
|
|
||||||
*
|
|
||||||
* Note that it may require free &eattr in temporary &ea_list, so it must not be
|
|
||||||
* called more times than @max argument of rte_init_tmp_attrs()
|
|
||||||
*/
|
|
||||||
uintptr_t
|
|
||||||
rte_store_tmp_attr(rte *r, uint id)
|
|
||||||
{
|
|
||||||
ea_list *e = r->attrs->eattrs;
|
|
||||||
eattr *a = ea_find(e->next, id);
|
|
||||||
|
|
||||||
if (a)
|
|
||||||
{
|
|
||||||
e->attrs[e->count++] = (struct eattr) { .id = id, .type = EAF_TYPE_UNDEF };
|
|
||||||
r->pflags |= EA_ID_FLAG(id);
|
|
||||||
return (a->type & EAF_EMBEDDED) ? a->u.data : (uintptr_t) a->u.ptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
r->pflags &= ~EA_ID_FLAG(id);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* rte_make_tmp_attrs - prepare route by adding all relevant temporary route attributes
|
|
||||||
* @r: route entry to be modified (may be replaced if COW)
|
|
||||||
* @lp: linpool from which to allocate attributes
|
|
||||||
* @old_attrs: temporary ref to old &rta (may be NULL)
|
|
||||||
*
|
|
||||||
* This function expands privately stored protocol-dependent route attributes
|
|
||||||
* to a uniform &eattr / &ea_list representation. It is essentially a wrapper
|
|
||||||
* around protocol make_tmp_attrs() hook, which does some additional work like
|
|
||||||
* ensuring that route @r is writable.
|
|
||||||
*
|
|
||||||
* The route @r may be read-only (with %REF_COW flag), in that case rw copy is
|
|
||||||
* obtained by rte_cow() and @r is replaced. If @rte is originally rw, it may be
|
|
||||||
* directly modified (and it is never copied).
|
|
||||||
*
|
|
||||||
* If the @old_attrs ptr is supplied, the function obtains another reference of
|
|
||||||
* old cached &rta, that is necessary in some cases (see rte_cow_rta() for
|
|
||||||
* details). It is freed by rte_store_tmp_attrs(), or manually by rta_free().
|
|
||||||
*
|
|
||||||
* Generally, if caller ensures that @r is read-only (e.g. in route export) then
|
|
||||||
* it may ignore @old_attrs (and set it to NULL), but must handle replacement of
|
|
||||||
* @r. If caller ensures that @r is writable (e.g. in route import) then it may
|
|
||||||
* ignore replacement of @r, but it must handle @old_attrs.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
rte_make_tmp_attrs(rte **r, linpool *lp, rta **old_attrs)
|
|
||||||
{
|
|
||||||
void (*make_tmp_attrs)(rte *r, linpool *lp);
|
|
||||||
make_tmp_attrs = (*r)->src->proto->make_tmp_attrs;
|
|
||||||
|
|
||||||
if (!make_tmp_attrs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* We may need to keep ref to old attributes, will be freed in rte_store_tmp_attrs() */
|
|
||||||
if (old_attrs)
|
|
||||||
*old_attrs = rta_is_cached((*r)->attrs) ? rta_clone((*r)->attrs) : NULL;
|
|
||||||
|
|
||||||
*r = rte_cow_rta(*r, lp);
|
|
||||||
make_tmp_attrs(*r, lp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* rte_store_tmp_attrs - store temporary route attributes back to private route fields
|
|
||||||
* @r: route entry to be modified
|
|
||||||
* @lp: linpool from which to allocate attributes
|
|
||||||
* @old_attrs: temporary ref to old &rta
|
|
||||||
*
|
|
||||||
* This function stores temporary route attributes that were expanded by
|
|
||||||
* rte_make_tmp_attrs() back to private route fields and also undefines them.
|
|
||||||
* It is essentially a wrapper around protocol store_tmp_attrs() hook, which
|
|
||||||
* does some additional work like shortcut if there is no change and cleanup
|
|
||||||
* of @old_attrs reference obtained by rte_make_tmp_attrs().
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
rte_store_tmp_attrs(rte *r, linpool *lp, rta *old_attrs)
|
|
||||||
{
|
|
||||||
void (*store_tmp_attrs)(rte *rt, linpool *lp);
|
|
||||||
store_tmp_attrs = r->src->proto->store_tmp_attrs;
|
|
||||||
|
|
||||||
if (!store_tmp_attrs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ASSERT(!rta_is_cached(r->attrs));
|
|
||||||
|
|
||||||
/* If there is no new ea_list, we just skip the temporary ea_list */
|
|
||||||
ea_list *ea = r->attrs->eattrs;
|
|
||||||
if (ea && (ea->flags & EALF_TEMP))
|
|
||||||
r->attrs->eattrs = ea->next;
|
|
||||||
else
|
|
||||||
store_tmp_attrs(r, lp);
|
|
||||||
|
|
||||||
/* Free ref we got in rte_make_tmp_attrs(), have to do rta_lookup() first */
|
|
||||||
r->attrs = rta_lookup(r->attrs);
|
|
||||||
rta_free(old_attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int /* Actually better or at least as good as */
|
static int /* Actually better or at least as good as */
|
||||||
rte_better(rte *new, rte *old)
|
rte_better(rte *new, rte *old)
|
||||||
{
|
{
|
||||||
|
@ -862,8 +693,8 @@ rte_mergable(rte *pri, rte *sec)
|
||||||
static void
|
static void
|
||||||
rte_trace(struct channel *c, rte *e, int dir, char *msg)
|
rte_trace(struct channel *c, rte *e, int dir, char *msg)
|
||||||
{
|
{
|
||||||
log(L_TRACE "%s.%s %c %s %N %s",
|
log(L_TRACE "%s.%s %c %s %N %uL %uG %s",
|
||||||
c->proto->name, c->name ?: "?", dir, msg, e->net->n.addr,
|
c->proto->name, c->name ?: "?", dir, msg, e->net->n.addr, e->src->private_id, e->src->global_id,
|
||||||
rta_dest_name(e->attrs->dest));
|
rta_dest_name(e->attrs->dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -911,8 +742,6 @@ export_filter_(struct channel *c, rte *rt0, rte **rt_free, linpool *pool, int si
|
||||||
goto accept;
|
goto accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
rte_make_tmp_attrs(&rt, pool, NULL);
|
|
||||||
|
|
||||||
v = filter && ((filter == FILTER_REJECT) ||
|
v = filter && ((filter == FILTER_REJECT) ||
|
||||||
(f_run(filter, &rt, pool,
|
(f_run(filter, &rt, pool,
|
||||||
(silent ? FF_SILENT : 0)) > F_ACCEPT));
|
(silent ? FF_SILENT : 0)) > F_ACCEPT));
|
||||||
|
@ -926,12 +755,6 @@ export_filter_(struct channel *c, rte *rt0, rte **rt_free, linpool *pool, int si
|
||||||
goto reject;
|
goto reject;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PIPE
|
|
||||||
/* Pipes need rte with stored tmpattrs, remaining protocols need expanded tmpattrs */
|
|
||||||
if (p->proto == &proto_pipe)
|
|
||||||
rte_store_tmp_attrs(rt, pool, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
accept:
|
accept:
|
||||||
if (rt != rt0)
|
if (rt != rt0)
|
||||||
*rt_free = rt;
|
*rt_free = rt;
|
||||||
|
@ -1382,7 +1205,6 @@ rte_same(rte *x, rte *y)
|
||||||
x->attrs == y->attrs &&
|
x->attrs == y->attrs &&
|
||||||
x->pflags == y->pflags &&
|
x->pflags == y->pflags &&
|
||||||
x->src == y->src &&
|
x->src == y->src &&
|
||||||
(!x->src->proto->rte_same || x->src->proto->rte_same(x, y)) &&
|
|
||||||
rte_is_filtered(x) == rte_is_filtered(y);
|
rte_is_filtered(x) == rte_is_filtered(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1770,9 +1592,6 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
||||||
}
|
}
|
||||||
else if (filter)
|
else if (filter)
|
||||||
{
|
{
|
||||||
rta *old_attrs = NULL;
|
|
||||||
rte_make_tmp_attrs(&new, rte_update_pool, &old_attrs);
|
|
||||||
|
|
||||||
int fr = f_run(filter, &new, rte_update_pool, 0);
|
int fr = f_run(filter, &new, rte_update_pool, 0);
|
||||||
if (fr > F_ACCEPT)
|
if (fr > F_ACCEPT)
|
||||||
{
|
{
|
||||||
|
@ -1780,15 +1599,10 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
||||||
rte_trace_in(D_FILTERS, c, new, "filtered out");
|
rte_trace_in(D_FILTERS, c, new, "filtered out");
|
||||||
|
|
||||||
if (! c->in_keep_filtered)
|
if (! c->in_keep_filtered)
|
||||||
{
|
|
||||||
rta_free(old_attrs);
|
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
|
||||||
|
|
||||||
new->flags |= REF_FILTERED;
|
new->flags |= REF_FILTERED;
|
||||||
}
|
}
|
||||||
|
|
||||||
rte_store_tmp_attrs(new, rte_update_pool, old_attrs);
|
|
||||||
}
|
}
|
||||||
if (!rta_is_cached(new->attrs)) /* Need to copy attributes */
|
if (!rta_is_cached(new->attrs)) /* Need to copy attributes */
|
||||||
new->attrs = rta_lookup(new->attrs);
|
new->attrs = rta_lookup(new->attrs);
|
||||||
|
@ -1882,10 +1696,7 @@ rt_examine(rtable *t, net_addr *a, struct proto *p, const struct filter *filter)
|
||||||
/* Rest is stripped down export_filter() */
|
/* Rest is stripped down export_filter() */
|
||||||
int v = p->preexport ? p->preexport(p, rt) : 0;
|
int v = p->preexport ? p->preexport(p, rt) : 0;
|
||||||
if (v == RIC_PROCESS)
|
if (v == RIC_PROCESS)
|
||||||
{
|
|
||||||
rte_make_tmp_attrs(&rt, rte_update_pool, NULL);
|
|
||||||
v = (f_run(filter, &rt, rte_update_pool, FF_SILENT) <= F_ACCEPT);
|
v = (f_run(filter, &rt, rte_update_pool, FF_SILENT) <= F_ACCEPT);
|
||||||
}
|
|
||||||
|
|
||||||
/* Discard temporary rte */
|
/* Discard temporary rte */
|
||||||
if (rt != n->routes)
|
if (rt != n->routes)
|
||||||
|
@ -1987,8 +1798,6 @@ rte_dump(rte *e)
|
||||||
debug("%-1N ", n->n.addr);
|
debug("%-1N ", n->n.addr);
|
||||||
debug("PF=%02x ", e->pflags);
|
debug("PF=%02x ", e->pflags);
|
||||||
rta_dump(e->attrs);
|
rta_dump(e->attrs);
|
||||||
if (e->src->proto->proto->dump_attrs)
|
|
||||||
e->src->proto->proto->dump_attrs(e);
|
|
||||||
debug("\n");
|
debug("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3426,8 +3235,6 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, rte **
|
||||||
net = net_get(tab, n);
|
net = net_get(tab, n);
|
||||||
src = new->src;
|
src = new->src;
|
||||||
|
|
||||||
rte_store_tmp_attrs(new, rte_update_pool, NULL);
|
|
||||||
|
|
||||||
if (!rta_is_cached(new->attrs))
|
if (!rta_is_cached(new->attrs))
|
||||||
new->attrs = rta_lookup(new->attrs);
|
new->attrs = rta_lookup(new->attrs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1900,14 +1900,24 @@ bgp_get_neighbor(rte *r)
|
||||||
static inline int
|
static inline int
|
||||||
rte_stale(rte *r)
|
rte_stale(rte *r)
|
||||||
{
|
{
|
||||||
if (r->u.bgp.stale < 0)
|
if (r->pflags & BGP_REF_STALE)
|
||||||
{
|
return 1;
|
||||||
|
|
||||||
|
if (r->pflags & BGP_REF_NOT_STALE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* If staleness is unknown, compute and cache it */
|
/* If staleness is unknown, compute and cache it */
|
||||||
eattr *a = ea_find(r->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY));
|
eattr *a = ea_find(r->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY));
|
||||||
r->u.bgp.stale = a && int_set_contains(a->u.ptr, BGP_COMM_LLGR_STALE);
|
if (a && int_set_contains(a->u.ptr, BGP_COMM_LLGR_STALE))
|
||||||
|
{
|
||||||
|
r->pflags |= BGP_REF_STALE;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r->pflags |= BGP_REF_NOT_STALE;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r->u.bgp.stale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1919,8 +1929,8 @@ bgp_rte_better(rte *new, rte *old)
|
||||||
u32 n, o;
|
u32 n, o;
|
||||||
|
|
||||||
/* Skip suppressed routes (see bgp_rte_recalculate()) */
|
/* Skip suppressed routes (see bgp_rte_recalculate()) */
|
||||||
n = new->u.bgp.suppressed;
|
n = new->pflags & BGP_REF_SUPPRESSED;
|
||||||
o = old->u.bgp.suppressed;
|
o = old->pflags & BGP_REF_SUPPRESSED;
|
||||||
if (n > o)
|
if (n > o)
|
||||||
return 0;
|
return 0;
|
||||||
if (n < o)
|
if (n < o)
|
||||||
|
@ -2064,17 +2074,14 @@ bgp_rte_mergable(rte *pri, rte *sec)
|
||||||
u32 p, s;
|
u32 p, s;
|
||||||
|
|
||||||
/* Skip suppressed routes (see bgp_rte_recalculate()) */
|
/* Skip suppressed routes (see bgp_rte_recalculate()) */
|
||||||
if (pri->u.bgp.suppressed != sec->u.bgp.suppressed)
|
/* LLGR draft - depreference stale routes */
|
||||||
|
if (pri->pflags != sec->pflags)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* RFC 4271 9.1.2.1. Route resolvability test */
|
/* RFC 4271 9.1.2.1. Route resolvability test */
|
||||||
if (rte_resolvable(pri) != rte_resolvable(sec))
|
if (rte_resolvable(pri) != rte_resolvable(sec))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* LLGR draft - depreference stale routes */
|
|
||||||
if (rte_stale(pri) != rte_stale(sec))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Start with local preferences */
|
/* Start with local preferences */
|
||||||
x = ea_find(pri->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF));
|
x = ea_find(pri->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF));
|
||||||
y = ea_find(sec->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF));
|
y = ea_find(sec->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF));
|
||||||
|
@ -2154,7 +2161,7 @@ bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best)
|
||||||
rte *key = new ? new : old;
|
rte *key = new ? new : old;
|
||||||
u32 lpref = key->attrs->pref;
|
u32 lpref = key->attrs->pref;
|
||||||
u32 lasn = bgp_get_neighbor(key);
|
u32 lasn = bgp_get_neighbor(key);
|
||||||
int old_suppressed = old ? old->u.bgp.suppressed : 0;
|
int old_suppressed = old ? !!(old->pflags & BGP_REF_SUPPRESSED) : 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Proper RFC 4271 path selection is a bit complicated, it cannot be
|
* Proper RFC 4271 path selection is a bit complicated, it cannot be
|
||||||
|
@ -2206,11 +2213,11 @@ bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (new)
|
if (new)
|
||||||
new->u.bgp.suppressed = 1;
|
new->pflags |= BGP_REF_SUPPRESSED;
|
||||||
|
|
||||||
if (old)
|
if (old)
|
||||||
{
|
{
|
||||||
old->u.bgp.suppressed = 1;
|
old->pflags |= BGP_REF_SUPPRESSED;
|
||||||
|
|
||||||
/* The fast case - replace not best with worse (or remove not best) */
|
/* 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(new, old)))
|
||||||
|
@ -2222,7 +2229,7 @@ bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best)
|
||||||
for (s=net->routes; rte_is_valid(s); s=s->next)
|
for (s=net->routes; rte_is_valid(s); s=s->next)
|
||||||
if (use_deterministic_med(s) && same_group(s, lpref, lasn))
|
if (use_deterministic_med(s) && same_group(s, lpref, lasn))
|
||||||
{
|
{
|
||||||
s->u.bgp.suppressed = 1;
|
s->pflags |= BGP_REF_SUPPRESSED;
|
||||||
if (!r || bgp_rte_better(s, r))
|
if (!r || bgp_rte_better(s, r))
|
||||||
r = s;
|
r = s;
|
||||||
}
|
}
|
||||||
|
@ -2233,16 +2240,16 @@ bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best)
|
||||||
|
|
||||||
/* Found if new is mergable with best-in-group */
|
/* Found if new is mergable with best-in-group */
|
||||||
if (new && (new != r) && bgp_rte_mergable(r, new))
|
if (new && (new != r) && bgp_rte_mergable(r, new))
|
||||||
new->u.bgp.suppressed = 0;
|
new->pflags &= ~BGP_REF_SUPPRESSED;
|
||||||
|
|
||||||
/* Found all existing routes mergable with best-in-group */
|
/* Found all existing routes mergable with best-in-group */
|
||||||
for (s=net->routes; rte_is_valid(s); s=s->next)
|
for (s=net->routes; rte_is_valid(s); s=s->next)
|
||||||
if (use_deterministic_med(s) && same_group(s, lpref, lasn))
|
if (use_deterministic_med(s) && same_group(s, lpref, lasn))
|
||||||
if ((s != r) && bgp_rte_mergable(r, s))
|
if ((s != r) && bgp_rte_mergable(r, s))
|
||||||
s->u.bgp.suppressed = 0;
|
s->pflags &= ~BGP_REF_SUPPRESSED;
|
||||||
|
|
||||||
/* Found best-in-group */
|
/* Found best-in-group */
|
||||||
r->u.bgp.suppressed = 0;
|
r->pflags &= ~BGP_REF_SUPPRESSED;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are generally two reasons why we have to force
|
* There are generally two reasons why we have to force
|
||||||
|
@ -2290,7 +2297,7 @@ bgp_rte_modify_stale(struct rte *r, struct linpool *pool)
|
||||||
r = rte_cow_rta(r, pool);
|
r = rte_cow_rta(r, pool);
|
||||||
bgp_set_attr_ptr(&(r->attrs->eattrs), pool, BA_COMMUNITY, flags,
|
bgp_set_attr_ptr(&(r->attrs->eattrs), pool, BA_COMMUNITY, flags,
|
||||||
int_set_add(pool, ad, BGP_COMM_LLGR_STALE));
|
int_set_add(pool, ad, BGP_COMM_LLGR_STALE));
|
||||||
r->u.bgp.stale = 1;
|
r->pflags |= BGP_REF_STALE;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -2377,7 +2384,7 @@ bgp_get_route_info(rte *e, byte *buf)
|
||||||
|
|
||||||
buf += bsprintf(buf, " (%d", e->attrs->pref);
|
buf += bsprintf(buf, " (%d", e->attrs->pref);
|
||||||
|
|
||||||
if (e->u.bgp.suppressed)
|
if (e->pflags & BGP_REF_SUPPRESSED)
|
||||||
buf += bsprintf(buf, "-");
|
buf += bsprintf(buf, "-");
|
||||||
|
|
||||||
if (rte_stale(e))
|
if (rte_stale(e))
|
||||||
|
|
|
@ -202,6 +202,10 @@ struct bgp_channel_config {
|
||||||
|
|
||||||
#define BGP_BFD_GRACEFUL 2 /* BFD down triggers graceful restart */
|
#define BGP_BFD_GRACEFUL 2 /* BFD down triggers graceful restart */
|
||||||
|
|
||||||
|
/* rte->pflags */
|
||||||
|
#define BGP_REF_SUPPRESSED 0x1 /* Used for deterministic MED comparison */
|
||||||
|
#define BGP_REF_STALE 0x2 /* Route is LLGR_STATE */
|
||||||
|
#define BGP_REF_NOT_STALE 0x4 /* Route is NOT LLGR_STATE */
|
||||||
|
|
||||||
struct bgp_af_caps {
|
struct bgp_af_caps {
|
||||||
u32 afi;
|
u32 afi;
|
||||||
|
|
|
@ -1393,8 +1393,6 @@ bgp_rte_update(struct bgp_parse_state *s, const net_addr *n, u32 path_id, rta *a
|
||||||
rte *e = rte_get_temp(a, s->last_src);
|
rte *e = rte_get_temp(a, s->last_src);
|
||||||
|
|
||||||
e->pflags = 0;
|
e->pflags = 0;
|
||||||
e->u.bgp.suppressed = 0;
|
|
||||||
e->u.bgp.stale = -1;
|
|
||||||
rte_update3(&s->channel->c, n, e, s->last_src);
|
rte_update3(&s->channel->c, n, e, s->last_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -525,8 +525,6 @@ mrt_rib_table_dump(struct mrt_table_dump_state *s, net *n, int add_path)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rte_make_tmp_attrs(&rt, s->linpool, NULL);
|
|
||||||
|
|
||||||
if (f_run(s->filter, &rt, s->linpool, 0) <= F_ACCEPT)
|
if (f_run(s->filter, &rt, s->linpool, 0) <= F_ACCEPT)
|
||||||
mrt_rib_table_entry(s, rt);
|
mrt_rib_table_entry(s, rt);
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,10 @@
|
||||||
|
|
||||||
#include "pipe.h"
|
#include "pipe.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_BGP
|
||||||
|
#include "proto/bgp/bgp.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *old)
|
pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *old)
|
||||||
{
|
{
|
||||||
|
@ -73,16 +77,12 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *o
|
||||||
a->cached = 0;
|
a->cached = 0;
|
||||||
a->hostentry = NULL;
|
a->hostentry = NULL;
|
||||||
e = rte_get_temp(a, src);
|
e = rte_get_temp(a, src);
|
||||||
e->pflags = 0;
|
|
||||||
|
|
||||||
/* Copy protocol specific embedded attributes. */
|
|
||||||
memcpy(&(e->u), &(new->u), sizeof(e->u));
|
|
||||||
e->pflags = new->pflags;
|
e->pflags = new->pflags;
|
||||||
|
|
||||||
#ifdef CONFIG_BGP
|
#ifdef CONFIG_BGP
|
||||||
/* Hack to cleanup cached value */
|
/* Hack to cleanup cached value */
|
||||||
if (e->src->proto->proto == &proto_bgp)
|
if (e->src->proto->proto == &proto_bgp)
|
||||||
e->u.bgp.stale = -1;
|
e->pflags &= ~(BGP_REF_STALE | BGP_REF_NOT_STALE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -210,8 +210,6 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
|
||||||
rta *a = rta_lookup(&a0);
|
rta *a = rta_lookup(&a0);
|
||||||
rte *e = rte_get_temp(a, p->p.main_source);
|
rte *e = rte_get_temp(a, p->p.main_source);
|
||||||
|
|
||||||
e->pflags = EA_ID_FLAG(EA_RIP_METRIC) | EA_ID_FLAG(EA_RIP_TAG);
|
|
||||||
|
|
||||||
rte_update(&p->p, en->n.addr, e);
|
rte_update(&p->p, en->n.addr, e);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -577,8 +577,6 @@ krt_export_net(struct krt_proto *p, net *net, rte **rt_free)
|
||||||
if (filter == FILTER_REJECT)
|
if (filter == FILTER_REJECT)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
rte_make_tmp_attrs(&rt, krt_filter_lp, NULL);
|
|
||||||
|
|
||||||
/* We could run krt_preexport() here, but it is already handled by krt_is_installed() */
|
/* We could run krt_preexport() here, but it is already handled by krt_is_installed() */
|
||||||
|
|
||||||
if (filter == FILTER_ACCEPT)
|
if (filter == FILTER_ACCEPT)
|
||||||
|
|
Loading…
Reference in a new issue