This is an attempt to prevent frequently triggering dnsmasq to reload when
only the validity timers have changed.  This is necessary because it seems
the state file is being used for multiple purposes: 1) to transfer address
information to dnsmasq, and 2) to provide state information that is useful
for debugging but not relevant to dnsmasq.

Reference: 
https://lists.openwrt.org/pipermail/openwrt-devel/2013-October/021699.html

Signed-off-by: Nathan Hintz <nlhi...@hotmail.com>
---
 src/dhcpv6-ia.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c
index aced2c0..cce419b 100644
--- a/src/dhcpv6-ia.c
+++ b/src/dhcpv6-ia.c
@@ -203,7 +203,7 @@ static int send_reconf(struct relayd_interface *iface, 
struct assignment *assign
 }
 
 
-static void write_statefile(void)
+static void write_statefile(bool address_change)
 {
        if (config->dhcpv6_statefile) {
                time_t now = monotonic_time(), wall_time = time(NULL);
@@ -272,7 +272,7 @@ static void write_statefile(void)
                fclose(fp);
        }
 
-       if (config->dhcpv6_cb) {
+       if (address_change && config->dhcpv6_cb) {
                char *argv[2] = {config->dhcpv6_cb, NULL};
                if (!vfork()) {
                        execv(argv[0], argv);
@@ -384,7 +384,7 @@ static int prefixcmp(const void *va, const void *vb)
 
 static void update(struct relayd_interface *iface)
 {
-       struct relayd_ipaddr addr[8];
+       struct relayd_ipaddr addr[8], old_addr[8];
        memset(addr, 0, sizeof(addr));
        int len = relayd_get_interface_addresses(iface->ifindex, addr, 8);
 
@@ -396,6 +396,8 @@ static void update(struct relayd_interface *iface)
        time_t now = monotonic_time();
        int minprefix = -1;
 
+       memcpy(old_addr, iface->pd_addr, iface->pd_addr_len * sizeof(*addr));
+
        for (int i = 0; i < len; ++i) {
                if (addr[i].prefix > minprefix)
                        minprefix = addr[i].prefix;
@@ -408,6 +410,11 @@ static void update(struct relayd_interface *iface)
 
                if (addr[i].valid < UINT32_MAX - now)
                        addr[i].valid += now;
+
+               old_addr[i].addr.s6_addr32[2] = addr[i].addr.s6_addr32[2];
+               old_addr[i].addr.s6_addr32[3] = addr[i].addr.s6_addr32[3];
+               old_addr[i].preferred = addr[i].preferred;
+               old_addr[i].valid = addr[i].valid;
        }
 
        struct assignment *border = list_last_entry(&iface->pd_assignments, 
struct assignment, head);
@@ -415,6 +422,8 @@ static void update(struct relayd_interface *iface)
 
        bool change = len != (int)iface->pd_addr_len
                        || memcmp(iface->pd_addr, addr, len * sizeof(*addr));
+       bool address_change = len != (int)iface->pd_addr_len
+                       || memcmp(old_addr, addr, len * sizeof(*addr));
 
        if (change) {
                struct assignment *c;
@@ -461,7 +470,7 @@ static void update(struct relayd_interface *iface)
                        }
                }
 
-               write_statefile();
+               write_statefile(address_change);
        }
 }
 
@@ -885,7 +894,7 @@ size_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct 
relayd_interface *if
        }
 
        if (update_state)
-               write_statefile();
+               write_statefile(true);
 
 out:
        return response_len;
-- 
1.8.3.1
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to