Commit d05ec6bf authored by Matthieu Boutier's avatar Matthieu Boutier Committed by Juliusz Chroboczek

Use standard v4mapped encoding for source prefixes.

parent 221c60ce
......@@ -25,7 +25,7 @@ struct buffered_update {
unsigned char prefix[16];
unsigned char src_prefix[16];
unsigned char plen;
unsigned char src_plen; /* 0 <=> no src prefix */
unsigned char src_plen;
unsigned char pad[2];
};
......
......@@ -29,7 +29,7 @@ struct kernel_route {
unsigned char prefix[16];
int plen;
unsigned char src_prefix[16];
int src_plen; /* no source prefix <=> src_plen == 0 */
int src_plen;
int metric;
unsigned int ifindex;
int proto;
......
......@@ -955,12 +955,12 @@ kernel_route(int operation, int table,
/* Check that the protocol family is consistent. */
if(plen >= 96 && v4mapped(dest)) {
if(!v4mapped(gate) ||
(src_plen > 0 && (!v4mapped(src) || src_plen < 96))) {
!v4mapped(src)) {
errno = EINVAL;
return -1;
}
} else {
if(v4mapped(gate)|| (src_plen > 0 && v4mapped(src))) {
if(v4mapped(gate) || v4mapped(src)) {
errno = EINVAL;
return -1;
}
......@@ -995,7 +995,7 @@ kernel_route(int operation, int table,
ipv4 = v4mapped(gate);
use_src = (src_plen != 0 && kernel_disambiguate(ipv4));
use_src = (!is_default(src, src_plen) && kernel_disambiguate(ipv4));
kdebugf("kernel_route: %s %s from %s "
"table %d metric %d dev %d nexthop %s\n",
......@@ -1096,6 +1096,7 @@ parse_kernel_route_rta(struct rtmsg *rtm, int len, struct kernel_route *route)
/* if RTA_DST is not a TLV, that's a default destination */
const unsigned char zeroes[4] = {0, 0, 0, 0};
v4tov6(route->prefix, zeroes);
v4tov6(route->src_prefix, zeroes);
route->plen = 96;
}
route->proto = rtm->rtm_protocol;
......
......@@ -424,7 +424,7 @@ kernel_route(int operation, int table,
0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x01 }}};
/* Source-specific routes are not implemented yet for BSD. */
if(src_plen > 0) {
if(!is_default(src, src_plen)) {
errno = ENOSYS;
return -1;
}
......
This diff is collapsed.
......@@ -59,7 +59,7 @@ check_specific_first(void)
int specific = 1;
int i;
for(i = 0; i < route_slots; i++) {
if(routes[i]->src->src_plen == 0) {
if(is_default(routes[i]->src->src_prefix, routes[i]->src->src_plen)) {
specific = 0;
} else if(!specific) {
return 0;
......@@ -78,11 +78,13 @@ route_compare(const unsigned char *prefix, unsigned char plen,
struct babel_route *route)
{
int i;
int is_ss = !is_default(src_prefix, src_plen);
int is_ss_rt = !is_default(route->src->src_prefix, route->src->src_plen);
/* Put all source-specific routes in the front of the list. */
if(src_plen == 0 && route->src->src_plen > 0) {
if(!is_ss && is_ss_rt) {
return 1;
} else if(src_plen > 0 && route->src->src_plen == 0) {
} else if(is_ss && !is_ss_rt) {
return -1;
}
......@@ -95,10 +97,7 @@ route_compare(const unsigned char *prefix, unsigned char plen,
if(plen > route->src->plen)
return 1;
if(src_plen == 0) {
if(route->src->src_plen > 0)
return -1;
} else {
if(is_ss) {
i = memcmp(src_prefix, route->src->src_prefix, 16);
if(i != 0)
return i;
......@@ -401,7 +400,8 @@ route_stream_next(struct route_stream *stream)
if(stream->installed) {
while(stream->index < route_slots)
if(stream->installed == ROUTE_SS_INSTALLED &&
routes[stream->index]->src->src_plen == 0)
is_default(routes[stream->index]->src->src_prefix,
routes[stream->index]->src->src_plen))
return NULL;
else if(routes[stream->index]->installed)
break;
......@@ -858,10 +858,9 @@ update_route(const unsigned char *id,
}
is_v4 = v4mapped(prefix);
if(src_plen != 0 && is_v4 != v4mapped(src_prefix))
if(is_v4 != v4mapped(src_prefix))
return NULL;
add_metric = input_filter(id, prefix, plen, src_prefix, src_plen,
neigh->address, neigh->ifp->ifindex);
if(add_metric >= INFINITY)
......
......@@ -185,7 +185,7 @@ find_table(const unsigned char *dest, unsigned short plen,
install_filter(dest, plen, src, src_plen, &filter_result);
if(filter_result.table) {
return filter_result.table;
} else if(src_plen == 0) {
} else if(is_default(src, src_plen)) {
return export_table;
} else if(kernel_disambiguate(v4mapped(dest))) {
return export_table;
......
......@@ -103,6 +103,12 @@ void v4tov6(unsigned char *dst, const unsigned char *src);
int daemonise(void);
int set_src_prefix(unsigned char *src_addr, unsigned char *src_plen);
static inline int
is_default(const unsigned char *prefix, int plen)
{
return plen == 0 || (plen == 96 && v4mapped(prefix));
}
enum prefix_status {
PST_EQUALS = 0,
PST_DISJOINT,
......
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