Message ID | 20190318134328.2342-1-pavel.merzlyakov@gmail.com |
---|---|
State | Rejected |
Delegated to: | Hans Dedecker |
Headers | show |
Series | [OpenWrt-Devel,odhcp6c] ra: clear RA information and request new after link-up event or SIGUSR2 | expand |
Hi, On Mon, Mar 18, 2019 at 2:43 PM <pavel.merzlyakov@gmail.com> wrote: > > From: Pavel Merzlyakov <pavel.merzlyakov@gmail.com> > > A subnet may be changed after link-up event Can you be elaborate more in detail what use case you want to cover with this patch; in other words what is not working now ? > > Signed-off-by: Pavel Merzlyakov <pavel.merzlyakov@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(); Why do you want to restart RA if an SIGUSR2 signal is received ? Hans > + > 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@lists.openwrt.org > https://lists.openwrt.org/mailman/listinfo/openwrt-devel
Hi, >Can you be elaborate more in detail what use case you want to cover >with this patch; in other words what is not working now ? Ok, my setup: Two peer routers A and B which both connected to gateway C. Routers A and B have public IPv6 addresses on WAN interfaces from same subnet (because of RA on C) and private IPv6 addresses on LAN interfaces. and issue: If I unplug router B from C and then plug it in LAN port of router A: 1) Router B does not send Router Solicitation message. So router B does not have a valid gateway for some time. 2) Router B does not delete old IPv6 address on the WAN. After first Router Advertisement message router B is capable to send a request via new gateway A, but it can't receive responses because of invalid/old source address in request. >Why do you want to restart RA if an SIGUSR2 signal is received ? Because I assume that SIGUSR2 signal is equivalent to link-up event (see odhcp6c:674 -> https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=19a86f2654bf3c59b0f47cf0aedd87235187bf89;hb=d2e247d8d87ecf8c60fcf0acdad05667bd379521#l674 ). In my case I use hotplug script witch on link-up sends SIGUSR2 signal to odhcp6c (it's connected to bridge interface). ra_restart () could be called without condition in beginning of the main loop. Br, Pavel On Mon, 18 Mar 2019 at 18:26, Hans Dedecker <dedeckeh@gmail.com> wrote: > Hi, > > On Mon, Mar 18, 2019 at 2:43 PM <pavel.merzlyakov@gmail.com> wrote: > > > > From: Pavel Merzlyakov <pavel.merzlyakov@gmail.com> > > > > A subnet may be changed after link-up event > Can you be elaborate more in detail what use case you want to cover > with this patch; in other words what is not working now ? > > > > Signed-off-by: Pavel Merzlyakov <pavel.merzlyakov@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(); > Why do you want to restart RA if an SIGUSR2 signal is received ? > > Hans > > + > > 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@lists.openwrt.org > > https://lists.openwrt.org/mailman/listinfo/openwrt-devel > <div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Hi,<br><br>>Can you be elaborate more in detail what use case you want to cover</div><div>>with this patch; in other words what is not working now ?</div><div>Ok,</div><div>my setup:</div><div><span style="white-space:pre"> </span>Two peer routers A and B which both connected to gateway C.</div><div><span style="white-space:pre"> </span> Routers A and B have public IPv6 addresses on WAN interfaces from same subnet (because of RA on C) and private IPv6 addresses on LAN interfaces.</div><div>and issue:</div><div><span style="white-space:pre"> </span>If I unplug router B from C and then plug it in LAN port of router A:</div><div><span style="white-space:pre"> </span>1) Router B does not send Router Solicitation message. So router B does not have a valid gateway for some time.</div><div><span style="white-space:pre"> </span>2) Router B does not delete old IPv6 address on the WAN. After first Router Advertisement message router B is capable to send a request via new gateway A, but it can't receive responses because of invalid/old source address in request.</div><div><br><br></div><div>>Why do you want to restart RA if an SIGUSR2 signal is received ?</div><div>Because I assume that SIGUSR2 signal is equivalent to link-up event (see odhcp6c:674 -> <a href="https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=19a86f2654bf3c59b0f47cf0aedd87235187bf89;hb=d2e247d8d87ecf8c60fcf0acdad05667bd379521#l674">https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=19a86f2654bf3c59b0f47cf0aedd87235187bf89;hb=d2e247d8d87ecf8c60fcf0acdad05667bd379521#l674</a>).</div><div>In my case I use hotplug script witch on link-up sends SIGUSR2 signal to odhcp6c (it's connected to bridge interface).</div><div>ra_restart () could be called without condition in beginning of the main loop.<br><br>Br,<br>Pavel</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 18 Mar 2019 at 18:26, Hans Dedecker <<a href="mailto:dedeckeh@gmail.com">dedeckeh@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br> <br> On Mon, Mar 18, 2019 at 2:43 PM <<a href="mailto:pavel.merzlyakov@gmail.com" target="_blank">pavel.merzlyakov@gmail.com</a>> wrote:<br> ><br> > From: Pavel Merzlyakov <<a href="mailto:pavel.merzlyakov@gmail.com" target="_blank">pavel.merzlyakov@gmail.com</a>><br> ><br> > A subnet may be changed after link-up event<br> Can you be elaborate more in detail what use case you want to cover<br> with this patch; in other words what is not working now ?<br> ><br> > Signed-off-by: Pavel Merzlyakov <<a href="mailto:pavel.merzlyakov@gmail.com" target="_blank">pavel.merzlyakov@gmail.com</a>><br> > ---<br> > src/odhcp6c.c | 3 +++<br> > src/ra.c | 20 +++++++++++++++++---<br> > src/ra.h | 1 +<br> > 3 files changed, 21 insertions(+), 3 deletions(-)<br> ><br> > diff --git a/src/odhcp6c.c b/src/odhcp6c.c<br> > index 19a86f2..dd20f39 100644<br> > --- a/src/odhcp6c.c<br> > +++ b/src/odhcp6c.c<br> > @@ -455,6 +455,9 @@ int main(_unused int argc, char* const argv[])<br> ><br> > syslog(LOG_NOTICE, "(re)starting transaction on %s", ifname);<br> ><br> > + if (signal_usr2)<br> > + ra_restart();<br> Why do you want to restart RA if an SIGUSR2 signal is received ?<br> <br> Hans<br> > +<br> > signal_usr1 = signal_usr2 = false;<br> > int mode = dhcpv6_set_ia_mode(ia_na_mode, ia_pd_mode);<br> > if (mode != DHCPV6_STATELESS)<br> > diff --git a/src/ra.c b/src/ra.c<br> > index 898f449..917df11 100644<br> > --- a/src/ra.c<br> > +++ b/src/ra.c<br> > @@ -55,6 +55,7 @@ static int sock = -1, rtnl = -1;<br> > static int if_index = 0;<br> > static char if_name[IF_NAMESIZE] = {0};<br> > static volatile int rs_attempt = 0;<br> > +static const int rs_attempt_limit = 4;<br> > static struct in6_addr lladdr = IN6ADDR_ANY_INIT;<br> > static unsigned int ra_options = 0;<br> > static unsigned int ra_holdoff_interval = 0;<br> > @@ -179,6 +180,20 @@ failure:<br> > return -1;<br> > }<br> ><br> > +void ra_restart(void)<br> > +{<br> > + const int rs_attempt_old = rs_attempt;<br> > +<br> > + odhcp6c_clear_state(STATE_RA_PREFIX);<br> > + odhcp6c_clear_state(STATE_RA_ROUTE);<br> > + odhcp6c_clear_state(STATE_RA_DNS);<br> > + odhcp6c_clear_state(STATE_RA_SEARCH);<br> > +<br> > + rs_attempt = 0;<br> > + if (rs_attempt_old == 0 || rs_attempt_old >= rs_attempt_limit)<br> > + ra_send_rs(SIGALRM);<br> > +}<br> > +<br> > static void ra_send_rs(int signal __attribute__((unused)))<br> > {<br> > const struct sockaddr_in6 dest = {AF_INET6, 0, 0, ALL_IPV6_ROUTERS, if_index};<br> > @@ -193,7 +208,7 @@ static void ra_send_rs(int signal __attribute__((unused)))<br> > if (sendto(sock, &rs, len, MSG_DONTWAIT, (struct sockaddr*)&dest, sizeof(dest)) < 0)<br> > syslog(LOG_ERR, "Failed to send RS (%s)", strerror(errno));<br> ><br> > - if (++rs_attempt <= 3)<br> > + if (++rs_attempt < rs_attempt_limit)<br> > alarm(4);<br> > }<br> ><br> > @@ -243,8 +258,7 @@ bool ra_link_up(void)<br> > if (ret) {<br> > syslog(LOG_NOTICE, "carrier => %i event on %s", (int)!nocarrier, if_name);<br> ><br> > - rs_attempt = 0;<br> > - ra_send_rs(SIGALRM);<br> > + ra_restart();<br> > }<br> ><br> > return ret;<br> > diff --git a/src/ra.h b/src/ra.h<br> > index 9acc8cd..4ec208f 100644<br> > --- a/src/ra.h<br> > +++ b/src/ra.h<br> > @@ -46,5 +46,6 @@ struct icmpv6_opt_route_info {<br> ><br> > int ra_init(const char *ifname, const struct in6_addr *ifid,<br> > unsigned int options, unsigned int holdoff_interval);<br> > +void ra_restart(void);<br> > bool ra_link_up(void);<br> > bool ra_process(void);<br> > --<br> > 2.21.0<br> ><br> ><br> > _______________________________________________<br> > openwrt-devel mailing list<br> > <a href="mailto:openwrt-devel@lists.openwrt.org" target="_blank">openwrt-devel@lists.openwrt.org</a><br> > <a href="https://lists.openwrt.org/mailman/listinfo/openwrt-devel" rel="noreferrer" target="_blank">https://lists.openwrt.org/mailman/listinfo/openwrt-devel</a><br> </blockquote></div></div>
Hi, On Mon, Mar 18, 2019 at 8:51 PM Pavel Merzlyakov <pavel.merzlyakov@gmail.com> wrote: > > Hi, > > >Can you be elaborate more in detail what use case you want to cover > >with this patch; in other words what is not working now ? > Ok, > my setup: > Two peer routers A and B which both connected to gateway C. > Routers A and B have public IPv6 addresses on WAN interfaces from same subnet (because of RA on C) and private IPv6 addresses on LAN interfaces. > and issue: > If I unplug router B from C and then plug it in LAN port of router A: > 1) Router B does not send Router Solicitation message. So router B does not have a valid gateway for some time. Since we've linksensing support in netifd the wan/wan6 interface should be brought down when the cable is unplugged; the wan/wan6 interface will be brought up again when the cable is plugged in. This means odhcp6c will be restarted and will start sending RS; why is this not the case in your setup ? Hans > 2) Router B does not delete old IPv6 address on the WAN. After first Router Advertisement message router B is capable to send a request via new gateway A, but it can't receive responses because of invalid/old source address in request. > > > >Why do you want to restart RA if an SIGUSR2 signal is received ? > Because I assume that SIGUSR2 signal is equivalent to link-up event (see odhcp6c:674 -> https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=19a86f2654bf3c59b0f47cf0aedd87235187bf89;hb=d2e247d8d87ecf8c60fcf0acdad05667bd379521#l674). > In my case I use hotplug script witch on link-up sends SIGUSR2 signal to odhcp6c (it's connected to bridge interface). > ra_restart () could be called without condition in beginning of the main loop. > > Br, > Pavel > > On Mon, 18 Mar 2019 at 18:26, Hans Dedecker <dedeckeh@gmail.com> wrote: >> >> Hi, >> >> On Mon, Mar 18, 2019 at 2:43 PM <pavel.merzlyakov@gmail.com> wrote: >> > >> > From: Pavel Merzlyakov <pavel.merzlyakov@gmail.com> >> > >> > A subnet may be changed after link-up event >> Can you be elaborate more in detail what use case you want to cover >> with this patch; in other words what is not working now ? >> > >> > Signed-off-by: Pavel Merzlyakov <pavel.merzlyakov@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(); >> Why do you want to restart RA if an SIGUSR2 signal is received ? >> >> Hans >> > + >> > 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@lists.openwrt.org >> > https://lists.openwrt.org/mailman/listinfo/openwrt-devel
>why is this not the case in your setup ? Because sometimes odhcp6c miss restart, probably because of Bridge Mode (it's attached to bridge interface). Anyway, I use a hotplug script which sends SIGUSR2 signal to odhcp6c on link-up event. Of course I could send SIGTERM, but I think it's not the proper way to solve problem. I thought that it is an obvious bug because I see a lack of consistency. Why odhcp6c on SIGUSR2 clear STATE_IA_ and resend DHCPV6_MSG_ and don't do same with RA - clear STATE_RA_ and resend Router Solicitation message? Br, Pavel On Tue, 19 Mar 2019 at 12:36, Hans Dedecker <dedeckeh@gmail.com> wrote: > Hi, > > On Mon, Mar 18, 2019 at 8:51 PM Pavel Merzlyakov > <pavel.merzlyakov@gmail.com> wrote: > > > > Hi, > > > > >Can you be elaborate more in detail what use case you want to cover > > >with this patch; in other words what is not working now ? > > Ok, > > my setup: > > Two peer routers A and B which both connected to gateway C. > > Routers A and B have public IPv6 addresses on WAN interfaces from same > subnet (because of RA on C) and private IPv6 addresses on LAN interfaces. > > and issue: > > If I unplug router B from C and then plug it in LAN port of router A: > > 1) Router B does not send Router Solicitation message. So router B does > not have a valid gateway for some time. > Since we've linksensing support in netifd the wan/wan6 interface > should be brought down when the cable is unplugged; the wan/wan6 > interface will be brought up again when the cable is plugged in. This > means odhcp6c will be restarted and will start sending RS; why is this > not the case in your setup ? > > Hans > > 2) Router B does not delete old IPv6 address on the WAN. After first > Router Advertisement message router B is capable to send a request via new > gateway A, but it can't receive responses because of invalid/old source > address in request. > > > > > > >Why do you want to restart RA if an SIGUSR2 signal is received ? > > Because I assume that SIGUSR2 signal is equivalent to link-up event > (see odhcp6c:674 -> > https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=19a86f2654bf3c59b0f47cf0aedd87235187bf89;hb=d2e247d8d87ecf8c60fcf0acdad05667bd379521#l674 > ). > > In my case I use hotplug script witch on link-up sends SIGUSR2 signal to > odhcp6c (it's connected to bridge interface). > > ra_restart () could be called without condition in beginning of the main > loop. > > > > Br, > > Pavel > > > > On Mon, 18 Mar 2019 at 18:26, Hans Dedecker <dedeckeh@gmail.com> wrote: > >> > >> Hi, > >> > >> On Mon, Mar 18, 2019 at 2:43 PM <pavel.merzlyakov@gmail.com> wrote: > >> > > >> > From: Pavel Merzlyakov <pavel.merzlyakov@gmail.com> > >> > > >> > A subnet may be changed after link-up event > >> Can you be elaborate more in detail what use case you want to cover > >> with this patch; in other words what is not working now ? > >> > > >> > Signed-off-by: Pavel Merzlyakov <pavel.merzlyakov@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(); > >> Why do you want to restart RA if an SIGUSR2 signal is received ? > >> > >> Hans > >> > + > >> > 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@lists.openwrt.org > >> > https://lists.openwrt.org/mailman/listinfo/openwrt-devel > <div dir="ltr"><div dir="ltr"><div>>why is this not the case in your setup ?</div><div>Because sometimes odhcp6c miss restart, probably because of Bridge Mode (it's attached to bridge interface).</div><div>Anyway, I use a hotplug script which sends SIGUSR2 signal to odhcp6c on link-up event.</div><div>Of course I could send SIGTERM, but I think it's not the proper way to solve problem.</div><div><br></div><div>I thought that it is an obvious bug because I see a lack of consistency.</div><div>Why odhcp6c on SIGUSR2 </div><div>clear STATE_IA_ and resend DHCPV6_MSG_</div><div>and don't do same with RA - clear STATE_RA_ and resend Router Solicitation message?<br><br>Br,<br>Pavel</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 19 Mar 2019 at 12:36, Hans Dedecker <<a href="mailto:dedeckeh@gmail.com">dedeckeh@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br> <br> On Mon, Mar 18, 2019 at 8:51 PM Pavel Merzlyakov<br> <<a href="mailto:pavel.merzlyakov@gmail.com" target="_blank">pavel.merzlyakov@gmail.com</a>> wrote:<br> ><br> > Hi,<br> ><br> > >Can you be elaborate more in detail what use case you want to cover<br> > >with this patch; in other words what is not working now ?<br> > Ok,<br> > my setup:<br> > Two peer routers A and B which both connected to gateway C.<br> > Routers A and B have public IPv6 addresses on WAN interfaces from same subnet (because of RA on C) and private IPv6 addresses on LAN interfaces.<br> > and issue:<br> > If I unplug router B from C and then plug it in LAN port of router A:<br> > 1) Router B does not send Router Solicitation message. So router B does not have a valid gateway for some time.<br> Since we've linksensing support in netifd the wan/wan6 interface<br> should be brought down when the cable is unplugged; the wan/wan6<br> interface will be brought up again when the cable is plugged in. This<br> means odhcp6c will be restarted and will start sending RS; why is this<br> not the case in your setup ?<br> <br> Hans<br> > 2) Router B does not delete old IPv6 address on the WAN. After first Router Advertisement message router B is capable to send a request via new gateway A, but it can't receive responses because of invalid/old source address in request.<br> ><br> ><br> > >Why do you want to restart RA if an SIGUSR2 signal is received ?<br> > Because I assume that SIGUSR2 signal is equivalent to link-up event (see odhcp6c:674 -> <a href="https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=19a86f2654bf3c59b0f47cf0aedd87235187bf89;hb=d2e247d8d87ecf8c60fcf0acdad05667bd379521#l674" rel="noreferrer" target="_blank">https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=19a86f2654bf3c59b0f47cf0aedd87235187bf89;hb=d2e247d8d87ecf8c60fcf0acdad05667bd379521#l674</a>).<br> > In my case I use hotplug script witch on link-up sends SIGUSR2 signal to odhcp6c (it's connected to bridge interface).<br> > ra_restart () could be called without condition in beginning of the main loop.<br> ><br> > Br,<br> > Pavel<br> ><br> > On Mon, 18 Mar 2019 at 18:26, Hans Dedecker <<a href="mailto:dedeckeh@gmail.com" target="_blank">dedeckeh@gmail.com</a>> wrote:<br> >><br> >> Hi,<br> >><br> >> On Mon, Mar 18, 2019 at 2:43 PM <<a href="mailto:pavel.merzlyakov@gmail.com" target="_blank">pavel.merzlyakov@gmail.com</a>> wrote:<br> >> ><br> >> > From: Pavel Merzlyakov <<a href="mailto:pavel.merzlyakov@gmail.com" target="_blank">pavel.merzlyakov@gmail.com</a>><br> >> ><br> >> > A subnet may be changed after link-up event<br> >> Can you be elaborate more in detail what use case you want to cover<br> >> with this patch; in other words what is not working now ?<br> >> ><br> >> > Signed-off-by: Pavel Merzlyakov <<a href="mailto:pavel.merzlyakov@gmail.com" target="_blank">pavel.merzlyakov@gmail.com</a>><br> >> > ---<br> >> > src/odhcp6c.c | 3 +++<br> >> > src/ra.c | 20 +++++++++++++++++---<br> >> > src/ra.h | 1 +<br> >> > 3 files changed, 21 insertions(+), 3 deletions(-)<br> >> ><br> >> > diff --git a/src/odhcp6c.c b/src/odhcp6c.c<br> >> > index 19a86f2..dd20f39 100644<br> >> > --- a/src/odhcp6c.c<br> >> > +++ b/src/odhcp6c.c<br> >> > @@ -455,6 +455,9 @@ int main(_unused int argc, char* const argv[])<br> >> ><br> >> > syslog(LOG_NOTICE, "(re)starting transaction on %s", ifname);<br> >> ><br> >> > + if (signal_usr2)<br> >> > + ra_restart();<br> >> Why do you want to restart RA if an SIGUSR2 signal is received ?<br> >><br> >> Hans<br> >> > +<br> >> > signal_usr1 = signal_usr2 = false;<br> >> > int mode = dhcpv6_set_ia_mode(ia_na_mode, ia_pd_mode);<br> >> > if (mode != DHCPV6_STATELESS)<br> >> > diff --git a/src/ra.c b/src/ra.c<br> >> > index 898f449..917df11 100644<br> >> > --- a/src/ra.c<br> >> > +++ b/src/ra.c<br> >> > @@ -55,6 +55,7 @@ static int sock = -1, rtnl = -1;<br> >> > static int if_index = 0;<br> >> > static char if_name[IF_NAMESIZE] = {0};<br> >> > static volatile int rs_attempt = 0;<br> >> > +static const int rs_attempt_limit = 4;<br> >> > static struct in6_addr lladdr = IN6ADDR_ANY_INIT;<br> >> > static unsigned int ra_options = 0;<br> >> > static unsigned int ra_holdoff_interval = 0;<br> >> > @@ -179,6 +180,20 @@ failure:<br> >> > return -1;<br> >> > }<br> >> ><br> >> > +void ra_restart(void)<br> >> > +{<br> >> > + const int rs_attempt_old = rs_attempt;<br> >> > +<br> >> > + odhcp6c_clear_state(STATE_RA_PREFIX);<br> >> > + odhcp6c_clear_state(STATE_RA_ROUTE);<br> >> > + odhcp6c_clear_state(STATE_RA_DNS);<br> >> > + odhcp6c_clear_state(STATE_RA_SEARCH);<br> >> > +<br> >> > + rs_attempt = 0;<br> >> > + if (rs_attempt_old == 0 || rs_attempt_old >= rs_attempt_limit)<br> >> > + ra_send_rs(SIGALRM);<br> >> > +}<br> >> > +<br> >> > static void ra_send_rs(int signal __attribute__((unused)))<br> >> > {<br> >> > const struct sockaddr_in6 dest = {AF_INET6, 0, 0, ALL_IPV6_ROUTERS, if_index};<br> >> > @@ -193,7 +208,7 @@ static void ra_send_rs(int signal __attribute__((unused)))<br> >> > if (sendto(sock, &rs, len, MSG_DONTWAIT, (struct sockaddr*)&dest, sizeof(dest)) < 0)<br> >> > syslog(LOG_ERR, "Failed to send RS (%s)", strerror(errno));<br> >> ><br> >> > - if (++rs_attempt <= 3)<br> >> > + if (++rs_attempt < rs_attempt_limit)<br> >> > alarm(4);<br> >> > }<br> >> ><br> >> > @@ -243,8 +258,7 @@ bool ra_link_up(void)<br> >> > if (ret) {<br> >> > syslog(LOG_NOTICE, "carrier => %i event on %s", (int)!nocarrier, if_name);<br> >> ><br> >> > - rs_attempt = 0;<br> >> > - ra_send_rs(SIGALRM);<br> >> > + ra_restart();<br> >> > }<br> >> ><br> >> > return ret;<br> >> > diff --git a/src/ra.h b/src/ra.h<br> >> > index 9acc8cd..4ec208f 100644<br> >> > --- a/src/ra.h<br> >> > +++ b/src/ra.h<br> >> > @@ -46,5 +46,6 @@ struct icmpv6_opt_route_info {<br> >> ><br> >> > int ra_init(const char *ifname, const struct in6_addr *ifid,<br> >> > unsigned int options, unsigned int holdoff_interval);<br> >> > +void ra_restart(void);<br> >> > bool ra_link_up(void);<br> >> > bool ra_process(void);<br> >> > --<br> >> > 2.21.0<br> >> ><br> >> ><br> >> > _______________________________________________<br> >> > openwrt-devel mailing list<br> >> > <a href="mailto:openwrt-devel@lists.openwrt.org" target="_blank">openwrt-devel@lists.openwrt.org</a><br> >> > <a href="https://lists.openwrt.org/mailman/listinfo/openwrt-devel" rel="noreferrer" target="_blank">https://lists.openwrt.org/mailman/listinfo/openwrt-devel</a><br> </blockquote></div>
On Tue, Mar 19, 2019 at 1:15 PM Pavel Merzlyakov <pavel.merzlyakov@gmail.com> wrote: > > >why is this not the case in your setup ? > Because sometimes odhcp6c miss restart, probably because of Bridge Mode (it's attached to bridge interface). Can you share the network config you're using ? > Anyway, I use a hotplug script which sends SIGUSR2 signal to odhcp6c on link-up event. > Of course I could send SIGTERM, but I think it's not the proper way to solve problem. > > I thought that it is an obvious bug because I see a lack of consistency. > Why odhcp6c on SIGUSR2 > clear STATE_IA_ and resend DHCPV6_MSG_ > and don't do same with RA - clear STATE_RA_ and resend Router Solicitation message? This was the approach by the original author of the code to control only DHCPv6 via SIGUSR1 and SIGUSR2. I understand your need to trigger the sending of RS via a signal but I'm reluctant to change the current behavior of the SIGUSR2 signal as I would prefer to use another signal to trigger the sending of RS. Hans > > Br, > Pavel > > On Tue, 19 Mar 2019 at 12:36, Hans Dedecker <dedeckeh@gmail.com> wrote: >> >> Hi, >> >> On Mon, Mar 18, 2019 at 8:51 PM Pavel Merzlyakov >> <pavel.merzlyakov@gmail.com> wrote: >> > >> > Hi, >> > >> > >Can you be elaborate more in detail what use case you want to cover >> > >with this patch; in other words what is not working now ? >> > Ok, >> > my setup: >> > Two peer routers A and B which both connected to gateway C. >> > Routers A and B have public IPv6 addresses on WAN interfaces from same subnet (because of RA on C) and private IPv6 addresses on LAN interfaces. >> > and issue: >> > If I unplug router B from C and then plug it in LAN port of router A: >> > 1) Router B does not send Router Solicitation message. So router B does not have a valid gateway for some time. >> Since we've linksensing support in netifd the wan/wan6 interface >> should be brought down when the cable is unplugged; the wan/wan6 >> interface will be brought up again when the cable is plugged in. This >> means odhcp6c will be restarted and will start sending RS; why is this >> not the case in your setup ? >> >> Hans >> > 2) Router B does not delete old IPv6 address on the WAN. After first Router Advertisement message router B is capable to send a request via new gateway A, but it can't receive responses because of invalid/old source address in request. >> > >> > >> > >Why do you want to restart RA if an SIGUSR2 signal is received ? >> > Because I assume that SIGUSR2 signal is equivalent to link-up event (see odhcp6c:674 -> https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=19a86f2654bf3c59b0f47cf0aedd87235187bf89;hb=d2e247d8d87ecf8c60fcf0acdad05667bd379521#l674). >> > In my case I use hotplug script witch on link-up sends SIGUSR2 signal to odhcp6c (it's connected to bridge interface). >> > ra_restart () could be called without condition in beginning of the main loop. >> > >> > Br, >> > Pavel >> > >> > On Mon, 18 Mar 2019 at 18:26, Hans Dedecker <dedeckeh@gmail.com> wrote: >> >> >> >> Hi, >> >> >> >> On Mon, Mar 18, 2019 at 2:43 PM <pavel.merzlyakov@gmail.com> wrote: >> >> > >> >> > From: Pavel Merzlyakov <pavel.merzlyakov@gmail.com> >> >> > >> >> > A subnet may be changed after link-up event >> >> Can you be elaborate more in detail what use case you want to cover >> >> with this patch; in other words what is not working now ? >> >> > >> >> > Signed-off-by: Pavel Merzlyakov <pavel.merzlyakov@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(); >> >> Why do you want to restart RA if an SIGUSR2 signal is received ? >> >> >> >> Hans >> >> > + >> >> > 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@lists.openwrt.org >> >> > https://lists.openwrt.org/mailman/listinfo/openwrt-devel
>Can you share the network config you're using ? I'm sorry I can't do this. >I would prefer to use another signal to trigger the sending of RS. Of course, it's up to you. But I think there should be some signal witch restart both RA and DHCPv6. Regarding to the patch do you agree that we must clear STATE_RA_ on link-up event before we trigger Router Solicitation message (see ra.c:247 -> https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/ra.c;h=898f449168e29bae08e48e9395f420d13b2ec899;hb=HEAD#l247 )? Br, Pavel On Wed, 20 Mar 2019 at 10:52, Hans Dedecker <dedeckeh@gmail.com> wrote: > On Tue, Mar 19, 2019 at 1:15 PM Pavel Merzlyakov > <pavel.merzlyakov@gmail.com> wrote: > > > > >why is this not the case in your setup ? > > Because sometimes odhcp6c miss restart, probably because of Bridge Mode > (it's attached to bridge interface). > Can you share the network config you're using ? > > > Anyway, I use a hotplug script which sends SIGUSR2 signal to odhcp6c on > link-up event. > > Of course I could send SIGTERM, but I think it's not the proper way to > solve problem. > > > > I thought that it is an obvious bug because I see a lack of consistency. > > Why odhcp6c on SIGUSR2 > > clear STATE_IA_ and resend DHCPV6_MSG_ > > and don't do same with RA - clear STATE_RA_ and resend Router > Solicitation message? > This was the approach by the original author of the code to control > only DHCPv6 via SIGUSR1 and SIGUSR2. > I understand your need to trigger the sending of RS via a signal but > I'm reluctant to change the current behavior of the SIGUSR2 signal as > I would prefer to use another signal to trigger the sending of RS. > > Hans > > > > Br, > > Pavel > > > > On Tue, 19 Mar 2019 at 12:36, Hans Dedecker <dedeckeh@gmail.com> wrote: > >> > >> Hi, > >> > >> On Mon, Mar 18, 2019 at 8:51 PM Pavel Merzlyakov > >> <pavel.merzlyakov@gmail.com> wrote: > >> > > >> > Hi, > >> > > >> > >Can you be elaborate more in detail what use case you want to cover > >> > >with this patch; in other words what is not working now ? > >> > Ok, > >> > my setup: > >> > Two peer routers A and B which both connected to gateway C. > >> > Routers A and B have public IPv6 addresses on WAN interfaces from > same subnet (because of RA on C) and private IPv6 addresses on LAN > interfaces. > >> > and issue: > >> > If I unplug router B from C and then plug it in LAN port of router A: > >> > 1) Router B does not send Router Solicitation message. So router B > does not have a valid gateway for some time. > >> Since we've linksensing support in netifd the wan/wan6 interface > >> should be brought down when the cable is unplugged; the wan/wan6 > >> interface will be brought up again when the cable is plugged in. This > >> means odhcp6c will be restarted and will start sending RS; why is this > >> not the case in your setup ? > >> > >> Hans > >> > 2) Router B does not delete old IPv6 address on the WAN. After first > Router Advertisement message router B is capable to send a request via new > gateway A, but it can't receive responses because of invalid/old source > address in request. > >> > > >> > > >> > >Why do you want to restart RA if an SIGUSR2 signal is received ? > >> > Because I assume that SIGUSR2 signal is equivalent to link-up event > (see odhcp6c:674 -> > https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=19a86f2654bf3c59b0f47cf0aedd87235187bf89;hb=d2e247d8d87ecf8c60fcf0acdad05667bd379521#l674 > ). > >> > In my case I use hotplug script witch on link-up sends SIGUSR2 signal > to odhcp6c (it's connected to bridge interface). > >> > ra_restart () could be called without condition in beginning of the > main loop. > >> > > >> > Br, > >> > Pavel > >> > > >> > On Mon, 18 Mar 2019 at 18:26, Hans Dedecker <dedeckeh@gmail.com> > wrote: > >> >> > >> >> Hi, > >> >> > >> >> On Mon, Mar 18, 2019 at 2:43 PM <pavel.merzlyakov@gmail.com> wrote: > >> >> > > >> >> > From: Pavel Merzlyakov <pavel.merzlyakov@gmail.com> > >> >> > > >> >> > A subnet may be changed after link-up event > >> >> Can you be elaborate more in detail what use case you want to cover > >> >> with this patch; in other words what is not working now ? > >> >> > > >> >> > Signed-off-by: Pavel Merzlyakov <pavel.merzlyakov@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(); > >> >> Why do you want to restart RA if an SIGUSR2 signal is received ? > >> >> > >> >> Hans > >> >> > + > >> >> > 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@lists.openwrt.org > >> >> > https://lists.openwrt.org/mailman/listinfo/openwrt-devel > <div dir="ltr"><div dir="ltr"><div><p> >Can you share the network config you're using ?<br> I'm sorry I can't do this. </p> <p> >I would prefer to use another signal to trigger the sending of RS.<br> Of course, it's up to you.<br> But I think there should be some signal witch restart both RA and DHCPv6. </p> <p> Regarding to the patch<br> do you agree that we must clear STATE_RA_ on link-up event<br> before we trigger Router Solicitation message (see <a title="ra.c:247" class="gmail-page">ra.c:247</a> -> <a href="https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/ra.c;h=898f449168e29bae08e48e9395f420d13b2ec899;hb=HEAD#l247" title="https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/ra.c;h=898f449168e29bae08e48e9395f420d13b2ec899;hb=HEAD#l247" class="gmail-https">https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/ra.c;h=898f449168e29bae08e48e9395f420d13b2ec899;hb=HEAD#l247</a>)? </p></div><div>Br,<br>Pavel</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 20 Mar 2019 at 10:52, Hans Dedecker <<a href="mailto:dedeckeh@gmail.com">dedeckeh@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Tue, Mar 19, 2019 at 1:15 PM Pavel Merzlyakov<br> <<a href="mailto:pavel.merzlyakov@gmail.com" target="_blank">pavel.merzlyakov@gmail.com</a>> wrote:<br> ><br> > >why is this not the case in your setup ?<br> > Because sometimes odhcp6c miss restart, probably because of Bridge Mode (it's attached to bridge interface).<br> Can you share the network config you're using ?<br> <br> > Anyway, I use a hotplug script which sends SIGUSR2 signal to odhcp6c on link-up event.<br> > Of course I could send SIGTERM, but I think it's not the proper way to solve problem.<br> ><br> > I thought that it is an obvious bug because I see a lack of consistency.<br> > Why odhcp6c on SIGUSR2<br> > clear STATE_IA_ and resend DHCPV6_MSG_<br> > and don't do same with RA - clear STATE_RA_ and resend Router Solicitation message?<br> This was the approach by the original author of the code to control<br> only DHCPv6 via SIGUSR1 and SIGUSR2.<br> I understand your need to trigger the sending of RS via a signal but<br> I'm reluctant to change the current behavior of the SIGUSR2 signal as<br> I would prefer to use another signal to trigger the sending of RS.<br> <br> Hans<br> ><br> > Br,<br> > Pavel<br> ><br> > On Tue, 19 Mar 2019 at 12:36, Hans Dedecker <<a href="mailto:dedeckeh@gmail.com" target="_blank">dedeckeh@gmail.com</a>> wrote:<br> >><br> >> Hi,<br> >><br> >> On Mon, Mar 18, 2019 at 8:51 PM Pavel Merzlyakov<br> >> <<a href="mailto:pavel.merzlyakov@gmail.com" target="_blank">pavel.merzlyakov@gmail.com</a>> wrote:<br> >> ><br> >> > Hi,<br> >> ><br> >> > >Can you be elaborate more in detail what use case you want to cover<br> >> > >with this patch; in other words what is not working now ?<br> >> > Ok,<br> >> > my setup:<br> >> > Two peer routers A and B which both connected to gateway C.<br> >> > Routers A and B have public IPv6 addresses on WAN interfaces from same subnet (because of RA on C) and private IPv6 addresses on LAN interfaces.<br> >> > and issue:<br> >> > If I unplug router B from C and then plug it in LAN port of router A:<br> >> > 1) Router B does not send Router Solicitation message. So router B does not have a valid gateway for some time.<br> >> Since we've linksensing support in netifd the wan/wan6 interface<br> >> should be brought down when the cable is unplugged; the wan/wan6<br> >> interface will be brought up again when the cable is plugged in. This<br> >> means odhcp6c will be restarted and will start sending RS; why is this<br> >> not the case in your setup ?<br> >><br> >> Hans<br> >> > 2) Router B does not delete old IPv6 address on the WAN. After first Router Advertisement message router B is capable to send a request via new gateway A, but it can't receive responses because of invalid/old source address in request.<br> >> ><br> >> ><br> >> > >Why do you want to restart RA if an SIGUSR2 signal is received ?<br> >> > Because I assume that SIGUSR2 signal is equivalent to link-up event (see odhcp6c:674 -> <a href="https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=19a86f2654bf3c59b0f47cf0aedd87235187bf89;hb=d2e247d8d87ecf8c60fcf0acdad05667bd379521#l674" rel="noreferrer" target="_blank">https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=19a86f2654bf3c59b0f47cf0aedd87235187bf89;hb=d2e247d8d87ecf8c60fcf0acdad05667bd379521#l674</a>).<br> >> > In my case I use hotplug script witch on link-up sends SIGUSR2 signal to odhcp6c (it's connected to bridge interface).<br> >> > ra_restart () could be called without condition in beginning of the main loop.<br> >> ><br> >> > Br,<br> >> > Pavel<br> >> ><br> >> > On Mon, 18 Mar 2019 at 18:26, Hans Dedecker <<a href="mailto:dedeckeh@gmail.com" target="_blank">dedeckeh@gmail.com</a>> wrote:<br> >> >><br> >> >> Hi,<br> >> >><br> >> >> On Mon, Mar 18, 2019 at 2:43 PM <<a href="mailto:pavel.merzlyakov@gmail.com" target="_blank">pavel.merzlyakov@gmail.com</a>> wrote:<br> >> >> ><br> >> >> > From: Pavel Merzlyakov <<a href="mailto:pavel.merzlyakov@gmail.com" target="_blank">pavel.merzlyakov@gmail.com</a>><br> >> >> ><br> >> >> > A subnet may be changed after link-up event<br> >> >> Can you be elaborate more in detail what use case you want to cover<br> >> >> with this patch; in other words what is not working now ?<br> >> >> ><br> >> >> > Signed-off-by: Pavel Merzlyakov <<a href="mailto:pavel.merzlyakov@gmail.com" target="_blank">pavel.merzlyakov@gmail.com</a>><br> >> >> > ---<br> >> >> > src/odhcp6c.c | 3 +++<br> >> >> > src/ra.c | 20 +++++++++++++++++---<br> >> >> > src/ra.h | 1 +<br> >> >> > 3 files changed, 21 insertions(+), 3 deletions(-)<br> >> >> ><br> >> >> > diff --git a/src/odhcp6c.c b/src/odhcp6c.c<br> >> >> > index 19a86f2..dd20f39 100644<br> >> >> > --- a/src/odhcp6c.c<br> >> >> > +++ b/src/odhcp6c.c<br> >> >> > @@ -455,6 +455,9 @@ int main(_unused int argc, char* const argv[])<br> >> >> ><br> >> >> > syslog(LOG_NOTICE, "(re)starting transaction on %s", ifname);<br> >> >> ><br> >> >> > + if (signal_usr2)<br> >> >> > + ra_restart();<br> >> >> Why do you want to restart RA if an SIGUSR2 signal is received ?<br> >> >><br> >> >> Hans<br> >> >> > +<br> >> >> > signal_usr1 = signal_usr2 = false;<br> >> >> > int mode = dhcpv6_set_ia_mode(ia_na_mode, ia_pd_mode);<br> >> >> > if (mode != DHCPV6_STATELESS)<br> >> >> > diff --git a/src/ra.c b/src/ra.c<br> >> >> > index 898f449..917df11 100644<br> >> >> > --- a/src/ra.c<br> >> >> > +++ b/src/ra.c<br> >> >> > @@ -55,6 +55,7 @@ static int sock = -1, rtnl = -1;<br> >> >> > static int if_index = 0;<br> >> >> > static char if_name[IF_NAMESIZE] = {0};<br> >> >> > static volatile int rs_attempt = 0;<br> >> >> > +static const int rs_attempt_limit = 4;<br> >> >> > static struct in6_addr lladdr = IN6ADDR_ANY_INIT;<br> >> >> > static unsigned int ra_options = 0;<br> >> >> > static unsigned int ra_holdoff_interval = 0;<br> >> >> > @@ -179,6 +180,20 @@ failure:<br> >> >> > return -1;<br> >> >> > }<br> >> >> ><br> >> >> > +void ra_restart(void)<br> >> >> > +{<br> >> >> > + const int rs_attempt_old = rs_attempt;<br> >> >> > +<br> >> >> > + odhcp6c_clear_state(STATE_RA_PREFIX);<br> >> >> > + odhcp6c_clear_state(STATE_RA_ROUTE);<br> >> >> > + odhcp6c_clear_state(STATE_RA_DNS);<br> >> >> > + odhcp6c_clear_state(STATE_RA_SEARCH);<br> >> >> > +<br> >> >> > + rs_attempt = 0;<br> >> >> > + if (rs_attempt_old == 0 || rs_attempt_old >= rs_attempt_limit)<br> >> >> > + ra_send_rs(SIGALRM);<br> >> >> > +}<br> >> >> > +<br> >> >> > static void ra_send_rs(int signal __attribute__((unused)))<br> >> >> > {<br> >> >> > const struct sockaddr_in6 dest = {AF_INET6, 0, 0, ALL_IPV6_ROUTERS, if_index};<br> >> >> > @@ -193,7 +208,7 @@ static void ra_send_rs(int signal __attribute__((unused)))<br> >> >> > if (sendto(sock, &rs, len, MSG_DONTWAIT, (struct sockaddr*)&dest, sizeof(dest)) < 0)<br> >> >> > syslog(LOG_ERR, "Failed to send RS (%s)", strerror(errno));<br> >> >> ><br> >> >> > - if (++rs_attempt <= 3)<br> >> >> > + if (++rs_attempt < rs_attempt_limit)<br> >> >> > alarm(4);<br> >> >> > }<br> >> >> ><br> >> >> > @@ -243,8 +258,7 @@ bool ra_link_up(void)<br> >> >> > if (ret) {<br> >> >> > syslog(LOG_NOTICE, "carrier => %i event on %s", (int)!nocarrier, if_name);<br> >> >> ><br> >> >> > - rs_attempt = 0;<br> >> >> > - ra_send_rs(SIGALRM);<br> >> >> > + ra_restart();<br> >> >> > }<br> >> >> ><br> >> >> > return ret;<br> >> >> > diff --git a/src/ra.h b/src/ra.h<br> >> >> > index 9acc8cd..4ec208f 100644<br> >> >> > --- a/src/ra.h<br> >> >> > +++ b/src/ra.h<br> >> >> > @@ -46,5 +46,6 @@ struct icmpv6_opt_route_info {<br> >> >> ><br> >> >> > int ra_init(const char *ifname, const struct in6_addr *ifid,<br> >> >> > unsigned int options, unsigned int holdoff_interval);<br> >> >> > +void ra_restart(void);<br> >> >> > bool ra_link_up(void);<br> >> >> > bool ra_process(void);<br> >> >> > --<br> >> >> > 2.21.0<br> >> >> ><br> >> >> ><br> >> >> > _______________________________________________<br> >> >> > openwrt-devel mailing list<br> >> >> > <a href="mailto:openwrt-devel@lists.openwrt.org" target="_blank">openwrt-devel@lists.openwrt.org</a><br> >> >> > <a href="https://lists.openwrt.org/mailman/listinfo/openwrt-devel" rel="noreferrer" target="_blank">https://lists.openwrt.org/mailman/listinfo/openwrt-devel</a><br> </blockquote></div>
On Wed, Mar 20, 2019 at 12:44 PM Pavel Merzlyakov <pavel.merzlyakov@gmail.com> wrote: > > >Can you share the network config you're using ? > I'm sorry I can't do this. I'm wondering the added value of the patch for the OpenWrt project since this seems to be restricted to a config you don't want to disclose while restarting of odhcp6c by netifd based on link state events covers the different use cases hans > > >I would prefer to use another signal to trigger the sending of RS. > Of course, it's up to you. > But I think there should be some signal witch restart both RA and DHCPv6. > > Regarding to the patch > do you agree that we must clear STATE_RA_ on link-up event > before we trigger Router Solicitation message (see ra.c:247 -> https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/ra.c;h=898f449168e29bae08e48e9395f420d13b2ec899;hb=HEAD#l247)? > > Br, > Pavel > > On Wed, 20 Mar 2019 at 10:52, Hans Dedecker <dedeckeh@gmail.com> wrote: >> >> On Tue, Mar 19, 2019 at 1:15 PM Pavel Merzlyakov >> <pavel.merzlyakov@gmail.com> wrote: >> > >> > >why is this not the case in your setup ? >> > Because sometimes odhcp6c miss restart, probably because of Bridge Mode (it's attached to bridge interface). >> Can you share the network config you're using ? >> >> > Anyway, I use a hotplug script which sends SIGUSR2 signal to odhcp6c on link-up event. >> > Of course I could send SIGTERM, but I think it's not the proper way to solve problem. >> > >> > I thought that it is an obvious bug because I see a lack of consistency. >> > Why odhcp6c on SIGUSR2 >> > clear STATE_IA_ and resend DHCPV6_MSG_ >> > and don't do same with RA - clear STATE_RA_ and resend Router Solicitation message? >> This was the approach by the original author of the code to control >> only DHCPv6 via SIGUSR1 and SIGUSR2. >> I understand your need to trigger the sending of RS via a signal but >> I'm reluctant to change the current behavior of the SIGUSR2 signal as >> I would prefer to use another signal to trigger the sending of RS. >> >> Hans >> > >> > Br, >> > Pavel >> > >> > On Tue, 19 Mar 2019 at 12:36, Hans Dedecker <dedeckeh@gmail.com> wrote: >> >> >> >> Hi, >> >> >> >> On Mon, Mar 18, 2019 at 8:51 PM Pavel Merzlyakov >> >> <pavel.merzlyakov@gmail.com> wrote: >> >> > >> >> > Hi, >> >> > >> >> > >Can you be elaborate more in detail what use case you want to cover >> >> > >with this patch; in other words what is not working now ? >> >> > Ok, >> >> > my setup: >> >> > Two peer routers A and B which both connected to gateway C. >> >> > Routers A and B have public IPv6 addresses on WAN interfaces from same subnet (because of RA on C) and private IPv6 addresses on LAN interfaces. >> >> > and issue: >> >> > If I unplug router B from C and then plug it in LAN port of router A: >> >> > 1) Router B does not send Router Solicitation message. So router B does not have a valid gateway for some time. >> >> Since we've linksensing support in netifd the wan/wan6 interface >> >> should be brought down when the cable is unplugged; the wan/wan6 >> >> interface will be brought up again when the cable is plugged in. This >> >> means odhcp6c will be restarted and will start sending RS; why is this >> >> not the case in your setup ? >> >> >> >> Hans >> >> > 2) Router B does not delete old IPv6 address on the WAN. After first Router Advertisement message router B is capable to send a request via new gateway A, but it can't receive responses because of invalid/old source address in request. >> >> > >> >> > >> >> > >Why do you want to restart RA if an SIGUSR2 signal is received ? >> >> > Because I assume that SIGUSR2 signal is equivalent to link-up event (see odhcp6c:674 -> https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=19a86f2654bf3c59b0f47cf0aedd87235187bf89;hb=d2e247d8d87ecf8c60fcf0acdad05667bd379521#l674). >> >> > In my case I use hotplug script witch on link-up sends SIGUSR2 signal to odhcp6c (it's connected to bridge interface). >> >> > ra_restart () could be called without condition in beginning of the main loop. >> >> > >> >> > Br, >> >> > Pavel >> >> > >> >> > On Mon, 18 Mar 2019 at 18:26, Hans Dedecker <dedeckeh@gmail.com> wrote: >> >> >> >> >> >> Hi, >> >> >> >> >> >> On Mon, Mar 18, 2019 at 2:43 PM <pavel.merzlyakov@gmail.com> wrote: >> >> >> > >> >> >> > From: Pavel Merzlyakov <pavel.merzlyakov@gmail.com> >> >> >> > >> >> >> > A subnet may be changed after link-up event >> >> >> Can you be elaborate more in detail what use case you want to cover >> >> >> with this patch; in other words what is not working now ? >> >> >> > >> >> >> > Signed-off-by: Pavel Merzlyakov <pavel.merzlyakov@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(); >> >> >> Why do you want to restart RA if an SIGUSR2 signal is received ? >> >> >> >> >> >> Hans >> >> >> > + >> >> >> > 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@lists.openwrt.org >> >> >> > https://lists.openwrt.org/mailman/listinfo/openwrt-devel
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);