about summary refs log tree commit diff
path: root/src/platform/nm-platform-utils.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2016-08-26 02:18:32 +0200
committerMichael Biebl <biebl@debian.org>2016-08-26 02:18:32 +0200
commit7514efc2f38c9ace4557d4e69d68e7d380389030 (patch)
tree7fb00fda86cfcc2ca377f191633a7cfdbfea7ca3 /src/platform/nm-platform-utils.c
parentd6201f5d8daada3d64a0a3e0038e14eebec683ce (diff)
Imported Upstream version 1.4.0 upstream/1.4.0
Diffstat (limited to 'src/platform/nm-platform-utils.c')
-rw-r--r--src/platform/nm-platform-utils.c134
1 files changed, 110 insertions, 24 deletions
diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c
index b4542adf..068801ee 100644
--- a/src/platform/nm-platform-utils.c
+++ b/src/platform/nm-platform-utils.c
@@ -144,8 +144,7 @@ nmp_utils_ethtool_get_permanent_address (const char *ifname,
 		struct ethtool_perm_addr e;
 		guint8 _extra_data[NM_UTILS_HWADDR_LEN_MAX + 1];
 	} edata;
-	static const guint8 zeros[NM_UTILS_HWADDR_LEN_MAX] = { 0 };
-	static guint8 ones[NM_UTILS_HWADDR_LEN_MAX] = { 0 };
+	guint i;
 
 	if (!ifname)
 		return FALSE;
@@ -157,18 +156,23 @@ nmp_utils_ethtool_get_permanent_address (const char *ifname,
 	if (!ethtool_get (ifname, &edata.e))
 		return FALSE;
 
-	g_assert (edata.e.size <= NM_UTILS_HWADDR_LEN_MAX);
-
-	/* Some drivers might return a permanent address of all zeros.
-	 * Reject that (rh#1264024) */
-	if (memcmp (edata.e.data, zeros, edata.e.size) == 0)
+	if (edata.e.size > NM_UTILS_HWADDR_LEN_MAX)
+		return FALSE;
+	if (edata.e.size < 1)
 		return FALSE;
 
-	/* Some drivers return a permanent address of all ones. Reject that too */
-	if (G_UNLIKELY (ones[0] != 0xFF))
-		memset (ones, 0xFF, sizeof (ones));
-	if (memcmp (edata.e.data, ones, edata.e.size) == 0)
+	if (NM_IN_SET (edata.e.data[0], 0, 0xFF)) {
+		/* Some drivers might return a permanent address of all zeros.
+		 * Reject that (rh#1264024)
+		 *
+		 * Some drivers return a permanent address of all ones. Reject that too */
+		for (i = 1; i < edata.e.size; i++) {
+			if (edata.e.data[0] != edata.e.data[i])
+				goto not_all_0or1;
+		}
 		return FALSE;
+	}
+not_all_0or1:
 
 	memcpy (buf, edata.e.data, edata.e.size);
 	*length = edata.e.size;
@@ -433,14 +437,35 @@ nmp_utils_device_exists (const char *name)
 	return g_file_test (sysdir, G_FILE_TEST_EXISTS);
 }
 
-guint
-nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source)
+NMIPConfigSource
+nmp_utils_ip_config_source_from_rtprot (guint8 rtprot)
 {
-	switch (source) {
-	case NM_IP_CONFIG_SOURCE_UNKNOWN:
+	return ((int) rtprot) + 1;
+}
+
+NMIPConfigSource
+nmp_utils_ip_config_source_round_trip_rtprot (NMIPConfigSource source)
+{
+	/* when adding a route to kernel for a give @source, the resulting route
+	 * will be put into the cache with a source of NM_IP_CONFIG_SOURCE_RTPROT_*.
+	 * This function returns that. */
+	return nmp_utils_ip_config_source_from_rtprot (nmp_utils_ip_config_source_coerce_to_rtprot (source));
+}
+
+guint8
+nmp_utils_ip_config_source_coerce_to_rtprot (NMIPConfigSource source)
+{
+	/* when adding a route to kernel, we coerce the @source field
+	 * to rtm_protocol. This is not lossless as we map different
+	 * source values to the same RTPROT uint8 value. */
+	if (source <= NM_IP_CONFIG_SOURCE_UNKNOWN)
 		return RTPROT_UNSPEC;
+
+	if (source <= _NM_IP_CONFIG_SOURCE_RTPROT_LAST)
+		return source - 1;
+
+	switch (source) {
 	case NM_IP_CONFIG_SOURCE_KERNEL:
-	case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL:
 		return RTPROT_KERNEL;
 	case NM_IP_CONFIG_SOURCE_DHCP:
 		return RTPROT_DHCP;
@@ -453,18 +478,32 @@ nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source)
 }
 
 NMIPConfigSource
-nmp_utils_ip_config_source_from_rtprot (guint rtprot)
+nmp_utils_ip_config_source_coerce_from_rtprot (NMIPConfigSource source)
 {
-	switch (rtprot) {
-	case RTPROT_UNSPEC:
+	/* When we receive a route from kernel and put it into the platform cache,
+	 * we preserve the protocol field by converting it to a NMIPConfigSource
+	 * via nmp_utils_ip_config_source_from_rtprot().
+	 *
+	 * However, that is not the inverse of nmp_utils_ip_config_source_coerce_to_rtprot().
+	 * Instead, to go back to the original value, you need another step:
+	 *   nmp_utils_ip_config_source_coerce_from_rtprot (nmp_utils_ip_config_source_from_rtprot (rtprot)).
+	 *
+	 * This might partly restore the original source value, but of course that
+	 * is not really possible because nmp_utils_ip_config_source_coerce_to_rtprot()
+	 * is not injective.
+	 * */
+	switch (source) {
+	case NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC:
 		return NM_IP_CONFIG_SOURCE_UNKNOWN;
-	case RTPROT_KERNEL:
-		return NM_IP_CONFIG_SOURCE_RTPROT_KERNEL;
-	case RTPROT_REDIRECT:
+
+	case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL:
+	case NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT:
 		return NM_IP_CONFIG_SOURCE_KERNEL;
-	case RTPROT_RA:
+
+	case NM_IP_CONFIG_SOURCE_RTPROT_RA:
 		return NM_IP_CONFIG_SOURCE_RDISC;
-	case RTPROT_DHCP:
+
+	case NM_IP_CONFIG_SOURCE_RTPROT_DHCP:
 		return NM_IP_CONFIG_SOURCE_DHCP;
 
 	default:
@@ -472,3 +511,50 @@ nmp_utils_ip_config_source_from_rtprot (guint rtprot)
 	}
 }
 
+const char *
+nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize len)
+{
+	const char *s = NULL;
+	nm_utils_to_string_buffer_init (&buf, &len); \
+
+	if (!len)
+		return buf;
+
+	switch (source) {
+	case NM_IP_CONFIG_SOURCE_UNKNOWN:         s = "unknown"; break;
+
+	case NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC:   s = "rt-unspec"; break;
+	case NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT: s = "rt-redirect"; break;
+	case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL:   s = "rt-kernel"; break;
+	case NM_IP_CONFIG_SOURCE_RTPROT_BOOT:     s = "rt-boot"; break;
+	case NM_IP_CONFIG_SOURCE_RTPROT_STATIC:   s = "rt-static"; break;
+	case NM_IP_CONFIG_SOURCE_RTPROT_DHCP:     s = "rt-dhcp"; break;
+	case NM_IP_CONFIG_SOURCE_RTPROT_RA:       s = "rt-ra"; break;
+
+	case NM_IP_CONFIG_SOURCE_KERNEL:          s = "kernel"; break;
+	case NM_IP_CONFIG_SOURCE_SHARED:          s = "shared"; break;
+	case NM_IP_CONFIG_SOURCE_IP4LL:           s = "ipv4ll"; break;
+	case NM_IP_CONFIG_SOURCE_PPP:             s = "ppp"; break;
+	case NM_IP_CONFIG_SOURCE_WWAN:            s = "wwan"; break;
+	case NM_IP_CONFIG_SOURCE_VPN:             s = "vpn"; break;
+	case NM_IP_CONFIG_SOURCE_DHCP:            s = "dhcp"; break;
+	case NM_IP_CONFIG_SOURCE_RDISC:           s = "rdisc"; break;
+	case NM_IP_CONFIG_SOURCE_USER:            s = "user"; break;
+	default:
+		break;
+	}
+
+	if (source >= 1 && source <= 0x100) {
+		if (s)
+			g_snprintf (buf, len, "%s", s);
+		else
+			g_snprintf (buf, len, "rt-%d", ((int) source) - 1);
+	} else {
+		if (s)
+			g_strlcpy (buf, s, len);
+		else
+			g_snprintf (buf, len, "(%d)", source);
+	}
+	return buf;
+}
+