]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Checkpoint: added start/finish v6only
authorFrancis Dupont <fdupont@isc.org>
Mon, 12 Oct 2020 20:18:33 +0000 (22:18 +0200)
committerFrancis Dupont <fdupont@isc.org>
Mon, 12 Oct 2020 20:18:33 +0000 (22:18 +0200)
client/dhclient.c
client/scripts/linux
includes/dhcpd.h

index 7a7837cb8152796743a4c9aeec55ceb413c1cde6..b989d1b79492d5afbce7d9f33858562ab9c86583 100644 (file)
@@ -1242,6 +1242,73 @@ void state_init (cpp)
        send_discover (client);
 }
 
+/* v6only_timeout is called when the V6ONLY_WAIT timer expired. */
+
+void finish_v6only(cpp)
+       void *cpp;
+{
+       struct client_state *client = cpp;
+       client->state = S_INIT;
+       state_init(cpp);
+}
+
+/*
+ * state_v6only is called when a requested v6-only-preferred option was
+ * returned by the server. */
+
+void start_v6only(packet, client)
+       struct packet *packet;
+       struct client_state *client;
+{
+       struct option_cache *oc;
+       struct data_string data;
+       uint32_t v6only_wait = 0;
+       struct timeval tv;
+
+       /* Get the V6ONLY_WAIT timer. */
+       oc = lookup_option(&dhcp_universe, packet->options,
+                          DHO_V6_ONLY_PREFERRED);
+       if (!oc) {
+               /* Should not happen... */
+               return;
+       }
+
+       memset(&data, 0, sizeof(data));
+
+       if (evaluate_option_cache(&data, packet, (struct lease *)0, client,
+                                 packet->options, (struct option_state *)0,
+                                 &global_scope, oc, MDL)) {
+               if (data.len > 3)
+                       v6only_wait = getULong(data.data);
+               data_string_forget(&data, MDL);
+       }
+
+       if (v6only_wait < MIN_V6ONLY_WAIT)
+               v6only_wait = MIN_V6ONLY_WAIT;
+
+       /* Enter V6ONLY state. */
+
+       client->state = S_V6ONLY;
+
+       /* Run the client script. */
+       script_init(client, "V6ONLY", NULL);
+       if (client->active) {
+               script_write_params(client, "old_", client->active);
+               destroy_client_lease(client->active);
+               client->active = NULL;
+       }
+       script_write_requested(client);
+       client_envadd(client, "", "v6-only-preferred", "%lu",
+                     (long unsigned)v6only_wait);
+       script_go(client);
+
+       /* Trigger finish_v6only after V6ONLY_WAIT seconds. */
+       tv.tv_sec = cur_tv.tv_sec + v6only_wait;
+       tv.tv_usec = cur_tv.tv_usec;
+
+       add_timeout(&tv, finish_v6only, client, 0, 0);
+}
+
 /*
  * state_selecting is called when one or more DHCPOFFER packets have been
  * received and a configurable period of time has passed.
@@ -1650,6 +1717,7 @@ void state_stop (cpp)
        cancel_timeout(send_discover, client);
        cancel_timeout(send_request, client);
        cancel_timeout(state_bound, client);
+       cancel_timeout(finish_v6only, client);
 
        /* If we have an address, unconfigure it. */
        if (client->active) {
@@ -4623,6 +4691,7 @@ void client_location_changed ()
                              case S_REBINDING:
                              case S_STOPPED:
                              case S_DECLINING:
+                             case S_V6ONLY:
                                break;
                        }
                        client -> state = S_INIT;
@@ -4701,6 +4770,7 @@ void do_release(client)
        cancel_timeout (state_init, client);
        cancel_timeout (send_request, client);
        cancel_timeout (state_reboot, client);
+       cancel_timeout (finish_v6only, client);
        client -> state = S_STOPPED;
 
 #if defined(DHCPv6) && defined(DHCP4o6)
index 0c42969744e4fd0ea513f9d5516183cef207c3b4..63257bcad93cef9ee3b40a54cb39272bea1f50dd 100755 (executable)
@@ -400,6 +400,14 @@ case "$reason" in
 
         ;;
 
+    V6ONLY)
+        if [ -n "$old_ip_address" ]; then
+            # flush leased IP
+            ${ip} -4 addr flush dev ${interface} label ${interface}
+        fi
+
+        ;;
+
     ### DHCPv6 Handlers
     # TODO handle prefix change: ?based on ${old_ip6_prefix} and ${new_ip6_prefix}?
 
index b20dd24090dc5877115af75cbbcfc13ae3385297..caeeaeda1552d8b732eadad37c56e0a8da99555d 100644 (file)
@@ -877,6 +877,10 @@ struct lease_state {
 # define DEFAULT_ABANDON_LEASE_TIME 86400
 #endif
 
+#if !defined (MIN_V6ONLY_WAIT)
+# define MIN_V6ONLY_WAIT 300
+#endif
+
 #define PLM_IGNORE 0
 #define PLM_PREFER 1
 #define PLM_EXACT 2
@@ -1204,7 +1208,8 @@ enum dhcp_state {
        S_RENEWING = 6,
        S_REBINDING = 7,
        S_DECLINING = 8,
-       S_STOPPED = 9
+       S_STOPPED = 9,
+       S_V6ONLY = 10
 };
 
 /* Possible pending client operations. */
@@ -3003,6 +3008,9 @@ void state_bound (void *);
 void state_stop (void *);
 void state_panic (void *);
 
+void start_v6only (struct packet *, struct client_state *);
+void finish_v6only (void *);
+
 void bind_lease (struct client_state *);
 
 void make_client_options (struct client_state *,