diff options
author | Jan Moskyto Matejka <mq@ucw.cz> | 2016-01-21 10:59:52 +0100 |
---|---|---|
committer | Jan Moskyto Matejka <mq@ucw.cz> | 2016-01-21 14:55:33 +0100 |
commit | 3f35816136f1b57067d5ce426b031e4e3583085c (patch) | |
tree | f49e70ed6c3e5db3c9bdd75aa3c26864eade9207 | |
parent | 0e965f69914313857a95d03b2e6136d3e84019dd (diff) |
BSD: Explicitly dropping routes with mismatched AF's.
-rw-r--r-- | nest/rt-fib.c | 4 | ||||
-rw-r--r-- | sysdep/bsd/krt-sock.c | 28 |
2 files changed, 24 insertions, 8 deletions
diff --git a/nest/rt-fib.c b/nest/rt-fib.c index 55387c5e..8021ea24 100644 --- a/nest/rt-fib.c +++ b/nest/rt-fib.c @@ -183,6 +183,8 @@ fib_rehash(struct fib *f, int step) static u32 fib_hash(struct fib *f, const net_addr *a) { + ASSERT(f->addr_type == a->type); + switch (f->addr_type) { case NET_IP4: return FIB_HASH(f, a, ip4); @@ -232,6 +234,8 @@ fib_find(struct fib *f, const net_addr *a) static void fib_insert(struct fib *f, const net_addr *a, struct fib_node *e) { + ASSERT(f->addr_type == a->type); + switch (f->addr_type) { case NET_IP4: FIB_INSERT(f, a, e, ip4); return; diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index 2a64e4e7..93c15e8e 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -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 */ + int ipv6; rte *e; net *net; 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) { case AF_INET: + ipv6 = 0; + break; case AF_INET6: - /* 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; + ipv6 = 1; break; default: 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); imask = ipa_from_sa(&mask); 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) { 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) SKIP("unknown table id %d\n", table_id); } #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); if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK)) SKIP("strange class/scope\n"); int pxlen; - if (ipa_is_ip4(imask)) - pxlen = (flags & RTF_HOST) ? IP4_MAX_PREFIX_LENGTH : ip4_masklen(ipa_to_ip4(imask)); - else + if (ipv6) 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) { 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)) { log(L_ERR "%s (%N) - missing gateway", errmsg, ndst); return; } |