]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[master] Added --prefix-len-hint command line argument to dhclient
authorThomas Markwalder <tmark@isc.org>
Mon, 27 Nov 2017 13:54:00 +0000 (08:54 -0500)
committerThomas Markwalder <tmark@isc.org>
Mon, 27 Nov 2017 13:55:13 +0000 (08:55 -0500)
    Merges in rt43792

RELNOTES
client/dhc6.c
client/dhclient.8
client/dhclient.c
includes/dhcp6.h

index e52051d3117321983fd79a979e78049ee405710f..990f156bb3ff8575a17684c95cd7b79f31e7b213 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -183,6 +183,11 @@ dhcp-users@lists.isc.org.
   they are received.
   [ISC-Bugs #39669]
 
+- Added a new dhclient command line parameter, --prefix-len-hint <length>.
+  When used in conjunction with -P, it directs dhclient to use the given
+  length as the prefix length hint when requesting prefixes.
+  [ISC-Bugs #43792]
+
                        Changes since 4.3.0 (bug fixes)
 
 - Tidy up several small tickets.
index ce6e03c47bbb5e00d8782e1c0d0fb44142b08d52..a6b8ff426031f8f68027289288e7f9443c336824 100644 (file)
@@ -146,6 +146,8 @@ static int dhc6_score_lease(struct client_state *client,
 
 extern int onetry;
 extern int stateless;
+extern int prefix_len_hint;
+
 
 /*
  * Assign DHCPv6 port numbers as a client.
@@ -1708,7 +1710,7 @@ dhc6_create_iaid(struct client_state *client,
        int start_idx, copy_len;
 
        memset(ia, 0, sizeof(*ia));
-       if (!buffer_allocate(&ia->buffer, 12, MDL)) {
+       if (!buffer_allocate(&ia->buffer, len, MDL)) {
                return (ISC_R_NOMEMORY);
        }
        ia->data = ia->buffer->data;
@@ -1771,18 +1773,22 @@ dhc6_bare_ia_xx(struct client_state *client,
              case D6O_IA_NA:
                type_string = "IA_NA";
                type_option = ia_na_option;
-               len = 12;
+               len = IA_NA_OFFSET;
                break;
              case D6O_IA_TA:
                type_string = "IA_TA";
                type_option = ia_ta_option;
-               len = 4;
+               len = IA_TA_OFFSET;
                break;
              case D6O_IA_PD:
                type_string = "IA_PD";
                type_option = ia_pd_option;
-               len = 12;
+               len = IA_PD_OFFSET;
+               if (prefix_len_hint > 0) {
+                       len += IASUBOPT_PD_LEN;
+               }
                break;
+
              default:
                return (ISC_R_FAILURE);
        }
@@ -1811,7 +1817,7 @@ dhc6_bare_ia_xx(struct client_state *client,
                /* If we are requesting an NA or a PD we also want to add
                 * the renew and rebind times we are requesting.
                 */
-               if (len == 12) {
+               if (ia_type != D6O_IA_TA) {
                        t1 = client->config->requested_lease / 2;
                        t2 = t1 + (t1 / 2);
                        putULong(ia.buffer->data + 4, t1);
@@ -1823,6 +1829,18 @@ dhc6_bare_ia_xx(struct client_state *client,
                                  (unsigned)t2);
                }
 
+               if (ia_type == D6O_IA_PD && prefix_len_hint > 0) {
+                       unsigned char *ptr = ia.buffer->data + IA_NA_OFFSET;
+                       putUShort(ptr, D6O_IAPREFIX);
+                       ptr += 2;
+                       putUShort(ptr, IASUBOPT_PD_LEN);
+                       ptr += 2;
+                       putUChar(ptr + IASUBOPT_PD_PREFLEN_OFFSET,
+                                prefix_len_hint);
+                       log_debug("XMT:  | | X-- Request prefix ::/%u.",
+                                 prefix_len_hint);
+               }
+
                /* and append it to the packet */
                append_option(packet, &dhcpv6_universe, type_option, &ia);
                data_string_forget(&ia, MDL);
@@ -2128,6 +2146,25 @@ do_init6(void *input)
 
                                data_string_forget(&addr, MDL);
                        }
+               } else if (prefix_len_hint > 0) {
+                       memset(&addr, 0, sizeof(addr));
+                       if (!buffer_allocate(&addr.buffer, 25, MDL)) {
+                               log_error("Unable to allocate memory "
+                                         "for IAPREFIX.");
+                               data_string_forget(&ia, MDL);
+                               data_string_forget(&ds, MDL);
+                               return;
+                       }
+
+                       addr.data = addr.buffer->data;
+                       addr.len = 25;
+
+                       putUChar(addr.buffer->data + 8, prefix_len_hint);
+                       log_debug("XMT:  | | X-- Request prefix ::/%u.",
+                                 prefix_len_hint);
+                       append_option(&ia, &dhcpv6_universe, iaprefix_option,
+                                     &addr);
+                       data_string_forget(&addr, MDL);
                }
 
                append_option(&ds, &dhcpv6_universe, ia_pd_option, &ia);
index 928cecbc03f6662071d27c10ba1f6b6ba67da4e2..ab4b77d4e7d94576df053e1d699d0b61dc3cb67b 100644 (file)
@@ -138,6 +138,10 @@ dhclient - Dynamic Host Configuration Protocol Client
 .I seconds
 ]
 [
+.B --prefix-len-hint
+.I length
+]
+[
 .B -v
 ]
 [
@@ -168,7 +172,7 @@ so on.
 There are two versions of the DHCP protocol DHCPv4 and DHCPv6.  At
 startup the client may be started for one or the other via the
 .B -4
-or 
+or
 .B -6
 options.
 .PP
@@ -301,15 +305,15 @@ combination with the
 flag.
 .TP
 .BI \-e \ VAR=value
-Define additional environment variables for the environment where 
+Define additional environment variables for the environment where
 .B dhclient-script
-executes.  You may specify multiple 
+executes.  You may specify multiple
 .B \-e
 options on the command line.
 .TP
 .BI \-r
 Release the current lease and stop the running DHCP client as previously
-recorded in the PID file.  When shutdown via this method 
+recorded in the PID file.  When shutdown via this method
 .B dhclient-script
 will be executed with the specific reason for calling the script set.
 The client normally doesn't release the current lease as this is not
@@ -321,7 +325,7 @@ to notify the server if they wish to release an assigned IP address.
 .BI \-x
 Stop the running DHCP client without releasing the current lease.
 Kills existing \fBdhclient\fR process as previously recorded in the
-PID file.  When shutdown via this method 
+PID file.  When shutdown via this method
 .B dhclient-script
 will be executed with the specific reason for calling the script set.
 .TP
@@ -336,7 +340,7 @@ one less than the specified port.
 .TP
 .BI \-s \ server-addr
 Specify the server IP address or fully qualified domain name to use as
-a destination for DHCP protocol messages before 
+a destination for DHCP protocol messages before
 .B dhclient
 has acquired an IP address.  Normally,
 .B dhclient
@@ -359,7 +363,7 @@ setting a client id in the configuration file.  Overridding the
 client id in this fashion is discouraged.
 .TP
 .BI \-I
-Use the standard DDNS scheme from RFCs 4701 & 4702.  
+Use the standard DDNS scheme from RFCs 4701 & 4702.
 .TP
 .BI \--version
 Print version number and exit.
@@ -423,6 +427,11 @@ variable. If any of the IPv6 addresses on the interface are tentative
 seconds for DAD to complete. If the script ignores this variable the
 parameter has no effect.
 .PP
+.TP
+.BI \--prefix-len-hint \ length
+When used in conjunction with -P, it directs the client to use the given
+length to use a prefix hint of, "::/length", when requesting new prefixes.
+.PP
 .I Modifying default file locations:
 The following options can be used to modify the locations a client uses
 for its files.  They can be particularly useful if, for example,
@@ -504,7 +513,7 @@ The DHCP client provides some ability to control it while it is
 running, without stopping it.  This capability is provided using OMAPI,
 an API for manipulating remote objects.  OMAPI clients connect to the
 client using TCP/IP, authenticate, and can then examine the client's
-current status and make changes to it. 
+current status and make changes to it.
 .PP
 Rather than implementing the underlying OMAPI protocol directly, user
 programs should use the dhcpctl API or OMAPI itself.  Dhcpctl is a
index 46efee504442b35acd7bce12a395a228e49b3e5f..e25ab94baedc816320c81673ab97380e59b97a20 100644 (file)
@@ -98,7 +98,11 @@ int wanted_ia_pd = 0;
 int require_all_ias = 0;       /* If the user requires all of the IAs to
                                   be available before accepting a lease
                                   0 = no, 1 = requries */
+#if defined(DHCPv6)
 int dad_wait_time = 0;
+int prefix_len_hint = 0;
+#endif
+
 char *mockup_relay = NULL;
 
 char *progname = NULL;
@@ -156,11 +160,12 @@ static const char use_v6command[] = "Command not used for DHCPv4: %s";
 #ifdef DHCP4o6
 #define DHCLIENT_USAGE0 \
 "[-4|-6] [-SNTPRI1dvrxi] [-nw] -4o6 <port>] [-p <port>]\n" \
-"                [-D LL|LLT] [--dad-wait-time seconds]\n"
+"                [-D LL|LLT] [--dad-wait-time seconds]\n" \
+"                [--prefix-len-hint length]\n"
 #else /* DHCP4o6 */
 #define DHCLIENT_USAGE0 \
 "[-4|-6] [-SNTPRI1dvrxi] [-nw] [-p <port>] [-D LL|LLT]\n" \
-"                [--dad-wait-time seconds]\n"
+"                [--dad-wait-time seconds] [--prefix-len-hint length]\n"
 #endif
 #else /* DHCPv6 */
 #define DHCLIENT_USAGE0 \
@@ -490,7 +495,17 @@ main(int argc, char **argv) {
                        if (errno || (*s != '\0') || (dad_wait_time < 0)) {
                                usage("Invalid value for --dad-wait-time: %s", argv[i]);
                        }
+               } else if (!strcmp(argv[i], "--prefix-len-hint")) {
+                       if (++i == argc) {
+                               usage(use_noarg, argv[i-1]);
+                       }
 
+                       errno = 0;
+                       prefix_len_hint = (int)strtol(argv[i], &s, 10);
+                       if (errno || (*s != '\0') || (prefix_len_hint < 0)) {
+                               usage("Invalid value for --prefix-len-hint: %s",
+                                     argv[i]);
+                       }
 #endif /* DHCPv6 */
                } else if (!strcmp(argv[i], "-D")) {
                        duid_v4 = 1;
index de6e1c43880c590628125acd6a2dbab28a78b474..4e9c46c074845f4121e01dc333640caa09961a26 100644 (file)
@@ -280,3 +280,15 @@ struct dhcpv4_over_dhcpv6_packet {
 #define EUI_64_ID_LEN 12  /* 2 for duid-type, 2 for hardware type, 8 for ID */
 #define IAID_LEN 4
 
+/* Offsets with iasubopt wire data of data values for IA_NA and TA */
+#define IASUBOPT_NA_ADDR_OFFSET         0
+#define IASUBOPT_NA_PREF_OFFSET         16
+#define IASUBOPT_NA_VALID_OFFSET        20
+#define IASUBOPT_NA_LEN                 24
+
+/* Offsets with iasubopt wire data of data values for PD */
+#define IASUBOPT_PD_PREF_OFFSET         0
+#define IASUBOPT_PD_VALID_OFFSET        4
+#define IASUBOPT_PD_PREFLEN_OFFSET      8
+#define IASUBOPT_PD_PREFIX_OFFSET       9
+#define IASUBOPT_PD_LEN                 25