summary refs log tree commit diff
path: root/shared
diff options
context:
space:
mode:
Diffstat (limited to 'shared')
-rw-r--r--shared/n-dhcp4/src/n-dhcp4-c-connection.c25
-rw-r--r--shared/n-dhcp4/src/n-dhcp4-c-probe.c101
-rw-r--r--shared/n-dhcp4/src/n-dhcp4-client.c7
-rw-r--r--shared/n-dhcp4/src/n-dhcp4-private.h1
-rw-r--r--shared/nm-glib-aux/nm-dbus-aux.c4
-rw-r--r--shared/nm-libnm-core-intern/nm-libnm-core-utils.h4
-rw-r--r--shared/nm-version-macros.h3
-rw-r--r--shared/nm-version-macros.h.in1
8 files changed, 133 insertions, 13 deletions
diff --git a/shared/n-dhcp4/src/n-dhcp4-c-connection.c b/shared/n-dhcp4/src/n-dhcp4-c-connection.c
index 8a2ddb36..e51a3e32 100644
--- a/shared/n-dhcp4/src/n-dhcp4-c-connection.c
+++ b/shared/n-dhcp4/src/n-dhcp4-c-connection.c
@@ -139,7 +139,19 @@ int n_dhcp4_c_connection_listen(NDhcp4CConnection *connection) {
         _c_cleanup_(c_closep) int fd_packet = -1;
         int r;
 
-        c_assert(connection->state == N_DHCP4_C_CONNECTION_STATE_INIT);
+        c_assert(connection->state == N_DHCP4_C_CONNECTION_STATE_INIT ||
+                 connection->state == N_DHCP4_C_CONNECTION_STATE_DRAINING ||
+                 connection->state == N_DHCP4_C_CONNECTION_STATE_UDP);
+
+        if (connection->fd_packet >= 0) {
+                epoll_ctl(connection->fd_epoll, EPOLL_CTL_DEL, connection->fd_packet, NULL);
+                connection->fd_packet = c_close(connection->fd_packet);
+        }
+
+        if (connection->fd_udp >= 0) {
+                epoll_ctl(connection->fd_epoll, EPOLL_CTL_DEL, connection->fd_udp, NULL);
+                connection->fd_udp = c_close(connection->fd_udp);
+        }
 
         r = n_dhcp4_c_socket_packet_new(&fd_packet, connection->client_config->ifindex);
         if (r)
@@ -319,7 +331,6 @@ void n_dhcp4_c_connection_get_timeout(NDhcp4CConnection *connection,
         switch (connection->request->userdata.type) {
         case N_DHCP4_C_MESSAGE_DISCOVER:
         case N_DHCP4_C_MESSAGE_SELECT:
-        case N_DHCP4_C_MESSAGE_REBOOT:
         case N_DHCP4_C_MESSAGE_INFORM:
                 /*
                  * Resend with an exponential backoff and a one second random
@@ -338,6 +349,7 @@ void n_dhcp4_c_connection_get_timeout(NDhcp4CConnection *connection,
                 break;
         case N_DHCP4_C_MESSAGE_REBIND:
         case N_DHCP4_C_MESSAGE_RENEW:
+        case N_DHCP4_C_MESSAGE_REBOOT:
                 /*
                  * Resend every sixty seconds with a one second random slack.
                  *
@@ -992,6 +1004,7 @@ static int n_dhcp4_c_connection_send_request(NDhcp4CConnection *connection,
         char server_addr[INET_ADDRSTRLEN];
         char client_addr[INET_ADDRSTRLEN];
         int r;
+        bool broadcast = false;
 
         /*
          * Increment the base time and reset the xid field,
@@ -1026,12 +1039,14 @@ static int n_dhcp4_c_connection_send_request(NDhcp4CConnection *connection,
         case N_DHCP4_C_MESSAGE_SELECT:
         case N_DHCP4_C_MESSAGE_REBOOT:
         case N_DHCP4_C_MESSAGE_DECLINE:
+        case N_DHCP4_C_MESSAGE_REBIND:
+                broadcast = true;
                 r = n_dhcp4_c_connection_packet_broadcast(connection, request);
                 if (r)
                         return r;
                 break;
         case N_DHCP4_C_MESSAGE_INFORM:
-        case N_DHCP4_C_MESSAGE_REBIND:
+                broadcast = true;
                 r = n_dhcp4_c_connection_udp_broadcast(connection, request);
                 if (r)
                         return r;
@@ -1052,6 +1067,8 @@ static int n_dhcp4_c_connection_send_request(NDhcp4CConnection *connection,
                 n_dhcp4_c_log(connection->client_config, LOG_INFO,
                               "sent %s to %s",
                               message_type_to_str(request->userdata.message_type),
+                              broadcast ?
+                              "255.255.255.255" :
                               inet_ntop(AF_INET, &connection->server_ip,
                                         server_addr, sizeof(server_addr)));
         } else {
@@ -1060,6 +1077,8 @@ static int n_dhcp4_c_connection_send_request(NDhcp4CConnection *connection,
                               message_type_to_str(request->userdata.message_type),
                               inet_ntop(AF_INET, &request->userdata.client_addr,
                                         client_addr, sizeof(client_addr)),
+                              broadcast ?
+                              "255.255.255.255" :
                               inet_ntop(AF_INET, &connection->server_ip,
                                         server_addr, sizeof(server_addr)));
         }
diff --git a/shared/n-dhcp4/src/n-dhcp4-c-probe.c b/shared/n-dhcp4/src/n-dhcp4-c-probe.c
index 2bced4cf..4fb7d389 100644
--- a/shared/n-dhcp4/src/n-dhcp4-c-probe.c
+++ b/shared/n-dhcp4/src/n-dhcp4-c-probe.c
@@ -170,8 +170,6 @@ _c_public_ void n_dhcp4_client_probe_config_set_inform_only(NDhcp4ClientProbeCon
  * INIT-REBOOT path, as described by the DHCP specification. In most cases, you
  * do not want this.
  *
- * XXX: This is currently not implemented, and setting the property has no effect.
- *
  * Background: The INIT-REBOOT path allows a DHCP client to skip
  *             server-discovery when rebooting/resuming their machine. The DHCP
  *             client simply re-requests the lease it had acquired before. This
@@ -438,11 +436,17 @@ int n_dhcp4_client_probe_new(NDhcp4ClientProbe **probep,
         if (r)
                 return r;
 
+        if (probe->config->init_reboot && probe->config->requested_ip.s_addr != INADDR_ANY)
+                probe->state = N_DHCP4_CLIENT_PROBE_STATE_INIT_REBOOT;
+        else
+                probe->state = N_DHCP4_CLIENT_PROBE_STATE_INIT;
+
         if (active) {
                 /*
                  * Defer the sending of DISCOVER by a random amount (by default up to 9 seconds).
                  */
-                probe->ns_deferred = ns_now + (n_dhcp4_client_probe_config_get_random(probe->config) % (probe->config->ms_start_delay * 1000000ULL));
+                if (probe->state == N_DHCP4_CLIENT_PROBE_STATE_INIT)
+                        probe->ns_deferred = ns_now + (n_dhcp4_client_probe_config_get_random(probe->config) % (probe->config->ms_start_delay * 1000000ULL));
                 probe->client->current_probe = probe;
         } else {
                 r = n_dhcp4_client_probe_raise(probe,
@@ -575,6 +579,14 @@ void n_dhcp4_client_probe_get_timeout(NDhcp4ClientProbe *probe, uint64_t *timeou
         n_dhcp4_c_connection_get_timeout(&probe->connection, &timeout);
 
         switch (probe->state) {
+        case N_DHCP4_CLIENT_PROBE_STATE_INIT_REBOOT:
+                /* send DHCP request immediately */
+                timeout = 1;
+                break;
+        case N_DHCP4_CLIENT_PROBE_STATE_REBOOTING:
+                if (probe->ns_reinit && (!timeout || probe->ns_reinit < timeout))
+                        timeout = probe->ns_reinit;
+                break;
         case N_DHCP4_CLIENT_PROBE_STATE_INIT:
                 if (probe->ns_deferred && (!timeout || probe->ns_deferred < timeout))
                         timeout = probe->ns_deferred;
@@ -626,6 +638,52 @@ static int n_dhcp4_client_probe_outgoing_append_options(NDhcp4ClientProbe *probe
         return 0;
 }
 
+static int n_dhcp4_client_probe_transition_reboot(NDhcp4ClientProbe *probe, uint64_t ns_now) {
+        _c_cleanup_(n_dhcp4_outgoing_freep) NDhcp4Outgoing *request = NULL;
+        int r;
+
+        switch (probe->state) {
+        case N_DHCP4_CLIENT_PROBE_STATE_INIT_REBOOT:
+                r = n_dhcp4_c_connection_listen(&probe->connection);
+                if (r)
+                        return r;
+
+                r = n_dhcp4_c_connection_reboot_new(&probe->connection, &request, &probe->config->requested_ip);
+                if (r)
+                        return r;
+
+                r = n_dhcp4_client_probe_outgoing_append_options(probe, request);
+                if (r)
+                        return r;
+
+                r = n_dhcp4_c_connection_start_request(&probe->connection, request, ns_now);
+                if (r)
+                        return r;
+                else
+                        request = NULL; /* consumed */
+
+                probe->state = N_DHCP4_CLIENT_PROBE_STATE_REBOOTING;
+                probe->ns_reinit = ns_now + 2000000000ULL;
+
+                break;
+
+        case N_DHCP4_CLIENT_PROBE_STATE_SELECTING:
+        case N_DHCP4_CLIENT_PROBE_STATE_INIT:
+        case N_DHCP4_CLIENT_PROBE_STATE_REBOOTING:
+        case N_DHCP4_CLIENT_PROBE_STATE_REQUESTING:
+        case N_DHCP4_CLIENT_PROBE_STATE_GRANTED:
+        case N_DHCP4_CLIENT_PROBE_STATE_BOUND:
+        case N_DHCP4_CLIENT_PROBE_STATE_RENEWING:
+        case N_DHCP4_CLIENT_PROBE_STATE_REBINDING:
+        case N_DHCP4_CLIENT_PROBE_STATE_EXPIRED:
+        default:
+                abort();
+                break;
+        }
+
+        return 0;
+}
+
 static int n_dhcp4_client_probe_transition_deferred(NDhcp4ClientProbe *probe, uint64_t ns_now) {
         _c_cleanup_(n_dhcp4_outgoing_freep) NDhcp4Outgoing *request = NULL;
         int r;
@@ -635,12 +693,14 @@ static int n_dhcp4_client_probe_transition_deferred(NDhcp4ClientProbe *probe, ui
                 r = n_dhcp4_c_connection_listen(&probe->connection);
                 if (r)
                         return r;
+                /* fall-through */
 
+        case N_DHCP4_CLIENT_PROBE_STATE_REBOOTING:
                 r = n_dhcp4_c_connection_discover_new(&probe->connection, &request);
                 if (r)
                         return r;
 
-                if (probe->config->requested_ip.s_addr != INADDR_ANY) {
+                if (!probe->config->init_reboot && probe->config->requested_ip.s_addr != INADDR_ANY) {
                         r = n_dhcp4_outgoing_append_requested_ip(request, probe->config->requested_ip);
                         if (r)
                                 return r;
@@ -663,7 +723,6 @@ static int n_dhcp4_client_probe_transition_deferred(NDhcp4ClientProbe *probe, ui
 
         case N_DHCP4_CLIENT_PROBE_STATE_SELECTING:
         case N_DHCP4_CLIENT_PROBE_STATE_INIT_REBOOT:
-        case N_DHCP4_CLIENT_PROBE_STATE_REBOOTING:
         case N_DHCP4_CLIENT_PROBE_STATE_REQUESTING:
         case N_DHCP4_CLIENT_PROBE_STATE_GRANTED:
         case N_DHCP4_CLIENT_PROBE_STATE_BOUND:
@@ -726,6 +785,10 @@ static int n_dhcp4_client_probe_transition_t2(NDhcp4ClientProbe *probe, uint64_t
         switch (probe->state) {
         case N_DHCP4_CLIENT_PROBE_STATE_BOUND:
         case N_DHCP4_CLIENT_PROBE_STATE_RENEWING:
+                r = n_dhcp4_c_connection_listen(&probe->connection);
+                if (r)
+                        return r;
+
                 r = n_dhcp4_c_connection_rebind_new(&probe->connection, &request);
                 if (r)
                         return r;
@@ -848,11 +911,22 @@ static int n_dhcp4_client_probe_transition_ack(NDhcp4ClientProbe *probe, NDhcp4I
         _c_cleanup_(n_dhcp4_incoming_freep) NDhcp4Incoming *message = message_take;
         _c_cleanup_(n_dhcp4_client_lease_unrefp) NDhcp4ClientLease *lease = NULL;
         NDhcp4CEventNode *node;
+        struct in_addr client = {};
+        struct in_addr server = {};
         int r;
 
         switch (probe->state) {
-        case N_DHCP4_CLIENT_PROBE_STATE_RENEWING:
         case N_DHCP4_CLIENT_PROBE_STATE_REBINDING:
+                n_dhcp4_incoming_get_yiaddr(message, &client);
+
+                r = n_dhcp4_incoming_query_server_identifier(message, &server);
+                if (r)
+                        return r;
+                r = n_dhcp4_c_connection_connect(&probe->connection, &client, &server);
+                if (r)
+                        return r;
+                /* fall-through */
+        case N_DHCP4_CLIENT_PROBE_STATE_RENEWING:
 
                 r = n_dhcp4_client_probe_raise(probe,
                                                &node,
@@ -876,6 +950,7 @@ static int n_dhcp4_client_probe_transition_ack(NDhcp4ClientProbe *probe, NDhcp4I
                 break;
 
         case N_DHCP4_CLIENT_PROBE_STATE_REQUESTING:
+        case N_DHCP4_CLIENT_PROBE_STATE_REBOOTING:
 
                 r = n_dhcp4_client_probe_raise(probe,
                                                &node,
@@ -900,7 +975,6 @@ static int n_dhcp4_client_probe_transition_ack(NDhcp4ClientProbe *probe, NDhcp4I
         case N_DHCP4_CLIENT_PROBE_STATE_INIT:
         case N_DHCP4_CLIENT_PROBE_STATE_SELECTING:
         case N_DHCP4_CLIENT_PROBE_STATE_INIT_REBOOT:
-        case N_DHCP4_CLIENT_PROBE_STATE_REBOOTING:
         case N_DHCP4_CLIENT_PROBE_STATE_BOUND:
         case N_DHCP4_CLIENT_PROBE_STATE_GRANTED:
         case N_DHCP4_CLIENT_PROBE_STATE_EXPIRED:
@@ -1079,6 +1153,19 @@ int n_dhcp4_client_probe_dispatch_timer(NDhcp4ClientProbe *probe, uint64_t ns_no
         int r;
 
         switch (probe->state) {
+        case N_DHCP4_CLIENT_PROBE_STATE_INIT_REBOOT:
+                r = n_dhcp4_client_probe_transition_reboot(probe, ns_now);
+                if (r)
+                        return r;
+                break;
+        case N_DHCP4_CLIENT_PROBE_STATE_REBOOTING:
+                if (ns_now >= probe->ns_reinit) {
+                        r = n_dhcp4_client_probe_transition_deferred(probe, ns_now);
+                        if (r)
+                                return r;
+                }
+
+                break;
         case N_DHCP4_CLIENT_PROBE_STATE_INIT:
                 if (ns_now >= probe->ns_deferred) {
                         r = n_dhcp4_client_probe_transition_deferred(probe, ns_now);
diff --git a/shared/n-dhcp4/src/n-dhcp4-client.c b/shared/n-dhcp4/src/n-dhcp4-client.c
index 0bfe48ee..4fa3d65d 100644
--- a/shared/n-dhcp4/src/n-dhcp4-client.c
+++ b/shared/n-dhcp4/src/n-dhcp4-client.c
@@ -681,7 +681,12 @@ _c_public_ int n_dhcp4_client_dispatch(NDhcp4Client *client) {
 
                                 /* continue normally */
                         } else if (r) {
-                                c_assert(r < _N_DHCP4_E_INTERNAL);
+                                if (r >= _N_DHCP4_E_INTERNAL) {
+                                        n_dhcp4_c_log(client->config, LOG_ERR,
+                                                      "invalid internal error code %d after dispatch",
+                                                      r);
+                                        return N_DHCP4_E_INTERNAL;
+                                }
                                 return r;
                         }
                 }
diff --git a/shared/n-dhcp4/src/n-dhcp4-private.h b/shared/n-dhcp4/src/n-dhcp4-private.h
index 1cf5f25e..fcfb0f35 100644
--- a/shared/n-dhcp4/src/n-dhcp4-private.h
+++ b/shared/n-dhcp4/src/n-dhcp4-private.h
@@ -351,6 +351,7 @@ struct NDhcp4ClientProbe {
 
         unsigned int state;                     /* current probe state */
         uint64_t ns_deferred;                   /* timeout for deferred action */
+        uint64_t ns_reinit;
         NDhcp4ClientLease *current_lease;       /* current lease */
 
         NDhcp4CConnection connection;           /* client connection wrapper */
diff --git a/shared/nm-glib-aux/nm-dbus-aux.c b/shared/nm-glib-aux/nm-dbus-aux.c
index 75b282bc..86061aef 100644
--- a/shared/nm-glib-aux/nm-dbus-aux.c
+++ b/shared/nm-glib-aux/nm-dbus-aux.c
@@ -357,8 +357,10 @@ _nm_dbus_error_is (GError *error, ...)
 
 	va_start (ap, error);
 	while ((name = va_arg (ap, const char *))) {
-		if (nm_streq (dbus_error, name))
+		if (nm_streq (dbus_error, name)) {
+			va_end (ap);
 			return TRUE;
+		}
 	}
 	va_end (ap);
 
diff --git a/shared/nm-libnm-core-intern/nm-libnm-core-utils.h b/shared/nm-libnm-core-intern/nm-libnm-core-utils.h
index 42e9fc64..1449a8ba 100644
--- a/shared/nm-libnm-core-intern/nm-libnm-core-utils.h
+++ b/shared/nm-libnm-core-intern/nm-libnm-core-utils.h
@@ -95,4 +95,8 @@ nm_setting_ip_config_get_addr_family (NMSettingIPConfig *s_ip)
  * depends on other factors. */
 #define NM_INFINIBAND_MAX_MTU ((guint) 65520)
 
+/*****************************************************************************/
+
+#define _NM_CAPABILITY_MAX NM_CAPABILITY_OVS
+
 #endif /* __NM_LIBNM_SHARED_UTILS_H__ */
diff --git a/shared/nm-version-macros.h b/shared/nm-version-macros.h
index a5c79c1e..c79a0e13 100644
--- a/shared/nm-version-macros.h
+++ b/shared/nm-version-macros.h
@@ -30,7 +30,7 @@
  * Evaluates to the micro version number of NetworkManager which this source
  * compiled against.
  */
-#define NM_MICRO_VERSION (0)
+#define NM_MICRO_VERSION (2)
 
 /**
  * NM_CHECK_VERSION:
@@ -63,6 +63,7 @@
 #define NM_VERSION_1_18   (NM_ENCODE_VERSION (1, 18, 0))
 #define NM_VERSION_1_20   (NM_ENCODE_VERSION (1, 20, 0))
 #define NM_VERSION_1_22   (NM_ENCODE_VERSION (1, 22, 0))
+#define NM_VERSION_1_22_2 (NM_ENCODE_VERSION (1, 22, 2))
 
 /* For releases, NM_API_VERSION is equal to NM_VERSION.
  *
diff --git a/shared/nm-version-macros.h.in b/shared/nm-version-macros.h.in
index 961febb0..a9dcab8d 100644
--- a/shared/nm-version-macros.h.in
+++ b/shared/nm-version-macros.h.in
@@ -63,6 +63,7 @@
 #define NM_VERSION_1_18   (NM_ENCODE_VERSION (1, 18, 0))
 #define NM_VERSION_1_20   (NM_ENCODE_VERSION (1, 20, 0))
 #define NM_VERSION_1_22   (NM_ENCODE_VERSION (1, 22, 0))
+#define NM_VERSION_1_22_2 (NM_ENCODE_VERSION (1, 22, 2))
 
 /* For releases, NM_API_VERSION is equal to NM_VERSION.
  *