about summary refs log tree commit diff
path: root/shared
diff options
context:
space:
mode:
authorSebastien Bacher <seb128@ubuntu.com>2020-02-26 16:25:55 +0100
committerSebastien Bacher <seb128@ubuntu.com>2020-02-26 16:25:55 +0100
commitee7b95167028fdbb2a4bd32aa686e27817d8dfe0 (patch)
treef7a1abab0400789979f860dda724247a9bbbdef1 /shared
parentc1b3616485604f3fddfad9521cb8818cd8eece2b (diff)
parente536d40eaea5dcdc0743b0a5e8e17faa46608a50 (diff)
Merge branch 'upstream/latest' of https://salsa.debian.org/utopia-team/network-manager into upstream/latest
Diffstat (limited to 'shared')
-rw-r--r--shared/n-dhcp4/src/n-dhcp4-c-connection.c11
-rw-r--r--shared/n-dhcp4/src/n-dhcp4-c-probe.c24
-rw-r--r--shared/n-dhcp4/src/n-dhcp4-incoming.c8
-rw-r--r--shared/n-dhcp4/src/n-dhcp4-outgoing.c5
-rw-r--r--shared/n-dhcp4/src/n-dhcp4-private.h3
-rw-r--r--shared/nm-glib-aux/nm-glib.h4
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.c101
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.h21
-rw-r--r--shared/nm-version-macros.h3
-rw-r--r--shared/nm-version-macros.h.in1
10 files changed, 156 insertions, 25 deletions
diff --git a/shared/n-dhcp4/src/n-dhcp4-c-connection.c b/shared/n-dhcp4/src/n-dhcp4-c-connection.c
index f3ae44e2..d4354467 100644
--- a/shared/n-dhcp4/src/n-dhcp4-c-connection.c
+++ b/shared/n-dhcp4/src/n-dhcp4-c-connection.c
@@ -89,7 +89,7 @@ void n_dhcp4_c_connection_deinit(NDhcp4CConnection *connection) {
 }
 
 static void n_dhcp4_c_connection_outgoing_set_secs(NDhcp4Outgoing *message) {
-        uint32_t secs;
+        uint64_t secs;
 
         /*
          * This function sets the `secs` field for outgoing messages. It
@@ -125,12 +125,12 @@ static void n_dhcp4_c_connection_outgoing_set_secs(NDhcp4Outgoing *message) {
          *
          * Note: Some DHCP relays reject a `secs` value of 0 (which might look
          *       like it is uninitialized). Hence, we always clamp the value to
-         *       the range `[1, INF[`.
+         *       the range `[1, 65535]`.
          */
 
         secs = message->userdata.base_time - message->userdata.start_time;
         secs /= 1000ULL * 1000ULL * 1000ULL; /* nsecs to secs */
-        secs = secs ?: 1; /* clamp to `[1, INF[` */
+        secs = C_CLAMP(secs, 1, UINT16_MAX);
 
         n_dhcp4_outgoing_set_secs(message, secs);
 }
@@ -1104,13 +1104,14 @@ int n_dhcp4_c_connection_start_request(NDhcp4CConnection *connection,
         if (request->userdata.start_time == 0)
                 request->userdata.start_time = timestamp;
 
-        n_dhcp4_outgoing_free(connection->request);
-        connection->request = request;
+        connection->request = n_dhcp4_outgoing_free(connection->request);
 
         r = n_dhcp4_c_connection_send_request(connection, request, timestamp);
         if (r)
                 return r;
 
+        connection->request = request;
+
         return 0;
 }
 
diff --git a/shared/n-dhcp4/src/n-dhcp4-c-probe.c b/shared/n-dhcp4/src/n-dhcp4-c-probe.c
index 5bed15b8..e4477a7c 100644
--- a/shared/n-dhcp4/src/n-dhcp4-c-probe.c
+++ b/shared/n-dhcp4/src/n-dhcp4-c-probe.c
@@ -436,7 +436,10 @@ 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)
+        if (probe->config->requested_ip.s_addr != INADDR_ANY)
+                probe->last_address = probe->config->requested_ip;
+
+        if (probe->config->init_reboot && probe->last_address.s_addr != INADDR_ANY)
                 probe->state = N_DHCP4_CLIENT_PROBE_STATE_INIT_REBOOT;
         else
                 probe->state = N_DHCP4_CLIENT_PROBE_STATE_INIT;
@@ -648,7 +651,7 @@ static int n_dhcp4_client_probe_transition_reboot(NDhcp4ClientProbe *probe, uint
                 if (r)
                         return r;
 
-                r = n_dhcp4_c_connection_reboot_new(&probe->connection, &request, &probe->config->requested_ip);
+                r = n_dhcp4_c_connection_reboot_new(&probe->connection, &request, &probe->last_address);
                 if (r)
                         return r;
 
@@ -700,8 +703,8 @@ static int n_dhcp4_client_probe_transition_deferred(NDhcp4ClientProbe *probe, ui
                 if (r)
                         return r;
 
-                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 (probe->last_address.s_addr != INADDR_ANY) {
+                        r = n_dhcp4_outgoing_append_requested_ip(request, probe->last_address);
                         if (r)
                                 return r;
                 }
@@ -841,11 +844,11 @@ static int n_dhcp4_client_probe_transition_lifetime(NDhcp4ClientProbe *probe) {
                         return r;
 
                 c_assert(probe->client->current_probe == probe);
-                probe->client->current_probe = NULL;
 
-                n_dhcp4_c_connection_close(&probe->connection);
+                probe->current_lease = n_dhcp4_client_lease_unref(probe->current_lease);
 
-                probe->state = N_DHCP4_CLIENT_PROBE_STATE_EXPIRED;
+                probe->state = N_DHCP4_CLIENT_PROBE_STATE_INIT;
+                probe->ns_deferred =  n_dhcp4_gettime(CLOCK_BOOTTIME) + UINT64_C(1);
 
                 break;
 
@@ -946,6 +949,7 @@ static int n_dhcp4_client_probe_transition_ack(NDhcp4ClientProbe *probe, NDhcp4I
                 n_dhcp4_client_lease_unref(probe->current_lease);
                 probe->current_lease = n_dhcp4_client_lease_ref(lease);
                 probe->state = N_DHCP4_CLIENT_PROBE_STATE_BOUND;
+                n_dhcp4_client_lease_get_yiaddr(lease, &probe->last_address);
                 probe->ns_nak_restart_delay = 0;
                 break;
 
@@ -1005,9 +1009,9 @@ static int n_dhcp4_client_probe_transition_nak(NDhcp4ClientProbe *probe) {
 
                 probe->state = N_DHCP4_CLIENT_PROBE_STATE_INIT;
                 probe->ns_deferred = n_dhcp4_gettime(CLOCK_BOOTTIME) + probe->ns_nak_restart_delay;
-                probe->ns_nak_restart_delay = C_CLAMP(probe->ns_nak_restart_delay * 2,
-                                                      UINT64_C(1000000000 * 2),
-                                                      UINT64_C(1000000000 * 300));
+                probe->ns_nak_restart_delay = C_CLAMP(probe->ns_nak_restart_delay * 2u,
+                                                      UINT64_C(2)   * UINT64_C(1000000000),
+                                                      UINT64_C(300) * UINT64_C(1000000000));
                 break;
         case N_DHCP4_CLIENT_PROBE_STATE_SELECTING:
         case N_DHCP4_CLIENT_PROBE_STATE_INIT_REBOOT:
diff --git a/shared/n-dhcp4/src/n-dhcp4-incoming.c b/shared/n-dhcp4/src/n-dhcp4-incoming.c
index e7234c0a..f739413b 100644
--- a/shared/n-dhcp4/src/n-dhcp4-incoming.c
+++ b/shared/n-dhcp4/src/n-dhcp4-incoming.c
@@ -326,7 +326,7 @@ static int n_dhcp4_incoming_query_u8(NDhcp4Incoming *message, uint8_t option, ui
         r = n_dhcp4_incoming_query(message, option, &data, &n_data);
         if (r)
                 return r;
-        else if (n_data != sizeof(*data))
+        else if (n_data < sizeof(*data))
                 return N_DHCP4_E_MALFORMED;
 
         *u8p = *data;
@@ -342,7 +342,7 @@ static int n_dhcp4_incoming_query_u16(NDhcp4Incoming *message, uint8_t option, u
         r = n_dhcp4_incoming_query(message, option, &data, &n_data);
         if (r)
                 return r;
-        else if (n_data != sizeof(be16))
+        else if (n_data < sizeof(be16))
                 return N_DHCP4_E_MALFORMED;
 
         memcpy(&be16, data, sizeof(be16));
@@ -360,7 +360,7 @@ static int n_dhcp4_incoming_query_u32(NDhcp4Incoming *message, uint8_t option, u
         r = n_dhcp4_incoming_query(message, option, &data, &n_data);
         if (r)
                 return r;
-        else if (n_data != sizeof(be32))
+        else if (n_data < sizeof(be32))
                 return N_DHCP4_E_MALFORMED;
 
         memcpy(&be32, data, sizeof(be32));
@@ -378,7 +378,7 @@ static int n_dhcp4_incoming_query_in_addr(NDhcp4Incoming *message, uint8_t optio
         r = n_dhcp4_incoming_query(message, option, &data, &n_data);
         if (r)
                 return r;
-        else if (n_data != sizeof(be32))
+        else if (n_data < sizeof(be32))
                 return N_DHCP4_E_MALFORMED;
 
         memcpy(&be32, data, sizeof(be32));
diff --git a/shared/n-dhcp4/src/n-dhcp4-outgoing.c b/shared/n-dhcp4/src/n-dhcp4-outgoing.c
index 99123308..bcab407f 100644
--- a/shared/n-dhcp4/src/n-dhcp4-outgoing.c
+++ b/shared/n-dhcp4/src/n-dhcp4-outgoing.c
@@ -277,6 +277,7 @@ int n_dhcp4_outgoing_append(NDhcp4Outgoing *outgoing,
                         return 0;
                 }
 
+                overload = outgoing->overload;
                 if (overload & N_DHCP4_OVERLOAD_SNAME)
                         outgoing->i_message = offsetof(NDhcp4Message, sname);
                 else
@@ -341,7 +342,7 @@ int n_dhcp4_outgoing_append_requested_ip(NDhcp4Outgoing *message, struct in_addr
         return n_dhcp4_outgoing_append_in_addr(message, N_DHCP4_OPTION_REQUESTED_IP_ADDRESS, addr);
 }
 
-void n_dhcp4_outgoing_set_secs(NDhcp4Outgoing *message, uint32_t secs) {
+void n_dhcp4_outgoing_set_secs(NDhcp4Outgoing *message, uint16_t secs) {
         NDhcp4Header *header = n_dhcp4_outgoing_get_header(message);
 
         /*
@@ -350,7 +351,7 @@ void n_dhcp4_outgoing_set_secs(NDhcp4Outgoing *message, uint32_t secs) {
          */
         c_assert(secs);
 
-        header->secs = htonl(secs);
+        header->secs = htons(secs);
 }
 
 void n_dhcp4_outgoing_set_xid(NDhcp4Outgoing *message, uint32_t xid) {
diff --git a/shared/n-dhcp4/src/n-dhcp4-private.h b/shared/n-dhcp4/src/n-dhcp4-private.h
index c092ae8f..436ee806 100644
--- a/shared/n-dhcp4/src/n-dhcp4-private.h
+++ b/shared/n-dhcp4/src/n-dhcp4-private.h
@@ -350,6 +350,7 @@ struct NDhcp4ClientProbe {
         void *userdata;
 
         unsigned int state;                     /* current probe state */
+        struct in_addr last_address;            /* last address obtained */
         uint64_t ns_deferred;                   /* timeout for deferred action */
         uint64_t ns_reinit;
         uint64_t ns_nak_restart_delay;          /* restart delay after a nak */
@@ -477,7 +478,7 @@ int n_dhcp4_outgoing_append_lifetime(NDhcp4Outgoing *message, uint32_t lifetime)
 int n_dhcp4_outgoing_append_server_identifier(NDhcp4Outgoing *message, struct in_addr addr);
 int n_dhcp4_outgoing_append_requested_ip(NDhcp4Outgoing *message, struct in_addr addr);
 
-void n_dhcp4_outgoing_set_secs(NDhcp4Outgoing *message, uint32_t secs);
+void n_dhcp4_outgoing_set_secs(NDhcp4Outgoing *message, uint16_t secs);
 void n_dhcp4_outgoing_set_xid(NDhcp4Outgoing *message, uint32_t xid);
 void n_dhcp4_outgoing_set_yiaddr(NDhcp4Outgoing *message, struct in_addr yiaddr);
 
diff --git a/shared/nm-glib-aux/nm-glib.h b/shared/nm-glib-aux/nm-glib.h
index dfb75bf0..26d0eacd 100644
--- a/shared/nm-glib-aux/nm-glib.h
+++ b/shared/nm-glib-aux/nm-glib.h
@@ -569,9 +569,9 @@ _nm_g_value_unset (GValue *value)
 
 /*****************************************************************************/
 
-#if !GLIB_CHECK_VERSION (2, 57, 2)
+/* G_SOURCE_FUNC was added in 2.57.2. */
+#undef G_SOURCE_FUNC
 #define G_SOURCE_FUNC(f) ((GSourceFunc) (void (*)(void)) (f))
-#endif
 
 /*****************************************************************************/
 
diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c
index 8e1c8b58..d47c465c 100644
--- a/shared/nm-glib-aux/nm-shared-utils.c
+++ b/shared/nm-glib-aux/nm-shared-utils.c
@@ -12,6 +12,7 @@
 #include <fcntl.h>
 #include <sys/syscall.h>
 #include <glib-unix.h>
+#include <net/if.h>
 
 #include "nm-errno.h"
 
@@ -2506,6 +2507,7 @@ nm_utils_hash_values_to_array (GHashTable *hash,
 		                   user_data);
 	}
 
+	NM_SET_OUT (out_len, len);
 	return arr;
 }
 
@@ -3987,3 +3989,102 @@ nm_utils_g_main_context_create_integrate_source (GMainContext *inner_context)
 
 	return &ctx_src->source;
 }
+
+gboolean
+nm_utils_ifname_valid_kernel (const char *name, GError **error)
+{
+	int i;
+
+	/* This function follows kernel's interface validation
+	 * function dev_valid_name() in net/core/dev.c.
+	 */
+
+	if (!name) {
+		g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
+		                     _("interface name is missing"));
+		return FALSE;
+	}
+
+	if (name[0] == '\0') {
+		g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
+		                     _("interface name is too short"));
+		return FALSE;
+	}
+
+	if (   name[0] == '.'
+	    && (   name[1] == '\0'
+	        || (   name[1] == '.'
+	            && name[2] == '\0'))) {
+		g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
+		                     _("interface name is reserved"));
+		return FALSE;
+	}
+
+	for (i = 0; i < IFNAMSIZ; i++) {
+		char ch = name[i];
+
+		if (ch == '\0')
+			return TRUE;
+		if (   NM_IN_SET (ch, '/', ':')
+		    || g_ascii_isspace (ch)) {
+			g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
+			                     _("interface name contains an invalid character"));
+			return FALSE;
+		}
+	}
+
+	g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
+	                     _("interface name is longer than 15 characters"));
+	return FALSE;
+}
+
+static gboolean
+_nm_utils_ifname_valid_ovs (const char* name, GError **error)
+{
+	const char *ch;
+
+	/* OVS actually accepts a wider range of chars (all printable UTF-8 chars),
+	 NetworkManager restricts this to ASCII char as it's a safer option for
+	 now since OVS is not well documented on this matter.
+	 */
+	for (ch = name; *ch; ++ch) {
+		if (   *ch == '\\'
+		    || *ch == '/'
+		    || !g_ascii_isgraph (*ch)) {
+			g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
+			                     _("interface name must be alphanumerical with "
+			                       "no forward or backward slashes"));
+			return FALSE;
+		}
+	};
+	return TRUE;
+}
+
+gboolean
+nm_utils_ifname_valid (const char* name,
+                       NMUtilsIfaceType type,
+                       GError **error)
+{
+	g_return_val_if_fail (!error || !(*error), FALSE);
+
+	if (!name || !(name[0])) {
+		g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
+		                     _("interface name must not be empty"));
+		return FALSE;
+	}
+
+	if (!g_utf8_validate (name, -1, NULL)) {
+		g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
+		                     _("interface name must be UTF-8 encoded"));
+		return FALSE;
+	}
+
+	switch (type) {
+	case NMU_IFACE_KERNEL:
+		return nm_utils_ifname_valid_kernel (name, error);
+	case NMU_IFACE_OVS:
+		return _nm_utils_ifname_valid_ovs (name, error);
+	}
+
+	g_return_val_if_reached (FALSE);
+}
diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h
index 3bd1afae..740e61d0 100644
--- a/shared/nm-glib-aux/nm-shared-utils.h
+++ b/shared/nm-glib-aux/nm-shared-utils.h
@@ -973,6 +973,14 @@ NM_AUTO_DEFINE_FCN0 (GSource *, _nm_auto_destroy_and_unref_gsource, nm_g_source_
 NM_AUTO_DEFINE_FCN0 (GMainContext *, _nm_auto_pop_gmaincontext, g_main_context_pop_thread_default)
 #define nm_auto_pop_gmaincontext nm_auto (_nm_auto_pop_gmaincontext)
 
+static inline gboolean
+nm_source_func_unref_gobject (gpointer user_data)
+{
+	nm_assert (G_IS_OBJECT (user_data));
+	g_object_unref (user_data);
+	return G_SOURCE_REMOVE;
+}
+
 GSource *nm_g_idle_source_new (int priority,
                                GSourceFunc func,
                                gpointer user_data,
@@ -1432,4 +1440,17 @@ guint nm_utils_parse_debug_string (const char *string,
                                    const GDebugKey *keys,
                                    guint nkeys);
 
+/*****************************************************************************/
+
+typedef enum {
+	NMU_IFACE_KERNEL = 0,
+	NMU_IFACE_OVS,
+} NMUtilsIfaceType;
+
+gboolean nm_utils_ifname_valid_kernel (const char *name, GError **error);
+
+gboolean nm_utils_ifname_valid (const char* name,
+                                NMUtilsIfaceType type,
+                                GError **error);
+
 #endif /* __NM_SHARED_UTILS_H__ */
diff --git a/shared/nm-version-macros.h b/shared/nm-version-macros.h
index b8c5fbb9..1d98c935 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 (4)
+#define NM_MICRO_VERSION (8)
 
 /**
  * NM_CHECK_VERSION:
@@ -64,6 +64,7 @@
 #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))
+#define NM_VERSION_1_22_8 (NM_ENCODE_VERSION (1, 22, 8))
 
 /* 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 a9dcab8d..8704ac57 100644
--- a/shared/nm-version-macros.h.in
+++ b/shared/nm-version-macros.h.in
@@ -64,6 +64,7 @@
 #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))
+#define NM_VERSION_1_22_8 (NM_ENCODE_VERSION (1, 22, 8))
 
 /* For releases, NM_API_VERSION is equal to NM_VERSION.
  *