mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 07:31:54 +00:00
Internal API change: passing all the rt_notify() data as a single structure.
This commit is contained in:
parent
a267d569ee
commit
eb5298f3e1
@ -210,7 +210,7 @@ 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 (*rt_notify)(struct channel *, struct rte_export *);
|
||||
void (*neigh_notify)(struct neighbor *neigh);
|
||||
int (*preexport)(struct proto *, struct rte **rt, struct linpool *pool);
|
||||
void (*reload_routes)(struct channel *);
|
||||
|
10
nest/route.h
10
nest/route.h
@ -223,6 +223,16 @@ typedef struct rte {
|
||||
btime lastmod; /* Last modified */
|
||||
} rte;
|
||||
|
||||
/* Route export structure. Protocols get this structure as an information about
|
||||
* new routes on the channel. */
|
||||
struct rte_export {
|
||||
net *net; /* Network information */
|
||||
struct rte_src *new_src; /* New route src (NULL for withdraw) */
|
||||
rte *new; /* New route (NULL for withdraw) */
|
||||
struct rte_src *old_src; /* Old route src */
|
||||
rte *old; /* Old route */
|
||||
};
|
||||
|
||||
#define REF_COW 1 /* Copy this rte on write */
|
||||
#define REF_FILTERED 2 /* Route is rejected by import filter */
|
||||
#define REF_STALE 4 /* Route is stale in a refresh cycle */
|
||||
|
@ -543,7 +543,15 @@ do_rt_notify(struct channel *c, net *net, rte *new, rte *old, int refeed)
|
||||
rte_trace_out(D_ROUTES, p, old, "removed");
|
||||
}
|
||||
|
||||
p->rt_notify(p, c, net, new, old);
|
||||
struct rte_export export = {
|
||||
.net = net,
|
||||
.new_src = new ? new->attrs->src : NULL,
|
||||
.new = new,
|
||||
.old_src = old ? old->attrs->src : NULL,
|
||||
.old = old,
|
||||
};
|
||||
|
||||
p->rt_notify(c, &export);
|
||||
|
||||
if (c->out_table && old_exported)
|
||||
rte_free_quick(old_exported);
|
||||
|
@ -2121,38 +2121,32 @@ babel_preexport(struct proto *P, struct rte **new, struct linpool *pool UNUSED)
|
||||
* so store it into our data structures.
|
||||
*/
|
||||
static void
|
||||
babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
|
||||
struct rte *new, struct rte *old UNUSED)
|
||||
babel_rt_notify(struct channel *c, struct rte_export *export)
|
||||
{
|
||||
struct babel_proto *p = (void *) P;
|
||||
struct babel_proto *p = (void *) c->proto;
|
||||
struct babel_entry *e;
|
||||
|
||||
if (new)
|
||||
if (export->new)
|
||||
{
|
||||
/* Update */
|
||||
uint rt_seqno;
|
||||
uint rt_metric = ea_get_int(new->attrs->eattrs, EA_BABEL_METRIC, 0);
|
||||
uint rt_metric = ea_get_int(export->new->attrs->eattrs, EA_BABEL_METRIC, 0);
|
||||
uint rt_seqno = ea_get_int(export->new->attrs->eattrs, EA_BABEL_SEQNO, p->update_seqno);
|
||||
u64 rt_router_id;
|
||||
|
||||
if (new->attrs->src->proto == P)
|
||||
{
|
||||
rt_seqno = ea_find(new->attrs->eattrs, EA_BABEL_SEQNO)->u.data;
|
||||
memcpy(&rt_router_id, ea_find(new->attrs->eattrs, EA_BABEL_ROUTER_ID)->u.ptr->data, sizeof(u64));
|
||||
}
|
||||
eattr *ea;
|
||||
if (ea = ea_find(export->new->attrs->eattrs, EA_BABEL_ROUTER_ID))
|
||||
memcpy(&rt_router_id, ea->u.ptr->data, sizeof(u64));
|
||||
else
|
||||
{
|
||||
rt_seqno = p->router_id;
|
||||
rt_router_id = p->router_id;
|
||||
}
|
||||
|
||||
if (rt_metric > BABEL_INFINITY)
|
||||
{
|
||||
log(L_WARN "%s: Invalid babel_metric value %u for route %N",
|
||||
p->p.name, rt_metric, net->n.addr);
|
||||
p->p.name, rt_metric, export->net->n.addr);
|
||||
rt_metric = BABEL_INFINITY;
|
||||
}
|
||||
|
||||
e = babel_get_entry(p, net->n.addr);
|
||||
e = babel_get_entry(p, export->net->n.addr);
|
||||
|
||||
/* Activate triggered updates */
|
||||
if ((e->valid != BABEL_ENTRY_VALID) ||
|
||||
@ -2170,7 +2164,7 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net,
|
||||
else
|
||||
{
|
||||
/* Withdraw */
|
||||
e = babel_find_entry(p, net->n.addr);
|
||||
e = babel_find_entry(p, export->net->n.addr);
|
||||
|
||||
if (!e || e->valid != BABEL_ENTRY_VALID)
|
||||
return;
|
||||
|
@ -1802,31 +1802,31 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
|
||||
}
|
||||
|
||||
void
|
||||
bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old)
|
||||
bgp_rt_notify(struct channel *C, struct rte_export *e)
|
||||
{
|
||||
struct bgp_proto *p = (void *) P;
|
||||
struct bgp_proto *p = (void *) C->proto;
|
||||
struct bgp_channel *c = (void *) C;
|
||||
struct bgp_bucket *buck;
|
||||
struct bgp_prefix *px;
|
||||
u32 path;
|
||||
|
||||
if (new)
|
||||
if (e->new)
|
||||
{
|
||||
struct ea_list *attrs = bgp_update_attrs(p, c, new, new->attrs->eattrs, bgp_linpool2);
|
||||
struct ea_list *attrs = bgp_update_attrs(p, c, e->new, e->new->attrs->eattrs, bgp_linpool2);
|
||||
|
||||
/* If attributes are invalid, we fail back to withdraw */
|
||||
buck = attrs ? bgp_get_bucket(c, attrs) : bgp_get_withdraw_bucket(c);
|
||||
path = new->attrs->src->global_id;
|
||||
path = e->new_src->global_id;
|
||||
|
||||
lp_flush(bgp_linpool2);
|
||||
}
|
||||
else
|
||||
{
|
||||
buck = bgp_get_withdraw_bucket(c);
|
||||
path = old->attrs->src->global_id;
|
||||
path = e->old_src->global_id;
|
||||
}
|
||||
|
||||
px = bgp_get_prefix(c, n->n.addr, c->add_path_tx ? path : 0);
|
||||
px = bgp_get_prefix(c, e->net->n.addr, c->add_path_tx ? path : 0);
|
||||
add_tail(&buck->prefixes, &px->buck_node);
|
||||
|
||||
bgp_schedule_packet(p->conn, c, PKT_UPDATE);
|
||||
|
@ -583,7 +583,7 @@ int bgp_rte_better(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);
|
||||
struct rte *bgp_rte_modify_stale(struct rte *r, struct linpool *pool);
|
||||
void bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old);
|
||||
void bgp_rt_notify(struct channel *C, struct rte_export *e);
|
||||
int bgp_preexport(struct proto *, struct rte **, struct linpool *);
|
||||
int bgp_get_attr(const struct eattr *e, byte *buf, int buflen);
|
||||
void bgp_get_route_info(struct rte *, byte *buf);
|
||||
|
@ -1303,9 +1303,9 @@ find_surrogate_fwaddr(struct ospf_proto *p, struct ospf_area *oa)
|
||||
}
|
||||
|
||||
void
|
||||
ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED)
|
||||
ospf_rt_notify(struct channel *ch, struct rte_export *e)
|
||||
{
|
||||
struct ospf_proto *p = (struct ospf_proto *) P;
|
||||
struct ospf_proto *p = (struct ospf_proto *) ch->proto;
|
||||
struct ospf_area *oa = NULL; /* non-NULL for NSSA-LSA */
|
||||
ort *nf;
|
||||
|
||||
@ -1320,9 +1320,9 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
|
||||
if ((p->areano == 1) && oa_is_nssa(HEAD(p->area_list)))
|
||||
oa = HEAD(p->area_list);
|
||||
|
||||
if (!new)
|
||||
if (!e->new)
|
||||
{
|
||||
nf = fib_find(&p->rtf, n->n.addr);
|
||||
nf = fib_find(&p->rtf, e->net->n.addr);
|
||||
|
||||
if (!nf || !nf->external_rte)
|
||||
return;
|
||||
@ -1340,7 +1340,7 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
|
||||
ASSERT(p->asbr);
|
||||
|
||||
/* Get route attributes */
|
||||
rta *a = new->attrs;
|
||||
rta *a = e->new->attrs;
|
||||
eattr *m1a = ea_find(a->eattrs, EA_OSPF_METRIC1);
|
||||
eattr *m2a = ea_find(a->eattrs, EA_OSPF_METRIC2);
|
||||
uint m1 = m1a ? m1a->u.data : 0;
|
||||
@ -1349,14 +1349,14 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
|
||||
if (m1 > LSINFINITY)
|
||||
{
|
||||
log(L_WARN "%s: Invalid ospf_metric1 value %u for route %N",
|
||||
p->p.name, m1, n->n.addr);
|
||||
p->p.name, m1, e->net->n.addr);
|
||||
m1 = LSINFINITY;
|
||||
}
|
||||
|
||||
if (m2 > LSINFINITY)
|
||||
{
|
||||
log(L_WARN "%s: Invalid ospf_metric2 value %u for route %N",
|
||||
p->p.name, m2, n->n.addr);
|
||||
p->p.name, m2, e->net->n.addr);
|
||||
m2 = LSINFINITY;
|
||||
}
|
||||
|
||||
@ -1380,12 +1380,12 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
|
||||
if (ipa_zero(fwd))
|
||||
{
|
||||
log(L_ERR "%s: Cannot find forwarding address for NSSA-LSA %N",
|
||||
p->p.name, n->n.addr);
|
||||
p->p.name, e->net->n.addr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nf = fib_get(&p->rtf, n->n.addr);
|
||||
nf = fib_get(&p->rtf, e->net->n.addr);
|
||||
ospf_originate_ext_lsa(p, oa, nf, LSA_M_EXPORT, metric, ebit, fwd, tag, 1, p->vpn_pe);
|
||||
nf->external_rte = 1;
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ void ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, u32 d
|
||||
void ospf_originate_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, u8 mode, u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit, int dn);
|
||||
void ospf_originate_gr_lsa(struct ospf_proto *p, struct ospf_iface *ifa);
|
||||
|
||||
void ospf_rt_notify(struct proto *P, struct channel *ch, net *n, rte *new, rte *old);
|
||||
void ospf_rt_notify(struct channel *ch, struct rte_export *e);
|
||||
void ospf_update_topology(struct ospf_proto *p);
|
||||
|
||||
struct top_hash_entry *ospf_hash_find(struct top_graph *, u32 domain, u32 lsa, u32 rtr, u32 type);
|
||||
|
@ -204,9 +204,9 @@ perf_loop(void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
perf_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net UNUSED, struct rte *new UNUSED, struct rte *old UNUSED)
|
||||
perf_rt_notify(struct channel *c, struct rte_export *e UNUSED)
|
||||
{
|
||||
struct perf_proto *p = (struct perf_proto *) P;
|
||||
struct perf_proto *p = (struct perf_proto *) c->proto;
|
||||
p->exp++;
|
||||
return;
|
||||
}
|
||||
|
@ -48,51 +48,45 @@
|
||||
#include "pipe.h"
|
||||
|
||||
static void
|
||||
pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *old)
|
||||
pipe_rt_notify(struct channel *src_ch, struct rte_export *export)
|
||||
{
|
||||
struct pipe_proto *p = (void *) P;
|
||||
struct pipe_proto *p = (void *) src_ch->proto;
|
||||
struct channel *dst = (src_ch == p->pri) ? p->sec : p->pri;
|
||||
struct rte_src *src;
|
||||
|
||||
rte e0 = {}, *e = &e0;
|
||||
rta *a;
|
||||
|
||||
if (!new && !old)
|
||||
if (!export->new && !export->old)
|
||||
return;
|
||||
|
||||
if (dst->table->pipe_busy)
|
||||
{
|
||||
log(L_ERR "Pipe loop detected when sending %N to table %s",
|
||||
n->n.addr, dst->table->name);
|
||||
export->net->n.addr, dst->table->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (new)
|
||||
if (export->new)
|
||||
{
|
||||
a = alloca(rta_size(new->attrs));
|
||||
memcpy(a, new->attrs, rta_size(new->attrs));
|
||||
rta *a = alloca(rta_size(export->new->attrs));
|
||||
memcpy(a, export->new->attrs, rta_size(export->new->attrs));
|
||||
|
||||
a->cached = 0;
|
||||
a->uc = 0;
|
||||
a->hostentry = NULL;
|
||||
|
||||
e->attrs = rta_lookup(a);
|
||||
e->pflags = 0;
|
||||
rte e0 = {
|
||||
.attrs = rta_lookup(a),
|
||||
};
|
||||
|
||||
src = a->src;
|
||||
src_ch->table->pipe_busy = 1;
|
||||
rte_update(dst, export->net->n.addr, &e0);
|
||||
src_ch->table->pipe_busy = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
e = NULL;
|
||||
src = old->attrs->src;
|
||||
}
|
||||
|
||||
src_ch->table->pipe_busy = 1;
|
||||
if (e)
|
||||
rte_update(dst, n->n.addr, e);
|
||||
else
|
||||
rte_withdraw(dst, n->n.addr, src);
|
||||
rte_withdraw(dst, export->net->n.addr, export->old_src);
|
||||
src_ch->table->pipe_busy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pipe_preexport(struct proto *P, rte **ee, struct linpool *p UNUSED)
|
||||
|
@ -406,17 +406,17 @@ radv_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
|
||||
}
|
||||
|
||||
static void
|
||||
radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED)
|
||||
radv_rt_notify(struct channel *ch, struct rte_export *e)
|
||||
{
|
||||
struct radv_proto *p = (struct radv_proto *) P;
|
||||
struct radv_config *cf = (struct radv_config *) (P->cf);
|
||||
struct radv_proto *p = (struct radv_proto *) ch->proto;
|
||||
struct radv_config *cf = (struct radv_config *) (ch->proto->cf);
|
||||
struct radv_route *rt;
|
||||
eattr *ea;
|
||||
|
||||
if (radv_net_match_trigger(cf, n))
|
||||
if (radv_net_match_trigger(cf, e->net))
|
||||
{
|
||||
u8 old_active = p->active;
|
||||
p->active = !!new;
|
||||
p->active = !!e->new;
|
||||
|
||||
if (p->active == old_active)
|
||||
return;
|
||||
@ -440,15 +440,15 @@ radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
|
||||
* And yes, we exclude the trigger route on purpose.
|
||||
*/
|
||||
|
||||
if (new)
|
||||
if (e->new)
|
||||
{
|
||||
/* Update */
|
||||
|
||||
ea = ea_find(new->attrs->eattrs, EA_RA_PREFERENCE);
|
||||
ea = ea_find(e->new->attrs->eattrs, EA_RA_PREFERENCE);
|
||||
uint preference = ea ? ea->u.data : RA_PREF_MEDIUM;
|
||||
uint preference_set = !!ea;
|
||||
|
||||
ea = ea_find(new->attrs->eattrs, EA_RA_LIFETIME);
|
||||
ea = ea_find(e->new->attrs->eattrs, EA_RA_LIFETIME);
|
||||
uint lifetime = ea ? ea->u.data : 0;
|
||||
uint lifetime_set = !!ea;
|
||||
|
||||
@ -457,14 +457,14 @@ radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
|
||||
(preference != RA_PREF_HIGH))
|
||||
{
|
||||
log(L_WARN "%s: Invalid ra_preference value %u on route %N",
|
||||
p->p.name, preference, n->n.addr);
|
||||
p->p.name, preference, e->net->n.addr);
|
||||
preference = RA_PREF_MEDIUM;
|
||||
preference_set = 1;
|
||||
lifetime = 0;
|
||||
lifetime_set = 1;
|
||||
}
|
||||
|
||||
rt = fib_get(&p->routes, n->n.addr);
|
||||
rt = fib_get(&p->routes, e->net->n.addr);
|
||||
|
||||
/* Ignore update if nothing changed */
|
||||
if (rt->valid &&
|
||||
@ -487,7 +487,7 @@ radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
|
||||
else
|
||||
{
|
||||
/* Withdraw */
|
||||
rt = fib_find(&p->routes, n->n.addr);
|
||||
rt = fib_find(&p->routes, e->net->n.addr);
|
||||
|
||||
if (!rt || !rt->valid)
|
||||
return;
|
||||
|
@ -309,31 +309,31 @@ rip_withdraw_rte(struct rip_proto *p, net_addr *n, struct rip_neighbor *from)
|
||||
* it into our data structures.
|
||||
*/
|
||||
static void
|
||||
rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, struct rte *new,
|
||||
struct rte *old UNUSED)
|
||||
rip_rt_notify(struct channel *ch, struct rte_export *e)
|
||||
{
|
||||
struct rip_proto *p = (struct rip_proto *) P;
|
||||
struct rip_proto *p = (struct rip_proto *) ch->proto;
|
||||
struct rip_entry *en;
|
||||
int old_metric;
|
||||
|
||||
if (new)
|
||||
if (e->new)
|
||||
{
|
||||
/* Update */
|
||||
u32 rt_tag = ea_get_int(new->attrs->eattrs, EA_RIP_TAG, 0);
|
||||
u32 rt_metric = ea_get_int(new->attrs->eattrs, EA_RIP_METRIC, 1);
|
||||
struct iface *rt_from = (struct iface *) ea_get_int(new->attrs->eattrs, EA_RIP_FROM, 0);
|
||||
rta *a = e->new->attrs;
|
||||
u32 rt_tag = ea_get_int(a->eattrs, EA_RIP_TAG, 0);
|
||||
u32 rt_metric = ea_get_int(a->eattrs, EA_RIP_METRIC, 1);
|
||||
struct iface *rt_from = (struct iface *) ea_get_int(a->eattrs, EA_RIP_FROM, 0);
|
||||
|
||||
if (rt_metric > p->infinity)
|
||||
{
|
||||
log(L_WARN "%s: Invalid rip_metric value %u for route %N",
|
||||
p->p.name, rt_metric, net->n.addr);
|
||||
p->p.name, rt_metric, e->net->n.addr);
|
||||
rt_metric = p->infinity;
|
||||
}
|
||||
|
||||
if (rt_tag > 0xffff)
|
||||
{
|
||||
log(L_WARN "%s: Invalid rip_tag value %u for route %N",
|
||||
p->p.name, rt_tag, net->n.addr);
|
||||
p->p.name, rt_tag, e->net->n.addr);
|
||||
rt_metric = p->infinity;
|
||||
rt_tag = 0;
|
||||
}
|
||||
@ -345,7 +345,7 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s
|
||||
* collection.
|
||||
*/
|
||||
|
||||
en = fib_get(&p->rtable, net->n.addr);
|
||||
en = fib_get(&p->rtable, e->net->n.addr);
|
||||
|
||||
old_metric = en->valid ? en->metric : -1;
|
||||
|
||||
@ -353,13 +353,13 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s
|
||||
en->metric = rt_metric;
|
||||
en->tag = rt_tag;
|
||||
en->from = rt_from;
|
||||
en->iface = new->attrs->nh.iface;
|
||||
en->next_hop = new->attrs->nh.gw;
|
||||
en->iface = a->nh.iface;
|
||||
en->next_hop = a->nh.gw;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Withdraw */
|
||||
en = fib_find(&p->rtable, net->n.addr);
|
||||
en = fib_find(&p->rtable, e->net->n.addr);
|
||||
|
||||
if (!en || en->valid != RIP_ENTRY_VALID)
|
||||
return;
|
||||
|
@ -889,10 +889,9 @@ krt_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED)
|
||||
}
|
||||
|
||||
static void
|
||||
krt_rt_notify(struct proto *P, struct channel *ch UNUSED, net *net,
|
||||
rte *new, rte *old)
|
||||
krt_rt_notify(struct channel *ch, struct rte_export *e)
|
||||
{
|
||||
struct krt_proto *p = (struct krt_proto *) P;
|
||||
struct krt_proto *p = (struct krt_proto *) ch->proto;
|
||||
|
||||
if (config->shutdown)
|
||||
return;
|
||||
@ -904,13 +903,13 @@ krt_rt_notify(struct proto *P, struct channel *ch UNUSED, net *net,
|
||||
* but if we processed the update as usual, we would send withdraw to the
|
||||
* kernel, which would remove the new imported route instead.
|
||||
*/
|
||||
rte *best = net->routes;
|
||||
if (!new && best && (best->attrs->src->proto == P))
|
||||
rte *best = e->net->routes;
|
||||
if (!e->new && best && (best->attrs->src->proto == ch->proto))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (p->initialized) /* Before first scan we don't touch the routes */
|
||||
krt_replace_rte(p, net, new, old);
|
||||
krt_replace_rte(p, e->net, e->new, e->old);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user