[PATCH] Implemented support for stateless DHCPv6. Udhcpc6 will send Information-Request to request configuration parameters without IP address if using 'l' option.

Denys Vlasenko vda.linux at googlemail.com
Thu Aug 22 13:53:36 UTC 2019


Please describe the scenario where you are using this,
what command line switches do you use,
what server gives to you in the initial response,
what happens when "lease" expires?

Why "no -d, -r no" command line usage does not work for you?

On Tue, Aug 20, 2019 at 9:54 AM Eivind Versvik <versvikeivind at gmail.com> wrote:
> @@ -841,6 +843,45 @@ int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6)
>         );
>  }
>
> +/* RFC 3315 18.1.5. Creation and Transmission of Information-request Messages
...
> +*/
> +
> +/* NOINLINE: limit stack usage in caller */
> +static NOINLINE int send_d6_info(uint32_t xid)
> +{
> +       struct d6_packet packet;
> +       uint8_t *opt_ptr;
> +       unsigned len;
> +
> +       /* Fill in: msg type, client id */
> +       opt_ptr = init_d6_packet(&packet, D6_MSG_INFORMATION_REQUEST, xid);
> +
> +       opt_ptr = add_d6_client_options(opt_ptr);
> +
> +       bb_error_msg("sending %s", "info");
> +       return d6_mcast_from_client_config_ifindex(&packet, opt_ptr);
> +}

So, this looks similar to send_d6_discover() when no -d options was given,
and "-r no" was given to suppress IP address request.
The only difference in the packet will be D6_MSG_SOLICIT message type
instead of D6_MSG_INFORMATION_REQUEST, right?

What happens on your network if you just use "no -d, -r no"
with non-patched udhcpc6?

> @@ -1117,6 +1158,7 @@ static void client_background(void)
>  //usage:     "\n       -T N            Pause between packets (default 3 seconds)"
>  //usage:     "\n       -A N            Wait N seconds (default 20) after failure"
>  //usage:     "\n       -f              Run in foreground"
> +//usage:     "\n       -l              Use stateless mode, only send informational request and dont request ip"

I, as a user, do not feel like this help text helps much.
How about:

        Send 'information request' packets instead of 'solicit'

which brings the question: what about the case when people need to do both?
First get the IP, then get D6_MSG_INFORMATION_REQUEST?

> @@ -1208,6 +1251,11 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
>                         requested_ipv6 = &ipv6_buf;
>                 }
>         }
> +
> +       if (opt & OPT_l) {
> +               /* no ip request when stateless */
> +               option_mask32 = option_mask32 & ~OPT_r;
> +       }

OPT_r bit can already be cleared with "-r no" syntax.

>  #if ENABLE_FEATURE_UDHCP_PORT
>         if (opt & OPT_P) {
>                 CLIENT_PORT6 = xatou16(str_P);
> @@ -1358,7 +1406,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
>                                         if (packet_num == 0)
>                                                 xid = random_xid();
>                                         /* multicast */
> -                                       send_d6_discover(xid, requested_ipv6);
> +                                       if(opt & OPT_l)
> +                                               send_d6_info(xid);
> +                                       else
> +                                               send_d6_discover(xid, requested_ipv6);
>                                         timeout = discover_timeout;
>                                         packet_num++;
>                                         continue;
> @@ -1401,7 +1452,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
>                                 /* 1/2 lease passed, enter renewing state */
>                                 state = RENEWING;
>                                 client_config.first_secs = 0; /* make secs field count from 0 */
> -                               change_listen_mode(LISTEN_KERNEL);
> +                               if(opt & OPT_l)
> +                                       change_listen_mode(LISTEN_RAW);
> +                               else
> +                                       change_listen_mode(LISTEN_KERNEL);

Obvious question - why? A comment would be good to have here.

> @@ -1417,7 +1471,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
>                          * Anyway, it does recover by eventually failing through
>                          * into INIT_SELECTING state.
>                          */
> -                                       send_d6_renew(xid, &srv6_buf, requested_ipv6);
> +                                       if(opt & OPT_l)
> +                                               send_d6_info(xid);
> +                                       else
> +                                               send_d6_renew(xid, &srv6_buf, requested_ipv6);
>                                         timeout >>= 1;
>                                         continue;
>                                 }
> @@ -1431,8 +1488,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
>                                 /* Lease is *really* about to run out,
>                                  * try to find DHCP server using broadcast */
>                                 if (timeout > 0) {
> -                                       /* send a broadcast renew request */
> -                                       send_d6_renew(xid, /*server_ipv6:*/ NULL, requested_ipv6);
> +                                       if(opt & OPT_l)
> +                                               send_d6_info(xid);
> +                                       else /* send a broadcast renew request */
> +                                               send_d6_renew(xid, /*server_ipv6:*/ NULL, requested_ipv6);
>                                         timeout >>= 1;
>                                         continue;
>                                 }
> @@ -1739,6 +1798,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
>                                         prefix_timeout = address_timeout;
>                                 /* note: "int timeout" will not overflow even with 0xffffffff inputs here: */
>                                 timeout = (prefix_timeout < address_timeout ? prefix_timeout : address_timeout) / 2;
> +
> +                               if(opt & OPT_l) /* no lease timeout will be received, use stateless timeout */
> +                                       timeout = stateless_timeout;

So, you will be re-requesting D6_MSG_INFORMATION_REQUEST every ~12 hours,
unconditionally (not configurable). I don't see why we can assume user
wants this behavior.
Users may want to have a different repetition rate. They may even want
to do it just once.

Overall, I think this needs a bit more thought. We seem to have
several possibilities
here with use cases:
(1) user may need to request D6_MSG_INFORMATION_REQUEST after the
usual negotiation.
(2) user may have e.g. static IPv6, and thus want to request
D6_MSG_INFORMATION_REQUEST
    *instead of* the usual negotiation...
(2a) once, or
(2b) periodically. User likely would want to set the period.


More information about the busybox mailing list