*
* Author: Steven Barth <cyrus@openwrt.org>
* Copyright (c) 2014-2015 cisco Systems, Inc.
+ * Copyright (c) 2015 Steven Barth <cyrus@openwrt.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
}
static void match_prefix(int *pdlen, struct in6_addr *pd, struct blob_attr *cur,
- const struct in6_addr *ipv6prefix, int prefix6len)
+ const struct in6_addr *ipv6prefix, int prefix6len, bool lw4o6)
{
struct blob_attr *d;
unsigned drem;
inet_pton(AF_INET6, blobmsg_get_string(ptb[PREFIX_ATTR_ADDRESS]), &prefix);
// lw4over6 /128-address-as-PD matching madness workaround
- if (mask == 128)
+ if (lw4o6 && mask == 128)
mask = 64;
if (*pdlen < mask && mask >= prefix6len &&
!bmemcmp(&prefix, ipv6prefix, prefix6len)) {
bmemcpy(pd, &prefix, mask);
*pdlen = mask;
+ } else if (lw4o6 && *pdlen < prefix6len && mask < prefix6len &&
+ !bmemcmp(&prefix, ipv6prefix, mask)) {
+ bmemcpy(pd, ipv6prefix, prefix6len);
+ *pdlen = prefix6len;
}
}
}
ealen = intval;
} else if (idx == OPT_PREFIX4LEN && (intval = strtoul(value, NULL, 0)) <= 32 && !errno) {
prefix4len = intval;
- } else if (idx == OPT_PREFIX6LEN && (intval = strtoul(value, NULL, 0)) <= 112 && !errno) {
+ } else if (idx == OPT_PREFIX6LEN && (intval = strtoul(value, NULL, 0)) <= 128 && !errno) {
prefix6len = intval;
} else if (idx == OPT_IPV4PREFIX && inet_pton(AF_INET, value, &ipv4prefix) == 1) {
// dummy
blobmsg_get_string(tb[IFACE_ATTR_INTERFACE]))))
continue;
- match_prefix(&pdlen, &pd, tb[IFACE_ATTR_PREFIX], &ipv6prefix, prefix6len);
+ match_prefix(&pdlen, &pd, tb[IFACE_ATTR_PREFIX], &ipv6prefix, prefix6len, lw4o6);
if (lw4o6)
- match_prefix(&pdlen, &pd, tb[IFACE_ATTR_ADDRESS], &ipv6prefix, prefix6len);
+ match_prefix(&pdlen, &pd, tb[IFACE_ATTR_ADDRESS], &ipv6prefix, prefix6len, lw4o6);
if (pdlen >= 0) {
iface = blobmsg_get_string(tb[IFACE_ATTR_INTERFACE]);