0
0
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:
Maria Matejka 2023-09-27 16:29:44 +02:00
parent 860fbf0d65
commit bf84daca8c
2 changed files with 53 additions and 8 deletions

View File

@ -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;
}

View File

@ -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; }