int
virNetDevSetVfVlan(const char *ifname,
int vf,
- int vlanid)
+ const int *vlanid)
{
int ret = -1;
struct ifla_vf_vlan ifla_vf_vlan = {
.vf = vf,
- .vlan = vlanid,
+ .vlan = 0,
.qos = 0,
};
- /* VLAN ids 0 and 4095 are reserved per 802.1Q but are valid values. */
- if ((vlanid < 0 || vlanid > 4095)) {
- virReportError(ERANGE, _("vlanid out of range: %d"), vlanid);
- return -ERANGE;
+ /* If vlanid is NULL, assume it needs to be cleared. */
+ if (vlanid) {
+ /* VLAN ids 0 and 4095 are reserved per 802.1Q but are valid values. */
+ if ((*vlanid < 0 || *vlanid > 4095)) {
+ virReportError(ERANGE, _("vlanid out of range: %d"), *vlanid);
+ return -ERANGE;
+ }
+ ifla_vf_vlan.vlan = *vlanid;
}
ret = virNetDevSendVfSetLinkRequest(ifname, IFLA_VF_VLAN,
if (ret < 0) {
virReportSystemError(-ret,
_("Cannot set interface vlanid to %d for ifname %s vf %d"),
- vlanid, ifname ? ifname : "(unspecified)", vf);
+ ifla_vf_vlan.vlan, ifname ? ifname : "(unspecified)", vf);
}
VIR_DEBUG("RTM_SETLINK %s vf %d vlanid=%d - %s",
- ifname, vf, vlanid, ret < 0 ? "Fail" : "Success");
+ ifname, vf, ifla_vf_vlan.vlan, ret < 0 ? "Fail" : "Success");
return ret;
}
virNetDevSetVfConfig(const char *ifname,
int vf,
const virMacAddr *macaddr,
- int vlanid,
+ const int *vlanid,
bool *allowRetry)
{
int ret = -1;
const char *pfDevName = NULL;
g_autofree char *pfDevOrig = NULL;
g_autofree char *vfDevOrig = NULL;
- int vlanTag = -1;
+ g_autofree int *vlanTag = NULL;
g_autoptr(virPCIDevice) vfPCIDevice = NULL;
if (vf >= 0) {
return -1;
}
- vlanTag = vlan->tag[0];
+ vlanTag = g_new0(int, 1);
+ *vlanTag = vlan->tag[0];
} else if (setVlan) {
- vlanTag = 0; /* assure any existing vlan tag is reset */
+ vlanTag = g_new0(int, 1);
+ /* Assure any existing vlan tag is reset. */
+ *vlanTag = 0;
+ } else {
+ /* Indicate that setting a VLAN has not been explicitly requested.
+ * This allows selected errors in clearing a VF VLAN to be ignored. */
+ vlanTag = NULL;
}
}
}
}
- if (adminMAC || vlanTag >= 0) {
+ if (adminMAC) {
/* Set vlanTag and admin MAC using an RTM_SETLINK request sent to
* PFdevname+VF#, if mac != NULL this will set the "admin MAC" via
* the PF, *not* the actual VF MAC - the admin MAC only takes
int
virNetDevSetVfVlan(const char *ifname G_GNUC_UNUSED,
int vf G_GNUC_UNUSED,
- int vlanid G_GNUC_UNUSED)
+ const int *vlanid G_GNUC_UNUSED)
{
virReportSystemError(ENOSYS, "%s",
_("Unable to set a VF VLAN on this platform"));
virNetDevSetVfConfig(const char *ifname G_GNUC_UNUSED,
int vf G_GNUC_UNUSED,
const virMacAddr *macaddr G_GNUC_UNUSED,
- int vlanid G_GNUC_UNUSED,
+ const int *vlanid G_GNUC_UNUSED,
bool *allowRetry G_GNUC_UNUSED)
{
virReportSystemError(ENOSYS, "%s",
int
(*real_virNetDevSetVfVlan)(const char *ifname,
int vf,
- int vlanid);
+ const int *vlanid);
static void
init_syms(void)
int
virNetDevSetVfVlan(const char *ifname,
int vf,
- int vlanid)
+ const int *vlanid)
{
init_syms();
const int vlan_id;
const int rc;
};
+ struct nullVlanTestCase {
+ const char *ifname;
+ const int vf_num;
+ const int rc;
+ };
size_t i = 0;
int rc = 0;
const struct testCase testCases[] = {
{ .ifname = "fakeiface-ok", .vf_num = 1, .vlan_id = 42, .rc = 0 },
};
+ const struct nullVlanTestCase nullVLANTestCases[] = {
+ { .ifname = "fakeiface-eperm", .vf_num = 1, .rc = -EPERM },
+ { .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 },
+ };
+
for (i = 0; i < sizeof(testCases) / sizeof(struct testCase); ++i) {
- rc = virNetDevSetVfVlan(testCases[i].ifname, testCases[i].vf_num, testCases[i].vlan_id);
+ rc = virNetDevSetVfVlan(testCases[i].ifname, testCases[i].vf_num, &testCases[i].vlan_id);
if (rc != testCases[i].rc) {
return -1;
}
}
+ for (i = 0; i < sizeof(nullVLANTestCases) / sizeof(struct nullVlanTestCase); ++i) {
+ rc = virNetDevSetVfVlan(nullVLANTestCases[i].ifname, nullVLANTestCases[i].vf_num, NULL);
+ if (rc != nullVLANTestCases[i].rc) {
+ return -1;
+ }
+ }
+
return 0;
}
};
for (i = 0; i < sizeof(testCases) / sizeof(struct testCase); ++i) {
- rc = virNetDevSetVfConfig(testCases[i].ifname, vfNum, &mac, vlanid, allowRetry);
+ rc = virNetDevSetVfConfig(testCases[i].ifname, vfNum, &mac, &vlanid, allowRetry);
if (rc != testCases[i].rc) {
return -1;
}