platform: avoid copying arguments for nmp_utils_ethtool_get_driver_info()
We call nmp_utils_ethtool_get_driver_info() twice when receiving a netlink message, but we don't need a clone of the string values. Instead, expose a data structure that should be stack allocated by the caller.
This commit is contained in:
@@ -676,21 +676,21 @@ _linktype_get_type (NMPlatform *platform,
|
||||
return NM_LINK_TYPE_IP6TNL;
|
||||
|
||||
if (ifname) {
|
||||
NMPUtilsEthtoolDriverInfo driver_info;
|
||||
nm_auto_close int dirfd = -1;
|
||||
gs_free char *driver = NULL;
|
||||
gs_free char *devtype = NULL;
|
||||
char ifname_verified[IFNAMSIZ];
|
||||
|
||||
/* Fallback OVS detection for kernel <= 3.16 */
|
||||
if (nmp_utils_ethtool_get_driver_info (ifindex, &driver, NULL, NULL)) {
|
||||
if (!g_strcmp0 (driver, "openvswitch"))
|
||||
if (nmp_utils_ethtool_get_driver_info (ifindex, &driver_info)) {
|
||||
if (nm_streq (driver_info.driver, "openvswitch"))
|
||||
return NM_LINK_TYPE_OPENVSWITCH;
|
||||
|
||||
if (arptype == 256) {
|
||||
/* Some s390 CTC-type devices report 256 for the encapsulation type
|
||||
* for some reason, but we need to call them Ethernet.
|
||||
*/
|
||||
if (!g_strcmp0 (driver, "ctcm"))
|
||||
if (nm_streq (driver_info.driver, "ctcm"))
|
||||
return NM_LINK_TYPE_ETHERNET;
|
||||
}
|
||||
}
|
||||
@@ -5535,14 +5535,17 @@ link_get_driver_info (NMPlatform *platform,
|
||||
char **out_fw_version)
|
||||
{
|
||||
nm_auto_pop_netns NMPNetns *netns = NULL;
|
||||
NMPUtilsEthtoolDriverInfo driver_info;
|
||||
|
||||
if (!nm_platform_netns_push (platform, &netns))
|
||||
return FALSE;
|
||||
|
||||
return nmp_utils_ethtool_get_driver_info (ifindex,
|
||||
out_driver_name,
|
||||
out_driver_version,
|
||||
out_fw_version);
|
||||
if (!nmp_utils_ethtool_get_driver_info (ifindex, &driver_info))
|
||||
return FALSE;
|
||||
NM_SET_OUT (out_driver_name, g_strdup (driver_info.driver));
|
||||
NM_SET_OUT (out_driver_version, g_strdup (driver_info.version));
|
||||
NM_SET_OUT (out_fw_version, g_strdup (driver_info.fw_version));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@@ -172,26 +172,25 @@ ethtool_get_stringset_index (int ifindex, int stringset_id, const char *string)
|
||||
|
||||
gboolean
|
||||
nmp_utils_ethtool_get_driver_info (int ifindex,
|
||||
char **out_driver_name,
|
||||
char **out_driver_version,
|
||||
char **out_fw_version)
|
||||
NMPUtilsEthtoolDriverInfo *data)
|
||||
{
|
||||
struct ethtool_drvinfo drvinfo = { 0 };
|
||||
struct ethtool_drvinfo *drvinfo;
|
||||
G_STATIC_ASSERT (sizeof (*data) == sizeof (*drvinfo));
|
||||
G_STATIC_ASSERT (offsetof (NMPUtilsEthtoolDriverInfo, driver) == offsetof (struct ethtool_drvinfo, driver));
|
||||
G_STATIC_ASSERT (offsetof (NMPUtilsEthtoolDriverInfo, version) == offsetof (struct ethtool_drvinfo, version));
|
||||
G_STATIC_ASSERT (offsetof (NMPUtilsEthtoolDriverInfo, fw_version) == offsetof (struct ethtool_drvinfo, fw_version));
|
||||
G_STATIC_ASSERT (sizeof (data->driver) == sizeof (drvinfo->driver));
|
||||
G_STATIC_ASSERT (sizeof (data->version) == sizeof (drvinfo->version));
|
||||
G_STATIC_ASSERT (sizeof (data->fw_version) == sizeof (drvinfo->fw_version));
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||
g_return_val_if_fail (data, FALSE);
|
||||
|
||||
drvinfo.cmd = ETHTOOL_GDRVINFO;
|
||||
if (!ethtool_get (ifindex, &drvinfo))
|
||||
return FALSE;
|
||||
drvinfo = (struct ethtool_drvinfo *) data;
|
||||
|
||||
if (out_driver_name)
|
||||
*out_driver_name = g_strdup (drvinfo.driver);
|
||||
if (out_driver_version)
|
||||
*out_driver_version = g_strdup (drvinfo.version);
|
||||
if (out_fw_version)
|
||||
*out_fw_version = g_strdup (drvinfo.fw_version);
|
||||
|
||||
return TRUE;
|
||||
memset (drvinfo, 0, sizeof (*drvinfo));
|
||||
drvinfo->cmd = ETHTOOL_GDRVINFO;
|
||||
return ethtool_get (ifindex, drvinfo);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@@ -38,10 +38,25 @@ gboolean nmp_utils_ethtool_set_wake_on_lan (int ifindex, NMSettingWiredWakeOnLan
|
||||
gboolean nmp_utils_ethtool_get_link_settings (int ifindex, gboolean *out_autoneg, guint32 *out_speed, NMPlatformLinkDuplexType *out_duplex);
|
||||
gboolean nmp_utils_ethtool_set_link_settings (int ifindex, gboolean autoneg, guint32 speed, NMPlatformLinkDuplexType duplex);
|
||||
|
||||
typedef struct {
|
||||
/* We don't want to include <linux/ethtool.h> in header files,
|
||||
* thus create a ABI compatible version of struct ethtool_drvinfo.*/
|
||||
guint32 _private_cmd;
|
||||
char driver[32];
|
||||
char version[32];
|
||||
char fw_version[32];
|
||||
char _private_bus_info[32];
|
||||
char _private_erom_version[32];
|
||||
char _private_reserved2[12];
|
||||
guint32 _private_n_priv_flags;
|
||||
guint32 _private_n_stats;
|
||||
guint32 _private_testinfo_len;
|
||||
guint32 _private_eedump_len;
|
||||
guint32 _private_regdump_len;
|
||||
} NMPUtilsEthtoolDriverInfo;
|
||||
|
||||
gboolean nmp_utils_ethtool_get_driver_info (int ifindex,
|
||||
char **out_driver_name,
|
||||
char **out_driver_version,
|
||||
char **out_fw_version);
|
||||
NMPUtilsEthtoolDriverInfo *data);
|
||||
|
||||
gboolean nmp_utils_ethtool_get_permanent_address (int ifindex,
|
||||
guint8 *buf,
|
||||
|
@@ -141,13 +141,11 @@ _link_get_driver (GUdevDevice *udev_device, const char *kind, int ifindex)
|
||||
return kind;
|
||||
|
||||
if (ifindex > 0) {
|
||||
char *d;
|
||||
NMPUtilsEthtoolDriverInfo driver_info;
|
||||
|
||||
if (nmp_utils_ethtool_get_driver_info (ifindex, &d, NULL, NULL)) {
|
||||
driver = d && d[0] ? g_intern_string (d) : NULL;
|
||||
g_free (d);
|
||||
if (driver)
|
||||
return driver;
|
||||
if (nmp_utils_ethtool_get_driver_info (ifindex, &driver_info)) {
|
||||
if (driver_info.driver[0])
|
||||
return g_intern_string (driver_info.driver);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1956,6 +1956,7 @@ test_netns_general (gpointer fixture, gconstpointer test_data)
|
||||
char sbuf[100];
|
||||
int i, j, k;
|
||||
gboolean ethtool_support;
|
||||
NMPUtilsEthtoolDriverInfo driver_info;
|
||||
|
||||
if (_test_netns_check_skip ())
|
||||
return;
|
||||
@@ -2026,8 +2027,8 @@ test_netns_general (gpointer fixture, gconstpointer test_data)
|
||||
* skip asserts that are known to fail. */
|
||||
ethtool_support = nmtstp_run_command ("ethtool -i dummy1_ > /dev/null") == 0;
|
||||
if (ethtool_support) {
|
||||
g_assert (nmp_utils_ethtool_get_driver_info (nmtstp_link_get_typed (platform_1, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex, NULL, NULL, NULL));
|
||||
g_assert (nmp_utils_ethtool_get_driver_info (nmtstp_link_get_typed (platform_1, 0, "dummy2a", NM_LINK_TYPE_DUMMY)->ifindex, NULL, NULL, NULL));
|
||||
g_assert (nmp_utils_ethtool_get_driver_info (nmtstp_link_get_typed (platform_1, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex, &driver_info));
|
||||
g_assert (nmp_utils_ethtool_get_driver_info (nmtstp_link_get_typed (platform_1, 0, "dummy2a", NM_LINK_TYPE_DUMMY)->ifindex, &driver_info));
|
||||
g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy1_ > /dev/null"), ==, 0);
|
||||
g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2a > /dev/null"), ==, 0);
|
||||
g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2b 2> /dev/null"), !=, 0);
|
||||
@@ -2036,8 +2037,8 @@ test_netns_general (gpointer fixture, gconstpointer test_data)
|
||||
g_assert (nm_platform_netns_push (platform_2, &netns_tmp));
|
||||
|
||||
if (ethtool_support) {
|
||||
g_assert (nmp_utils_ethtool_get_driver_info (nmtstp_link_get_typed (platform_2, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex, NULL, NULL, NULL));
|
||||
g_assert (nmp_utils_ethtool_get_driver_info (nmtstp_link_get_typed (platform_2, 0, "dummy2b", NM_LINK_TYPE_DUMMY)->ifindex, NULL, NULL, NULL));
|
||||
g_assert (nmp_utils_ethtool_get_driver_info (nmtstp_link_get_typed (platform_2, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex, &driver_info));
|
||||
g_assert (nmp_utils_ethtool_get_driver_info (nmtstp_link_get_typed (platform_2, 0, "dummy2b", NM_LINK_TYPE_DUMMY)->ifindex, &driver_info));
|
||||
g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy1_ > /dev/null"), ==, 0);
|
||||
g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2a 2> /dev/null"), !=, 0);
|
||||
g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2b > /dev/null"), ==, 0);
|
||||
|
Reference in New Issue
Block a user