Commit 421838ff authored by Martin Mareš's avatar Martin Mareš

rte_update: Check sanity of incoming entries. Throw out (and log) all routes

to bogus prefixes and non-local routes to host scope addresses.
parent 529c4149
......@@ -165,6 +165,38 @@ rt_feed_baby(struct proto *p)
}
}
static inline int
rte_validate(rte *e)
{
int c;
net *n = e->net;
ASSERT(!ipa_nonzero(ipa_and(n->n.prefix, ipa_not(ipa_mkmask(n->n.pxlen)))));
if (n->n.pxlen)
{
c = ipa_classify(n->n.prefix);
if (c < 0 || !(c & IADDR_HOST))
{
if (!ipa_nonzero(n->n.prefix) && n->n.pxlen <= 1)
return 1; /* Default route and half-default route is OK */
log(L_WARN "Ignoring bogus route %I/%d received from %I via %s",
n->n.prefix, n->n.pxlen, e->attrs->from, e->attrs->proto->name);
return 0;
}
if ((c & IADDR_SCOPE_MASK) == SCOPE_HOST)
{
int s = e->attrs->source;
if (s != RTS_STATIC && s != RTS_DEVICE && s != RTS_STATIC_DEVICE)
{
log(L_WARN "Ignoring host scope route %I/%d received from %I via %s",
n->n.prefix, n->n.pxlen, e->attrs->from, e->attrs->proto->name);
return 0;
}
}
}
return 1;
}
void
rte_free(rte *e)
{
......@@ -187,15 +219,17 @@ rte_update(net *net, struct proto *p, rte *new)
rte *old = NULL;
rte **k, *r, *s;
if (new && p->in_filter && f_run(p->in_filter, new, NULL) != F_ACCEPT)
if (new)
{
rte_free(new);
return;
if (!rte_validate(new) || p->in_filter && f_run(p->in_filter, new, NULL) != F_ACCEPT)
{
rte_free(new);
return;
}
if (!(new->attrs->aflags & RTAF_CACHED)) /* Need to copy attributes */
new->attrs = rta_lookup(new->attrs);
}
if (new && !(new->attrs->aflags & RTAF_CACHED)) /* Need to copy attributes */
new->attrs = rta_lookup(new->attrs);
k = &net->routes; /* Find and remove original route from the same protocol */
while (old = *k)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment