Commit 079bea95 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Fix parsing of IPv4 source prefix.

An empty IPv4 source prefix is represented by a v4mapped
default prefix.  This was not always the case.  Thanks to
Fabian Blaese.
parent 41aa314d
......@@ -1081,12 +1081,10 @@ dump_route(FILE *out, struct babel_route *route)
snprintf(channels + j, 100 - j, ")");
}
fprintf(out, "%s%s%s metric %d (%d) refmetric %d id %s "
fprintf(out, "%s from %s metric %d (%d) refmetric %d id %s "
"seqno %d%s age %d via %s neigh %s%s%s%s\n",
format_prefix(route->src->prefix, route->src->plen),
route->src->src_plen > 0 ? " from " : "",
route->src->src_plen > 0 ?
format_prefix(route->src->src_prefix, route->src->src_plen) : "",
format_prefix(route->src->src_prefix, route->src->src_plen),
route_metric(route), route_smoothed_metric(route), route->refmetric,
format_eui64(route->src->id),
(int)route->seqno,
......@@ -1103,11 +1101,9 @@ dump_route(FILE *out, struct babel_route *route)
static void
dump_xroute(FILE *out, struct xroute *xroute)
{
fprintf(out, "%s%s%s metric %d (exported)\n",
fprintf(out, "%s from %s metric %d (exported)\n",
format_prefix(xroute->prefix, xroute->plen),
xroute->src_plen > 0 ? " from " : "",
xroute->src_plen > 0 ?
format_prefix(xroute->src_prefix, xroute->src_plen) : "",
format_prefix(xroute->src_prefix, xroute->src_plen),
xroute->metric);
}
......
......@@ -127,6 +127,7 @@ parse_update_subtlv(struct interface *ifp, int metric, int ae,
{
int type, len, i = 0;
int channels_len;
int have_src_prefix = 0;
/* This will be overwritten if there's a DIVERSITY_HOPS sub-TLV. */
if(*channels_len_return < 1 || (ifp->flags & IF_FARAWAY)) {
......@@ -142,8 +143,6 @@ parse_update_subtlv(struct interface *ifp, int metric, int ae,
}
}
*src_plen = 0;
while(i < alen) {
type = a[i];
if(type == SUBTLV_PAD1) {
......@@ -168,15 +167,17 @@ parse_update_subtlv(struct interface *ifp, int metric, int ae,
goto fail;
if(a[i + 2] == 0) /* source prefix cannot be default */
goto fail;
if(*src_plen != 0) /* source prefix can only be specified once */
if(have_src_prefix != 0) /* source prefix can only appear once */
goto fail;
*src_plen = a[i + 2];
rc = network_prefix(ae, *src_plen, 0, a + i + 3, NULL,
rc = network_prefix(ae, a[i + 2], 0, a + i + 3, NULL,
len - 1, src_prefix);
if(rc < 0)
goto fail;
if(ae == 1)
(*src_plen) += 96;
*src_plen = a[i + 2] + 96;
else
*src_plen = a[i + 2];
have_src_prefix = 1;
} else {
debugf("Received unknown%s Update sub-TLV %d.\n",
(type & 0x80) != 0 ? " mandatory" : "", type);
......@@ -309,8 +310,7 @@ parse_request_subtlv(int ae, const unsigned char *a, int alen,
unsigned char *src_prefix, unsigned char *src_plen)
{
int type, len, i = 0;
*src_plen = 0;
int have_src_prefix = 0;
while(i < alen) {
type = a[0];
......@@ -334,15 +334,17 @@ parse_request_subtlv(int ae, const unsigned char *a, int alen,
goto fail;
if(a[i + 2] == 0)
goto fail;
if(*src_plen != 0)
if(have_src_prefix != 0)
goto fail;
*src_plen = a[i + 2];
rc = network_prefix(ae, *src_plen, 0, a + i + 3, NULL,
rc = network_prefix(ae, a[i + 2], 0, a + i + 3, NULL,
len - 1, src_prefix);
if(rc < 0)
goto fail;
if(ae == 1)
(*src_plen) += 96;
*src_plen = a[i + 2] + 96;
else
*src_plen = a[i + 2];
have_src_prefix = 1;
} else {
debugf("Received unknown%s Route Request sub-TLV %d.\n",
((type & 0x80) != 0) ? " mandatory" : "", type);
......
......@@ -276,8 +276,13 @@ filter_address(struct kernel_addr *addr, void *data) {
return 0;
route = &routes[*found];
memset(route, 0, sizeof(struct kernel_route));
memcpy(route->prefix, addr->addr.s6_addr, 16);
route->plen = 128;
if(v4mapped(route->prefix)) {
memcpy(route->src_prefix, v4prefix, 16);
route->src_plen = 96;
}
route->metric = 0;
route->ifindex = addr->ifindex;
route->proto = RTPROT_BABEL_LOCAL;
......
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