mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-22 02:35:25 +00:00
devlink: get and set eswitch inline-mode and encap-mode
The setter function allow to set to "preserve" to modify only some of
them.
(cherry picked from commit bf654ef39e
)
This commit is contained in:
parent
a8c4372d42
commit
03aaff8fc2
|
@ -278,12 +278,31 @@ typedef enum {
|
|||
} _NMVlanFlags;
|
||||
|
||||
typedef enum {
|
||||
/* Mirrors libnm's NMSriovEswitchMode */
|
||||
/* Mirrors libnm's NMSriovEswitchMode.
|
||||
* Values >= 0 mirror kernel's enum devlink_eswitch_mode. */
|
||||
_NM_SRIOV_ESWITCH_MODE_PRESERVE = -1,
|
||||
_NM_SRIOV_ESWITCH_MODE_LEGACY = 0,
|
||||
_NM_SRIOV_ESWITCH_MODE_SWITCHDEV = 1,
|
||||
} _NMSriovEswitchMode;
|
||||
|
||||
typedef enum {
|
||||
/* Mirrors libnm's NMSriovEswitchInlineMode.
|
||||
* Values >= 0 mirror kernel's enum devlink_eswitch_inline_mode. */
|
||||
_NM_SRIOV_ESWITCH_INLINE_MODE_PRESERVE = -1,
|
||||
_NM_SRIOV_ESWITCH_INLINE_MODE_NONE = 0,
|
||||
_NM_SRIOV_ESWITCH_INLINE_MODE_LINK = 1,
|
||||
_NM_SRIOV_ESWITCH_INLINE_MODE_NETWORK = 2,
|
||||
_NM_SRIOV_ESWITCH_INLINE_MODE_TRANSPORT = 3,
|
||||
} _NMSriovEswitchInlineMode;
|
||||
|
||||
typedef enum {
|
||||
/* Mirrors libnm's NMSriovEswitchEncapMode.
|
||||
* Values >= 0 mirror kernel's enum devlink_eswitch_encap_mode. */
|
||||
_NM_SRIOV_ESWITCH_ENCAP_MODE_PRESERVE = -1,
|
||||
_NM_SRIOV_ESWITCH_ENCAP_MODE_NONE = 0,
|
||||
_NM_SRIOV_ESWITCH_ENCAP_MODE_BASIC = 1,
|
||||
} _NMSriovEswitchEncapMode;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -58,7 +58,7 @@ struct _NMDevlink {
|
|||
NMDevlink *
|
||||
nm_devlink_new(NMPlatform *platform, struct nl_sock *genl_sock_sync, int ifindex)
|
||||
{
|
||||
NMDevlink *self = g_new(NMDevlink, 1);
|
||||
NMDevlink *self = g_new(NMDevlink, 1);
|
||||
|
||||
self->plat = platform;
|
||||
self->genl_sock_sync = genl_sock_sync;
|
||||
|
@ -230,81 +230,41 @@ static int
|
|||
devlink_parse_eswitch_mode(const struct nl_msg *msg, void *data)
|
||||
{
|
||||
static const struct nla_policy eswitch_policy[] = {
|
||||
[DEVLINK_ATTR_ESWITCH_MODE] = {.type = NLA_U16},
|
||||
[DEVLINK_ATTR_ESWITCH_MODE] = {.type = NLA_U16},
|
||||
[DEVLINK_ATTR_ESWITCH_INLINE_MODE] = {.type = NLA_U8},
|
||||
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = {.type = NLA_U8},
|
||||
};
|
||||
enum devlink_eswitch_mode *eswitch_mode = data;
|
||||
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
|
||||
struct nlattr *tb[G_N_ELEMENTS(eswitch_policy)];
|
||||
NMDevlinkEswitchParams *params = data;
|
||||
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
|
||||
struct nlattr *tb[G_N_ELEMENTS(eswitch_policy)];
|
||||
|
||||
if (nla_parse_arr(tb, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), eswitch_policy) < 0)
|
||||
return NL_SKIP;
|
||||
|
||||
if (!tb[DEVLINK_ATTR_ESWITCH_MODE])
|
||||
if (!tb[DEVLINK_ATTR_ESWITCH_MODE] || !tb[DEVLINK_ATTR_ESWITCH_INLINE_MODE]
|
||||
|| !tb[DEVLINK_ATTR_ESWITCH_ENCAP_MODE])
|
||||
return NL_SKIP;
|
||||
|
||||
*eswitch_mode = nla_get_u16(tb[DEVLINK_ATTR_ESWITCH_MODE]);
|
||||
params->mode = (_NMSriovEswitchMode) nla_get_u16(tb[DEVLINK_ATTR_ESWITCH_MODE]);
|
||||
params->encap_mode = (_NMSriovEswitchEncapMode) nla_get_u8(tb[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
|
||||
params->inline_mode =
|
||||
(_NMSriovEswitchInlineMode) nla_get_u8(tb[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
|
||||
return NL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_devlink_get_eswitch_mode:
|
||||
* nm_devlink_get_eswitch_params:
|
||||
* @self: the #NMDevlink
|
||||
* @out_params: the eswitch parameters read via Devlink
|
||||
* @error: the error location
|
||||
*
|
||||
* Get the eswitch mode of the device related to the #NMDevlink instance. Note
|
||||
* that this might be unsupported by the device (see nm_devlink_get_dev()).
|
||||
*
|
||||
* Returns: the eswitch mode of the device, or <0 in case of error
|
||||
*/
|
||||
int
|
||||
nm_devlink_get_eswitch_mode(NMDevlink *self, GError **error)
|
||||
{
|
||||
nm_auto_nlmsg struct nl_msg *msg = NULL;
|
||||
gs_free char *bus = NULL;
|
||||
gs_free char *addr = NULL;
|
||||
enum devlink_eswitch_mode eswitch_mode;
|
||||
gs_free char *err_msg = NULL;
|
||||
int rc;
|
||||
|
||||
if (!nm_devlink_get_dev_identifier(self, &bus, &addr, error))
|
||||
return -1;
|
||||
|
||||
msg = devlink_alloc_msg(self, DEVLINK_CMD_ESWITCH_GET, 0);
|
||||
NLA_PUT_STRING(msg, DEVLINK_ATTR_BUS_NAME, bus);
|
||||
NLA_PUT_STRING(msg, DEVLINK_ATTR_DEV_NAME, addr);
|
||||
|
||||
rc = devlink_send_and_recv(self, msg, devlink_parse_eswitch_mode, &eswitch_mode, &err_msg);
|
||||
if (rc < 0) {
|
||||
g_set_error(error,
|
||||
NM_UTILS_ERROR,
|
||||
NM_UTILS_ERROR_UNKNOWN,
|
||||
"devlink: get-eswitch-mode: failed (%d) %s",
|
||||
rc,
|
||||
err_msg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
_LOGD("get-eswitch-mode: success");
|
||||
|
||||
return (int) eswitch_mode;
|
||||
|
||||
nla_put_failure:
|
||||
g_return_val_if_reached(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_devlink_set_eswitch_mode:
|
||||
* @self: the #NMDevlink
|
||||
* @mode: the eswitch mode to set
|
||||
* @error: the error location
|
||||
*
|
||||
* Set the eswitch mode of the device related to the #NMDevlink instance. Note
|
||||
* Get the eswitch configuration of the device related to the #NMDevlink instance. Note
|
||||
* that this might be unsupported by the device (see nm_devlink_get_dev()).
|
||||
*
|
||||
* Returns: FALSE in case of error, TRUE otherwise
|
||||
*/
|
||||
gboolean
|
||||
nm_devlink_set_eswitch_mode(NMDevlink *self, enum devlink_eswitch_mode mode, GError **error)
|
||||
nm_devlink_get_eswitch_params(NMDevlink *self, NMDevlinkEswitchParams *out_params, GError **error)
|
||||
{
|
||||
nm_auto_nlmsg struct nl_msg *msg = NULL;
|
||||
gs_free char *bus = NULL;
|
||||
|
@ -312,26 +272,87 @@ nm_devlink_set_eswitch_mode(NMDevlink *self, enum devlink_eswitch_mode mode, GEr
|
|||
gs_free char *err_msg = NULL;
|
||||
int rc;
|
||||
|
||||
nm_assert(out_params);
|
||||
|
||||
if (!nm_devlink_get_dev_identifier(self, &bus, &addr, error))
|
||||
return FALSE;
|
||||
|
||||
msg = devlink_alloc_msg(self, DEVLINK_CMD_ESWITCH_SET, 0);
|
||||
msg = devlink_alloc_msg(self, DEVLINK_CMD_ESWITCH_GET, 0);
|
||||
NLA_PUT_STRING(msg, DEVLINK_ATTR_BUS_NAME, bus);
|
||||
NLA_PUT_STRING(msg, DEVLINK_ATTR_DEV_NAME, addr);
|
||||
NLA_PUT_U16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
|
||||
|
||||
rc = devlink_send_and_recv(self, msg, NULL, NULL, &err_msg);
|
||||
rc = devlink_send_and_recv(self, msg, devlink_parse_eswitch_mode, out_params, &err_msg);
|
||||
if (rc < 0) {
|
||||
g_set_error(error,
|
||||
NM_UTILS_ERROR,
|
||||
NM_UTILS_ERROR_UNKNOWN,
|
||||
"devlink: set-eswitch-mode: failed (%d) %s",
|
||||
"devlink: eswitch get: failed (%d) %s",
|
||||
rc,
|
||||
err_msg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_LOGD("set-eswitch-mode: success");
|
||||
_LOGD("eswitch get: success");
|
||||
|
||||
return TRUE;
|
||||
|
||||
nla_put_failure:
|
||||
g_return_val_if_reached(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_devlink_set_eswitch_params:
|
||||
* @self: the #NMDevlink
|
||||
* @params: the eswitch parameters to set
|
||||
* @error: the error location
|
||||
*
|
||||
* Set the eswitch configuration of the device related to the #NMDevlink instance. Note
|
||||
* that this might be unsupported by the device (see nm_devlink_get_dev()).
|
||||
*
|
||||
* If any of the eswitch parameters is set to "preserve" it won't be modified.
|
||||
*
|
||||
* Returns: FALSE in case of error, TRUE otherwise
|
||||
*/
|
||||
gboolean
|
||||
nm_devlink_set_eswitch_params(NMDevlink *self, NMDevlinkEswitchParams params, GError **error)
|
||||
{
|
||||
nm_auto_nlmsg struct nl_msg *msg = NULL;
|
||||
gs_free char *bus = NULL;
|
||||
gs_free char *addr = NULL;
|
||||
gs_free char *err_msg = NULL;
|
||||
int rc;
|
||||
|
||||
if (params.mode == _NM_SRIOV_ESWITCH_MODE_PRESERVE
|
||||
&& params.inline_mode == _NM_SRIOV_ESWITCH_INLINE_MODE_PRESERVE
|
||||
&& params.encap_mode == _NM_SRIOV_ESWITCH_ENCAP_MODE_PRESERVE)
|
||||
return TRUE;
|
||||
|
||||
if (!nm_devlink_get_dev_identifier(self, &bus, &addr, error))
|
||||
return FALSE;
|
||||
|
||||
msg = devlink_alloc_msg(self, DEVLINK_CMD_ESWITCH_SET, 0);
|
||||
NLA_PUT_STRING(msg, DEVLINK_ATTR_BUS_NAME, bus);
|
||||
NLA_PUT_STRING(msg, DEVLINK_ATTR_DEV_NAME, addr);
|
||||
|
||||
if (params.mode != _NM_SRIOV_ESWITCH_MODE_PRESERVE)
|
||||
NLA_PUT_U16(msg, DEVLINK_ATTR_ESWITCH_MODE, params.mode);
|
||||
if (params.inline_mode != _NM_SRIOV_ESWITCH_INLINE_MODE_PRESERVE)
|
||||
NLA_PUT_U8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE, params.inline_mode);
|
||||
if (params.encap_mode != _NM_SRIOV_ESWITCH_ENCAP_MODE_PRESERVE)
|
||||
NLA_PUT_U8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, params.encap_mode);
|
||||
|
||||
rc = devlink_send_and_recv(self, msg, NULL, NULL, &err_msg);
|
||||
if (rc < 0) {
|
||||
g_set_error(error,
|
||||
NM_UTILS_ERROR,
|
||||
NM_UTILS_ERROR_UNKNOWN,
|
||||
"devlink: eswitch set: failed (%d) %s",
|
||||
rc,
|
||||
err_msg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_LOGD("eswitch set: success");
|
||||
|
||||
return TRUE;
|
||||
|
||||
|
|
|
@ -6,17 +6,25 @@
|
|||
#ifndef __NMP_DEVLINK_H__
|
||||
#define __NMP_DEVLINK_H__
|
||||
|
||||
#include "libnm-base/nm-base.h"
|
||||
#include <linux/devlink.h>
|
||||
|
||||
struct nl_sock;
|
||||
typedef struct _NMPlatform NMPlatform;
|
||||
typedef struct _NMDevlink NMDevlink;
|
||||
|
||||
typedef struct {
|
||||
_NMSriovEswitchMode mode;
|
||||
_NMSriovEswitchInlineMode inline_mode;
|
||||
_NMSriovEswitchEncapMode encap_mode;
|
||||
} NMDevlinkEswitchParams;
|
||||
|
||||
NMDevlink *nm_devlink_new(NMPlatform *platform, struct nl_sock *genl_sock_sync, int ifindex);
|
||||
gboolean
|
||||
nm_devlink_get_dev_identifier(NMDevlink *self, char **out_bus, char **out_addr, GError **error);
|
||||
int nm_devlink_get_eswitch_mode(NMDevlink *self, GError **error);
|
||||
gboolean
|
||||
nm_devlink_set_eswitch_mode(NMDevlink *self, enum devlink_eswitch_mode mode, GError **error);
|
||||
nm_devlink_get_eswitch_params(NMDevlink *self, NMDevlinkEswitchParams *out_params, GError **error);
|
||||
gboolean
|
||||
nm_devlink_set_eswitch_params(NMDevlink *self, NMDevlinkEswitchParams params, GError **error);
|
||||
|
||||
#endif /* __NMP_DEVLINK_H__ */
|
|
@ -9076,16 +9076,20 @@ sriov_async_step2_set_eswitch_mode(SriovAsyncState *async_state)
|
|||
{
|
||||
NMPlatform *platform = async_state->platform;
|
||||
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE(platform);
|
||||
enum devlink_eswitch_mode eswitch_mode = (enum devlink_eswitch_mode) async_state->eswitch_mode;
|
||||
gs_free NMDevlink *devlink = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
NMDevlinkEswitchParams eswitch_params;
|
||||
|
||||
_LOGD("setting eswitch-mode to '%d'", (int) eswitch_mode);
|
||||
_LOGD("setting eswitch-mode to '%d'", (int) async_state->eswitch_mode);
|
||||
|
||||
eswitch_params.mode = (_NMSriovEswitchMode) async_state->eswitch_mode;
|
||||
eswitch_params.inline_mode = _NM_SRIOV_ESWITCH_INLINE_MODE_PRESERVE;
|
||||
eswitch_params.encap_mode = _NM_SRIOV_ESWITCH_ENCAP_MODE_PRESERVE;
|
||||
|
||||
/* We set eswitch mode as a sriov_async step because it's in the middle of
|
||||
* other steps that are async. However, this step itself is synchronous. */
|
||||
devlink = nm_devlink_new(platform, priv->sk_genl_sync, async_state->ifindex);
|
||||
if (!nm_devlink_set_eswitch_mode(devlink, eswitch_mode, &error)) {
|
||||
if (!nm_devlink_set_eswitch_params(devlink, eswitch_params, &error)) {
|
||||
sriov_async_finish_err(async_state, g_steal_pointer(&error));
|
||||
return;
|
||||
}
|
||||
|
@ -9135,6 +9139,7 @@ link_set_sriov_params_async(NMPlatform *platform,
|
|||
int max_vfs;
|
||||
int current_num_vfs;
|
||||
int current_eswitch_mode = _NM_SRIOV_ESWITCH_MODE_PRESERVE;
|
||||
NMDevlinkEswitchParams eswitch_params;
|
||||
gboolean need_change_eswitch_mode;
|
||||
gboolean need_change_vfs;
|
||||
gboolean need_destroy_vfs;
|
||||
|
@ -9202,11 +9207,11 @@ link_set_sriov_params_async(NMPlatform *platform,
|
|||
if (eswitch_mode != _NM_SRIOV_ESWITCH_MODE_PRESERVE) {
|
||||
gs_free NMDevlink *devlink = nm_devlink_new(platform, priv->sk_genl_sync, ifindex);
|
||||
|
||||
current_eswitch_mode = nm_devlink_get_eswitch_mode(devlink, &error);
|
||||
if (current_eswitch_mode < 0) {
|
||||
if (!nm_devlink_get_eswitch_params(devlink, &eswitch_params, &error)) {
|
||||
sriov_async_finish_err(async_state, g_steal_pointer(&error));
|
||||
return;
|
||||
}
|
||||
current_eswitch_mode = eswitch_params.mode;
|
||||
}
|
||||
|
||||
/* Decide what actions we must do. Note that we might need to destroy the VFs even
|
||||
|
|
Loading…
Reference in a new issue