diff --git a/src/util/interface.c b/src/util/interface.c index 16ad155efc..8264e7cb64 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -55,95 +55,6 @@ virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__) -/** - * 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' - * - * Determine whether a given interface is still available. If so, - * it must have the given MAC address and if an interface index is - * passed, it must also match the interface index. - * - * Returns 1 if the config matches, 0 if the config does not match, or interface does not exist, -1 on error - */ -#ifdef __linux__ -int virNetDevValidateConfig(const char *ifname, - const unsigned char *macaddr, int ifindex) -{ - int fd = -1; - 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) { - 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) { - virReportSystemError(ERANGE, - _("invalid interface name %s"), - ifname); - goto cleanup; - } - - if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { - 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) { - ret = 0; - goto cleanup; - } - } - - if (ifindex != -1) { - if (virNetDevGetIndex(ifname, &idx) < 0) - goto cleanup; - else if (idx != ifindex) { - ret = 0; - goto cleanup; - } - } - - ret = 1; - - cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} -#else /* ! __linux__ */ -int virNetDevValidateConfig(const char *ifname ATTRIBUTE_UNUSED, - const unsigned char *macaddr ATTRIBUTE_UNUSED, - int ifindex ATTRIBUTE_UNUSED) -{ - return -ENOSYS; -} -#endif /* ! __linux__ */ - - #if defined(__linux__) && defined(IFLA_PORT_MAX) diff --git a/src/util/interface.h b/src/util/interface.h index c230264d5c..4256f295d1 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -30,10 +30,6 @@ struct nlattr; # define NET_SYSFS "/sys/class/net/" -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, uint32_t (*getPidFunc)(void)); diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 8a26d4a883..4ad7883229 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -856,3 +856,80 @@ int virNetDevGetIPv4Address(const char *ifname ATTRIBUTE_UNUSED, } #endif /* __linux__ */ + + +/** + * 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' + * + * Determine whether a given interface is still available. If so, + * it must have the given MAC address and if an interface index is + * passed, it must also match the interface index. + * + * Returns 1 if the config matches, 0 if the config does not match, or interface does not exist, -1 on error + */ +#ifdef __linux__ +int virNetDevValidateConfig(const char *ifname, + const unsigned char *macaddr, int ifindex) +{ + int fd = -1; + 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) { + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { + 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) { + ret = 0; + goto cleanup; + } + } + + if (ifindex != -1) { + if (virNetDevGetIndex(ifname, &idx) < 0) + goto cleanup; + else if (idx != ifindex) { + ret = 0; + goto cleanup; + } + } + + ret = 1; + + cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else /* ! __linux__ */ +int virNetDevValidateConfig(const char *ifname ATTRIBUTE_UNUSED, + const unsigned char *macaddr ATTRIBUTE_UNUSED, + int ifindex ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to check interface config on this platform")); + return -1; +} +#endif /* ! __linux__ */ diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index 08bbcbf50d..86280720b8 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -84,5 +84,9 @@ int virNetDevGetIndex(const char *ifname, int *ifindex) int virNetDevGetVLanID(const char *ifname, int *vlanid) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevValidateConfig(const char *ifname, + const unsigned char *macaddr, int ifindex) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + #endif /* __VIR_NETDEV_H__ */