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