map: be less restrictive when matching lw4over6 prefixes
authorSteven Barth <cyrus@openwrt.org>
Tue, 8 Sep 2015 12:13:29 +0000 (12:13 +0000)
committerSteven Barth <cyrus@openwrt.org>
Tue, 8 Sep 2015 12:13:29 +0000 (12:13 +0000)
Signed-off-by: Steven Barth <steven@midlink.org>
SVN-Revision: 46819

package/network/ipv6/map/Makefile
package/network/ipv6/map/src/mapcalc.c

index 1d42315..f6f2cd6 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=map
 PKG_VERSION:=4
-PKG_RELEASE:=4
+PKG_RELEASE:=5
 PKG_LICENSE:=GPL-2.0
 
 include $(INCLUDE_DIR)/package.mk
index 7aa28e5..648840d 100644 (file)
@@ -3,6 +3,7 @@
  *
  * 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
@@ -112,7 +113,7 @@ static void handle_dump(struct ubus_request *req __attribute__((unused)),
 }
 
 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;
@@ -133,13 +134,17 @@ static void match_prefix(int *pdlen, struct in6_addr *pd, struct blob_attr *cur,
                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;
                }
        }
 }
@@ -237,7 +242,7 @@ int main(int argc, char *argv[])
                                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
@@ -289,10 +294,10 @@ int main(int argc, char *argv[])
                                                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]);