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

Pavel Merzlyakov pavel.merzlyakov at gmail.com
Mon Mar 18 15:51:29 EDT 2019


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 at gmail.com> wrote:

> Hi,
>
> On Mon, Mar 18, 2019 at 2:43 PM <pavel.merzlyakov at gmail.com> wrote:
> >
> > From: Pavel Merzlyakov <pavel.merzlyakov at 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 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();
> 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 at lists.openwrt.org
> > https://lists.openwrt.org/mailman/listinfo/openwrt-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/openwrt-devel/attachments/20190318/b46b267f/attachment.htm>
-------------- next part --------------
_______________________________________________
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