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;
|
return NM_LINK_TYPE_IP6TNL;
|
||||||
|
|
||||||
if (ifname) {
|
if (ifname) {
|
||||||
|
NMPUtilsEthtoolDriverInfo driver_info;
|
||||||
nm_auto_close int dirfd = -1;
|
nm_auto_close int dirfd = -1;
|
||||||
gs_free char *driver = NULL;
|
|
||||||
gs_free char *devtype = NULL;
|
gs_free char *devtype = NULL;
|
||||||
char ifname_verified[IFNAMSIZ];
|
char ifname_verified[IFNAMSIZ];
|
||||||
|
|
||||||
/* Fallback OVS detection for kernel <= 3.16 */
|
/* Fallback OVS detection for kernel <= 3.16 */
|
||||||
if (nmp_utils_ethtool_get_driver_info (ifindex, &driver, NULL, NULL)) {
|
if (nmp_utils_ethtool_get_driver_info (ifindex, &driver_info)) {
|
||||||
if (!g_strcmp0 (driver, "openvswitch"))
|
if (nm_streq (driver_info.driver, "openvswitch"))
|
||||||
return NM_LINK_TYPE_OPENVSWITCH;
|
return NM_LINK_TYPE_OPENVSWITCH;
|
||||||
|
|
||||||
if (arptype == 256) {
|
if (arptype == 256) {
|
||||||
/* Some s390 CTC-type devices report 256 for the encapsulation type
|
/* Some s390 CTC-type devices report 256 for the encapsulation type
|
||||||
* for some reason, but we need to call them Ethernet.
|
* 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;
|
return NM_LINK_TYPE_ETHERNET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5535,14 +5535,17 @@ link_get_driver_info (NMPlatform *platform,
|
|||||||
char **out_fw_version)
|
char **out_fw_version)
|
||||||
{
|
{
|
||||||
nm_auto_pop_netns NMPNetns *netns = NULL;
|
nm_auto_pop_netns NMPNetns *netns = NULL;
|
||||||
|
NMPUtilsEthtoolDriverInfo driver_info;
|
||||||
|
|
||||||
if (!nm_platform_netns_push (platform, &netns))
|
if (!nm_platform_netns_push (platform, &netns))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return nmp_utils_ethtool_get_driver_info (ifindex,
|
if (!nmp_utils_ethtool_get_driver_info (ifindex, &driver_info))
|
||||||
out_driver_name,
|
return FALSE;
|
||||||
out_driver_version,
|
NM_SET_OUT (out_driver_name, g_strdup (driver_info.driver));
|
||||||
out_fw_version);
|
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
|
gboolean
|
||||||
nmp_utils_ethtool_get_driver_info (int ifindex,
|
nmp_utils_ethtool_get_driver_info (int ifindex,
|
||||||
char **out_driver_name,
|
NMPUtilsEthtoolDriverInfo *data)
|
||||||
char **out_driver_version,
|
|
||||||
char **out_fw_version)
|
|
||||||
{
|
{
|
||||||
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 (ifindex > 0, FALSE);
|
||||||
|
g_return_val_if_fail (data, FALSE);
|
||||||
|
|
||||||
drvinfo.cmd = ETHTOOL_GDRVINFO;
|
drvinfo = (struct ethtool_drvinfo *) data;
|
||||||
if (!ethtool_get (ifindex, &drvinfo))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (out_driver_name)
|
memset (drvinfo, 0, sizeof (*drvinfo));
|
||||||
*out_driver_name = g_strdup (drvinfo.driver);
|
drvinfo->cmd = ETHTOOL_GDRVINFO;
|
||||||
if (out_driver_version)
|
return ethtool_get (ifindex, drvinfo);
|
||||||
*out_driver_version = g_strdup (drvinfo.version);
|
|
||||||
if (out_fw_version)
|
|
||||||
*out_fw_version = g_strdup (drvinfo.fw_version);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
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_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);
|
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,
|
gboolean nmp_utils_ethtool_get_driver_info (int ifindex,
|
||||||
char **out_driver_name,
|
NMPUtilsEthtoolDriverInfo *data);
|
||||||
char **out_driver_version,
|
|
||||||
char **out_fw_version);
|
|
||||||
|
|
||||||
gboolean nmp_utils_ethtool_get_permanent_address (int ifindex,
|
gboolean nmp_utils_ethtool_get_permanent_address (int ifindex,
|
||||||
guint8 *buf,
|
guint8 *buf,
|
||||||
|
@@ -141,13 +141,11 @@ _link_get_driver (GUdevDevice *udev_device, const char *kind, int ifindex)
|
|||||||
return kind;
|
return kind;
|
||||||
|
|
||||||
if (ifindex > 0) {
|
if (ifindex > 0) {
|
||||||
char *d;
|
NMPUtilsEthtoolDriverInfo driver_info;
|
||||||
|
|
||||||
if (nmp_utils_ethtool_get_driver_info (ifindex, &d, NULL, NULL)) {
|
if (nmp_utils_ethtool_get_driver_info (ifindex, &driver_info)) {
|
||||||
driver = d && d[0] ? g_intern_string (d) : NULL;
|
if (driver_info.driver[0])
|
||||||
g_free (d);
|
return g_intern_string (driver_info.driver);
|
||||||
if (driver)
|
|
||||||
return driver;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1956,6 +1956,7 @@ test_netns_general (gpointer fixture, gconstpointer test_data)
|
|||||||
char sbuf[100];
|
char sbuf[100];
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
gboolean ethtool_support;
|
gboolean ethtool_support;
|
||||||
|
NMPUtilsEthtoolDriverInfo driver_info;
|
||||||
|
|
||||||
if (_test_netns_check_skip ())
|
if (_test_netns_check_skip ())
|
||||||
return;
|
return;
|
||||||
@@ -2026,8 +2027,8 @@ test_netns_general (gpointer fixture, gconstpointer test_data)
|
|||||||
* skip asserts that are known to fail. */
|
* skip asserts that are known to fail. */
|
||||||
ethtool_support = nmtstp_run_command ("ethtool -i dummy1_ > /dev/null") == 0;
|
ethtool_support = nmtstp_run_command ("ethtool -i dummy1_ > /dev/null") == 0;
|
||||||
if (ethtool_support) {
|
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, "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, NULL, NULL, NULL));
|
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 dummy1_ > /dev/null"), ==, 0);
|
||||||
g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2a > /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);
|
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));
|
g_assert (nm_platform_netns_push (platform_2, &netns_tmp));
|
||||||
|
|
||||||
if (ethtool_support) {
|
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, "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, NULL, NULL, NULL));
|
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 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 dummy2a 2> /dev/null"), !=, 0);
|
||||||
g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2b > /dev/null"), ==, 0);
|
g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2b > /dev/null"), ==, 0);
|
||||||
|
Reference in New Issue
Block a user