diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8255100b0b..aaa81dbf07 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -575,7 +575,7 @@ virHookPresent; # interface.h -ifaceCheck; +virNetDevValidateConfig; virNetDevGetIndex; virNetDevGetIPv4Address; ifaceGetNthParent; diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 608e3940a8..5a9cc88b09 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -715,7 +715,8 @@ virNWFilterInstantiate(virConnectPtr conn, if (teardownOld && rc == 0) techdriver->tearOldRules(conn, ifname); - if (rc == 0 && (ifaceCheck(false, ifname, NULL, ifindex) < 0)) { + if (rc == 0 && (virNetDevValidateConfig(ifname, NULL, ifindex) <= 0)) { + virResetLastError(); /* interface changed/disppeared */ techdriver->allTeardown(ifname); rc = 1; @@ -964,8 +965,9 @@ virNWFilterInstantiateFilterLate(virConnectPtr conn, &foundNewFilter); if (rc) { /* something went wrong... 'DOWN' the interface */ - if ((ifaceCheck(false, ifname, NULL, ifindex) < 0) || + if ((virNetDevValidateConfig(ifname, NULL, ifindex) <= 0) || (virNetDevSetOnline(ifname, false) < 0)) { + virResetLastError(); /* assuming interface disappeared... */ _virNWFilterTeardownFilter(ifname); } diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c index 319f317665..03716ea205 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -434,7 +434,8 @@ learnIPAddressThread(void *arg) req->status = 0; /* anything change to the VM's interface -- check at least once */ - if (ifaceCheck(false, req->ifname, NULL, req->ifindex) < 0) { + if (virNetDevValidateConfig(req->ifname, NULL, req->ifindex) <= 0) { + virResetLastError(); req->status = ENODEV; goto done; } @@ -504,7 +505,8 @@ learnIPAddressThread(void *arg) } /* check whether VM's dev is still there */ - if (ifaceCheck(false, req->ifname, NULL, req->ifindex) < 0) { + if (virNetDevValidateConfig(req->ifname, NULL, req->ifindex) <= 0) { + virResetLastError(); req->status = ENODEV; showError = false; break; diff --git a/src/util/interface.c b/src/util/interface.c index e86d1836de..16ad155efc 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -56,9 +56,7 @@ __FUNCTION__, __LINE__, __VA_ARGS__) /** - * ifaceCheck - * - * @reportError: whether to report errors or keep silent + * virNetDevValidateConfig: * @ifname: Name of the interface * @macaddr: expected MAC address of the interface; not checked if NULL * @ifindex: expected index of the interface; not checked if '-1' @@ -67,78 +65,83 @@ * it must have the given MAC address and if an interface index is * passed, it must also match the interface index. * - * Returns 0 on success, -errno on failure. - * -ENODEV : if interface with given name does not exist or its interface - * index is different than the one passed - * -EINVAL : if interface name is invalid (too long) + * Returns 1 if the config matches, 0 if the config does not match, or interface does not exist, -1 on error */ #ifdef __linux__ -int -ifaceCheck(bool reportError, const char *ifname, - const unsigned char *macaddr, int ifindex) +int virNetDevValidateConfig(const char *ifname, + const unsigned char *macaddr, int ifindex) { - struct ifreq ifr; int fd = -1; - int rc = 0; + int ret = -1; + struct ifreq ifr; int idx; + int rc; + + if ((rc = virNetDevExists(ifname)) < 0) + return -1; + if (rc == 0) { + ret = 0; + goto cleanup; + } if (macaddr != NULL) { 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(&ifr, 0, sizeof(ifr)); if (virStrncpy(ifr.ifr_name, ifname, strlen(ifname), sizeof(ifr.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, SIOCGIFHWADDR, &ifr) < 0) { - if (reportError) - ifaceError(VIR_ERR_INTERNAL_ERROR, - _("coud not get MAC address of interface %s"), - ifname); - rc = -errno; + if (errno == ENODEV) { + ret = 0; + goto cleanup; + } + virReportSystemError(errno, + _("coud not get MAC address of interface %s"), + ifname); goto cleanup; } if (memcmp(&ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN) != 0) { - rc = -ENODEV; + ret = 0; goto cleanup; } } if (ifindex != -1) { if (virNetDevGetIndex(ifname, &idx) < 0) - virResetLastError(); - else if (idx != ifindex) - rc = -ENODEV; + goto cleanup; + else if (idx != ifindex) { + ret = 0; + goto cleanup; + } } + ret = 1; + cleanup: VIR_FORCE_CLOSE(fd); - - return rc; + return ret; } - -#else - -int -ifaceCheck(bool reportError ATTRIBUTE_UNUSED, - const char *ifname ATTRIBUTE_UNUSED, - const unsigned char *macaddr ATTRIBUTE_UNUSED, - int ifindex ATTRIBUTE_UNUSED) +#else /* ! __linux__ */ +int virNetDevValidateConfig(const char *ifname ATTRIBUTE_UNUSED, + const unsigned char *macaddr ATTRIBUTE_UNUSED, + int ifindex ATTRIBUTE_UNUSED) { return -ENOSYS; } - -#endif /* __linux__ */ +#endif /* ! __linux__ */ diff --git a/src/util/interface.h b/src/util/interface.h index afe417dbc5..c230264d5c 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -30,8 +30,9 @@ struct nlattr; # define NET_SYSFS "/sys/class/net/" -int ifaceCheck(bool reportError, const char *ifname, - const unsigned char *macaddr, int ifindex); +int virNetDevValidateConfig(const char *ifname, + const unsigned char *macaddr, int ifindex) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, struct nlattr **tb, unsigned char **recvbuf,