diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index dfc1f10967..8885b1dc8d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -576,12 +576,12 @@ virHookPresent; # interface.h ifaceCheck; -ifaceGetIndex; +virNetDevGetIndex; ifaceGetIPAddress; ifaceGetNthParent; ifaceGetPhysicalFunction; ifaceGetVirtualFunctionIndex; -ifaceGetVlanID; +virNetDevGetVLanID; ifaceIsVirtualFunction; virNetDevMacVLanCreate; virNetDevMacVLanDelete; diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 899bd322fd..608e3940a8 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -903,9 +903,11 @@ _virNWFilterInstantiateFilter(virConnectPtr conn, /* after grabbing the filter update lock check for the interface; if it's not there anymore its filters will be or are being removed (while holding the lock) and we don't want to build new ones */ - if (ifaceGetIndex(false, net->ifname, &ifindex) < 0) { + if (virNetDevExists(net->ifname) != 1 || + virNetDevGetIndex(net->ifname, &ifindex) < 0) { /* interfaces / VMs can disappear during filter instantiation; don't mark it as an error */ + virResetLastError(); rc = 0; goto cleanup; } @@ -1021,8 +1023,9 @@ int virNWFilterRollbackUpdateFilter(virConnectPtr conn, } /* don't tear anything while the address is being learned */ - if (ifaceGetIndex(true, net->ifname, &ifindex) == 0 && - virNWFilterLookupLearnReq(ifindex) != NULL) + if (virNetDevGetIndex(net->ifname, &ifindex) < 0) + virResetLastError(); + else if (virNWFilterLookupLearnReq(ifindex) != NULL) return 0; return techdriver->tearNewRules(conn, net->ifname); @@ -1047,8 +1050,9 @@ virNWFilterTearOldFilter(virConnectPtr conn, } /* don't tear anything while the address is being learned */ - if (ifaceGetIndex(true, net->ifname, &ifindex) == 0 && - virNWFilterLookupLearnReq(ifindex) != NULL) + if (virNetDevGetIndex(net->ifname, &ifindex) < 0) + virResetLastError(); + else if (virNWFilterLookupLearnReq(ifindex) != NULL) return 0; return techdriver->tearOldRules(conn, net->ifname); diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c index 68bdcfcb1d..9a51fc278a 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -252,21 +252,23 @@ virNWFilterTerminateLearnReq(const char *ifname) { int ifindex; virNWFilterIPAddrLearnReqPtr req; - if (ifaceGetIndex(false, ifname, &ifindex) == 0) { - - IFINDEX2STR(ifindex_str, ifindex); - - virMutexLock(&pendingLearnReqLock); - - req = virHashLookup(pendingLearnReq, ifindex_str); - if (req) { - rc = 0; - req->terminate = true; - } - - virMutexUnlock(&pendingLearnReqLock); + if (virNetDevGetIndex(ifname, &ifindex) < 0) { + virResetLastError(); + return rc; } + IFINDEX2STR(ifindex_str, ifindex); + + virMutexLock(&pendingLearnReqLock); + + req = virHashLookup(pendingLearnReq, ifindex_str); + if (req) { + rc = 0; + req->terminate = true; + } + + virMutexUnlock(&pendingLearnReqLock); + return rc; } diff --git a/src/util/interface.c b/src/util/interface.c index ebe537e3cc..af1def23cd 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -115,8 +115,9 @@ ifaceCheck(bool reportError, const char *ifname, } if (ifindex != -1) { - rc = ifaceGetIndex(reportError, ifname, &idx); - if (rc == 0 && idx != ifindex) + if (virNetDevGetIndex(ifname, &idx) < 0) + virResetLastError(); + else if (idx != ifindex) rc = -ENODEV; } @@ -141,114 +142,112 @@ ifaceCheck(bool reportError ATTRIBUTE_UNUSED, /** - * ifaceGetIndex - * - * @reportError: whether to report errors or keep silent + * virNetDevGetIndex * @ifname : Name of the interface whose index is to be found * @ifindex: Pointer to int where the index will be written into * * Get the index of an interface given its name. * - * Returns 0 on success, -errno on failure. - * -ENODEV : if interface with given name does not exist - * -EINVAL : if interface name is invalid (too long) + * Returns 0 on success, -1 on failure */ #ifdef __linux__ int -ifaceGetIndex(bool reportError, const char *ifname, int *ifindex) +virNetDevGetIndex(const char *ifname, int *ifindex) { - int rc = 0; + int ret = -1; struct ifreq ifreq; int fd = socket(PF_PACKET, SOCK_DGRAM, 0); - if (fd < 0) - return -errno; + if (fd < 0) { + virReportSystemError(errno, "%s", + _("Unable to open control socket")); + return -1; + } memset(&ifreq, 0, sizeof(ifreq)); if (virStrncpy(ifreq.ifr_name, ifname, strlen(ifname), sizeof(ifreq.ifr_name)) == NULL) { - if (reportError) - ifaceError(VIR_ERR_INTERNAL_ERROR, - _("invalid interface name %s"), - ifname); - rc = -EINVAL; + virReportSystemError(ERANGE, + _("invalid interface name %s"), + ifname); goto cleanup; } - if (ioctl(fd, SIOCGIFINDEX, &ifreq) >= 0) - *ifindex = ifreq.ifr_ifindex; - else { - if (reportError) - ifaceError(VIR_ERR_INTERNAL_ERROR, - _("interface %s does not exist"), - ifname); - rc = -ENODEV; + if (ioctl(fd, SIOCGIFINDEX, &ifreq) < 0) { + virReportSystemError(errno, + _("Unable to get index for interface %s"), ifname); + goto cleanup; } + *ifindex = ifreq.ifr_ifindex; + ret = 0; + cleanup: VIR_FORCE_CLOSE(fd); - - return rc; + return ret; } #else int -ifaceGetIndex(bool reportError, - const char *ifname ATTRIBUTE_UNUSED, - int *ifindex ATTRIBUTE_UNUSED) +virNetDevGetIndex(const char *ifname ATTRIBUTE_UNUSED, + int *ifindex ATTRIBUTE_UNUSED) { - if (reportError) { - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("ifaceGetIndex is not supported on non-linux platforms")); - } - - return -ENOSYS; + virReportSystemError(ENOSYS, "%s", + _("Unable to get interface index on this platform")); + return -1; } #endif /* __linux__ */ #ifdef __linux__ int -ifaceGetVlanID(const char *vlanifname, int *vlanid) { +virNetDevGetVLanID(const char *ifname, int *vlanid) +{ struct vlan_ioctl_args vlanargs = { .cmd = GET_VLAN_VID_CMD, }; - int rc = 0; + int ret = -1; int fd = socket(PF_PACKET, SOCK_DGRAM, 0); - if (fd < 0) - return -errno; + if (fd < 0) { + virReportSystemError(errno, "%s", + _("Unable to open control socket")); + return -1; + } - if (virStrcpyStatic(vlanargs.device1, vlanifname) == NULL) { - rc = -EINVAL; + if (virStrcpyStatic(vlanargs.device1, ifname) == NULL) { + virReportSystemError(ERANGE, + _("invalid interface name %s"), + ifname); goto cleanup; } if (ioctl(fd, SIOCGIFVLAN, &vlanargs) != 0) { - rc = -errno; + virReportSystemError(errno, + _("Unable to get VLAN for interface %s"), ifname); goto cleanup; } *vlanid = vlanargs.u.VID; + ret = 0; cleanup: VIR_FORCE_CLOSE(fd); - return rc; + return ret; } #else int -ifaceGetVlanID(const char *vlanifname ATTRIBUTE_UNUSED, - int *vlanid ATTRIBUTE_UNUSED) { - - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("ifaceGetVlanID is not supported on non-linux platforms")); - - return -ENOSYS; +virNetDevGetVLanID(const char *ifname ATTRIBUTE_UNUSED, + int *vlanid ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to get VLAN on this platform")); + return -1; } #endif /* __linux__ */ @@ -496,7 +495,7 @@ ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent, *nth = 0; - if (ifindex <= 0 && ifaceGetIndex(true, ifname, &ifindex) < 0) + if (ifindex <= 0 && virNetDevGetIndex(ifname, &ifindex) < 0) return -1; while (!end && i <= nthParent) { diff --git a/src/util/interface.h b/src/util/interface.h index e322a2128f..51d5c28e07 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -33,9 +33,11 @@ struct nlattr; int ifaceCheck(bool reportError, const char *ifname, const unsigned char *macaddr, int ifindex); -int ifaceGetIndex(bool reportError, const char *ifname, int *ifindex); +int virNetDevGetIndex(const char *ifname, int *ifindex) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int ifaceGetVlanID(const char *vlanifname, int *vlanid); +int virNetDevGetVLanID(const char *ifname, int *vlanid) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int ifaceGetIPAddress(const char *ifname, virSocketAddrPtr addr); diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index 8e2e737051..e3f90dd8e6 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -107,7 +107,7 @@ virNetDevMacVLanCreate(const char *ifname, struct nl_msg *nl_msg; struct nlattr *linkinfo, *info_data; - if (ifaceGetIndex(true, srcdev, &ifindex) < 0) + if (virNetDevGetIndex(srcdev, &ifindex) < 0) return -1; *retry = 0; @@ -481,7 +481,7 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname, int retries, do_retry = 0; uint32_t macvtapMode; const char *cr_ifname; - int ifindex; + int ret; macvtapMode = modeMap[mode]; @@ -502,13 +502,16 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname, } if (tgifname) { - if(ifaceGetIndex(false, tgifname, &ifindex) == 0) { + if ((ret = virNetDevExists(tgifname)) < 0) + return -1; + + if (ret) { if (STRPREFIX(tgifname, MACVTAP_NAME_PREFIX)) { goto create_name; } - virReportSystemError(errno, - _("Interface %s already exists"), tgifname); + virReportSystemError(EEXIST, + _("Unable to create macvlan device %s"), tgifname); return -1; } cr_ifname = tgifname; @@ -521,7 +524,9 @@ create_name: retries = 5; for (c = 0; c < 8192; c++) { snprintf(ifname, sizeof(ifname), MACVTAP_NAME_PATTERN, c); - if (ifaceGetIndex(false, ifname, &ifindex) == -ENODEV) { + if ((ret = virNetDevExists(ifname)) < 0) + return -1; + if (!ret) { rc = virNetDevMacVLanCreate(ifname, type, macaddress, linkdev, macvtapMode, &do_retry); if (rc == 0) diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c index ec86e2c4e1..c49d5146ed 100644 --- a/src/util/virnetdevvportprofile.c +++ b/src/util/virnetdevvportprofile.c @@ -544,8 +544,10 @@ virNetDevVPortProfileGetPhysdevAndVlan(const char *ifname, int *root_ifindex, ch if (nth == 0) break; if (*vlanid == -1) { - if (ifaceGetVlanID(root_ifname, vlanid) < 0) + if (virNetDevGetVLanID(root_ifname, vlanid) < 0) { + virResetLastError(); *vlanid = -1; + } } ifindex = *root_ifindex; @@ -676,7 +678,7 @@ virNetDevVPortProfileOp8021Qbh(const char *ifname, if (rc < 0) goto err_exit; - rc = ifaceGetIndex(true, physfndev, &ifindex); + rc = virNetDevGetIndex(physfndev, &ifindex); if (rc < 0) goto err_exit;