mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-09 20:58:44 +00:00
RIP: Properly handle route refeed
This commit is contained in:
parent
860fbf0d65
commit
bf84daca8c
@ -328,6 +328,17 @@ rip_withdraw_rte(struct rip_proto *p, net_addr *n, struct rip_neighbor *from)
|
||||
rip_announce_rte(p, en);
|
||||
}
|
||||
|
||||
static void
|
||||
rip_withdraw_entry(struct rip_proto *p, struct rip_entry *en)
|
||||
{
|
||||
en->valid = RIP_ENTRY_STALE;
|
||||
en->metric = p->infinity;
|
||||
en->tag = 0;
|
||||
en->from = NULL;
|
||||
en->iface = NULL;
|
||||
en->next_hop = IPA_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* rip_rt_notify - core tells us about new route, so store
|
||||
* it into our data structures.
|
||||
@ -392,17 +403,11 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, const net_addr *net, s
|
||||
/* Withdraw */
|
||||
en = fib_find(&p->rtable, net);
|
||||
|
||||
if (!en || en->valid != RIP_ENTRY_VALID)
|
||||
if (!en || !(en->valid & RIP_ENTRY_VALID))
|
||||
return;
|
||||
|
||||
old_metric = en->metric;
|
||||
|
||||
en->valid = RIP_ENTRY_STALE;
|
||||
en->metric = p->infinity;
|
||||
en->tag = 0;
|
||||
en->from = NULL;
|
||||
en->iface = NULL;
|
||||
en->next_hop = IPA_NONE;
|
||||
rip_withdraw_entry(p, en);
|
||||
}
|
||||
|
||||
/* Activate triggered updates */
|
||||
@ -413,6 +418,43 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, const net_addr *net, s
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rip_feed_begin(struct channel *C, int initial)
|
||||
{
|
||||
if (initial)
|
||||
return;
|
||||
|
||||
struct rip_proto *p = (struct rip_proto *) C->proto;
|
||||
|
||||
FIB_WALK(&p->rtable, struct rip_entry, en)
|
||||
{
|
||||
if (en->valid == RIP_ENTRY_VALID)
|
||||
en->valid = RIP_ENTRY_REFEEDING;
|
||||
}
|
||||
FIB_WALK_END;
|
||||
}
|
||||
|
||||
void
|
||||
rip_feed_end(struct channel *C)
|
||||
{
|
||||
struct rip_proto *p = (struct rip_proto *) C->proto;
|
||||
int changed = 0;
|
||||
|
||||
FIB_WALK(&p->rtable, struct rip_entry, en)
|
||||
{
|
||||
if (en->valid == RIP_ENTRY_REFEEDING)
|
||||
{
|
||||
rip_withdraw_entry(p, en);
|
||||
changed++;
|
||||
}
|
||||
}
|
||||
FIB_WALK_END;
|
||||
|
||||
if (changed)
|
||||
rip_trigger_update(p);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rip_flush_table(struct rip_proto *p, struct rip_neighbor *n)
|
||||
{
|
||||
@ -1159,6 +1201,8 @@ rip_init(struct proto_config *CF)
|
||||
P->iface_sub.neigh_notify = rip_neigh_notify;
|
||||
P->reload_routes = rip_reload_routes;
|
||||
P->sources.class = &rip_rte_owner_class;
|
||||
P->feed_begin = rip_feed_begin;
|
||||
P->feed_end = rip_feed_end;
|
||||
|
||||
return P;
|
||||
}
|
||||
|
@ -194,6 +194,7 @@ struct rip_rte
|
||||
#define RIP_ENTRY_DUMMY 0 /* Only used to store list of incoming routes */
|
||||
#define RIP_ENTRY_VALID 1 /* Valid outgoing route */
|
||||
#define RIP_ENTRY_STALE 2 /* Stale outgoing route, waiting for GC */
|
||||
#define RIP_ENTRY_REFEEDING 3 /* Route valid until feed ends */
|
||||
|
||||
static inline int rip_is_v2(struct rip_proto *p)
|
||||
{ return p->rip2; }
|
||||
|
Loading…
Reference in New Issue
Block a user