[OpenWrt-Devel] [PATCH] [odhcp6c] ra: clear RA information and request new after link-up event or SIGUSR2

pavel.merzlyakov at gmail.com pavel.merzlyakov at gmail.com
Mon Mar 18 09:43:28 EDT 2019


From: Pavel Merzlyakov <pavel.merzlyakov at gmail.com>

A subnet may be changed after link-up event

Signed-off-by: Pavel Merzlyakov <pavel.merzlyakov at gmail.com>
---
 src/odhcp6c.c |  3 +++
 src/ra.c      | 20 +++++++++++++++++---
 src/ra.h      |  1 +
 3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/odhcp6c.c b/src/odhcp6c.c
index 19a86f2..dd20f39 100644
--- a/src/odhcp6c.c
+++ b/src/odhcp6c.c
@@ -455,6 +455,9 @@ int main(_unused int argc, char* const argv[])
 
 		syslog(LOG_NOTICE, "(re)starting transaction on %s", ifname);
 
+		if (signal_usr2)
+			ra_restart();
+
 		signal_usr1 = signal_usr2 = false;
 		int mode = dhcpv6_set_ia_mode(ia_na_mode, ia_pd_mode);
 		if (mode != DHCPV6_STATELESS)
diff --git a/src/ra.c b/src/ra.c
index 898f449..917df11 100644
--- a/src/ra.c
+++ b/src/ra.c
@@ -55,6 +55,7 @@ static int sock = -1, rtnl = -1;
 static int if_index = 0;
 static char if_name[IF_NAMESIZE] = {0};
 static volatile int rs_attempt = 0;
+static const int rs_attempt_limit = 4;
 static struct in6_addr lladdr = IN6ADDR_ANY_INIT;
 static unsigned int ra_options = 0;
 static unsigned int ra_holdoff_interval = 0;
@@ -179,6 +180,20 @@ failure:
 	return -1;
 }
 
+void ra_restart(void)
+{
+	const int rs_attempt_old = rs_attempt;
+
+	odhcp6c_clear_state(STATE_RA_PREFIX);
+	odhcp6c_clear_state(STATE_RA_ROUTE);
+	odhcp6c_clear_state(STATE_RA_DNS);
+	odhcp6c_clear_state(STATE_RA_SEARCH);
+
+	rs_attempt = 0;
+	if (rs_attempt_old == 0 || rs_attempt_old >= rs_attempt_limit)
+		ra_send_rs(SIGALRM);
+}
+
 static void ra_send_rs(int signal __attribute__((unused)))
 {
 	const struct sockaddr_in6 dest = {AF_INET6, 0, 0, ALL_IPV6_ROUTERS, if_index};
@@ -193,7 +208,7 @@ static void ra_send_rs(int signal __attribute__((unused)))
 	if (sendto(sock, &rs, len, MSG_DONTWAIT, (struct sockaddr*)&dest, sizeof(dest)) < 0)
 		syslog(LOG_ERR, "Failed to send RS (%s)",  strerror(errno));
 
-	if (++rs_attempt <= 3)
+	if (++rs_attempt < rs_attempt_limit)
 		alarm(4);
 }
 
@@ -243,8 +258,7 @@ bool ra_link_up(void)
 	if (ret) {
 		syslog(LOG_NOTICE, "carrier => %i event on %s", (int)!nocarrier, if_name);
 
-		rs_attempt = 0;
-		ra_send_rs(SIGALRM);
+		ra_restart();
 	}
 
 	return ret;
diff --git a/src/ra.h b/src/ra.h
index 9acc8cd..4ec208f 100644
--- a/src/ra.h
+++ b/src/ra.h
@@ -46,5 +46,6 @@ struct icmpv6_opt_route_info {
 
 int ra_init(const char *ifname, const struct in6_addr *ifid,
 		unsigned int options, unsigned int holdoff_interval);
+void ra_restart(void);
 bool ra_link_up(void);
 bool ra_process(void);
-- 
2.21.0


_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list