mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
Ignore EPERM on implicit clearing of VF VLAN ID
SmartNIC DPUs may not expose some privileged eswitch operations to the hypervisor hosts. For example, this happens with Bluefield devices running in the ECPF (default) mode for security reasons. While VF MAC address programming is possible via an RTM_SETLINK operation, trying to set a VLAN ID in the same operation will fail with EPERM. The equivalent ip link commands below provide an illustration: 1. This works: sudo ip link set enp130s0f0 vf 2 mac de:ad:be:ef:ca:fe 2. Setting (or clearing) a VLAN fails with EPERM: sudo ip link set enp130s0f0 vf 2 vlan 0 RTNETLINK answers: Operation not permitted 3. This is what Libvirt attempts to do today (when trying to clear a VF VLAN at the same time as programming a VF MAC). sudo ip link set enp130s0f0 vf 2 vlan 0 mac de:ad:be:ef:ca:fe RTNETLINK answers: Operation not permitted If setting an explicit VLAN ID results in an EPERM, clearing a VLAN (setting a VLAN ID to 0) can be handled gracefully by ignoring the EPERM error with the rationale being that if we cannot set this state in the first place, we cannot clear it either. In order to keep explicit clearing of VLAN ID working as it used to be passing a NULL pointer for VLAN ID is used. Signed-off-by: Dmitrii Shcherbakov <dmitrii.shcherbakov@canonical.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
73961771a1
commit
09cdd16a9b
@ -1610,7 +1610,15 @@ virNetDevSetVfVlan(const char *ifname,
|
||||
ret = virNetDevSendVfSetLinkRequest(ifname, IFLA_VF_VLAN,
|
||||
&ifla_vf_vlan, sizeof(ifla_vf_vlan));
|
||||
|
||||
if (ret < 0) {
|
||||
/* If vlanid is NULL - we are attempting to implicitly clear an existing
|
||||
* VLAN id. An EPERM received at this stage is an indicator that the
|
||||
* embedded switch is not exposed to this host and the network driver is
|
||||
* not able to set a VLAN for a VF, whereas the Libvirt client has not
|
||||
* explicitly configured a VLAN or requested it to be cleared via VLAN id
|
||||
* 0. */
|
||||
if (ret == -EPERM && vlanid == NULL) {
|
||||
ret = 0;
|
||||
} else if (ret < 0) {
|
||||
virReportSystemError(-ret,
|
||||
_("Cannot set interface vlanid to %d for ifname %s vf %d"),
|
||||
ifla_vf_vlan.vlan, ifname ? ifname : "(unspecified)", vf);
|
||||
|
@ -248,7 +248,7 @@ testVirNetDevSetVfVlan(const void *opaque G_GNUC_UNUSED)
|
||||
};
|
||||
|
||||
const struct nullVlanTestCase nullVLANTestCases[] = {
|
||||
{ .ifname = "fakeiface-eperm", .vf_num = 1, .rc = -EPERM },
|
||||
{ .ifname = "fakeiface-eperm", .vf_num = 1, .rc = 0 },
|
||||
{ .ifname = "fakeiface-eagain", .vf_num = 1, .rc = -EAGAIN },
|
||||
/* Successful requests with vlan id 0 need to have a zero return code. */
|
||||
{ .ifname = "fakeiface-ok", .vf_num = 1, .rc = 0 },
|
||||
|
Loading…
Reference in New Issue
Block a user