platform: refactor nmp_utils_sysctl_open_netdir()
- use nm_auto_close cleanup attribute - optionally, return the found ifname - don't stat "phy80211". If such an entity can be opened, just assume it's a directory.
This commit is contained in:
@@ -38,9 +38,12 @@
|
|||||||
|
|
||||||
#include "nm-core-utils.h"
|
#include "nm-core-utils.h"
|
||||||
|
|
||||||
|
extern char *if_indextoname (unsigned int __ifindex, char *__ifname);
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* ethtool
|
* ethtool
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
|
||||||
#define ethtool_cmd_speed(pedata) ((pedata)->speed)
|
#define ethtool_cmd_speed(pedata) ((pedata)->speed)
|
||||||
|
|
||||||
@@ -48,8 +51,6 @@
|
|||||||
G_STMT_START { (pedata)->speed = (guint16) (speed); } G_STMT_END
|
G_STMT_START { (pedata)->speed = (guint16) (speed); } G_STMT_END
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern char *if_indextoname (unsigned int __ifindex, char *__ifname);
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
ethtool_get (const char *name, gpointer edata)
|
ethtool_get (const char *name, gpointer edata)
|
||||||
{
|
{
|
||||||
@@ -625,51 +626,83 @@ nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nmp_utils_sysctl_open_netdir:
|
||||||
|
* @ifindex: the ifindex for which to open "/sys/class/net/%s"
|
||||||
|
* @ifname_guess: (allow-none): optional argument, if present used as initial
|
||||||
|
* guess as the current name for @ifindex. If guessed right,
|
||||||
|
* it saves an addtional if_indextoname() call.
|
||||||
|
* @out_ifname: (allow-none): if present, must be at least IFNAMSIZ
|
||||||
|
* characters. On success, this will contain the actual ifname
|
||||||
|
* found while opening the directory.
|
||||||
|
*
|
||||||
|
* Returns: a negative value on failure, on success returns the open fd
|
||||||
|
* to the "/sys/class/net/%s" directory for @ifindex.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
nmp_utils_open_sysctl(int ifindex, const char *ifname)
|
nmp_utils_sysctl_open_netdir (int ifindex,
|
||||||
|
const char *ifname_guess,
|
||||||
|
char *out_ifname)
|
||||||
{
|
{
|
||||||
#define SYS_CLASS_NET "/sys/class/net/"
|
#define SYS_CLASS_NET "/sys/class/net/"
|
||||||
|
const char *ifname = ifname_guess;
|
||||||
|
char ifname_buf_last_try[IFNAMSIZ];
|
||||||
char ifname_buf[IFNAMSIZ];
|
char ifname_buf[IFNAMSIZ];
|
||||||
guint try_count = 0;
|
guint try_count = 0;
|
||||||
char sysdir[NM_STRLEN (SYS_CLASS_NET) + IFNAMSIZ + 1] = SYS_CLASS_NET;
|
char sysdir[NM_STRLEN (SYS_CLASS_NET) + IFNAMSIZ] = SYS_CLASS_NET;
|
||||||
char fd_buf[256];
|
char fd_buf[256];
|
||||||
int fd;
|
|
||||||
int fd_ifindex;
|
|
||||||
ssize_t nn;
|
ssize_t nn;
|
||||||
|
|
||||||
while (++try_count < 4) {
|
g_return_val_if_fail (ifindex >= 0, -1);
|
||||||
|
|
||||||
|
ifname_buf_last_try[0] = '\0';
|
||||||
|
|
||||||
|
for (try_count = 0; try_count < 10; try_count++, ifname = NULL) {
|
||||||
|
nm_auto_close int fd_dir = -1;
|
||||||
|
nm_auto_close int fd_ifindex = -1;
|
||||||
|
int fd;
|
||||||
|
|
||||||
if (!ifname) {
|
if (!ifname) {
|
||||||
ifname = if_indextoname (ifindex, ifname_buf);
|
ifname = if_indextoname (ifindex, ifname_buf);
|
||||||
if (!ifname)
|
if (!ifname)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nm_utils_ifname_cpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], ifname);
|
nm_assert (nm_utils_iface_valid_name (ifname));
|
||||||
fd = open (sysdir, O_DIRECTORY);
|
|
||||||
if (fd < 0)
|
|
||||||
goto next;
|
|
||||||
fd_ifindex = openat (fd, "ifindex", 0);
|
|
||||||
if (fd_ifindex < 0) {
|
|
||||||
close (fd);
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
/* read ifindex file, and compare it to @ifindex. If match, return fd. */
|
|
||||||
nn = nm_utils_fd_read_loop (fd_ifindex, fd_buf, sizeof (fd_buf) - 1, FALSE);
|
|
||||||
if (nn < 0) {
|
|
||||||
close (fd);
|
|
||||||
close (fd_ifindex);
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
fd_buf[sizeof (fd_buf) - 1] = '\0';
|
|
||||||
|
|
||||||
if (ifindex != _nm_utils_ascii_str_to_int64 (fd_buf, 10, 1, G_MAXINT, -1)) {
|
if (g_strlcpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], ifname, IFNAMSIZ) >= IFNAMSIZ)
|
||||||
close (fd);
|
g_return_val_if_reached (-1);
|
||||||
close (fd_ifindex);
|
|
||||||
goto next;
|
/* we only retry, if the name changed since previous attempt.
|
||||||
}
|
* Hence, it is extremely unlikely that this loop runes until the
|
||||||
|
* end of the @try_count. */
|
||||||
|
if (nm_streq (ifname, ifname_buf_last_try))
|
||||||
|
return -1;
|
||||||
|
strcpy (ifname_buf_last_try, ifname);
|
||||||
|
|
||||||
|
fd_dir = open (sysdir, O_DIRECTORY | O_CLOEXEC);
|
||||||
|
if (fd_dir < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fd_ifindex = openat (fd_dir, "ifindex", O_CLOEXEC);
|
||||||
|
if (fd_ifindex < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
nn = nm_utils_fd_read_loop (fd_ifindex, fd_buf, sizeof (fd_buf) - 2, FALSE);
|
||||||
|
if (nn <= 0)
|
||||||
|
continue;
|
||||||
|
fd_buf[nn] = '\0';
|
||||||
|
|
||||||
|
if (ifindex != _nm_utils_ascii_str_to_int64 (fd_buf, 10, 1, G_MAXINT, -1))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (out_ifname)
|
||||||
|
strcpy (out_ifname, ifname);
|
||||||
|
|
||||||
|
fd = fd_dir;
|
||||||
|
fd_dir = -1;
|
||||||
return fd;
|
return fd;
|
||||||
next:
|
|
||||||
ifname = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@@ -61,6 +61,8 @@ NMIPConfigSource nmp_utils_ip_config_source_coerce_from_rtprot (NMIPConfigSource
|
|||||||
NMIPConfigSource nmp_utils_ip_config_source_round_trip_rtprot (NMIPConfigSource source) _nm_const;
|
NMIPConfigSource nmp_utils_ip_config_source_round_trip_rtprot (NMIPConfigSource source) _nm_const;
|
||||||
const char * nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize len);
|
const char * nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize len);
|
||||||
|
|
||||||
int nmp_utils_open_sysctl(int ifindex, const char *ifname);
|
int nmp_utils_sysctl_open_netdir (int ifindex,
|
||||||
|
const char *ifname_guess,
|
||||||
|
char *out_ifname);
|
||||||
|
|
||||||
#endif /* __NM_PLATFORM_UTILS_H__ */
|
#endif /* __NM_PLATFORM_UTILS_H__ */
|
||||||
|
@@ -187,29 +187,26 @@ wifi_utils_is_wifi (int ifindex, const char *ifname)
|
|||||||
{
|
{
|
||||||
int fd_sysnet;
|
int fd_sysnet;
|
||||||
int fd_phy80211;
|
int fd_phy80211;
|
||||||
struct stat s;
|
char ifname_verified[IFNAMSIZ];
|
||||||
|
|
||||||
g_return_val_if_fail (ifname != NULL, FALSE);
|
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||||
|
|
||||||
fd_sysnet = nmp_utils_open_sysctl (ifindex, ifname);
|
fd_sysnet = nmp_utils_sysctl_open_netdir (ifindex, ifname, ifname_verified);
|
||||||
if (fd_sysnet < 0)
|
if (fd_sysnet < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
fd_phy80211 = openat (fd_sysnet, "phy80211", 0);
|
/* there might have been a race and ifname might be wrong. Below for checking
|
||||||
if (fd_phy80211 < 0) {
|
* wext, use the possibly improved name that we just verified. */
|
||||||
close (fd_sysnet);
|
ifname = ifname_verified;
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((fstat (fd_phy80211, &s) == 0 && (s.st_mode & S_IFDIR))) {
|
fd_phy80211 = openat (fd_sysnet, "phy80211", O_CLOEXEC);
|
||||||
close (fd_sysnet);
|
close (fd_sysnet);
|
||||||
|
|
||||||
|
if (fd_phy80211 >= 0) {
|
||||||
close (fd_phy80211);
|
close (fd_phy80211);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
close (fd_sysnet);
|
|
||||||
close (fd_phy80211);
|
|
||||||
|
|
||||||
#if HAVE_WEXT
|
#if HAVE_WEXT
|
||||||
if (wifi_wext_is_wifi (ifname))
|
if (wifi_wext_is_wifi (ifname))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
Reference in New Issue
Block a user