interface-ip: add missing IPv6 policy rule
authorHans Dedecker <dedeckeh@gmail.com>
Thu, 16 Nov 2017 14:42:41 +0000 (15:42 +0100)
committerHans Dedecker <dedeckeh@gmail.com>
Fri, 17 Nov 2017 15:28:36 +0000 (16:28 +0100)
Commit 2f31bff38d4dc2f36006ded6b8a7d039cb569eaa added interface routing
table support; as a result for IPv6 the prefix route linked to the IPv6
address is added to the specified IPv6 interface routing table.
In order to route traffic having as destination the IPv6 prefix a policy
rule is required using the prefix destination as policy so the traffic is
passed to the correct routing table.
The IPv6 prefix address logic was not installing this policy rule effectively
breaking routing when trying to reach a global or ULA IPv6 address in the
lan from either the device or another wan device.

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
interface-ip.c

index 45ffc6611ef8e238fa088964e23bdef25617bb76..1490ca4a7aa3302a22284f3b58413772c1a524cf 100644 (file)
@@ -787,6 +787,10 @@ interface_set_prefix_address(struct device_prefix_assignment *assignment,
                if (!addr.valid_until || addr.valid_until - now > 7200)
                        addr.valid_until = now + 7200;
 
+               if (iface->ip6table)
+                       set_ip_source_policy(false, true, IPRULE_PRIORITY_ADDR_MASK, &addr.addr,
+                                       addr.mask < 64 ? 64 : addr.mask, iface->ip6table, NULL, NULL, false);
+
                if (prefix->iface) {
                        if (prefix->iface->ip6table)
                                set_ip_source_policy(false, true, IPRULE_PRIORITY_NW, &addr.addr,
@@ -803,13 +807,19 @@ interface_set_prefix_address(struct device_prefix_assignment *assignment,
        } else if (add && (iface->state == IFS_UP || iface->state == IFS_SETUP) &&
                        !system_add_address(l3_downlink, &addr)) {
 
-               if (prefix->iface && !assignment->enabled) {
-                       set_ip_source_policy(true, true, IPRULE_PRIORITY_REJECT, &addr.addr,
-                                       addr.mask, 0, iface, "unreachable", true);
+               if (!assignment->enabled) {
+                       if (iface->ip6table)
+                               set_ip_source_policy(true, true, IPRULE_PRIORITY_ADDR_MASK, &addr.addr,
+                                               addr.mask < 64 ? 64 : addr.mask, iface->ip6table, NULL, NULL, false);
 
-                       if (prefix->iface->ip6table)
-                               set_ip_source_policy(true, true, IPRULE_PRIORITY_NW, &addr.addr,
-                                               addr.mask, prefix->iface->ip6table, iface, NULL, true);
+                       if (prefix->iface) {
+                               set_ip_source_policy(true, true, IPRULE_PRIORITY_REJECT, &addr.addr,
+                                               addr.mask, 0, iface, "unreachable", true);
+
+                               if (prefix->iface->ip6table)
+                                       set_ip_source_policy(true, true, IPRULE_PRIORITY_NW, &addr.addr,
+                                                       addr.mask, prefix->iface->ip6table, iface, NULL, true);
+                       }
                }
 
                route.metric = iface->metric;