diff options
Diffstat (limited to 'src/platform/nm-platform-utils.c')
-rw-r--r-- | src/platform/nm-platform-utils.c | 134 |
1 files changed, 110 insertions, 24 deletions
diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index b4542adf8d..068801ee69 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; +} + |