mirror of
https://gitlab.labs.nic.cz/labs/bird.git
synced 2024-05-11 16:54:54 +00:00
Many changes in (mainly) kernel syncers.
- BSD kernel syncer is now self-conscious and can learn alien routes - important bugfix in BSD kernel syncer (crash after protocol restart) - many minor changes and bugfixes in kernel syncers and neighbor cache - direct protocol does not generate host and link local routes - min_scope check is removed, all routes have SCOPE_UNIVERSE by default - also fixes some remaining compiler warnings
This commit is contained in:
@@ -97,6 +97,7 @@ typedef struct neighbor {
|
||||
} neighbor;
|
||||
|
||||
#define NEF_STICKY 1
|
||||
#define NEF_ONLINK 2
|
||||
|
||||
neighbor *neigh_find(struct proto *, ip_addr *, unsigned flags);
|
||||
neighbor *neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags);
|
||||
|
@@ -112,12 +112,12 @@ neighbor *
|
||||
neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags)
|
||||
{
|
||||
neighbor *n;
|
||||
int class, scope = SCOPE_HOST;
|
||||
int class, scope = -1; ;
|
||||
unsigned int h = neigh_hash(p, a);
|
||||
struct iface *i;
|
||||
|
||||
WALK_LIST(n, neigh_hash_table[h]) /* Search the cache */
|
||||
if (n->proto == p && ipa_equal(*a, n->addr))
|
||||
if (n->proto == p && ipa_equal(*a, n->addr) && (!ifa || (ifa == n->iface)))
|
||||
return n;
|
||||
|
||||
class = ipa_classify(*a);
|
||||
@@ -129,7 +129,12 @@ neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags)
|
||||
return NULL; /* Bad scope or a somecast */
|
||||
|
||||
if (ifa)
|
||||
scope = if_connected(a, ifa);
|
||||
{
|
||||
scope = if_connected(a, ifa);
|
||||
|
||||
if ((scope < 0) && (flags & NEF_ONLINK))
|
||||
scope = class & IADDR_SCOPE_MASK;
|
||||
}
|
||||
else
|
||||
WALK_LIST(i, iface_list)
|
||||
if ((scope = if_connected(a, i)) >= 0)
|
||||
@@ -138,22 +143,28 @@ neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ifa && !(flags & NEF_STICKY))
|
||||
/* scope < 0 means i don't know neighbor */
|
||||
/* scope >= 0 implies ifa != NULL */
|
||||
|
||||
if ((scope < 0) && !(flags & NEF_STICKY))
|
||||
return NULL;
|
||||
|
||||
n = sl_alloc(neigh_slab);
|
||||
n->addr = *a;
|
||||
n->iface = ifa;
|
||||
if (ifa)
|
||||
if (scope >= 0)
|
||||
{
|
||||
add_tail(&neigh_hash_table[h], &n->n);
|
||||
add_tail(&ifa->neighbors, &n->if_n);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* sticky flag does not work for link-local neighbors;
|
||||
fortunately, we don't use this combination */
|
||||
add_tail(&sticky_neigh_list, &n->n);
|
||||
ifa = NULL;
|
||||
scope = 0;
|
||||
}
|
||||
n->iface = ifa;
|
||||
n->proto = p;
|
||||
n->data = NULL;
|
||||
n->aux = 0;
|
||||
|
@@ -113,7 +113,6 @@ proto_new(struct proto_config *c, unsigned size)
|
||||
p->table = c->table->table;
|
||||
p->in_filter = c->in_filter;
|
||||
p->out_filter = c->out_filter;
|
||||
p->min_scope = SCOPE_SITE;
|
||||
p->hash_key = random_u32();
|
||||
c->proto = p;
|
||||
return p;
|
||||
|
@@ -130,7 +130,6 @@ struct proto {
|
||||
u32 debug; /* Debugging flags */
|
||||
u32 mrtdump; /* MRTDump flags */
|
||||
unsigned preference; /* Default route preference */
|
||||
int min_scope; /* Minimal route scope accepted */
|
||||
unsigned accept_ra_types; /* Which types of route announcements are accepted (RA_OPTIMAL or RA_ANY) */
|
||||
unsigned disabled; /* Manually disabled */
|
||||
unsigned proto_state; /* Protocol state machine (see below) */
|
||||
|
@@ -33,6 +33,10 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
|
||||
!iface_patt_find(&P->iface_list, ad->iface))
|
||||
/* Empty list is automagically treated as "*" */
|
||||
return;
|
||||
|
||||
if (ad->scope <= SCOPE_LINK)
|
||||
return;
|
||||
|
||||
if (c & IF_CHANGE_DOWN)
|
||||
{
|
||||
net *n;
|
||||
@@ -56,7 +60,7 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
|
||||
bzero(&A, sizeof(A));
|
||||
A.proto = p;
|
||||
A.source = RTS_DEVICE;
|
||||
A.scope = ad->scope;
|
||||
A.scope = SCOPE_UNIVERSE;
|
||||
A.cast = RTC_UNICAST;
|
||||
A.dest = RTD_DEVICE;
|
||||
A.iface = ad->iface;
|
||||
@@ -76,7 +80,6 @@ dev_init(struct proto_config *c)
|
||||
struct proto *p = proto_new(c, sizeof(struct proto));
|
||||
|
||||
p->ifa_notify = dev_ifa_notify;
|
||||
p->min_scope = SCOPE_HOST;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@@ -158,7 +158,7 @@ rte_trace_out(unsigned int flag, struct proto *p, rte *e, char *msg)
|
||||
}
|
||||
|
||||
static inline void
|
||||
do_rte_announce(struct announce_hook *a, int type UNUSED, net *net, rte *new, rte *old, ea_list *tmpa, int class, int refeed)
|
||||
do_rte_announce(struct announce_hook *a, int type UNUSED, net *net, rte *new, rte *old, ea_list *tmpa, int refeed)
|
||||
{
|
||||
struct proto *p = a->proto;
|
||||
struct filter *filter = p->out_filter;
|
||||
@@ -183,13 +183,7 @@ do_rte_announce(struct announce_hook *a, int type UNUSED, net *net, rte *new, rt
|
||||
stats->exp_updates_received++;
|
||||
|
||||
char *drop_reason = NULL;
|
||||
if ((class & IADDR_SCOPE_MASK) < p->min_scope)
|
||||
{
|
||||
stats->exp_updates_rejected++;
|
||||
drop_reason = "out of scope";
|
||||
fast_exit_hack = 1;
|
||||
}
|
||||
else if ((ok = p->import_control ? p->import_control(p, &new, &tmpa, rte_update_pool) : 0) < 0)
|
||||
if ((ok = p->import_control ? p->import_control(p, &new, &tmpa, rte_update_pool) : 0) < 0)
|
||||
{
|
||||
stats->exp_updates_rejected++;
|
||||
drop_reason = "rejected by protocol";
|
||||
@@ -332,7 +326,6 @@ static void
|
||||
rte_announce(rtable *tab, unsigned type, net *net, rte *new, rte *old, ea_list *tmpa)
|
||||
{
|
||||
struct announce_hook *a;
|
||||
int class = ipa_classify(net->n.prefix);
|
||||
|
||||
if (type == RA_OPTIMAL)
|
||||
{
|
||||
@@ -346,7 +339,7 @@ rte_announce(rtable *tab, unsigned type, net *net, rte *new, rte *old, ea_list *
|
||||
{
|
||||
ASSERT(a->proto->core_state == FS_HAPPY || a->proto->core_state == FS_FEEDING);
|
||||
if (a->proto->accept_ra_types == type)
|
||||
do_rte_announce(a, type, net, new, old, tmpa, class, 0);
|
||||
do_rte_announce(a, type, net, new, old, tmpa, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,33 +355,15 @@ rte_validate(rte *e)
|
||||
n->n.prefix, n->n.pxlen, e->sender->name);
|
||||
return 0;
|
||||
}
|
||||
if (n->n.pxlen)
|
||||
|
||||
c = ipa_classify_net(n->n.prefix);
|
||||
if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
|
||||
{
|
||||
c = ipa_classify(n->n.prefix);
|
||||
if (c < 0 || !(c & IADDR_HOST))
|
||||
{
|
||||
if (!ipa_nonzero(n->n.prefix))
|
||||
{
|
||||
/* Various default routes */
|
||||
#ifdef IPV6
|
||||
if (n->n.pxlen == 96)
|
||||
#else
|
||||
if (n->n.pxlen <= 1)
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
log(L_WARN "Ignoring bogus route %I/%d received via %s",
|
||||
n->n.prefix, n->n.pxlen, e->sender->name);
|
||||
return 0;
|
||||
}
|
||||
if ((c & IADDR_SCOPE_MASK) < e->sender->min_scope)
|
||||
{
|
||||
log(L_WARN "Ignoring %s scope route %I/%d received from %I via %s",
|
||||
ip_scope_text(c & IADDR_SCOPE_MASK),
|
||||
n->n.prefix, n->n.pxlen, e->attrs->from, e->sender->name);
|
||||
return 0;
|
||||
}
|
||||
log(L_WARN "Ignoring bogus route %I/%d received via %s",
|
||||
n->n.prefix, n->n.pxlen, e->sender->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1018,7 +993,7 @@ do_feed_baby(struct proto *p, int type, struct announce_hook *h, net *n, rte *e)
|
||||
|
||||
rte_update_lock();
|
||||
tmpa = q->make_tmp_attrs ? q->make_tmp_attrs(e, rte_update_pool) : NULL;
|
||||
do_rte_announce(h, type, n, e, p->refeeding ? e : NULL, tmpa, ipa_classify(n->n.prefix), p->refeeding);
|
||||
do_rte_announce(h, type, n, e, p->refeeding ? e : NULL, tmpa, p->refeeding);
|
||||
rte_update_unlock();
|
||||
}
|
||||
|
||||
@@ -1190,11 +1165,8 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
|
||||
if (p2 && p2 != p0) ok = 0;
|
||||
if (ok && d->export_mode)
|
||||
{
|
||||
int class = ipa_classify(n->n.prefix);
|
||||
int ic;
|
||||
if ((class & IADDR_SCOPE_MASK) < p1->min_scope)
|
||||
ok = 0;
|
||||
else if ((ic = p1->import_control ? p1->import_control(p1, &e, &tmpa, rte_update_pool) : 0) < 0)
|
||||
if ((ic = p1->import_control ? p1->import_control(p1, &e, &tmpa, rte_update_pool) : 0) < 0)
|
||||
ok = 0;
|
||||
else if (!ic && d->export_mode > 1)
|
||||
{
|
||||
|
Reference in New Issue
Block a user