platform: replace ring ethtool ioctl calls with netlink

This commit is contained in:
Beniamino Galvani
2025-03-24 21:36:22 +01:00
parent 3580dfe517
commit 250475c0fd
7 changed files with 173 additions and 67 deletions

View File

@@ -11877,6 +11877,28 @@ ethtool_set_eee(NMPlatform *platform, int ifindex, const NMEthtoolEEEState *eee)
eee);
}
static gboolean
ethtool_get_ring(NMPlatform *platform, int ifindex, NMEthtoolRingState *ring)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform);
return nmp_ethtool_get_ring(priv->sk_genl_sync,
genl_get_family_id(platform, NMP_GENL_FAMILY_TYPE_ETHTOOL),
ifindex,
ring);
}
static gboolean
ethtool_set_ring(NMPlatform *platform, int ifindex, const NMEthtoolRingState *ring)
{
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform);
return nmp_ethtool_set_ring(priv->sk_genl_sync,
genl_get_family_id(platform, NMP_GENL_FAMILY_TYPE_ETHTOOL),
ifindex,
ring);
}
/*****************************************************************************/
static void
@@ -12381,4 +12403,6 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass)
platform_class->ethtool_get_pause = ethtool_get_pause;
platform_class->ethtool_set_eee = ethtool_set_eee;
platform_class->ethtool_get_eee = ethtool_get_eee;
platform_class->ethtool_set_ring = ethtool_set_ring;
platform_class->ethtool_get_ring = ethtool_get_ring;
}

View File

@@ -3671,7 +3671,7 @@ nm_platform_ethtool_get_ring(NMPlatform *self, int ifindex, NMEthtoolRingState *
g_return_val_if_fail(ifindex > 0, FALSE);
g_return_val_if_fail(ring, FALSE);
return nmp_ethtool_ioctl_get_ring(ifindex, ring);
return klass->ethtool_get_ring(self, ifindex, ring);
}
gboolean
@@ -3680,8 +3680,9 @@ nm_platform_ethtool_set_ring(NMPlatform *self, int ifindex, const NMEthtoolRingS
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
g_return_val_if_fail(ifindex > 0, FALSE);
g_return_val_if_fail(ring, FALSE);
return nmp_ethtool_ioctl_set_ring(ifindex, ring);
return klass->ethtool_set_ring(self, ifindex, ring);
}
gboolean

View File

@@ -1350,7 +1350,8 @@ typedef struct {
gboolean (*ethtool_set_pause)(NMPlatform *self, int ifindex, const NMEthtoolPauseState *pause);
gboolean (*ethtool_get_eee)(NMPlatform *self, int ifindex, NMEthtoolEEEState *eee);
gboolean (*ethtool_set_eee)(NMPlatform *self, int ifindex, const NMEthtoolEEEState *eee);
gboolean (*ethtool_get_ring)(NMPlatform *self, int ifindex, NMEthtoolRingState *ring);
gboolean (*ethtool_set_ring)(NMPlatform *self, int ifindex, const NMEthtoolRingState *ring);
} NMPlatformClass;
/* NMPlatform signals

View File

@@ -967,66 +967,6 @@ nmp_ethtool_ioctl_set_coalesce(int ifindex, const NMEthtoolCoalesceState *coales
return TRUE;
}
gboolean
nmp_ethtool_ioctl_get_ring(int ifindex, NMEthtoolRingState *ring)
{
struct ethtool_ringparam eth_data;
g_return_val_if_fail(ifindex > 0, FALSE);
g_return_val_if_fail(ring, FALSE);
eth_data.cmd = ETHTOOL_GRINGPARAM;
if (_ethtool_call_once(ifindex, &eth_data, sizeof(eth_data)) < 0) {
nm_log_trace(LOGD_PLATFORM,
"ethtool[%d]: %s: failure getting ring settings",
ifindex,
"get-ring");
return FALSE;
}
*ring = (NMEthtoolRingState) {
.rx_pending = eth_data.rx_pending,
.rx_jumbo_pending = eth_data.rx_jumbo_pending,
.rx_mini_pending = eth_data.rx_mini_pending,
.tx_pending = eth_data.tx_pending,
};
nm_log_trace(LOGD_PLATFORM,
"ethtool[%d]: %s: retrieved kernel ring settings",
ifindex,
"get-ring");
return TRUE;
}
gboolean
nmp_ethtool_ioctl_set_ring(int ifindex, const NMEthtoolRingState *ring)
{
struct ethtool_ringparam eth_data;
g_return_val_if_fail(ifindex > 0, FALSE);
g_return_val_if_fail(ring, FALSE);
eth_data = (struct ethtool_ringparam) {
.cmd = ETHTOOL_SRINGPARAM,
.rx_pending = ring->rx_pending,
.rx_jumbo_pending = ring->rx_jumbo_pending,
.rx_mini_pending = ring->rx_mini_pending,
.tx_pending = ring->tx_pending,
};
if (_ethtool_call_once(ifindex, &eth_data, sizeof(eth_data)) < 0) {
nm_log_trace(LOGD_PLATFORM,
"ethtool[%d]: %s: failure setting ring settings",
ifindex,
"set-ring");
return FALSE;
}
nm_log_trace(LOGD_PLATFORM, "ethtool[%d]: %s: set kernel ring settings", ifindex, "set-ring");
return TRUE;
}
gboolean
nmp_ethtool_ioctl_get_channels(int ifindex, NMEthtoolChannelsState *channels)
{

View File

@@ -42,10 +42,6 @@ gboolean nmp_ethtool_ioctl_get_coalesce(int ifindex, NMEthtoolCoalesceState *coa
gboolean nmp_ethtool_ioctl_set_coalesce(int ifindex, const NMEthtoolCoalesceState *coalesce);
gboolean nmp_ethtool_ioctl_get_ring(int ifindex, NMEthtoolRingState *ring);
gboolean nmp_ethtool_ioctl_set_ring(int ifindex, const NMEthtoolRingState *ring);
gboolean nmp_ethtool_ioctl_get_channels(int ifindex, NMEthtoolChannelsState *channels);
gboolean nmp_ethtool_ioctl_set_channels(int ifindex, const NMEthtoolChannelsState *channels);

View File

@@ -422,3 +422,138 @@ nmp_ethtool_set_eee(struct nl_sock *genl_sock,
nla_put_failure:
g_return_val_if_reached(FALSE);
}
/*****************************************************************************/
/* RINGS */
/*****************************************************************************/
enum {
ETHTOOL_A_RINGS_UNSPEC,
ETHTOOL_A_RINGS_HEADER, /* nest - _A_HEADER_* */
ETHTOOL_A_RINGS_RX_MAX, /* u32 */
ETHTOOL_A_RINGS_RX_MINI_MAX, /* u32 */
ETHTOOL_A_RINGS_RX_JUMBO_MAX, /* u32 */
ETHTOOL_A_RINGS_TX_MAX, /* u32 */
ETHTOOL_A_RINGS_RX, /* u32 */
ETHTOOL_A_RINGS_RX_MINI, /* u32 */
ETHTOOL_A_RINGS_RX_JUMBO, /* u32 */
ETHTOOL_A_RINGS_TX, /* u32 */
/* add new constants above here */
__ETHTOOL_A_RINGS_CNT,
ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1)
};
static int
ethtool_parse_ring(const struct nl_msg *msg, void *data)
{
NMEthtoolRingState *ring = data;
static const struct nla_policy policy[] = {
[ETHTOOL_A_RINGS_RX] = {.type = NLA_U32},
[ETHTOOL_A_RINGS_RX_MINI] = {.type = NLA_U32},
[ETHTOOL_A_RINGS_RX_JUMBO] = {.type = NLA_U32},
[ETHTOOL_A_RINGS_TX] = {.type = NLA_U32},
};
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *tb[G_N_ELEMENTS(policy)];
*ring = (NMEthtoolRingState) {};
if (nla_parse_arr(tb, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), policy) < 0)
return NL_SKIP;
if (tb[ETHTOOL_A_RINGS_RX])
ring->rx_pending = nla_get_u32(tb[ETHTOOL_A_RINGS_RX]);
if (tb[ETHTOOL_A_RINGS_RX_MINI])
ring->rx_mini_pending = nla_get_u32(tb[ETHTOOL_A_RINGS_RX_MINI]);
if (tb[ETHTOOL_A_RINGS_RX_JUMBO])
ring->rx_jumbo_pending = nla_get_u32(tb[ETHTOOL_A_RINGS_RX_JUMBO]);
if (tb[ETHTOOL_A_RINGS_TX])
ring->tx_pending = nla_get_u32(tb[ETHTOOL_A_RINGS_TX]);
return NL_OK;
}
gboolean
nmp_ethtool_get_ring(struct nl_sock *genl_sock,
guint16 family_id,
int ifindex,
NMEthtoolRingState *ring)
{
nm_auto_nlmsg struct nl_msg *msg = NULL;
gs_free char *err_msg = NULL;
int r;
g_return_val_if_fail(ring, FALSE);
_LOGT("get-ring: start");
*ring = (NMEthtoolRingState) {};
msg = ethtool_create_msg(family_id,
ifindex,
ETHTOOL_MSG_RINGS_GET,
ETHTOOL_A_RINGS_HEADER,
"get-ring");
if (!msg)
return FALSE;
r = ethtool_send_and_recv(genl_sock,
ifindex,
msg,
ethtool_parse_ring,
ring,
&err_msg,
"get-ring");
if (r < 0)
return FALSE;
_LOGT("get-ring: rx %u rx-mini %u rx-jumbo %u tx %u",
ring->rx_pending,
ring->rx_mini_pending,
ring->rx_jumbo_pending,
ring->tx_pending);
return TRUE;
}
gboolean
nmp_ethtool_set_ring(struct nl_sock *genl_sock,
guint16 family_id,
int ifindex,
const NMEthtoolRingState *ring)
{
nm_auto_nlmsg struct nl_msg *msg = NULL;
gs_free char *err_msg = NULL;
int r;
g_return_val_if_fail(ring, FALSE);
_LOGT("set-ring: rx %u rx-mini %u rx-jumbo %u tx %u",
ring->rx_pending,
ring->rx_mini_pending,
ring->rx_jumbo_pending,
ring->tx_pending);
msg = ethtool_create_msg(family_id,
ifindex,
ETHTOOL_MSG_RINGS_SET,
ETHTOOL_A_RINGS_HEADER,
"set-ring");
if (!msg)
return FALSE;
NLA_PUT_U32(msg, ETHTOOL_A_RINGS_RX, ring->rx_pending);
NLA_PUT_U32(msg, ETHTOOL_A_RINGS_RX_MINI, ring->rx_mini_pending);
NLA_PUT_U32(msg, ETHTOOL_A_RINGS_RX_JUMBO, ring->rx_jumbo_pending);
NLA_PUT_U32(msg, ETHTOOL_A_RINGS_TX, ring->tx_pending);
r = ethtool_send_and_recv(genl_sock, ifindex, msg, NULL, NULL, &err_msg, "set-ring");
if (r < 0)
return FALSE;
_LOGT("set-ring: succeeded");
return TRUE;
nla_put_failure:
g_return_val_if_reached(FALSE);
}

View File

@@ -23,4 +23,13 @@ gboolean nmp_ethtool_set_eee(struct nl_sock *genl_sock,
int ifindex,
const NMEthtoolEEEState *eee);
gboolean nmp_ethtool_get_ring(struct nl_sock *genl_sock,
guint16 family_id,
int ifindex,
NMEthtoolRingState *ring);
gboolean nmp_ethtool_set_ring(struct nl_sock *genl_sock,
guint16 family_id,
int ifindex,
const NMEthtoolRingState *ring);
#endif /* __NMP_ETHTOOL_H__ */