BSD: Explicitly dropping routes with mismatched AF's.
This commit is contained in:
parent
0e965f6991
commit
3f35816136
2 changed files with 24 additions and 8 deletions
|
@ -183,6 +183,8 @@ fib_rehash(struct fib *f, int step)
|
||||||
static u32
|
static u32
|
||||||
fib_hash(struct fib *f, const net_addr *a)
|
fib_hash(struct fib *f, const net_addr *a)
|
||||||
{
|
{
|
||||||
|
ASSERT(f->addr_type == a->type);
|
||||||
|
|
||||||
switch (f->addr_type)
|
switch (f->addr_type)
|
||||||
{
|
{
|
||||||
case NET_IP4: return FIB_HASH(f, a, ip4);
|
case NET_IP4: return FIB_HASH(f, a, ip4);
|
||||||
|
@ -232,6 +234,8 @@ fib_find(struct fib *f, const net_addr *a)
|
||||||
static void
|
static void
|
||||||
fib_insert(struct fib *f, const net_addr *a, struct fib_node *e)
|
fib_insert(struct fib *f, const net_addr *a, struct fib_node *e)
|
||||||
{
|
{
|
||||||
|
ASSERT(f->addr_type == a->type);
|
||||||
|
|
||||||
switch (f->addr_type)
|
switch (f->addr_type)
|
||||||
{
|
{
|
||||||
case NET_IP4: FIB_INSERT(f, a, e, ip4); return;
|
case NET_IP4: FIB_INSERT(f, a, e, ip4); return;
|
||||||
|
|
|
@ -344,6 +344,7 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
|
||||||
{
|
{
|
||||||
/* p is NULL iff KRT_SHARED_SOCKET and !scan */
|
/* p is NULL iff KRT_SHARED_SOCKET and !scan */
|
||||||
|
|
||||||
|
int ipv6;
|
||||||
rte *e;
|
rte *e;
|
||||||
net *net;
|
net *net;
|
||||||
sockaddr dst, gate, mask;
|
sockaddr dst, gate, mask;
|
||||||
|
@ -372,15 +373,19 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
|
||||||
|
|
||||||
switch (dst.sa.sa_family) {
|
switch (dst.sa.sa_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
ipv6 = 0;
|
||||||
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
/* We do not test family for RTA_NETMASK, because BSD sends us
|
ipv6 = 1;
|
||||||
some strange values, but interpreting them as IPv4/IPv6 works */
|
|
||||||
mask.sa.sa_family = dst.sa.sa_family;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SKIP("invalid DST");
|
SKIP("invalid DST");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We do not test family for RTA_NETMASK, because BSD sends us
|
||||||
|
some strange values, but interpreting them as IPv4/IPv6 works */
|
||||||
|
mask.sa.sa_family = dst.sa.sa_family;
|
||||||
|
|
||||||
idst = ipa_from_sa(&dst);
|
idst = ipa_from_sa(&dst);
|
||||||
imask = ipa_from_sa(&mask);
|
imask = ipa_from_sa(&mask);
|
||||||
igate = (gate.sa.sa_family == dst.sa.sa_family) ? ipa_from_sa(&gate) : IPA_NONE;
|
igate = (gate.sa.sa_family == dst.sa.sa_family) ? ipa_from_sa(&gate) : IPA_NONE;
|
||||||
|
@ -389,27 +394,34 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
|
||||||
if (!scan)
|
if (!scan)
|
||||||
{
|
{
|
||||||
int table_id = msg->rtm.rtm_tableid;
|
int table_id = msg->rtm.rtm_tableid;
|
||||||
p = (table_id < KRT_MAX_TABLES) ? krt_table_map[table_id][!ipa_is_ip4(idst)] : NULL;
|
p = (table_id < KRT_MAX_TABLES) ? krt_table_map[table_id][ipv6] : NULL;
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
SKIP("unknown table id %d\n", table_id);
|
SKIP("unknown table id %d\n", table_id);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if ((!ipv6) && (p->p.table->addr_type != NET_IP4))
|
||||||
|
SKIP("reading only IPv4 routes");
|
||||||
|
if ( ipv6 && (p->p.table->addr_type != NET_IP6))
|
||||||
|
SKIP("reading only IPv6 routes");
|
||||||
|
|
||||||
int c = ipa_classify_net(idst);
|
int c = ipa_classify_net(idst);
|
||||||
if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
|
if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
|
||||||
SKIP("strange class/scope\n");
|
SKIP("strange class/scope\n");
|
||||||
|
|
||||||
int pxlen;
|
int pxlen;
|
||||||
if (ipa_is_ip4(imask))
|
if (ipv6)
|
||||||
pxlen = (flags & RTF_HOST) ? IP4_MAX_PREFIX_LENGTH : ip4_masklen(ipa_to_ip4(imask));
|
|
||||||
else
|
|
||||||
pxlen = (flags & RTF_HOST) ? IP6_MAX_PREFIX_LENGTH : ip6_masklen(&ipa_to_ip6(imask));
|
pxlen = (flags & RTF_HOST) ? IP6_MAX_PREFIX_LENGTH : ip6_masklen(&ipa_to_ip6(imask));
|
||||||
|
else
|
||||||
|
pxlen = (flags & RTF_HOST) ? IP4_MAX_PREFIX_LENGTH : ip4_masklen(ipa_to_ip4(imask));
|
||||||
|
|
||||||
if (pxlen < 0)
|
if (pxlen < 0)
|
||||||
{ log(L_ERR "%s (%I) - netmask %I", errmsg, idst, imask); return; }
|
{ log(L_ERR "%s (%I) - netmask %I", errmsg, idst, imask); return; }
|
||||||
|
|
||||||
net_fill_ipa(&ndst, idst, pxlen);
|
if (ipv6)
|
||||||
|
net_fill_ip6(&ndst, ipa_to_ip6(idst), pxlen);
|
||||||
|
else
|
||||||
|
net_fill_ip4(&ndst, ipa_to_ip4(idst), pxlen);
|
||||||
|
|
||||||
if ((flags & RTF_GATEWAY) && ipa_zero(igate))
|
if ((flags & RTF_GATEWAY) && ipa_zero(igate))
|
||||||
{ log(L_ERR "%s (%N) - missing gateway", errmsg, ndst); return; }
|
{ log(L_ERR "%s (%N) - missing gateway", errmsg, ndst); return; }
|
||||||
|
|
Loading…
Reference in a new issue