[libvirt] [PATCH 00/33] Refactor all network device handling code

This series is a major re-arrangement and de-duplication of internal code for dealing with physical network interfaces. Currently code for physical network interfaces is split across the following files - bridge.c: bridge management, TAP device management and interface IPv4 address management - network.c: socket address management, network bandwidth and virtual port profile data management - interface.c: some generic interface management and macvtap/macvlan management - macvtap.c: more macvtap/macvlan management and virtual port profile interface setup code - lxc/veth.c: veth device management and generic interface management Furthermore across these files - Argument ordering is inconsistent - sometimes ifname is the first parameter, sometimes it isn't - Error handing is terribly inconsistent 1. Return errno values 2. Raise errors 3. Raise errors and return errno values 4. Raise errors, except when a parameter tells it not to - API naming is inconsistent. Some APIs have a vir prefix, others have different prefixes, other don't even follow a standard prefix, eg virSocketFormatAddr vs virSocketAddrMaks vs virSocketGetPort - The bridge.c APIs have an annoying 'brControl *' struct that must be passed around just to avoid opening & closing an unbound socket. - Some APIs are implemented natively, while others call out to external commands - Duplication of functionality across APIs - XML parsing & formatting code is in src/util instead of src/conf - Some of the API declarations are hidden behind #ifdefs forcing yet more #ifdefs in the callers of the APIs After applying this series, we get to a stage where the source file split is: - src/util/virnetdev.c: APIs relating to any type of interface - src/util/virnetdevbridge.c: APIs relating to bridge interfaces - src/util/virnetdevmacvlan.c: APIs relating to macvlan/macvtap interfaces - src/util/virnetdevveth.c: APIs relating to veth interfaces - src/util/virnetdevbandwidth.c: APIs for network bandwidth controls - src/util/virnetdevvportprofile.c: APIs for 802.11Qb{g,h} port profiles - src/util/virsocketaddr.c: the socket address management APIs - src/conf/netdev_bandwidth_conf.c: Parsing/formatting bandwidth XML - src/conf/netdev_vport_profile_conf.c: parsing/formatting 801.11Qb{g,h} profile XML The following style is followed - All APIs return -1 on error and raise a libvirt error. No exceptions or flags to turn off errors - Callers which don't want the raised error call virResetLastError - All APIs are annotated with ATTRIBUTE_NONNULL and ATTRIBUTE_RETURN_CHECK where appropriate - The first parameter of all APIs operating on a network interface is the interface name - All APIs have a fixed name prefix which matches the source file. No exceptions. - All XML handling code is under src/conf/ - All APIs are unconditionally declared in header files, and stubbed out with virReportSystemError(ENOSYS...) where unsupported. - No functionality is duplicated across files - External commands are avoided except in case of setting IPv4 addresses and network bandwidth controls The diffstat is a little bit misleading, showing a slight growth in the number of lines. This is primarily due to the extra GPL copyright header lines in the new files, being much larger than those removed from old files. Overall we have a decrease in actual real code, through removal of duplicated APIs b/configure.ac | 5 b/daemon/libvirtd.h | 1 b/daemon/remote.c | 1 b/libvirt.spec.in | 2 b/po/POTFILES.in | 12 b/src/Makefile.am | 26 b/src/conf/domain_conf.c | 59 - b/src/conf/domain_conf.h | 20 b/src/conf/netdev_bandwidth_conf.c | 230 ++++ b/src/conf/netdev_bandwidth_conf.h | 37 b/src/conf/netdev_vport_profile_conf.c | 236 ++++ b/src/conf/netdev_vport_profile_conf.h | 39 b/src/conf/network_conf.c | 101 +- b/src/conf/network_conf.h | 12 b/src/conf/nwfilter_conf.c | 16 b/src/conf/nwfilter_conf.h | 2 b/src/esx/esx_util.h | 2 b/src/libvirt_private.syms | 71 - b/src/lxc/lxc_container.c | 9 b/src/lxc/lxc_controller.c | 7 b/src/lxc/lxc_driver.c | 42 b/src/network/bridge_driver.c | 192 +-- b/src/nwfilter/nwfilter_ebiptables_driver.c | 4 b/src/nwfilter/nwfilter_gentech_driver.c | 25 b/src/nwfilter/nwfilter_learnipaddr.c | 32 b/src/openvz/openvz_driver.c | 1 b/src/qemu/qemu_command.c | 86 - b/src/qemu/qemu_command.h | 4 b/src/qemu/qemu_conf.c | 2 b/src/qemu/qemu_conf.h | 3 b/src/qemu/qemu_driver.c | 16 b/src/qemu/qemu_hotplug.c | 19 b/src/qemu/qemu_migration.c | 29 b/src/qemu/qemu_process.c | 15 b/src/qemu/qemu_process.h | 2 b/src/rpc/virnetsocket.c | 7 b/src/rpc/virnetsocket.h | 2 b/src/uml/uml_conf.c | 41 b/src/uml/uml_conf.h | 2 b/src/uml/uml_driver.c | 22 b/src/util/dnsmasq.c | 4 b/src/util/dnsmasq.h | 2 b/src/util/iptables.c | 20 b/src/util/iptables.h | 2 b/src/util/virnetdev.c | 1083 ++++++++++++++++++++++ b/src/util/virnetdev.h | 102 ++ b/src/util/virnetdevbandwidth.c | 265 +++++ b/src/util/virnetdevbandwidth.h | 53 + b/src/util/virnetdevbridge.c | 527 ++++++++++ b/src/util/virnetdevbridge.h | 54 + b/src/util/virnetdevmacvlan.c | 674 +++++++++++++ b/src/util/virnetdevmacvlan.h | 77 + b/src/util/virnetdevtap.c | 301 ++++++ b/src/util/virnetdevtap.h | 45 b/src/util/virnetdevveth.c | 189 +++ b/src/util/virnetdevveth.h | 35 b/src/util/virnetdevvportprofile.c | 1073 +++++++++++++++++++++ b/src/util/virnetdevvportprofile.h | 95 + b/src/util/virsocketaddr.c | 687 ++++++++++++++ b/src/util/virsocketaddr.h | 103 ++ b/src/vbox/vbox_tmpl.c | 10 b/tests/qemuxml2argvtest.c | 2 b/tests/qemuxmlnstest.c | 2 b/tests/sockettest.c | 20 b/tests/virnetsockettest.c | 1 b/tests/virnettlscontexttest.c | 6 b/tools/virsh.c | 6 src/lxc/veth.c | 319 ------ src/lxc/veth.h | 33 src/util/bridge.c | 845 ----------------- src/util/bridge.h | 120 -- src/util/interface.c | 1348 --------------------------- src/util/interface.h | 91 - src/util/macvtap.c | 1203 ------------------------ src/util/macvtap.h | 93 - src/util/network.c | 1370 ---------------------------- src/util/network.h | 167 --- 77 files changed, 6302 insertions(+), 6159 deletions(-)

From: "Daniel P. Berrange" <berrange@redhat.com> The bridge management APIs in src/util/bridge.c require a brControl object to be passed around. This holds the file descriptor for the control socket. This extra object complicates use of the API for only a minor efficiency gain, which is in turn entirely offset by the need to fork/exec the brctl command for STP configuration. This patch removes the 'brControl' object entirely, instead opening the control socket & closing it again within the scope of each method. The parameter names for the APIs are also made to consistently use 'brname' for bridge device name, and 'ifname' for an interface device name. Finally annotations are added for non-NULL parameters and return check validation * src/util/bridge.c, src/util/bridge.h: Remove brControl object and update API parameter names & annotations. * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/uml/uml_conf.h, src/uml/uml_conf.c, src/uml/uml_driver.c, src/qemu/qemu_command.c, src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Remove reference to 'brControl' object --- src/lxc/lxc_driver.c | 10 +- src/network/bridge_driver.c | 41 ++--- src/qemu/qemu_command.c | 8 +- src/qemu/qemu_conf.h | 1 - src/qemu/qemu_driver.c | 3 - src/uml/uml_conf.c | 13 +-- src/uml/uml_conf.h | 1 - src/uml/uml_driver.c | 9 +- src/util/bridge.c | 454 +++++++++++++++++++++---------------------- src/util/bridge.h | 104 +++++----- 10 files changed, 295 insertions(+), 349 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index d6e5e20..2505efc 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1194,15 +1194,8 @@ static int lxcSetupInterfaces(virConnectPtr conn, { int rc = -1, i; char *bridge = NULL; - brControl *brctl = NULL; int ret; - if ((ret = brInit(&brctl)) != 0) { - virReportSystemError(ret, "%s", - _("Unable to initialize bridging")); - return -1; - } - for (i = 0 ; i < def->nnets ; i++) { char *parentVeth; char *containerVeth = NULL; @@ -1277,7 +1270,7 @@ static int lxcSetupInterfaces(virConnectPtr conn, goto error_exit; } - if ((ret = brAddInterface(brctl, bridge, parentVeth)) != 0) { + if ((ret = brAddInterface(bridge, parentVeth)) != 0) { virReportSystemError(ret, _("Failed to add %s device to %s"), parentVeth, bridge); @@ -1303,7 +1296,6 @@ static int lxcSetupInterfaces(virConnectPtr conn, rc = 0; error_exit: - brShutdown(brctl); if (rc != 0) { for (i = 0 ; i < def->nnets ; i++) networkReleaseActualDevice(def->nets[i]); diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 445c3cb..053acfd 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -82,7 +82,6 @@ struct network_driver { virNetworkObjList networks; iptablesContext *iptables; - brControl *brctl; char *networkConfigDir; char *networkAutostartDir; char *logDir; @@ -212,7 +211,7 @@ networkFindActiveConfigs(struct network_driver *driver) { /* If bridge exists, then mark it active */ if (obj->def->bridge && - brHasBridge(driver->brctl, obj->def->bridge) == 0) { + brHasBridge(obj->def->bridge) == 0) { obj->active = 1; /* Try and read dnsmasq/radvd pids if any */ @@ -263,7 +262,6 @@ static int networkStartup(int privileged) { uid_t uid = geteuid(); char *base = NULL; - int err; if (VIR_ALLOC(driverState) < 0) goto error; @@ -312,12 +310,6 @@ networkStartup(int privileged) { VIR_FREE(base); - if ((err = brInit(&driverState->brctl))) { - virReportSystemError(err, "%s", - _("cannot initialize bridge support")); - goto error; - } - if (!(driverState->iptables = iptablesContextNew())) { goto out_of_memory; } @@ -416,8 +408,6 @@ networkShutdown(void) { VIR_FREE(driverState->networkConfigDir); VIR_FREE(driverState->networkAutostartDir); - if (driverState->brctl) - brShutdown(driverState->brctl); if (driverState->iptables) iptablesContextFree(driverState->iptables); @@ -1675,8 +1665,7 @@ out: } static int -networkAddAddrToBridge(struct network_driver *driver, - virNetworkObjPtr network, +networkAddAddrToBridge(virNetworkObjPtr network, virNetworkIpDefPtr ipdef) { int prefix = virNetworkIpDefPrefix(ipdef); @@ -1688,7 +1677,7 @@ networkAddAddrToBridge(struct network_driver *driver, return -1; } - if (brAddInetAddress(driver->brctl, network->def->bridge, + if (brAddInetAddress(network->def->bridge, &ipdef->address, prefix) < 0) { networkReportError(VIR_ERR_INTERNAL_ERROR, _("cannot set IP address on bridge '%s'"), @@ -1714,7 +1703,7 @@ networkStartNetworkVirtual(struct network_driver *driver, return -1; /* Create and configure the bridge device */ - if ((err = brAddBridge(driver->brctl, network->def->bridge))) { + if ((err = brAddBridge(network->def->bridge))) { virReportSystemError(err, _("cannot create bridge '%s'"), network->def->bridge); @@ -1733,7 +1722,7 @@ networkStartNetworkVirtual(struct network_driver *driver, virReportOOMError(); goto err0; } - if ((err = brAddTap(driver->brctl, network->def->bridge, + if ((err = brAddTap(network->def->bridge, &macTapIfName, network->def->mac, 0, false, NULL))) { virReportSystemError(err, _("cannot create dummy tap device '%s' to set mac" @@ -1745,7 +1734,7 @@ networkStartNetworkVirtual(struct network_driver *driver, } /* Set bridge options */ - if (brSetForwardDelay(driver->brctl, network->def->bridge, + if (brSetForwardDelay(network->def->bridge, network->def->delay)) { networkReportError(VIR_ERR_INTERNAL_ERROR, _("cannot set forward delay on bridge '%s'"), @@ -1753,7 +1742,7 @@ networkStartNetworkVirtual(struct network_driver *driver, goto err1; } - if (brSetEnableSTP(driver->brctl, network->def->bridge, + if (brSetEnableSTP(network->def->bridge, network->def->stp ? 1 : 0)) { networkReportError(VIR_ERR_INTERNAL_ERROR, _("cannot set STP '%s' on bridge '%s'"), @@ -1780,13 +1769,13 @@ networkStartNetworkVirtual(struct network_driver *driver, v6present = true; /* Add the IP address/netmask to the bridge */ - if (networkAddAddrToBridge(driver, network, ipdef) < 0) { + if (networkAddAddrToBridge(network, ipdef) < 0) { goto err2; } } /* Bring up the bridge interface */ - if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) { + if ((err = brSetInterfaceUp(network->def->bridge, 1))) { virReportSystemError(err, _("failed to bring the bridge '%s' up"), network->def->bridge); @@ -1839,7 +1828,7 @@ networkStartNetworkVirtual(struct network_driver *driver, err3: if (!save_err) save_err = virSaveLastError(); - if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) { + if ((err = brSetInterfaceUp(network->def->bridge, 0))) { char ebuf[1024]; VIR_WARN("Failed to bring down bridge '%s' : %s", network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); @@ -1854,7 +1843,7 @@ networkStartNetworkVirtual(struct network_driver *driver, if (!save_err) save_err = virSaveLastError(); - if ((err = brDeleteTap(driver->brctl, macTapIfName))) { + if ((err = brDeleteTap(macTapIfName))) { char ebuf[1024]; VIR_WARN("Failed to delete dummy tap device '%s' on bridge '%s' : %s", macTapIfName, network->def->bridge, @@ -1865,7 +1854,7 @@ networkStartNetworkVirtual(struct network_driver *driver, err0: if (!save_err) save_err = virSaveLastError(); - if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) { + if ((err = brDeleteBridge(network->def->bridge))) { char ebuf[1024]; VIR_WARN("Failed to delete bridge '%s' : %s", network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); @@ -1910,7 +1899,7 @@ static int networkShutdownNetworkVirtual(struct network_driver *driver, if (!macTapIfName) { virReportOOMError(); } else { - if ((err = brDeleteTap(driver->brctl, macTapIfName))) { + if ((err = brDeleteTap(macTapIfName))) { VIR_WARN("Failed to delete dummy tap device '%s' on bridge '%s' : %s", macTapIfName, network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); @@ -1919,14 +1908,14 @@ static int networkShutdownNetworkVirtual(struct network_driver *driver, } } - if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) { + if ((err = brSetInterfaceUp(network->def->bridge, 0))) { VIR_WARN("Failed to bring down bridge '%s' : %s", network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); } networkRemoveIptablesRules(driver, network); - if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) { + if ((err = brDeleteBridge(network->def->bridge))) { VIR_WARN("Failed to delete bridge '%s' : %s", network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); } diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 01ee23f..ee18858 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -261,12 +261,6 @@ qemuNetworkIfaceConnect(virDomainDefPtr def, return -1; } - if (!driver->brctl && (err = brInit(&driver->brctl))) { - virReportSystemError(err, "%s", - _("cannot initialize bridge support")); - goto cleanup; - } - if (!net->ifname || STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) || strchr(net->ifname, '%')) { @@ -285,7 +279,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def, memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ - err = brAddTap(driver->brctl, brname, &net->ifname, tapmac, + err = brAddTap(brname, &net->ifname, tapmac, vnet_hdr, true, &tapfd); virDomainAuditNetDevice(def, net, "/dev/net/tun", tapfd >= 0); if (err) { diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index ff5cf23..1ba2002 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -69,7 +69,6 @@ struct qemud_driver { virDomainObjList domains; - brControl *brctl; /* These four directories are ones libvirtd uses (so must be root:root * to avoid security risk from QEMU processes */ char *configDir; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 118197a..628dac1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -815,9 +815,6 @@ qemudShutdown(void) { /* Free domain callback list */ virDomainEventStateFree(qemu_driver->domainEventState); - if (qemu_driver->brctl) - brShutdown(qemu_driver->brctl); - virCgroupFree(&qemu_driver->cgroup); virLockManagerPluginUnref(qemu_driver->lockManager); diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c index f2bdd74..92d132b 100644 --- a/src/uml/uml_conf.c +++ b/src/uml/uml_conf.c @@ -121,17 +121,10 @@ umlConnectTapDevice(virConnectPtr conn, virDomainNetDefPtr net, const char *bridge) { - brControl *brctl = NULL; bool template_ifname = false; int err; unsigned char tapmac[VIR_MAC_BUFLEN]; - if ((err = brInit(&brctl))) { - virReportSystemError(err, "%s", - _("cannot initialize bridge support")); - goto error; - } - if (!net->ifname || STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) || strchr(net->ifname, '%')) { @@ -144,8 +137,7 @@ umlConnectTapDevice(virConnectPtr conn, memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ - if ((err = brAddTap(brctl, - bridge, + if ((err = brAddTap(bridge, &net->ifname, tapmac, 0, @@ -183,14 +175,11 @@ umlConnectTapDevice(virConnectPtr conn, } } - brShutdown(brctl); - return 0; no_memory: virReportOOMError(); error: - brShutdown(brctl); return -1; } diff --git a/src/uml/uml_conf.h b/src/uml/uml_conf.h index 657f877..01695c7 100644 --- a/src/uml/uml_conf.h +++ b/src/uml/uml_conf.h @@ -52,7 +52,6 @@ struct uml_driver { virDomainObjList domains; - brControl *brctl; char *configDir; char *autostartDir; char *logDir; diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 772e1c6..b87fa60 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -627,9 +627,6 @@ umlShutdown(void) { umlProcessAutoDestroyShutdown(uml_driver); - if (uml_driver->brctl) - brShutdown(uml_driver->brctl); - umlDriverUnlock(uml_driver); virMutexDestroy(¨_driver->lock); VIR_FREE(uml_driver); @@ -959,10 +956,7 @@ static int umlCleanupTapDevices(virDomainObjPtr vm) { int i; int err; int ret = 0; - brControl *brctl = NULL; VIR_ERROR(_("Cleanup tap")); - if (brInit(&brctl) < 0) - return -1; for (i = 0 ; i < vm->def->nnets ; i++) { virDomainNetDefPtr def = vm->def->nets[i]; @@ -972,14 +966,13 @@ static int umlCleanupTapDevices(virDomainObjPtr vm) { continue; VIR_ERROR(_("Cleanup '%s'"), def->ifname); - err = brDeleteTap(brctl, def->ifname); + err = brDeleteTap(def->ifname); if (err) { VIR_ERROR(_("Cleanup failed %d"), err); ret = -1; } } VIR_ERROR(_("Cleanup tap done")); - brShutdown(brctl); return ret; } diff --git a/src/util/bridge.c b/src/util/bridge.c index 6774f99..ae1d601 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -55,61 +55,45 @@ # define JIFFIES_TO_MS(j) (((j)*1000)/HZ) # define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000) -struct _brControl { - int fd; -}; -/** - * brInit: - * @ctlp: pointer to bridge control return value - * - * Initialize a new bridge layer. In case of success - * @ctlp will contain a pointer to the new bridge structure. - * - * Returns 0 in case of success, an error code otherwise. - */ -int -brInit(brControl **ctlp) +static int brSetupControlFull(const char *ifname, + struct ifreq *ifr, + int domain, + int type) { int fd; - if (!ctlp || *ctlp) - return EINVAL; + if (ifname && ifr) { + memset(ifr, 0, sizeof(*ifr)); - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0 || - virSetCloseExec(fd) < 0 || - VIR_ALLOC(*ctlp) < 0) { - VIR_FORCE_CLOSE(fd); - return errno; + if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) { + errno = EINVAL; + return -1; + } } - (*ctlp)->fd = fd; + if ((fd = socket(domain, type, 0)) < 0) + return -1; - return 0; -} + if (virSetInherit(fd, false) < 0) { + VIR_FORCE_CLOSE(fd); + return -1; + } -/** - * brShutdown: - * @ctl: pointer to a bridge control - * - * Shutdown the bridge layer and deallocate the associated structures - */ -void -brShutdown(brControl *ctl) -{ - if (!ctl) - return; + return fd; +} - VIR_FORCE_CLOSE(ctl->fd); - VIR_FREE(ctl); +static int brSetupControl(const char *ifname, + struct ifreq *ifr) +{ + return brSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); } + /** * brAddBridge: - * @ctl: bridge control pointer - * @name: the bridge name + * @brname: the bridge name * * This function register a new bridge * @@ -117,20 +101,27 @@ brShutdown(brControl *ctl) */ # ifdef SIOCBRADDBR int -brAddBridge(brControl *ctl, - const char *name) +brAddBridge(const char *brname) { - if (!ctl || !ctl->fd || !name) - return EINVAL; + int fd = -1; + int ret = -1; - if (ioctl(ctl->fd, SIOCBRADDBR, name) == 0) - return 0; + if ((fd = brSetupControl(NULL, NULL)) < 0) + return errno; - return errno; + if (ioctl(fd, SIOCBRADDBR, brname) < 0) { + ret = errno; + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } # else -int brAddBridge (brControl *ctl ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED) +int brAddBridge (const char *brname ATTRIBUTE_UNUSED) { return EINVAL; } @@ -138,32 +129,27 @@ int brAddBridge (brControl *ctl ATTRIBUTE_UNUSED, # ifdef SIOCBRDELBR int -brHasBridge(brControl *ctl, - const char *name) +brHasBridge(const char *brname) { + int fd = -1; + int ret = -1; struct ifreq ifr; - if (!ctl || !name) { - errno = EINVAL; - return -1; - } - - memset(&ifr, 0, sizeof(struct ifreq)); + if ((fd = brSetupControl(brname, &ifr)) < 0) + return errno; - if (virStrcpyStatic(ifr.ifr_name, name) == NULL) { - errno = EINVAL; - return -1; - } + if (ioctl(fd, SIOCGIFFLAGS, &ifr)) + goto cleanup; - if (ioctl(ctl->fd, SIOCGIFFLAGS, &ifr)) - return -1; + ret = 0; - return 0; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } # else int -brHasBridge(brControl *ctl ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED) +brHasBridge(const char *brname ATTRIBUTE_UNUSED) { return EINVAL; } @@ -171,8 +157,7 @@ brHasBridge(brControl *ctl ATTRIBUTE_UNUSED, /** * brDeleteBridge: - * @ctl: bridge control pointer - * @name: the bridge name + * @brname: the bridge name * * Remove a bridge from the layer. * @@ -180,52 +165,37 @@ brHasBridge(brControl *ctl ATTRIBUTE_UNUSED, */ # ifdef SIOCBRDELBR int -brDeleteBridge(brControl *ctl, - const char *name) +brDeleteBridge(const char *brname) { - if (!ctl || !ctl->fd || !name) - return EINVAL; + int fd = -1; + int ret = -1; + + if ((fd = brSetupControl(NULL, NULL)) < 0) + return errno; - return ioctl(ctl->fd, SIOCBRDELBR, name) == 0 ? 0 : errno; + if (ioctl(fd, SIOCBRDELBR, brname) < 0) { + ret = errno; + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } # else int -brDeleteBridge(brControl *ctl ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED) +brDeleteBridge(const char *brname ATTRIBUTE_UNUSED) { return EINVAL; } # endif -# if defined(SIOCBRADDIF) && defined(SIOCBRDELIF) -static int -brAddDelInterface(brControl *ctl, - int cmd, - const char *bridge, - const char *iface) -{ - struct ifreq ifr; - - if (!ctl || !ctl->fd || !bridge || !iface) - return EINVAL; - - memset(&ifr, 0, sizeof(struct ifreq)); - - if (virStrcpyStatic(ifr.ifr_name, bridge) == NULL) - return EINVAL; - - if (!(ifr.ifr_ifindex = if_nametoindex(iface))) - return ENODEV; - - return ioctl(ctl->fd, cmd, &ifr) == 0 ? 0 : errno; -} -# endif - /** * brAddInterface: - * @ctl: bridge control pointer - * @bridge: the bridge name - * @iface: the network interface name + * @brname: the bridge name + * @ifname: the network interface name * * Adds an interface to a bridge * @@ -233,17 +203,35 @@ brAddDelInterface(brControl *ctl, */ # ifdef SIOCBRADDIF int -brAddInterface(brControl *ctl, - const char *bridge, - const char *iface) +brAddInterface(const char *brname, + const char *ifname) { - return brAddDelInterface(ctl, SIOCBRADDIF, bridge, iface); + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = brSetupControl(brname, &ifr)) < 0) + return errno; + + if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { + ret = errno; + goto cleanup; + } + + if (ioctl(fd, SIOCBRADDIF, &ifr) < 0) { + ret = errno; + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } # else int -brAddInterface(brControl *ctl ATTRIBUTE_UNUSED, - const char *bridge ATTRIBUTE_UNUSED, - const char *iface ATTRIBUTE_UNUSED) +brAddInterface(const char *brname ATTRIBUTE_UNUSED, + const char *ifname ATTRIBUTE_UNUSED) { return EINVAL; } @@ -251,9 +239,8 @@ brAddInterface(brControl *ctl ATTRIBUTE_UNUSED, /** * brDeleteInterface: - * @ctl: bridge control pointer - * @bridge: the bridge name - * @iface: the network interface name + * @brname: the bridge name + * @ifname: the network interface name * * Removes an interface from a bridge * @@ -261,17 +248,35 @@ brAddInterface(brControl *ctl ATTRIBUTE_UNUSED, */ # ifdef SIOCBRDELIF int -brDeleteInterface(brControl *ctl, - const char *bridge, - const char *iface) +brDeleteInterface(const char *brname, + const char *ifname) { - return brAddDelInterface(ctl, SIOCBRDELIF, bridge, iface); + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = brSetupControl(brname, &ifr)) < 0) + return errno; + + if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { + ret = errno; + goto cleanup; + } + + if (ioctl(fd, SIOCBRDELIF, &ifr) < 0) { + ret = errno; + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } # else int -brDeleteInterface(brControl *ctl ATTRIBUTE_UNUSED, - const char *bridge ATTRIBUTE_UNUSED, - const char *iface ATTRIBUTE_UNUSED) +brDeleteInterface(const char *brname ATTRIBUTE_UNUSED, + const char *ifname ATTRIBUTE_UNUSED) { return EINVAL; } @@ -279,7 +284,6 @@ brDeleteInterface(brControl *ctl ATTRIBUTE_UNUSED, /** * brSetInterfaceMac: - * @ctl: bridge control pointer * @ifname: interface name to set MTU for * @macaddr: MAC address (VIR_MAC_BUFLEN in size) * @@ -289,30 +293,38 @@ brDeleteInterface(brControl *ctl ATTRIBUTE_UNUSED, * Returns 0 in case of success or an errno code in case of failure. */ int -brSetInterfaceMac(brControl *ctl, const char *ifname, +brSetInterfaceMac(const char *ifname, const unsigned char *macaddr) { + int fd = -1; + int ret = -1; struct ifreq ifr; - if (!ctl || !ifname) - return EINVAL; - - memset(&ifr, 0, sizeof(struct ifreq)); - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) - return EINVAL; + if ((fd = brSetupControl(ifname, &ifr)) < 0) + return errno; /* To fill ifr.ifr_hdaddr.sa_family field */ - if (ioctl(ctl->fd, SIOCGIFHWADDR, &ifr) != 0) - return errno; + if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { + ret = errno; + goto cleanup; + } memcpy(ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN); - return ioctl(ctl->fd, SIOCSIFHWADDR, &ifr) == 0 ? 0 : errno; + if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) { + ret = errno; + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } /** * ifGetMtu - * @ctl: bridge control pointer * @ifname: interface name get MTU for * * This function gets the @mtu value set for a given interface @ifname. @@ -320,32 +332,27 @@ brSetInterfaceMac(brControl *ctl, const char *ifname, * Returns the MTU value in case of success. * On error, returns -1 and sets errno accordingly */ -static int ifGetMtu(brControl *ctl, const char *ifname) +static int ifGetMtu(const char *ifname) { + int fd = -1; + int ret = -1; struct ifreq ifr; - if (!ctl || !ifname) { - errno = EINVAL; + if ((fd = brSetupControl(ifname, &ifr)) < 0) return -1; - } - memset(&ifr, 0, sizeof(struct ifreq)); - - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { - errno = EINVAL; - return -1; - } - - if (ioctl(ctl->fd, SIOCGIFMTU, &ifr)) - return -1; + if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) + goto cleanup; - return ifr.ifr_mtu; + ret = ifr.ifr_mtu; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } /** * ifSetMtu: - * @ctl: bridge control pointer * @ifname: interface name to set MTU for * @mtu: MTU value * @@ -354,42 +361,47 @@ static int ifGetMtu(brControl *ctl, const char *ifname) * * Returns 0 in case of success or an errno code in case of failure. */ -static int ifSetMtu(brControl *ctl, const char *ifname, int mtu) +static int ifSetMtu(const char *ifname, int mtu) { + int fd = -1; + int ret = -1; struct ifreq ifr; - if (!ctl || !ifname) - return EINVAL; - - memset(&ifr, 0, sizeof(struct ifreq)); + if ((fd = brSetupControl(ifname, &ifr)) < 0) + return errno; - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) - return EINVAL; ifr.ifr_mtu = mtu; - return ioctl(ctl->fd, SIOCSIFMTU, &ifr) == 0 ? 0 : errno; + if (ioctl(fd, SIOCSIFMTU, &ifr) < 0) { + ret = errno; + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } /** * brSetInterfaceMtu - * @ctl: bridge control pointer - * @bridge: name of the bridge interface + * @brname: name of the bridge interface * @ifname: name of the interface whose MTU we want to set * * Sets the interface mtu to the same MTU of the bridge * * Returns 0 in case of success or an errno code in case of failure. */ -static int brSetInterfaceMtu(brControl *ctl, - const char *bridge, +static int brSetInterfaceMtu(const char *brname, const char *ifname) { - int mtu = ifGetMtu(ctl, bridge); + int mtu = ifGetMtu(brname); if (mtu < 0) return errno; - return ifSetMtu(ctl, ifname, mtu); + return ifSetMtu(ifname, mtu); } /** @@ -453,8 +465,7 @@ brProbeVnetHdr(int tapfd) /** * brAddTap: - * @ctl: bridge control pointer - * @bridge: the bridge name + * @brname: the bridge name * @ifname: the interface name (or name template) * @macaddr: desired MAC address (VIR_MAC_BUFLEN long) * @vnet_hdr: whether to try enabling IFF_VNET_HDR @@ -471,18 +482,14 @@ brProbeVnetHdr(int tapfd) * Returns 0 in case of success or an errno code in case of failure. */ int -brAddTap(brControl *ctl, - const char *bridge, +brAddTap(const char *brname, char **ifname, const unsigned char *macaddr, int vnet_hdr, bool up, int *tapfd) { - if (!ctl || !ctl->fd || !bridge || !ifname) - return EINVAL; - - errno = brCreateTap(ctl, ifname, vnet_hdr, tapfd); + errno = brCreateTap(ifname, vnet_hdr, tapfd); /* fd has been closed in brCreateTap() when it failed. */ if (errno) @@ -494,18 +501,19 @@ brAddTap(brControl *ctl, * seeing the kernel allocate random MAC for the TAP * device before we set our static MAC. */ - if ((errno = brSetInterfaceMac(ctl, *ifname, macaddr))) + if ((errno = brSetInterfaceMac(*ifname, macaddr))) goto close_fd; /* We need to set the interface MTU before adding it * to the bridge, because the bridge will have its * MTU adjusted automatically when we add the new interface. */ - if ((errno = brSetInterfaceMtu(ctl, bridge, *ifname))) + if ((errno = brSetInterfaceMtu(brname, *ifname))) goto close_fd; - if ((errno = brAddInterface(ctl, bridge, *ifname))) + if ((errno = brAddInterface(brname, *ifname))) goto close_fd; - if (up && ((errno = brSetInterfaceUp(ctl, *ifname, 1)))) + if (up && ((errno = brSetInterfaceUp(*ifname, 1)))) goto close_fd; + return 0; close_fd: @@ -515,15 +523,11 @@ error: return errno; } -int brDeleteTap(brControl *ctl, - const char *ifname) +int brDeleteTap(const char *ifname) { struct ifreq try; int fd; - if (!ctl || !ctl->fd || !ifname) - return EINVAL; - if ((fd = open("/dev/net/tun", O_RDWR)) < 0) return errno; @@ -549,7 +553,6 @@ int brDeleteTap(brControl *ctl, /** * brSetInterfaceUp: - * @ctl: bridge control pointer * @ifname: the interface name * @up: 1 for up, 0 for down * @@ -558,39 +561,44 @@ int brDeleteTap(brControl *ctl, * Returns 0 in case of success or an errno code in case of failure. */ int -brSetInterfaceUp(brControl *ctl, - const char *ifname, +brSetInterfaceUp(const char *ifname, int up) { + int fd = -1; + int ret = -1; struct ifreq ifr; int ifflags; - if (!ctl || !ifname) - return EINVAL; - - memset(&ifr, 0, sizeof(struct ifreq)); - - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) - return EINVAL; - - if (ioctl(ctl->fd, SIOCGIFFLAGS, &ifr) < 0) + if ((fd = brSetupControl(ifname, &ifr)) < 0) return errno; - ifflags = up ? (ifr.ifr_flags | IFF_UP) : (ifr.ifr_flags & ~IFF_UP); + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + ret = errno; + goto cleanup; + } + + if (up) + ifflags = ifr.ifr_flags | IFF_UP; + else + ifflags = ifr.ifr_flags & ~IFF_UP; if (ifr.ifr_flags != ifflags) { ifr.ifr_flags = ifflags; - - if (ioctl(ctl->fd, SIOCSIFFLAGS, &ifr) < 0) - return errno; + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { + ret = errno; + goto cleanup; + } } - return 0; + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } /** * brGetInterfaceUp: - * @ctl: bridge control pointer * @ifname: the interface name * @up: where to store the status * @@ -599,31 +607,31 @@ brSetInterfaceUp(brControl *ctl, * Returns 0 in case of success or an errno code in case of failure. */ int -brGetInterfaceUp(brControl *ctl, - const char *ifname, +brGetInterfaceUp(const char *ifname, int *up) { + int fd = -1; + int ret = -1; struct ifreq ifr; - if (!ctl || !ifname || !up) - return EINVAL; - - memset(&ifr, 0, sizeof(struct ifreq)); - - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) - return EINVAL; - - if (ioctl(ctl->fd, SIOCGIFFLAGS, &ifr) < 0) + if ((fd = brSetupControl(ifname, &ifr)) < 0) return errno; + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + ret = errno; + goto cleanup; + } + *up = (ifr.ifr_flags & IFF_UP) ? 1 : 0; + ret = 0; - return 0; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } /** * brAddInetAddress: - * @ctl: bridge control pointer * @ifname: the interface name * @addr: the IP address (IPv4 or IPv6) * @prefix: number of 1 bits in the netmask @@ -636,8 +644,7 @@ brGetInterfaceUp(brControl *ctl, */ int -brAddInetAddress(brControl *ctl ATTRIBUTE_UNUSED, - const char *ifname, +brAddInetAddress(const char *ifname, virSocketAddr *addr, unsigned int prefix) { @@ -674,7 +681,6 @@ cleanup: /** * brDelInetAddress: - * @ctl: bridge control pointer * @ifname: the interface name * @addr: the IP address (IPv4 or IPv6) * @prefix: number of 1 bits in the netmask @@ -685,8 +691,7 @@ cleanup: */ int -brDelInetAddress(brControl *ctl ATTRIBUTE_UNUSED, - const char *ifname, +brDelInetAddress(const char *ifname, virSocketAddr *addr, unsigned int prefix) { @@ -713,8 +718,7 @@ cleanup: /** * brSetForwardDelay: - * @ctl: bridge control pointer - * @bridge: the bridge name + * @brname: the bridge name * @delay: delay in seconds * * Set the bridge forward delay @@ -723,15 +727,14 @@ cleanup: */ int -brSetForwardDelay(brControl *ctl ATTRIBUTE_UNUSED, - const char *bridge, +brSetForwardDelay(const char *brname, int delay) { virCommandPtr cmd; int ret = -1; cmd = virCommandNew(BRCTL); - virCommandAddArgList(cmd, "setfd", bridge, NULL); + virCommandAddArgList(cmd, "setfd", brname, NULL); virCommandAddArgFormat(cmd, "%d", delay); if (virCommandRun(cmd, NULL) < 0) @@ -745,8 +748,7 @@ cleanup: /** * brSetEnableSTP: - * @ctl: bridge control pointer - * @bridge: the bridge name + * @brname: the bridge name * @enable: 1 to enable, 0 to disable * * Control whether the bridge participates in the spanning tree protocol, @@ -755,15 +757,14 @@ cleanup: * Returns 0 in case of success or -1 on failure */ int -brSetEnableSTP(brControl *ctl ATTRIBUTE_UNUSED, - const char *bridge, +brSetEnableSTP(const char *brname, int enable) { virCommandPtr cmd; int ret = -1; cmd = virCommandNew(BRCTL); - virCommandAddArgList(cmd, "stp", bridge, + virCommandAddArgList(cmd, "stp", brname, enable ? "on" : "off", NULL); @@ -778,7 +779,6 @@ cleanup: /** * brCreateTap: - * @ctl: bridge control pointer * @ifname: the interface name * @vnet_hr: whether to try enabling IFF_VNET_HDR * @tapfd: file descriptor return value for the new tap device @@ -793,17 +793,13 @@ cleanup: */ int -brCreateTap(brControl *ctl ATTRIBUTE_UNUSED, - char **ifname, +brCreateTap(char **ifname, int vnet_hdr ATTRIBUTE_UNUSED, int *tapfd) { int fd; struct ifreq ifr; - if (!ifname) - return EINVAL; - if ((fd = open("/dev/net/tun", O_RDWR)) < 0) return errno; diff --git a/src/util/bridge.h b/src/util/bridge.h index c462a08..2bfc4b4 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -42,78 +42,76 @@ */ # define BR_INET_ADDR_MAXLEN INET_ADDRSTRLEN -typedef struct _brControl brControl; +int brAddBridge (const char *brname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int brDeleteBridge (const char *brname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int brHasBridge (const char *brname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brInit (brControl **ctl); -void brShutdown (brControl *ctl); +int brAddInterface (const char *brname, + const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int brAddBridge (brControl *ctl, - const char *name); -int brDeleteBridge (brControl *ctl, - const char *name); -int brHasBridge (brControl *ctl, - const char *name); - -int brAddInterface (brControl *ctl, - const char *bridge, - const char *iface); -int brDeleteInterface (brControl *ctl, - const char *bridge, - const char *iface); +int brDeleteInterface (const char *brname, + const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; enum { BR_TAP_VNET_HDR = (1 << 0), BR_TAP_PERSIST = (1 << 1), }; -int brAddTap (brControl *ctl, - const char *bridge, +int brAddTap (const char *brname, char **ifname, const unsigned char *macaddr, int vnet_hdr, bool up, - int *tapfd); + int *tapfd) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_RETURN_CHECK; + -int brDeleteTap (brControl *ctl, - const char *ifname); +int brDeleteTap (const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brSetInterfaceUp (brControl *ctl, - const char *ifname, - int up); -int brGetInterfaceUp (brControl *ctl, - const char *ifname, - int *up); +int brSetInterfaceUp (const char *ifname, + int up) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int brGetInterfaceUp (const char *ifname, + int *up) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int brAddInetAddress (brControl *ctl, - const char *ifname, +int brAddInetAddress (const char *ifname, virSocketAddr *addr, - unsigned int prefix); -int brDelInetAddress (brControl *ctl, - const char *ifname, + unsigned int prefix) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int brDelInetAddress (const char *ifname, virSocketAddr *addr, - unsigned int prefix); - -int brSetForwardDelay (brControl *ctl, - const char *bridge, - int delay); -int brGetForwardDelay (brControl *ctl, - const char *bridge, - int *delay); -int brSetEnableSTP (brControl *ctl, - const char *bridge, - int enable); -int brGetEnableSTP (brControl *ctl, - const char *bridge, - int *enable); - -int brCreateTap (brControl *ctl, - char **ifname, + unsigned int prefix) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int brSetForwardDelay (const char *brname, + int delay) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int brGetForwardDelay (const char *brname, + int *delay) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int brSetEnableSTP (const char *brname, + int enable) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int brGetEnableSTP (const char *brname, + int *enable) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int brCreateTap (char **ifname, int vnet_hdr, - int *tapfd); + int *tapfd) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brSetInterfaceMac (brControl *ctl, - const char *ifname, - const unsigned char *macaddr); +int brSetInterfaceMac (const char *ifname, + const unsigned char *macaddr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; # endif /* WITH_BRIDGE */ -- 1.7.6.4

On 11/03/2011 01:29 PM, Daniel P. Berrange wrote:
The bridge management APIs in src/util/bridge.c require a brControl object to be passed around. This holds the file descriptor for the control socket. This extra object complicates use of the API for only a minor efficiency gain, which is in turn entirely offset by the need to fork/exec the brctl command for STP configuration.
This patch removes the 'brControl' object entirely, instead opening the control socket& closing it again within the scope of each method.
The parameter names for the APIs are also made to consistently use 'brname' for bridge device name, and 'ifname' for an interface device name. Finally annotations are added for non-NULL parameters and return check validation
* src/util/bridge.c, src/util/bridge.h: Remove brControl object and update API parameter names& annotations. * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/uml/uml_conf.h, src/uml/uml_conf.c, src/uml/uml_driver.c, src/qemu/qemu_command.c, src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Remove reference to 'brControl' object --- src/lxc/lxc_driver.c | 10 +- src/network/bridge_driver.c | 41 ++--- src/qemu/qemu_command.c | 8 +- src/qemu/qemu_conf.h | 1 - src/qemu/qemu_driver.c | 3 - src/uml/uml_conf.c | 13 +-- src/uml/uml_conf.h | 1 - src/uml/uml_driver.c | 9 +- src/util/bridge.c | 454 +++++++++++++++++++++---------------------- src/util/bridge.h | 104 +++++----- 10 files changed, 295 insertions(+), 349 deletions(-)
ACK. Visually checks out, and make && make check && make syntax-check pass.

On 11/03/2011 01:29 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
The bridge management APIs in src/util/bridge.c require a brControl object to be passed around. This holds the file descriptor for the control socket. This extra object complicates use of the API for only a minor efficiency gain, which is in turn entirely offset by the need to fork/exec the brctl command for STP configuration.
This patch removes the 'brControl' object entirely, instead opening the control socket& closing it again within the scope of each method.
The parameter names for the APIs are also made to consistently use 'brname' for bridge device name, and 'ifname' for an interface device name. Finally annotations are added for non-NULL parameters and return check validation I looked at this one now top to bottom. It looks ok to me. ACK.
* src/util/bridge.c, src/util/bridge.h: Remove brControl object and update API parameter names& annotations. * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/uml/uml_conf.h, src/uml/uml_conf.c, src/uml/uml_driver.c, src/qemu/qemu_command.c, src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Remove reference to 'brControl' object --- src/lxc/lxc_driver.c | 10 +- src/network/bridge_driver.c | 41 ++--- src/qemu/qemu_command.c | 8 +- src/qemu/qemu_conf.h | 1 - src/qemu/qemu_driver.c | 3 - src/uml/uml_conf.c | 13 +-- src/uml/uml_conf.h | 1 - src/uml/uml_driver.c | 9 +- src/util/bridge.c | 454 +++++++++++++++++++++---------------------- src/util/bridge.h | 104 +++++----- 10 files changed, 295 insertions(+), 349 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index d6e5e20..2505efc 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1194,15 +1194,8 @@ static int lxcSetupInterfaces(virConnectPtr conn, { int rc = -1, i; char *bridge = NULL; - brControl *brctl = NULL; int ret;
- if ((ret = brInit(&brctl)) != 0) { - virReportSystemError(ret, "%s", - _("Unable to initialize bridging")); - return -1; - } - for (i = 0 ; i< def->nnets ; i++) { char *parentVeth; char *containerVeth = NULL; @@ -1277,7 +1270,7 @@ static int lxcSetupInterfaces(virConnectPtr conn, goto error_exit; }
- if ((ret = brAddInterface(brctl, bridge, parentVeth)) != 0) { + if ((ret = brAddInterface(bridge, parentVeth)) != 0) { virReportSystemError(ret, _("Failed to add %s device to %s"), parentVeth, bridge); @@ -1303,7 +1296,6 @@ static int lxcSetupInterfaces(virConnectPtr conn, rc = 0;
error_exit: - brShutdown(brctl); if (rc != 0) { for (i = 0 ; i< def->nnets ; i++) networkReleaseActualDevice(def->nets[i]); diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 445c3cb..053acfd 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -82,7 +82,6 @@ struct network_driver { virNetworkObjList networks;
iptablesContext *iptables; - brControl *brctl; char *networkConfigDir; char *networkAutostartDir; char *logDir; @@ -212,7 +211,7 @@ networkFindActiveConfigs(struct network_driver *driver) {
/* If bridge exists, then mark it active */ if (obj->def->bridge&& - brHasBridge(driver->brctl, obj->def->bridge) == 0) { + brHasBridge(obj->def->bridge) == 0) { obj->active = 1;
/* Try and read dnsmasq/radvd pids if any */ @@ -263,7 +262,6 @@ static int networkStartup(int privileged) { uid_t uid = geteuid(); char *base = NULL; - int err;
if (VIR_ALLOC(driverState)< 0) goto error; @@ -312,12 +310,6 @@ networkStartup(int privileged) {
VIR_FREE(base);
- if ((err = brInit(&driverState->brctl))) { - virReportSystemError(err, "%s", - _("cannot initialize bridge support")); - goto error; - } - if (!(driverState->iptables = iptablesContextNew())) { goto out_of_memory; } @@ -416,8 +408,6 @@ networkShutdown(void) { VIR_FREE(driverState->networkConfigDir); VIR_FREE(driverState->networkAutostartDir);
- if (driverState->brctl) - brShutdown(driverState->brctl); if (driverState->iptables) iptablesContextFree(driverState->iptables);
@@ -1675,8 +1665,7 @@ out: }
static int -networkAddAddrToBridge(struct network_driver *driver, - virNetworkObjPtr network, +networkAddAddrToBridge(virNetworkObjPtr network, virNetworkIpDefPtr ipdef) { int prefix = virNetworkIpDefPrefix(ipdef); @@ -1688,7 +1677,7 @@ networkAddAddrToBridge(struct network_driver *driver, return -1; }
- if (brAddInetAddress(driver->brctl, network->def->bridge, + if (brAddInetAddress(network->def->bridge, &ipdef->address, prefix)< 0) { networkReportError(VIR_ERR_INTERNAL_ERROR, _("cannot set IP address on bridge '%s'"), @@ -1714,7 +1703,7 @@ networkStartNetworkVirtual(struct network_driver *driver, return -1;
/* Create and configure the bridge device */ - if ((err = brAddBridge(driver->brctl, network->def->bridge))) { + if ((err = brAddBridge(network->def->bridge))) { virReportSystemError(err, _("cannot create bridge '%s'"), network->def->bridge); @@ -1733,7 +1722,7 @@ networkStartNetworkVirtual(struct network_driver *driver, virReportOOMError(); goto err0; } - if ((err = brAddTap(driver->brctl, network->def->bridge, + if ((err = brAddTap(network->def->bridge, &macTapIfName, network->def->mac, 0, false, NULL))) { virReportSystemError(err, _("cannot create dummy tap device '%s' to set mac" @@ -1745,7 +1734,7 @@ networkStartNetworkVirtual(struct network_driver *driver, }
/* Set bridge options */ - if (brSetForwardDelay(driver->brctl, network->def->bridge, + if (brSetForwardDelay(network->def->bridge, network->def->delay)) { networkReportError(VIR_ERR_INTERNAL_ERROR, _("cannot set forward delay on bridge '%s'"), @@ -1753,7 +1742,7 @@ networkStartNetworkVirtual(struct network_driver *driver, goto err1; }
- if (brSetEnableSTP(driver->brctl, network->def->bridge, + if (brSetEnableSTP(network->def->bridge, network->def->stp ? 1 : 0)) { networkReportError(VIR_ERR_INTERNAL_ERROR, _("cannot set STP '%s' on bridge '%s'"), @@ -1780,13 +1769,13 @@ networkStartNetworkVirtual(struct network_driver *driver, v6present = true;
/* Add the IP address/netmask to the bridge */ - if (networkAddAddrToBridge(driver, network, ipdef)< 0) { + if (networkAddAddrToBridge(network, ipdef)< 0) { goto err2; } }
/* Bring up the bridge interface */ - if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) { + if ((err = brSetInterfaceUp(network->def->bridge, 1))) { virReportSystemError(err, _("failed to bring the bridge '%s' up"), network->def->bridge); @@ -1839,7 +1828,7 @@ networkStartNetworkVirtual(struct network_driver *driver, err3: if (!save_err) save_err = virSaveLastError(); - if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) { + if ((err = brSetInterfaceUp(network->def->bridge, 0))) { char ebuf[1024]; VIR_WARN("Failed to bring down bridge '%s' : %s", network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); @@ -1854,7 +1843,7 @@ networkStartNetworkVirtual(struct network_driver *driver, if (!save_err) save_err = virSaveLastError();
- if ((err = brDeleteTap(driver->brctl, macTapIfName))) { + if ((err = brDeleteTap(macTapIfName))) { char ebuf[1024]; VIR_WARN("Failed to delete dummy tap device '%s' on bridge '%s' : %s", macTapIfName, network->def->bridge, @@ -1865,7 +1854,7 @@ networkStartNetworkVirtual(struct network_driver *driver, err0: if (!save_err) save_err = virSaveLastError(); - if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) { + if ((err = brDeleteBridge(network->def->bridge))) { char ebuf[1024]; VIR_WARN("Failed to delete bridge '%s' : %s", network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); @@ -1910,7 +1899,7 @@ static int networkShutdownNetworkVirtual(struct network_driver *driver, if (!macTapIfName) { virReportOOMError(); } else { - if ((err = brDeleteTap(driver->brctl, macTapIfName))) { + if ((err = brDeleteTap(macTapIfName))) { VIR_WARN("Failed to delete dummy tap device '%s' on bridge '%s' : %s", macTapIfName, network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); @@ -1919,14 +1908,14 @@ static int networkShutdownNetworkVirtual(struct network_driver *driver, } }
- if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) { + if ((err = brSetInterfaceUp(network->def->bridge, 0))) { VIR_WARN("Failed to bring down bridge '%s' : %s", network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); }
networkRemoveIptablesRules(driver, network);
- if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) { + if ((err = brDeleteBridge(network->def->bridge))) { VIR_WARN("Failed to delete bridge '%s' : %s", network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); } diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 01ee23f..ee18858 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -261,12 +261,6 @@ qemuNetworkIfaceConnect(virDomainDefPtr def, return -1; }
- if (!driver->brctl&& (err = brInit(&driver->brctl))) { - virReportSystemError(err, "%s", - _("cannot initialize bridge support")); - goto cleanup; - } - if (!net->ifname || STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) || strchr(net->ifname, '%')) { @@ -285,7 +279,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ - err = brAddTap(driver->brctl, brname,&net->ifname, tapmac, + err = brAddTap(brname,&net->ifname, tapmac, vnet_hdr, true,&tapfd); virDomainAuditNetDevice(def, net, "/dev/net/tun", tapfd>= 0); if (err) { diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index ff5cf23..1ba2002 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -69,7 +69,6 @@ struct qemud_driver {
virDomainObjList domains;
- brControl *brctl; /* These four directories are ones libvirtd uses (so must be root:root * to avoid security risk from QEMU processes */ char *configDir; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 118197a..628dac1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -815,9 +815,6 @@ qemudShutdown(void) { /* Free domain callback list */ virDomainEventStateFree(qemu_driver->domainEventState);
- if (qemu_driver->brctl) - brShutdown(qemu_driver->brctl); - virCgroupFree(&qemu_driver->cgroup);
virLockManagerPluginUnref(qemu_driver->lockManager); diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c index f2bdd74..92d132b 100644 --- a/src/uml/uml_conf.c +++ b/src/uml/uml_conf.c @@ -121,17 +121,10 @@ umlConnectTapDevice(virConnectPtr conn, virDomainNetDefPtr net, const char *bridge) { - brControl *brctl = NULL; bool template_ifname = false; int err; unsigned char tapmac[VIR_MAC_BUFLEN];
- if ((err = brInit(&brctl))) { - virReportSystemError(err, "%s", - _("cannot initialize bridge support")); - goto error; - } - if (!net->ifname || STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) || strchr(net->ifname, '%')) { @@ -144,8 +137,7 @@ umlConnectTapDevice(virConnectPtr conn,
memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ - if ((err = brAddTap(brctl, - bridge, + if ((err = brAddTap(bridge, &net->ifname, tapmac, 0, @@ -183,14 +175,11 @@ umlConnectTapDevice(virConnectPtr conn, } }
- brShutdown(brctl); - return 0;
no_memory: virReportOOMError(); error: - brShutdown(brctl); return -1; }
diff --git a/src/uml/uml_conf.h b/src/uml/uml_conf.h index 657f877..01695c7 100644 --- a/src/uml/uml_conf.h +++ b/src/uml/uml_conf.h @@ -52,7 +52,6 @@ struct uml_driver {
virDomainObjList domains;
- brControl *brctl; char *configDir; char *autostartDir; char *logDir; diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 772e1c6..b87fa60 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -627,9 +627,6 @@ umlShutdown(void) {
umlProcessAutoDestroyShutdown(uml_driver);
- if (uml_driver->brctl) - brShutdown(uml_driver->brctl); - umlDriverUnlock(uml_driver); virMutexDestroy(¨_driver->lock); VIR_FREE(uml_driver); @@ -959,10 +956,7 @@ static int umlCleanupTapDevices(virDomainObjPtr vm) { int i; int err; int ret = 0; - brControl *brctl = NULL; VIR_ERROR(_("Cleanup tap")); - if (brInit(&brctl)< 0) - return -1;
for (i = 0 ; i< vm->def->nnets ; i++) { virDomainNetDefPtr def = vm->def->nets[i]; @@ -972,14 +966,13 @@ static int umlCleanupTapDevices(virDomainObjPtr vm) { continue;
VIR_ERROR(_("Cleanup '%s'"), def->ifname); - err = brDeleteTap(brctl, def->ifname); + err = brDeleteTap(def->ifname); if (err) { VIR_ERROR(_("Cleanup failed %d"), err); ret = -1; } } VIR_ERROR(_("Cleanup tap done")); - brShutdown(brctl); return ret; }
diff --git a/src/util/bridge.c b/src/util/bridge.c index 6774f99..ae1d601 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -55,61 +55,45 @@ # define JIFFIES_TO_MS(j) (((j)*1000)/HZ) # define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000)
-struct _brControl { - int fd; -};
-/** - * brInit: - * @ctlp: pointer to bridge control return value - * - * Initialize a new bridge layer. In case of success - * @ctlp will contain a pointer to the new bridge structure. - * - * Returns 0 in case of success, an error code otherwise. - */ -int -brInit(brControl **ctlp) +static int brSetupControlFull(const char *ifname, + struct ifreq *ifr, + int domain, + int type) { int fd;
- if (!ctlp || *ctlp) - return EINVAL; + if (ifname&& ifr) { + memset(ifr, 0, sizeof(*ifr));
- fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd< 0 || - virSetCloseExec(fd)< 0 || - VIR_ALLOC(*ctlp)< 0) { - VIR_FORCE_CLOSE(fd); - return errno; + if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) { + errno = EINVAL; + return -1; + } }
- (*ctlp)->fd = fd; + if ((fd = socket(domain, type, 0))< 0) + return -1;
- return 0; -} + if (virSetInherit(fd, false)< 0) { + VIR_FORCE_CLOSE(fd); + return -1; + }
-/** - * brShutdown: - * @ctl: pointer to a bridge control - * - * Shutdown the bridge layer and deallocate the associated structures - */ -void -brShutdown(brControl *ctl) -{ - if (!ctl) - return; + return fd; +}
- VIR_FORCE_CLOSE(ctl->fd);
- VIR_FREE(ctl); +static int brSetupControl(const char *ifname, + struct ifreq *ifr) +{ + return brSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); }
+ /** * brAddBridge: - * @ctl: bridge control pointer - * @name: the bridge name + * @brname: the bridge name * * This function register a new bridge * @@ -117,20 +101,27 @@ brShutdown(brControl *ctl) */ # ifdef SIOCBRADDBR int -brAddBridge(brControl *ctl, - const char *name) +brAddBridge(const char *brname) { - if (!ctl || !ctl->fd || !name) - return EINVAL; + int fd = -1; + int ret = -1;
- if (ioctl(ctl->fd, SIOCBRADDBR, name) == 0) - return 0; + if ((fd = brSetupControl(NULL, NULL))< 0) + return errno;
- return errno; + if (ioctl(fd, SIOCBRADDBR, brname)< 0) { + ret = errno; + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } # else -int brAddBridge (brControl *ctl ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED) +int brAddBridge (const char *brname ATTRIBUTE_UNUSED) { return EINVAL; } @@ -138,32 +129,27 @@ int brAddBridge (brControl *ctl ATTRIBUTE_UNUSED,
# ifdef SIOCBRDELBR int -brHasBridge(brControl *ctl, - const char *name) +brHasBridge(const char *brname) { + int fd = -1; + int ret = -1; struct ifreq ifr;
- if (!ctl || !name) { - errno = EINVAL; - return -1; - } - - memset(&ifr, 0, sizeof(struct ifreq)); + if ((fd = brSetupControl(brname,&ifr))< 0) + return errno;
- if (virStrcpyStatic(ifr.ifr_name, name) == NULL) { - errno = EINVAL; - return -1; - } + if (ioctl(fd, SIOCGIFFLAGS,&ifr)) + goto cleanup;
- if (ioctl(ctl->fd, SIOCGIFFLAGS,&ifr)) - return -1; + ret = 0;
- return 0; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } # else int -brHasBridge(brControl *ctl ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED) +brHasBridge(const char *brname ATTRIBUTE_UNUSED) { return EINVAL; } @@ -171,8 +157,7 @@ brHasBridge(brControl *ctl ATTRIBUTE_UNUSED,
/** * brDeleteBridge: - * @ctl: bridge control pointer - * @name: the bridge name + * @brname: the bridge name * * Remove a bridge from the layer. * @@ -180,52 +165,37 @@ brHasBridge(brControl *ctl ATTRIBUTE_UNUSED, */ # ifdef SIOCBRDELBR int -brDeleteBridge(brControl *ctl, - const char *name) +brDeleteBridge(const char *brname) { - if (!ctl || !ctl->fd || !name) - return EINVAL; + int fd = -1; + int ret = -1; + + if ((fd = brSetupControl(NULL, NULL))< 0) + return errno;
- return ioctl(ctl->fd, SIOCBRDELBR, name) == 0 ? 0 : errno; + if (ioctl(fd, SIOCBRDELBR, brname)< 0) { + ret = errno; + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } # else int -brDeleteBridge(brControl *ctl ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED) +brDeleteBridge(const char *brname ATTRIBUTE_UNUSED) { return EINVAL; } # endif
-# if defined(SIOCBRADDIF)&& defined(SIOCBRDELIF) -static int -brAddDelInterface(brControl *ctl, - int cmd, - const char *bridge, - const char *iface) -{ - struct ifreq ifr; - - if (!ctl || !ctl->fd || !bridge || !iface) - return EINVAL; - - memset(&ifr, 0, sizeof(struct ifreq)); - - if (virStrcpyStatic(ifr.ifr_name, bridge) == NULL) - return EINVAL; - - if (!(ifr.ifr_ifindex = if_nametoindex(iface))) - return ENODEV; - - return ioctl(ctl->fd, cmd,&ifr) == 0 ? 0 : errno; -} -# endif - /** * brAddInterface: - * @ctl: bridge control pointer - * @bridge: the bridge name - * @iface: the network interface name + * @brname: the bridge name + * @ifname: the network interface name * * Adds an interface to a bridge * @@ -233,17 +203,35 @@ brAddDelInterface(brControl *ctl, */ # ifdef SIOCBRADDIF int -brAddInterface(brControl *ctl, - const char *bridge, - const char *iface) +brAddInterface(const char *brname, + const char *ifname) { - return brAddDelInterface(ctl, SIOCBRADDIF, bridge, iface); + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = brSetupControl(brname,&ifr))< 0) + return errno; + + if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { + ret = errno; + goto cleanup; + } + + if (ioctl(fd, SIOCBRADDIF,&ifr)< 0) { + ret = errno; + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } # else int -brAddInterface(brControl *ctl ATTRIBUTE_UNUSED, - const char *bridge ATTRIBUTE_UNUSED, - const char *iface ATTRIBUTE_UNUSED) +brAddInterface(const char *brname ATTRIBUTE_UNUSED, + const char *ifname ATTRIBUTE_UNUSED) { return EINVAL; } @@ -251,9 +239,8 @@ brAddInterface(brControl *ctl ATTRIBUTE_UNUSED,
/** * brDeleteInterface: - * @ctl: bridge control pointer - * @bridge: the bridge name - * @iface: the network interface name + * @brname: the bridge name + * @ifname: the network interface name * * Removes an interface from a bridge * @@ -261,17 +248,35 @@ brAddInterface(brControl *ctl ATTRIBUTE_UNUSED, */ # ifdef SIOCBRDELIF int -brDeleteInterface(brControl *ctl, - const char *bridge, - const char *iface) +brDeleteInterface(const char *brname, + const char *ifname) { - return brAddDelInterface(ctl, SIOCBRDELIF, bridge, iface); + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = brSetupControl(brname,&ifr))< 0) + return errno; + + if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { + ret = errno; + goto cleanup; + } + + if (ioctl(fd, SIOCBRDELIF,&ifr)< 0) { + ret = errno; + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } # else int -brDeleteInterface(brControl *ctl ATTRIBUTE_UNUSED, - const char *bridge ATTRIBUTE_UNUSED, - const char *iface ATTRIBUTE_UNUSED) +brDeleteInterface(const char *brname ATTRIBUTE_UNUSED, + const char *ifname ATTRIBUTE_UNUSED) { return EINVAL; } @@ -279,7 +284,6 @@ brDeleteInterface(brControl *ctl ATTRIBUTE_UNUSED,
/** * brSetInterfaceMac: - * @ctl: bridge control pointer * @ifname: interface name to set MTU for * @macaddr: MAC address (VIR_MAC_BUFLEN in size) * @@ -289,30 +293,38 @@ brDeleteInterface(brControl *ctl ATTRIBUTE_UNUSED, * Returns 0 in case of success or an errno code in case of failure. */ int -brSetInterfaceMac(brControl *ctl, const char *ifname, +brSetInterfaceMac(const char *ifname, const unsigned char *macaddr) { + int fd = -1; + int ret = -1; struct ifreq ifr;
- if (!ctl || !ifname) - return EINVAL; - - memset(&ifr, 0, sizeof(struct ifreq)); - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) - return EINVAL; + if ((fd = brSetupControl(ifname,&ifr))< 0) + return errno;
/* To fill ifr.ifr_hdaddr.sa_family field */ - if (ioctl(ctl->fd, SIOCGIFHWADDR,&ifr) != 0) - return errno; + if (ioctl(fd, SIOCGIFHWADDR,&ifr)< 0) { + ret = errno; + goto cleanup; + }
memcpy(ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN);
- return ioctl(ctl->fd, SIOCSIFHWADDR,&ifr) == 0 ? 0 : errno; + if (ioctl(fd, SIOCSIFHWADDR,&ifr)< 0) { + ret = errno; + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; }
/** * ifGetMtu - * @ctl: bridge control pointer * @ifname: interface name get MTU for * * This function gets the @mtu value set for a given interface @ifname. @@ -320,32 +332,27 @@ brSetInterfaceMac(brControl *ctl, const char *ifname, * Returns the MTU value in case of success. * On error, returns -1 and sets errno accordingly */ -static int ifGetMtu(brControl *ctl, const char *ifname) +static int ifGetMtu(const char *ifname) { + int fd = -1; + int ret = -1; struct ifreq ifr;
- if (!ctl || !ifname) { - errno = EINVAL; + if ((fd = brSetupControl(ifname,&ifr))< 0) return -1; - }
- memset(&ifr, 0, sizeof(struct ifreq)); - - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { - errno = EINVAL; - return -1; - } - - if (ioctl(ctl->fd, SIOCGIFMTU,&ifr)) - return -1; + if (ioctl(fd, SIOCGIFMTU,&ifr)< 0) + goto cleanup;
- return ifr.ifr_mtu; + ret = ifr.ifr_mtu;
+cleanup: + VIR_FORCE_CLOSE(fd); + return ret; }
/** * ifSetMtu: - * @ctl: bridge control pointer * @ifname: interface name to set MTU for * @mtu: MTU value * @@ -354,42 +361,47 @@ static int ifGetMtu(brControl *ctl, const char *ifname) * * Returns 0 in case of success or an errno code in case of failure. */ -static int ifSetMtu(brControl *ctl, const char *ifname, int mtu) +static int ifSetMtu(const char *ifname, int mtu) { + int fd = -1; + int ret = -1; struct ifreq ifr;
- if (!ctl || !ifname) - return EINVAL; - - memset(&ifr, 0, sizeof(struct ifreq)); + if ((fd = brSetupControl(ifname,&ifr))< 0) + return errno;
- if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) - return EINVAL; ifr.ifr_mtu = mtu;
- return ioctl(ctl->fd, SIOCSIFMTU,&ifr) == 0 ? 0 : errno; + if (ioctl(fd, SIOCSIFMTU,&ifr)< 0) { + ret = errno; + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; }
/** * brSetInterfaceMtu - * @ctl: bridge control pointer - * @bridge: name of the bridge interface + * @brname: name of the bridge interface * @ifname: name of the interface whose MTU we want to set * * Sets the interface mtu to the same MTU of the bridge * * Returns 0 in case of success or an errno code in case of failure. */ -static int brSetInterfaceMtu(brControl *ctl, - const char *bridge, +static int brSetInterfaceMtu(const char *brname, const char *ifname) { - int mtu = ifGetMtu(ctl, bridge); + int mtu = ifGetMtu(brname);
if (mtu< 0) return errno;
- return ifSetMtu(ctl, ifname, mtu); + return ifSetMtu(ifname, mtu); }
/** @@ -453,8 +465,7 @@ brProbeVnetHdr(int tapfd)
/** * brAddTap: - * @ctl: bridge control pointer - * @bridge: the bridge name + * @brname: the bridge name * @ifname: the interface name (or name template) * @macaddr: desired MAC address (VIR_MAC_BUFLEN long) * @vnet_hdr: whether to try enabling IFF_VNET_HDR @@ -471,18 +482,14 @@ brProbeVnetHdr(int tapfd) * Returns 0 in case of success or an errno code in case of failure. */ int -brAddTap(brControl *ctl, - const char *bridge, +brAddTap(const char *brname, char **ifname, const unsigned char *macaddr, int vnet_hdr, bool up, int *tapfd) { - if (!ctl || !ctl->fd || !bridge || !ifname) - return EINVAL; - - errno = brCreateTap(ctl, ifname, vnet_hdr, tapfd); + errno = brCreateTap(ifname, vnet_hdr, tapfd);
/* fd has been closed in brCreateTap() when it failed. */ if (errno) @@ -494,18 +501,19 @@ brAddTap(brControl *ctl, * seeing the kernel allocate random MAC for the TAP * device before we set our static MAC. */ - if ((errno = brSetInterfaceMac(ctl, *ifname, macaddr))) + if ((errno = brSetInterfaceMac(*ifname, macaddr))) goto close_fd; /* We need to set the interface MTU before adding it * to the bridge, because the bridge will have its * MTU adjusted automatically when we add the new interface. */ - if ((errno = brSetInterfaceMtu(ctl, bridge, *ifname))) + if ((errno = brSetInterfaceMtu(brname, *ifname))) goto close_fd; - if ((errno = brAddInterface(ctl, bridge, *ifname))) + if ((errno = brAddInterface(brname, *ifname))) goto close_fd; - if (up&& ((errno = brSetInterfaceUp(ctl, *ifname, 1)))) + if (up&& ((errno = brSetInterfaceUp(*ifname, 1)))) goto close_fd; + return 0;
close_fd: @@ -515,15 +523,11 @@ error: return errno; }
-int brDeleteTap(brControl *ctl, - const char *ifname) +int brDeleteTap(const char *ifname) { struct ifreq try; int fd;
- if (!ctl || !ctl->fd || !ifname) - return EINVAL; - if ((fd = open("/dev/net/tun", O_RDWR))< 0) return errno;
@@ -549,7 +553,6 @@ int brDeleteTap(brControl *ctl,
/** * brSetInterfaceUp: - * @ctl: bridge control pointer * @ifname: the interface name * @up: 1 for up, 0 for down * @@ -558,39 +561,44 @@ int brDeleteTap(brControl *ctl, * Returns 0 in case of success or an errno code in case of failure. */ int -brSetInterfaceUp(brControl *ctl, - const char *ifname, +brSetInterfaceUp(const char *ifname, int up) { + int fd = -1; + int ret = -1; struct ifreq ifr; int ifflags;
- if (!ctl || !ifname) - return EINVAL; - - memset(&ifr, 0, sizeof(struct ifreq)); - - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) - return EINVAL; - - if (ioctl(ctl->fd, SIOCGIFFLAGS,&ifr)< 0) + if ((fd = brSetupControl(ifname,&ifr))< 0) return errno;
- ifflags = up ? (ifr.ifr_flags | IFF_UP) : (ifr.ifr_flags& ~IFF_UP); + if (ioctl(fd, SIOCGIFFLAGS,&ifr)< 0) { + ret = errno; + goto cleanup; + } + + if (up) + ifflags = ifr.ifr_flags | IFF_UP; + else + ifflags = ifr.ifr_flags& ~IFF_UP;
if (ifr.ifr_flags != ifflags) { ifr.ifr_flags = ifflags; - - if (ioctl(ctl->fd, SIOCSIFFLAGS,&ifr)< 0) - return errno; + if (ioctl(fd, SIOCSIFFLAGS,&ifr)< 0) { + ret = errno; + goto cleanup; + } }
- return 0; + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; }
/** * brGetInterfaceUp: - * @ctl: bridge control pointer * @ifname: the interface name * @up: where to store the status * @@ -599,31 +607,31 @@ brSetInterfaceUp(brControl *ctl, * Returns 0 in case of success or an errno code in case of failure. */ int -brGetInterfaceUp(brControl *ctl, - const char *ifname, +brGetInterfaceUp(const char *ifname, int *up) { + int fd = -1; + int ret = -1; struct ifreq ifr;
- if (!ctl || !ifname || !up) - return EINVAL; - - memset(&ifr, 0, sizeof(struct ifreq)); - - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) - return EINVAL; - - if (ioctl(ctl->fd, SIOCGIFFLAGS,&ifr)< 0) + if ((fd = brSetupControl(ifname,&ifr))< 0) return errno;
+ if (ioctl(fd, SIOCGIFFLAGS,&ifr)< 0) { + ret = errno; + goto cleanup; + } + *up = (ifr.ifr_flags& IFF_UP) ? 1 : 0; + ret = 0;
- return 0; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; }
/** * brAddInetAddress: - * @ctl: bridge control pointer * @ifname: the interface name * @addr: the IP address (IPv4 or IPv6) * @prefix: number of 1 bits in the netmask @@ -636,8 +644,7 @@ brGetInterfaceUp(brControl *ctl, */
int -brAddInetAddress(brControl *ctl ATTRIBUTE_UNUSED, - const char *ifname, +brAddInetAddress(const char *ifname, virSocketAddr *addr, unsigned int prefix) { @@ -674,7 +681,6 @@ cleanup:
/** * brDelInetAddress: - * @ctl: bridge control pointer * @ifname: the interface name * @addr: the IP address (IPv4 or IPv6) * @prefix: number of 1 bits in the netmask @@ -685,8 +691,7 @@ cleanup: */
int -brDelInetAddress(brControl *ctl ATTRIBUTE_UNUSED, - const char *ifname, +brDelInetAddress(const char *ifname, virSocketAddr *addr, unsigned int prefix) { @@ -713,8 +718,7 @@ cleanup:
/** * brSetForwardDelay: - * @ctl: bridge control pointer - * @bridge: the bridge name + * @brname: the bridge name * @delay: delay in seconds * * Set the bridge forward delay @@ -723,15 +727,14 @@ cleanup: */
int -brSetForwardDelay(brControl *ctl ATTRIBUTE_UNUSED, - const char *bridge, +brSetForwardDelay(const char *brname, int delay) { virCommandPtr cmd; int ret = -1;
cmd = virCommandNew(BRCTL); - virCommandAddArgList(cmd, "setfd", bridge, NULL); + virCommandAddArgList(cmd, "setfd", brname, NULL); virCommandAddArgFormat(cmd, "%d", delay);
if (virCommandRun(cmd, NULL)< 0) @@ -745,8 +748,7 @@ cleanup:
/** * brSetEnableSTP: - * @ctl: bridge control pointer - * @bridge: the bridge name + * @brname: the bridge name * @enable: 1 to enable, 0 to disable * * Control whether the bridge participates in the spanning tree protocol, @@ -755,15 +757,14 @@ cleanup: * Returns 0 in case of success or -1 on failure */ int -brSetEnableSTP(brControl *ctl ATTRIBUTE_UNUSED, - const char *bridge, +brSetEnableSTP(const char *brname, int enable) { virCommandPtr cmd; int ret = -1;
cmd = virCommandNew(BRCTL); - virCommandAddArgList(cmd, "stp", bridge, + virCommandAddArgList(cmd, "stp", brname, enable ? "on" : "off", NULL);
@@ -778,7 +779,6 @@ cleanup:
/** * brCreateTap: - * @ctl: bridge control pointer * @ifname: the interface name * @vnet_hr: whether to try enabling IFF_VNET_HDR * @tapfd: file descriptor return value for the new tap device @@ -793,17 +793,13 @@ cleanup: */
int -brCreateTap(brControl *ctl ATTRIBUTE_UNUSED, - char **ifname, +brCreateTap(char **ifname, int vnet_hdr ATTRIBUTE_UNUSED, int *tapfd) { int fd; struct ifreq ifr;
- if (!ifname) - return EINVAL; - if ((fd = open("/dev/net/tun", O_RDWR))< 0) return errno;
diff --git a/src/util/bridge.h b/src/util/bridge.h index c462a08..2bfc4b4 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -42,78 +42,76 @@ */ # define BR_INET_ADDR_MAXLEN INET_ADDRSTRLEN
-typedef struct _brControl brControl; +int brAddBridge (const char *brname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int brDeleteBridge (const char *brname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int brHasBridge (const char *brname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
-int brInit (brControl **ctl); -void brShutdown (brControl *ctl); +int brAddInterface (const char *brname, + const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
-int brAddBridge (brControl *ctl, - const char *name); -int brDeleteBridge (brControl *ctl, - const char *name); -int brHasBridge (brControl *ctl, - const char *name); - -int brAddInterface (brControl *ctl, - const char *bridge, - const char *iface); -int brDeleteInterface (brControl *ctl, - const char *bridge, - const char *iface); +int brDeleteInterface (const char *brname, + const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
enum { BR_TAP_VNET_HDR = (1<< 0), BR_TAP_PERSIST = (1<< 1), };
-int brAddTap (brControl *ctl, - const char *bridge, +int brAddTap (const char *brname, char **ifname, const unsigned char *macaddr, int vnet_hdr, bool up, - int *tapfd); + int *tapfd) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_RETURN_CHECK; +
-int brDeleteTap (brControl *ctl, - const char *ifname); +int brDeleteTap (const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
-int brSetInterfaceUp (brControl *ctl, - const char *ifname, - int up); -int brGetInterfaceUp (brControl *ctl, - const char *ifname, - int *up); +int brSetInterfaceUp (const char *ifname, + int up) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int brGetInterfaceUp (const char *ifname, + int *up) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
-int brAddInetAddress (brControl *ctl, - const char *ifname, +int brAddInetAddress (const char *ifname, virSocketAddr *addr, - unsigned int prefix); -int brDelInetAddress (brControl *ctl, - const char *ifname, + unsigned int prefix) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int brDelInetAddress (const char *ifname, virSocketAddr *addr, - unsigned int prefix); - -int brSetForwardDelay (brControl *ctl, - const char *bridge, - int delay); -int brGetForwardDelay (brControl *ctl, - const char *bridge, - int *delay); -int brSetEnableSTP (brControl *ctl, - const char *bridge, - int enable); -int brGetEnableSTP (brControl *ctl, - const char *bridge, - int *enable); - -int brCreateTap (brControl *ctl, - char **ifname, + unsigned int prefix) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int brSetForwardDelay (const char *brname, + int delay) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int brGetForwardDelay (const char *brname, + int *delay) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int brSetEnableSTP (const char *brname, + int enable) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int brGetEnableSTP (const char *brname, + int *enable) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int brCreateTap (char **ifname, int vnet_hdr, - int *tapfd); + int *tapfd) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
-int brSetInterfaceMac (brControl *ctl, - const char *ifname, - const unsigned char *macaddr); +int brSetInterfaceMac (const char *ifname, + const unsigned char *macaddr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
# endif /* WITH_BRIDGE */

From: "Daniel P. Berrange" <berrange@redhat.com> Currently every caller of the brXXX APIs has to store the returned errno value and then raise an error message. This results in inconsistent error messages across drivers, additional burden on the callers and makes the error reporting inaccurate since it is hard to distinguish different scenarios from 1 errno value. * src/util/bridge.c: Raise errors instead of returning errnos * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/uml/uml_conf.c, src/uml/uml_driver.c: Remove error reporting code --- po/POTFILES.in | 1 + src/lxc/lxc_driver.c | 7 +- src/network/bridge_driver.c | 78 +++----------- src/qemu/qemu_command.c | 23 +---- src/uml/uml_conf.c | 28 +----- src/uml/uml_driver.c | 14 +-- src/util/bridge.c | 262 +++++++++++++++++++++++++++++-------------- 7 files changed, 196 insertions(+), 217 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 5ce35ae..bd1d7bd 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -102,6 +102,7 @@ src/test/test_driver.c src/uml/uml_conf.c src/uml/uml_driver.c src/util/authhelper.c +src/util/bridge.c src/util/cgroup.c src/util/command.c src/util/conf.c diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 2505efc..8ee1306 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1194,7 +1194,6 @@ static int lxcSetupInterfaces(virConnectPtr conn, { int rc = -1, i; char *bridge = NULL; - int ret; for (i = 0 ; i < def->nnets ; i++) { char *parentVeth; @@ -1270,12 +1269,8 @@ static int lxcSetupInterfaces(virConnectPtr conn, goto error_exit; } - if ((ret = brAddInterface(bridge, parentVeth)) != 0) { - virReportSystemError(ret, - _("Failed to add %s device to %s"), - parentVeth, bridge); + if (brAddInterface(bridge, parentVeth) < 0) goto error_exit; - } if (vethInterfaceUpOrDown(parentVeth, 1) < 0) goto error_exit; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 053acfd..d5d2472 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -1678,12 +1678,8 @@ networkAddAddrToBridge(virNetworkObjPtr network, } if (brAddInetAddress(network->def->bridge, - &ipdef->address, prefix) < 0) { - networkReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot set IP address on bridge '%s'"), - network->def->bridge); + &ipdef->address, prefix) < 0) return -1; - } return 0; } @@ -1692,7 +1688,7 @@ static int networkStartNetworkVirtual(struct network_driver *driver, virNetworkObjPtr network) { - int ii, err; + int ii; bool v4present = false, v6present = false; virErrorPtr save_err = NULL; virNetworkIpDefPtr ipdef; @@ -1703,12 +1699,8 @@ networkStartNetworkVirtual(struct network_driver *driver, return -1; /* Create and configure the bridge device */ - if ((err = brAddBridge(network->def->bridge))) { - virReportSystemError(err, - _("cannot create bridge '%s'"), - network->def->bridge); + if (brAddBridge(network->def->bridge) < 0) return -1; - } if (network->def->mac_specified) { /* To set a mac for the bridge, we need to define a dummy tap @@ -1722,12 +1714,8 @@ networkStartNetworkVirtual(struct network_driver *driver, virReportOOMError(); goto err0; } - if ((err = brAddTap(network->def->bridge, - &macTapIfName, network->def->mac, 0, false, NULL))) { - virReportSystemError(err, - _("cannot create dummy tap device '%s' to set mac" - " address on bridge '%s'"), - macTapIfName, network->def->bridge); + if (brAddTap(network->def->bridge, + &macTapIfName, network->def->mac, 0, false, NULL) < 0) { VIR_FREE(macTapIfName); goto err0; } @@ -1735,20 +1723,12 @@ networkStartNetworkVirtual(struct network_driver *driver, /* Set bridge options */ if (brSetForwardDelay(network->def->bridge, - network->def->delay)) { - networkReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot set forward delay on bridge '%s'"), - network->def->bridge); + network->def->delay) < 0) goto err1; - } if (brSetEnableSTP(network->def->bridge, - network->def->stp ? 1 : 0)) { - networkReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot set STP '%s' on bridge '%s'"), - network->def->stp ? "on" : "off", network->def->bridge); + network->def->stp ? 1 : 0) < 0) goto err1; - } /* Disable IPv6 on the bridge if there are no IPv6 addresses * defined, and set other IPv6 sysctl tunables appropriately. @@ -1775,12 +1755,8 @@ networkStartNetworkVirtual(struct network_driver *driver, } /* Bring up the bridge interface */ - if ((err = brSetInterfaceUp(network->def->bridge, 1))) { - virReportSystemError(err, - _("failed to bring the bridge '%s' up"), - network->def->bridge); + if (brSetInterfaceUp(network->def->bridge, 1) < 0) goto err2; - } /* If forwardType != NONE, turn on global IP forwarding */ if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE && @@ -1828,11 +1804,7 @@ networkStartNetworkVirtual(struct network_driver *driver, err3: if (!save_err) save_err = virSaveLastError(); - if ((err = brSetInterfaceUp(network->def->bridge, 0))) { - char ebuf[1024]; - VIR_WARN("Failed to bring down bridge '%s' : %s", - network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); - } + ignore_value(brSetInterfaceUp(network->def->bridge, 0)); err2: if (!save_err) @@ -1843,22 +1815,13 @@ networkStartNetworkVirtual(struct network_driver *driver, if (!save_err) save_err = virSaveLastError(); - if ((err = brDeleteTap(macTapIfName))) { - char ebuf[1024]; - VIR_WARN("Failed to delete dummy tap device '%s' on bridge '%s' : %s", - macTapIfName, network->def->bridge, - virStrerror(err, ebuf, sizeof ebuf)); - } + ignore_value(brDeleteTap(macTapIfName)); VIR_FREE(macTapIfName); err0: if (!save_err) save_err = virSaveLastError(); - if ((err = brDeleteBridge(network->def->bridge))) { - char ebuf[1024]; - VIR_WARN("Failed to delete bridge '%s' : %s", - network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); - } + ignore_value(brDeleteBridge(network->def->bridge)); if (save_err) { virSetError(save_err); @@ -1870,9 +1833,6 @@ networkStartNetworkVirtual(struct network_driver *driver, static int networkShutdownNetworkVirtual(struct network_driver *driver, virNetworkObjPtr network) { - int err; - char ebuf[1024]; - if (virBandwidthDisable(network->def->bridge, true) < 0) { VIR_WARN("Failed to disable QoS on %s", network->def->name); @@ -1899,26 +1859,16 @@ static int networkShutdownNetworkVirtual(struct network_driver *driver, if (!macTapIfName) { virReportOOMError(); } else { - if ((err = brDeleteTap(macTapIfName))) { - VIR_WARN("Failed to delete dummy tap device '%s' on bridge '%s' : %s", - macTapIfName, network->def->bridge, - virStrerror(err, ebuf, sizeof ebuf)); - } + ignore_value(brDeleteTap(macTapIfName)); VIR_FREE(macTapIfName); } } - if ((err = brSetInterfaceUp(network->def->bridge, 0))) { - VIR_WARN("Failed to bring down bridge '%s' : %s", - network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); - } + ignore_value(brSetInterfaceUp(network->def->bridge, 0)); networkRemoveIptablesRules(driver, network); - if ((err = brDeleteBridge(network->def->bridge))) { - VIR_WARN("Failed to delete bridge '%s' : %s", - network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); - } + ignore_value(brDeleteBridge(network->def->bridge)); /* See if its still alive and really really kill it */ if (network->dnsmasqPid > 0 && diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ee18858..6fbdc20 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -282,28 +282,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def, err = brAddTap(brname, &net->ifname, tapmac, vnet_hdr, true, &tapfd); virDomainAuditNetDevice(def, net, "/dev/net/tun", tapfd >= 0); - if (err) { - if (err == ENOTSUP) { - /* In this particular case, give a better diagnostic. */ - qemuReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to add tap interface to bridge. " - "%s is not a bridge device"), brname); - } else if (err == ENOENT) { - /* When the tun drive is missing, give a better message. */ - qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Failed to add tap interface to bridge. " - "Your kernel is missing the 'tun' module or " - "CONFIG_TUN, or you need to add the " - "/dev/net/tun device node.")); - } else if (template_ifname) { - virReportSystemError(err, - _("Failed to add tap interface to bridge '%s'"), - brname); - } else { - virReportSystemError(err, - _("Failed to add tap interface '%s' to bridge '%s'"), - net->ifname, brname); - } + if (err < 0) { if (template_ifname) VIR_FREE(net->ifname); tapfd = -1; diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c index 92d132b..477a178 100644 --- a/src/uml/uml_conf.c +++ b/src/uml/uml_conf.c @@ -122,7 +122,6 @@ umlConnectTapDevice(virConnectPtr conn, const char *bridge) { bool template_ifname = false; - int err; unsigned char tapmac[VIR_MAC_BUFLEN]; if (!net->ifname || @@ -137,31 +136,8 @@ umlConnectTapDevice(virConnectPtr conn, memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ - if ((err = brAddTap(bridge, - &net->ifname, - tapmac, - 0, - true, - NULL))) { - if (err == ENOTSUP) { - /* In this particular case, give a better diagnostic. */ - umlReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to add tap interface to bridge. " - "%s is not a bridge device"), bridge); - } else if (err == ENOENT) { - virReportSystemError(err, "%s", - _("Failed to add tap interface to bridge. Your kernel " - "is missing the 'tun' module or CONFIG_TUN, or you need " - "to add the /dev/net/tun device node.")); - } else if (template_ifname) { - virReportSystemError(err, - _("Failed to add tap interface to bridge '%s'"), - bridge); - } else { - virReportSystemError(err, - _("Failed to add tap interface '%s' to bridge '%s'"), - net->ifname, bridge); - } + if (brAddTap(bridge, &net->ifname, tapmac, + 0, true, NULL) < 0) { if (template_ifname) VIR_FREE(net->ifname); goto error; diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index b87fa60..8ba06a5 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -952,11 +952,8 @@ error: } -static int umlCleanupTapDevices(virDomainObjPtr vm) { +static void umlCleanupTapDevices(virDomainObjPtr vm) { int i; - int err; - int ret = 0; - VIR_ERROR(_("Cleanup tap")); for (i = 0 ; i < vm->def->nnets ; i++) { virDomainNetDefPtr def = vm->def->nets[i]; @@ -965,15 +962,8 @@ static int umlCleanupTapDevices(virDomainObjPtr vm) { def->type != VIR_DOMAIN_NET_TYPE_NETWORK) continue; - VIR_ERROR(_("Cleanup '%s'"), def->ifname); - err = brDeleteTap(def->ifname); - if (err) { - VIR_ERROR(_("Cleanup failed %d"), err); - ret = -1; - } + ignore_value(brDeleteTap(def->ifname)); } - VIR_ERROR(_("Cleanup tap done")); - return ret; } static int umlStartVMDaemon(virConnectPtr conn, diff --git a/src/util/bridge.c b/src/util/bridge.c index ae1d601..351e482 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -51,10 +51,12 @@ # include "util.h" # include "logging.h" # include "network.h" +# include "virterror_internal.h" # define JIFFIES_TO_MS(j) (((j)*1000)/HZ) # define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000) +# define VIR_FROM_THIS VIR_FROM_NONE static int brSetupControlFull(const char *ifname, struct ifreq *ifr, @@ -67,15 +69,22 @@ static int brSetupControlFull(const char *ifname, memset(ifr, 0, sizeof(*ifr)); if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) { - errno = EINVAL; + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + ifname); return -1; } } - if ((fd = socket(domain, type, 0)) < 0) + if ((fd = socket(domain, type, 0)) < 0) { + virReportSystemError(errno, "%s", + _("Cannot open network interface control socket")); return -1; + } if (virSetInherit(fd, false) < 0) { + virReportSystemError(errno, "%s", + _("Cannot set close-on-exec flag for socket")); VIR_FORCE_CLOSE(fd); return -1; } @@ -97,7 +106,7 @@ static int brSetupControl(const char *ifname, * * This function register a new bridge * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success or -1 on failure */ # ifdef SIOCBRADDBR int @@ -107,10 +116,11 @@ brAddBridge(const char *brname) int ret = -1; if ((fd = brSetupControl(NULL, NULL)) < 0) - return errno; + return -1; if (ioctl(fd, SIOCBRADDBR, brname) < 0) { - ret = errno; + virReportSystemError(errno, + _("Unable to create bridge %s"), brname); goto cleanup; } @@ -121,13 +131,23 @@ cleanup: return ret; } # else -int brAddBridge (const char *brname ATTRIBUTE_UNUSED) +int brAddBridge(const char *brname) { - return EINVAL; + virReportSystemError(ENOSYS, + _("Unable to create bridge %s"), brname); + return -1; } # endif # ifdef SIOCBRDELBR +/** + * brHasBridge: + * @brname + * + * Check if the bridge @brname exists + * + * Returns 1 if it exists, 0 if it does not, -1 on error + */ int brHasBridge(const char *brname) { @@ -136,12 +156,18 @@ brHasBridge(const char *brname) struct ifreq ifr; if ((fd = brSetupControl(brname, &ifr)) < 0) - return errno; + return -1; - if (ioctl(fd, SIOCGIFFLAGS, &ifr)) + if (ioctl(fd, SIOCGIFFLAGS, &ifr)) { + if (errno == ENODEV) + ret = 0; + else + virReportSystemError(errno, + _("Unable to delete bridge %s"), brname); goto cleanup; + } - ret = 0; + ret = 1; cleanup: VIR_FORCE_CLOSE(fd); @@ -149,9 +175,11 @@ cleanup: } # else int -brHasBridge(const char *brname ATTRIBUTE_UNUSED) +brHasBridge(const char *brname) { - return EINVAL; + virReportSystemError(errno, + _("Unable to check bridge %s"), brname); + return -1; } # endif @@ -171,10 +199,11 @@ brDeleteBridge(const char *brname) int ret = -1; if ((fd = brSetupControl(NULL, NULL)) < 0) - return errno; + return -1; if (ioctl(fd, SIOCBRDELBR, brname) < 0) { - ret = errno; + virReportSystemError(errno, + _("Unable to delete bridge %s"), brname); goto cleanup; } @@ -188,6 +217,8 @@ cleanup: int brDeleteBridge(const char *brname ATTRIBUTE_UNUSED) { + virReportSystemError(errno, + _("Unable to delete bridge %s"), brname); return EINVAL; } # endif @@ -211,15 +242,17 @@ brAddInterface(const char *brname, struct ifreq ifr; if ((fd = brSetupControl(brname, &ifr)) < 0) - return errno; + return -1; if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { - ret = errno; + virReportSystemError(errno, + _("Unable to get interface index for %s"), ifname); goto cleanup; } if (ioctl(fd, SIOCBRADDIF, &ifr) < 0) { - ret = errno; + virReportSystemError(errno, + _("Unable to add bridge %s port %s"), brname, ifname); goto cleanup; } @@ -230,10 +263,12 @@ cleanup: } # else int -brAddInterface(const char *brname ATTRIBUTE_UNUSED, - const char *ifname ATTRIBUTE_UNUSED) +brAddInterface(const char *brname, + const char *ifname) { - return EINVAL; + virReportSystemError(ENOSYS, + _("Unable to add bridge %s port %s"), brname, ifname); + return -1; } # endif @@ -256,15 +291,18 @@ brDeleteInterface(const char *brname, struct ifreq ifr; if ((fd = brSetupControl(brname, &ifr)) < 0) - return errno; + return -1; if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { - ret = errno; + virReportSystemError(errno, + _("Unable to get interface index for %s"), ifname); + goto cleanup; } if (ioctl(fd, SIOCBRDELIF, &ifr) < 0) { - ret = errno; + virReportSystemError(errno, + _("Unable to remove bridge %s port %s"), brname, ifname); goto cleanup; } @@ -275,10 +313,12 @@ cleanup: } # else int -brDeleteInterface(const char *brname ATTRIBUTE_UNUSED, - const char *ifname ATTRIBUTE_UNUSED) +brDeleteInterface(const char *brname, + const char *ifname) { - return EINVAL; + virReportSystemError(errno, + _("Unable to remove bridge %s port %s"), brname, ifname); + return -1; } # endif @@ -290,7 +330,7 @@ brDeleteInterface(const char *brname ATTRIBUTE_UNUSED, * This function sets the @macaddr for a given interface @ifname. This * gets rid of the kernel's automatically assigned random MAC. * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success or -1 on failure */ int brSetInterfaceMac(const char *ifname, @@ -301,18 +341,22 @@ brSetInterfaceMac(const char *ifname, struct ifreq ifr; if ((fd = brSetupControl(ifname, &ifr)) < 0) - return errno; + return -1; /* To fill ifr.ifr_hdaddr.sa_family field */ if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { - ret = errno; + virReportSystemError(errno, + _("Cannot get interface MAC on '%s'"), + ifname); goto cleanup; } memcpy(ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN); if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) { - ret = errno; + virReportSystemError(errno, + _("Cannot set interface MAC on '%s'"), + ifname); goto cleanup; } @@ -329,8 +373,7 @@ cleanup: * * This function gets the @mtu value set for a given interface @ifname. * - * Returns the MTU value in case of success. - * On error, returns -1 and sets errno accordingly + * Returns the MTU value in case of success, or -1 on failure. */ static int ifGetMtu(const char *ifname) { @@ -341,8 +384,12 @@ static int ifGetMtu(const char *ifname) if ((fd = brSetupControl(ifname, &ifr)) < 0) return -1; - if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) + if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { + virReportSystemError(errno, + _("Cannot get interface MTU on '%s'"), + ifname); goto cleanup; + } ret = ifr.ifr_mtu; @@ -359,7 +406,7 @@ cleanup: * This function sets the @mtu for a given interface @ifname. Typically * used on a tap device to set up for Jumbo Frames. * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success, or -1 on failure */ static int ifSetMtu(const char *ifname, int mtu) { @@ -368,12 +415,14 @@ static int ifSetMtu(const char *ifname, int mtu) struct ifreq ifr; if ((fd = brSetupControl(ifname, &ifr)) < 0) - return errno; + return -1; ifr.ifr_mtu = mtu; if (ioctl(fd, SIOCSIFMTU, &ifr) < 0) { - ret = errno; + virReportSystemError(errno, + _("Cannot set interface MTU on '%s'"), + ifname); goto cleanup; } @@ -391,7 +440,7 @@ cleanup: * * Sets the interface mtu to the same MTU of the bridge * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success, or -1 on failure */ static int brSetInterfaceMtu(const char *brname, const char *ifname) @@ -399,7 +448,7 @@ static int brSetInterfaceMtu(const char *brname, int mtu = ifGetMtu(brname); if (mtu < 0) - return errno; + return -1; return ifSetMtu(ifname, mtu); } @@ -421,7 +470,7 @@ static int brSetInterfaceMtu(const char *brname, * kernel implements the TUNGETIFF ioctl(), which qemu needs to query * the supplied tapfd. * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 1 if VnetHdr is supported, 0 if not supported */ # ifdef IFF_VNET_HDR static int @@ -479,7 +528,7 @@ brProbeVnetHdr(int tapfd) * persistent and closed. The caller must use brDeleteTap to remove * a persistent TAP devices when it is no longer needed. * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success or -1 on failure */ int brAddTap(const char *brname, @@ -489,11 +538,8 @@ brAddTap(const char *brname, bool up, int *tapfd) { - errno = brCreateTap(ifname, vnet_hdr, tapfd); - - /* fd has been closed in brCreateTap() when it failed. */ - if (errno) - goto error; + if (brCreateTap(ifname, vnet_hdr, tapfd) < 0) + return -1; /* We need to set the interface MAC before adding it * to the bridge, because the bridge assumes the lowest @@ -501,53 +547,69 @@ brAddTap(const char *brname, * seeing the kernel allocate random MAC for the TAP * device before we set our static MAC. */ - if ((errno = brSetInterfaceMac(*ifname, macaddr))) - goto close_fd; + if (brSetInterfaceMac(*ifname, macaddr) < 0) + goto error; + /* We need to set the interface MTU before adding it * to the bridge, because the bridge will have its * MTU adjusted automatically when we add the new interface. */ - if ((errno = brSetInterfaceMtu(brname, *ifname))) - goto close_fd; - if ((errno = brAddInterface(brname, *ifname))) - goto close_fd; - if (up && ((errno = brSetInterfaceUp(*ifname, 1)))) - goto close_fd; + if (brSetInterfaceMtu(brname, *ifname) < 0) + goto error; + + if (brAddInterface(brname, *ifname) < 0) + goto error; + + if (brSetInterfaceUp(*ifname, up) < 0) + goto error; return 0; -close_fd: +error: if (tapfd) VIR_FORCE_CLOSE(*tapfd); -error: - return errno; + return -1; } int brDeleteTap(const char *ifname) { struct ifreq try; int fd; + int ret = -1; - if ((fd = open("/dev/net/tun", O_RDWR)) < 0) - return errno; + if ((fd = open("/dev/net/tun", O_RDWR)) < 0) { + virReportSystemError(errno, "%s", + _("Unable to open /dev/net/tun, is tun module loaded?")); + return -1; + } memset(&try, 0, sizeof(struct ifreq)); try.ifr_flags = IFF_TAP|IFF_NO_PI; if (virStrcpyStatic(try.ifr_name, ifname) == NULL) { - errno = EINVAL; - goto error; + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + ifname); + goto cleanup; } - if (ioctl(fd, TUNSETIFF, &try) == 0) { - if ((errno = ioctl(fd, TUNSETPERSIST, 0))) - goto error; + if (ioctl(fd, TUNSETIFF, &try) < 0) { + virReportSystemError(errno, "%s", + _("Unable to associate TAP device")); + goto cleanup; } - error: - VIR_FORCE_CLOSE(fd); + if (ioctl(fd, TUNSETPERSIST, 0) < 0) { + virReportSystemError(errno, "%s", + _("Unable to make TAP device non-persistent")); + goto cleanup; + } + + ret = 0; - return errno; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; } @@ -558,7 +620,7 @@ int brDeleteTap(const char *ifname) * * Function to control if an interface is activated (up, 1) or not (down, 0) * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success or -1 on error. */ int brSetInterfaceUp(const char *ifname, @@ -570,10 +632,12 @@ brSetInterfaceUp(const char *ifname, int ifflags; if ((fd = brSetupControl(ifname, &ifr)) < 0) - return errno; + return -1; if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { - ret = errno; + virReportSystemError(errno, + _("Cannot get interface flags on '%s'"), + ifname); goto cleanup; } @@ -585,7 +649,9 @@ brSetInterfaceUp(const char *ifname, if (ifr.ifr_flags != ifflags) { ifr.ifr_flags = ifflags; if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { - ret = errno; + virReportSystemError(errno, + _("Cannot set interface flags on '%s'"), + ifname); goto cleanup; } } @@ -615,10 +681,12 @@ brGetInterfaceUp(const char *ifname, struct ifreq ifr; if ((fd = brSetupControl(ifname, &ifr)) < 0) - return errno; + return -1; if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { - ret = errno; + virReportSystemError(errno, + _("Cannot get interface flags on '%s'"), + ifname); goto cleanup; } @@ -799,9 +867,13 @@ brCreateTap(char **ifname, { int fd; struct ifreq ifr; + int ret = -1; - if ((fd = open("/dev/net/tun", O_RDWR)) < 0) - return errno; + if ((fd = open("/dev/net/tun", O_RDWR)) < 0) { + virReportSystemError(errno, "%s", + _("Unable to open /dev/net/tun, is tun module loaded?")); + return -1; + } memset(&ifr, 0, sizeof(ifr)); @@ -813,29 +885,45 @@ brCreateTap(char **ifname, # endif if (virStrcpyStatic(ifr.ifr_name, *ifname) == NULL) { - errno = EINVAL; - goto error; + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + *ifname); + goto cleanup; + } - if (ioctl(fd, TUNSETIFF, &ifr) < 0) - goto error; + if (ioctl(fd, TUNSETIFF, &ifr) < 0) { + virReportSystemError(errno, + _("Unable to create tap device %s"), + NULLSTR(*ifname)); + goto cleanup; + } if (!tapfd && - (errno = ioctl(fd, TUNSETPERSIST, 1))) - goto error; + (errno = ioctl(fd, TUNSETPERSIST, 1))) { + virReportSystemError(errno, + _("Unable to set tap device %s to persistent"), + NULLSTR(*ifname)); + goto cleanup; + } + VIR_FREE(*ifname); - if (!(*ifname = strdup(ifr.ifr_name))) - goto error; - if(tapfd) + if (!(*ifname = strdup(ifr.ifr_name))) { + virReportOOMError(); + goto cleanup; + } + if (tapfd) *tapfd = fd; else VIR_FORCE_CLOSE(fd); - return 0; - error: - VIR_FORCE_CLOSE(fd); + ret = 0; - return errno; +cleanup: + if (ret < 0) + VIR_FORCE_CLOSE(fd); + + return ret; } #endif /* WITH_BRIDGE */ -- 1.7.6.4

On 11/03/2011 01:29 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
Currently every caller of the brXXX APIs has to store the returned errno value and then raise an error message. This results in inconsistent error messages across drivers, additional burden on the callers and makes the error reporting inaccurate since it is hard to distinguish different scenarios from 1 errno value.
* src/util/bridge.c: Raise errors instead of returning errnos * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/uml/uml_conf.c, src/uml/uml_driver.c: Remove error reporting code --- po/POTFILES.in | 1 + src/lxc/lxc_driver.c | 7 +- src/network/bridge_driver.c | 78 +++----------- src/qemu/qemu_command.c | 23 +---- src/uml/uml_conf.c | 28 +----- src/uml/uml_driver.c | 14 +-- src/util/bridge.c | 262 +++++++++++++++++++++++++++++-------------- 7 files changed, 196 insertions(+), 217 deletions(-)
diff --git a/po/POTFILES.in b/po/POTFILES.in index 5ce35ae..bd1d7bd 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -102,6 +102,7 @@ src/test/test_driver.c src/uml/uml_conf.c src/uml/uml_driver.c src/util/authhelper.c +src/util/bridge.c src/util/cgroup.c src/util/command.c src/util/conf.c diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 2505efc..8ee1306 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1194,7 +1194,6 @@ static int lxcSetupInterfaces(virConnectPtr conn, { int rc = -1, i; char *bridge = NULL; - int ret;
for (i = 0 ; i< def->nnets ; i++) { char *parentVeth; @@ -1270,12 +1269,8 @@ static int lxcSetupInterfaces(virConnectPtr conn, goto error_exit; }
- if ((ret = brAddInterface(bridge, parentVeth)) != 0) { - virReportSystemError(ret, - _("Failed to add %s device to %s"), - parentVeth, bridge); + if (brAddInterface(bridge, parentVeth)< 0) goto error_exit; - }
if (vethInterfaceUpOrDown(parentVeth, 1)< 0) goto error_exit; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 053acfd..d5d2472 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -1678,12 +1678,8 @@ networkAddAddrToBridge(virNetworkObjPtr network, }
if (brAddInetAddress(network->def->bridge, -&ipdef->address, prefix)< 0) { - networkReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot set IP address on bridge '%s'"), - network->def->bridge); +&ipdef->address, prefix)< 0) return -1; - }
return 0; } @@ -1692,7 +1688,7 @@ static int networkStartNetworkVirtual(struct network_driver *driver, virNetworkObjPtr network) { - int ii, err; + int ii; bool v4present = false, v6present = false; virErrorPtr save_err = NULL; virNetworkIpDefPtr ipdef; @@ -1703,12 +1699,8 @@ networkStartNetworkVirtual(struct network_driver *driver, return -1;
/* Create and configure the bridge device */ - if ((err = brAddBridge(network->def->bridge))) { - virReportSystemError(err, - _("cannot create bridge '%s'"), - network->def->bridge); + if (brAddBridge(network->def->bridge)< 0) return -1; - }
if (network->def->mac_specified) { /* To set a mac for the bridge, we need to define a dummy tap @@ -1722,12 +1714,8 @@ networkStartNetworkVirtual(struct network_driver *driver, virReportOOMError(); goto err0; } - if ((err = brAddTap(network->def->bridge, -&macTapIfName, network->def->mac, 0, false, NULL))) { - virReportSystemError(err, - _("cannot create dummy tap device '%s' to set mac" - " address on bridge '%s'"), - macTapIfName, network->def->bridge); + if (brAddTap(network->def->bridge, +&macTapIfName, network->def->mac, 0, false, NULL)< 0) { VIR_FREE(macTapIfName); goto err0; } @@ -1735,20 +1723,12 @@ networkStartNetworkVirtual(struct network_driver *driver,
/* Set bridge options */ if (brSetForwardDelay(network->def->bridge, - network->def->delay)) { - networkReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot set forward delay on bridge '%s'"), - network->def->bridge); + network->def->delay)< 0) goto err1; - }
if (brSetEnableSTP(network->def->bridge, - network->def->stp ? 1 : 0)) { - networkReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot set STP '%s' on bridge '%s'"), - network->def->stp ? "on" : "off", network->def->bridge); + network->def->stp ? 1 : 0)< 0) goto err1; - }
/* Disable IPv6 on the bridge if there are no IPv6 addresses * defined, and set other IPv6 sysctl tunables appropriately. @@ -1775,12 +1755,8 @@ networkStartNetworkVirtual(struct network_driver *driver, }
/* Bring up the bridge interface */ - if ((err = brSetInterfaceUp(network->def->bridge, 1))) { - virReportSystemError(err, - _("failed to bring the bridge '%s' up"), - network->def->bridge); + if (brSetInterfaceUp(network->def->bridge, 1)< 0) goto err2; - }
/* If forwardType != NONE, turn on global IP forwarding */ if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE&& @@ -1828,11 +1804,7 @@ networkStartNetworkVirtual(struct network_driver *driver, err3: if (!save_err) save_err = virSaveLastError(); - if ((err = brSetInterfaceUp(network->def->bridge, 0))) { - char ebuf[1024]; - VIR_WARN("Failed to bring down bridge '%s' : %s", - network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); - } + ignore_value(brSetInterfaceUp(network->def->bridge, 0));
err2: if (!save_err) @@ -1843,22 +1815,13 @@ networkStartNetworkVirtual(struct network_driver *driver, if (!save_err) save_err = virSaveLastError();
- if ((err = brDeleteTap(macTapIfName))) { - char ebuf[1024]; - VIR_WARN("Failed to delete dummy tap device '%s' on bridge '%s' : %s", - macTapIfName, network->def->bridge, - virStrerror(err, ebuf, sizeof ebuf)); - } + ignore_value(brDeleteTap(macTapIfName)); VIR_FREE(macTapIfName);
err0: if (!save_err) save_err = virSaveLastError(); - if ((err = brDeleteBridge(network->def->bridge))) { - char ebuf[1024]; - VIR_WARN("Failed to delete bridge '%s' : %s", - network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); - } + ignore_value(brDeleteBridge(network->def->bridge));
if (save_err) { virSetError(save_err); @@ -1870,9 +1833,6 @@ networkStartNetworkVirtual(struct network_driver *driver, static int networkShutdownNetworkVirtual(struct network_driver *driver, virNetworkObjPtr network) { - int err; - char ebuf[1024]; - if (virBandwidthDisable(network->def->bridge, true)< 0) { VIR_WARN("Failed to disable QoS on %s", network->def->name); @@ -1899,26 +1859,16 @@ static int networkShutdownNetworkVirtual(struct network_driver *driver, if (!macTapIfName) { virReportOOMError(); } else { - if ((err = brDeleteTap(macTapIfName))) { - VIR_WARN("Failed to delete dummy tap device '%s' on bridge '%s' : %s", - macTapIfName, network->def->bridge, - virStrerror(err, ebuf, sizeof ebuf)); - } + ignore_value(brDeleteTap(macTapIfName)); VIR_FREE(macTapIfName); } }
- if ((err = brSetInterfaceUp(network->def->bridge, 0))) { - VIR_WARN("Failed to bring down bridge '%s' : %s", - network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); - } + ignore_value(brSetInterfaceUp(network->def->bridge, 0));
networkRemoveIptablesRules(driver, network);
- if ((err = brDeleteBridge(network->def->bridge))) { - VIR_WARN("Failed to delete bridge '%s' : %s", - network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); - } + ignore_value(brDeleteBridge(network->def->bridge));
/* See if its still alive and really really kill it */ if (network->dnsmasqPid> 0&& diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ee18858..6fbdc20 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -282,28 +282,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def, err = brAddTap(brname,&net->ifname, tapmac, vnet_hdr, true,&tapfd); virDomainAuditNetDevice(def, net, "/dev/net/tun", tapfd>= 0); - if (err) { - if (err == ENOTSUP) { - /* In this particular case, give a better diagnostic. */ - qemuReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to add tap interface to bridge. " - "%s is not a bridge device"), brname); - } else if (err == ENOENT) { - /* When the tun drive is missing, give a better message. */ - qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Failed to add tap interface to bridge. " - "Your kernel is missing the 'tun' module or " - "CONFIG_TUN, or you need to add the " - "/dev/net/tun device node.")); - } else if (template_ifname) { - virReportSystemError(err, - _("Failed to add tap interface to bridge '%s'"), - brname); - } else { - virReportSystemError(err, - _("Failed to add tap interface '%s' to bridge '%s'"), - net->ifname, brname); - } + if (err< 0) { if (template_ifname) VIR_FREE(net->ifname); tapfd = -1; diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c index 92d132b..477a178 100644 --- a/src/uml/uml_conf.c +++ b/src/uml/uml_conf.c @@ -122,7 +122,6 @@ umlConnectTapDevice(virConnectPtr conn, const char *bridge) { bool template_ifname = false; - int err; unsigned char tapmac[VIR_MAC_BUFLEN];
if (!net->ifname || @@ -137,31 +136,8 @@ umlConnectTapDevice(virConnectPtr conn,
memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ - if ((err = brAddTap(bridge, -&net->ifname, - tapmac, - 0, - true, - NULL))) { - if (err == ENOTSUP) { - /* In this particular case, give a better diagnostic. */ - umlReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to add tap interface to bridge. " - "%s is not a bridge device"), bridge); - } else if (err == ENOENT) { - virReportSystemError(err, "%s", - _("Failed to add tap interface to bridge. Your kernel " - "is missing the 'tun' module or CONFIG_TUN, or you need " - "to add the /dev/net/tun device node.")); - } else if (template_ifname) { - virReportSystemError(err, - _("Failed to add tap interface to bridge '%s'"), - bridge); - } else { - virReportSystemError(err, - _("Failed to add tap interface '%s' to bridge '%s'"), - net->ifname, bridge); - } + if (brAddTap(bridge,&net->ifname, tapmac, + 0, true, NULL)< 0) { if (template_ifname) VIR_FREE(net->ifname); goto error; diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index b87fa60..8ba06a5 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -952,11 +952,8 @@ error: }
-static int umlCleanupTapDevices(virDomainObjPtr vm) { +static void umlCleanupTapDevices(virDomainObjPtr vm) { int i; - int err; - int ret = 0; - VIR_ERROR(_("Cleanup tap"));
for (i = 0 ; i< vm->def->nnets ; i++) { virDomainNetDefPtr def = vm->def->nets[i]; @@ -965,15 +962,8 @@ static int umlCleanupTapDevices(virDomainObjPtr vm) { def->type != VIR_DOMAIN_NET_TYPE_NETWORK) continue;
- VIR_ERROR(_("Cleanup '%s'"), def->ifname); - err = brDeleteTap(def->ifname); - if (err) { - VIR_ERROR(_("Cleanup failed %d"), err); - ret = -1; - } + ignore_value(brDeleteTap(def->ifname)); } - VIR_ERROR(_("Cleanup tap done")); - return ret; }
static int umlStartVMDaemon(virConnectPtr conn, diff --git a/src/util/bridge.c b/src/util/bridge.c index ae1d601..351e482 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -51,10 +51,12 @@ # include "util.h" # include "logging.h" # include "network.h" +# include "virterror_internal.h"
# define JIFFIES_TO_MS(j) (((j)*1000)/HZ) # define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000)
+# define VIR_FROM_THIS VIR_FROM_NONE
static int brSetupControlFull(const char *ifname, struct ifreq *ifr, @@ -67,15 +69,22 @@ static int brSetupControlFull(const char *ifname, memset(ifr, 0, sizeof(*ifr));
if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) { - errno = EINVAL; + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + ifname); return -1; } }
- if ((fd = socket(domain, type, 0))< 0) + if ((fd = socket(domain, type, 0))< 0) { + virReportSystemError(errno, "%s", + _("Cannot open network interface control socket")); return -1; + }
if (virSetInherit(fd, false)< 0) { + virReportSystemError(errno, "%s", + _("Cannot set close-on-exec flag for socket")); VIR_FORCE_CLOSE(fd); return -1; } @@ -97,7 +106,7 @@ static int brSetupControl(const char *ifname, * * This function register a new bridge * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success or -1 on failure */ # ifdef SIOCBRADDBR int @@ -107,10 +116,11 @@ brAddBridge(const char *brname) int ret = -1;
if ((fd = brSetupControl(NULL, NULL))< 0) - return errno; + return -1;
if (ioctl(fd, SIOCBRADDBR, brname)< 0) { - ret = errno; + virReportSystemError(errno, + _("Unable to create bridge %s"), brname); goto cleanup; }
@@ -121,13 +131,23 @@ cleanup: return ret; } # else -int brAddBridge (const char *brname ATTRIBUTE_UNUSED) +int brAddBridge(const char *brname) { - return EINVAL; + virReportSystemError(ENOSYS, + _("Unable to create bridge %s"), brname); + return -1; } # endif
# ifdef SIOCBRDELBR +/** + * brHasBridge: + * @brname + * + * Check if the bridge @brname exists + * + * Returns 1 if it exists, 0 if it does not, -1 on error + */ int brHasBridge(const char *brname) { @@ -136,12 +156,18 @@ brHasBridge(const char *brname) struct ifreq ifr;
if ((fd = brSetupControl(brname,&ifr))< 0) - return errno; + return -1;
- if (ioctl(fd, SIOCGIFFLAGS,&ifr)) + if (ioctl(fd, SIOCGIFFLAGS,&ifr)) { + if (errno == ENODEV) + ret = 0; + else + virReportSystemError(errno, + _("Unable to delete bridge %s"), brname);
wrong error message? You seem to want to get the flags of the bridge?
goto cleanup; + }
- ret = 0; + ret = 1;
cleanup: VIR_FORCE_CLOSE(fd); @@ -149,9 +175,11 @@ cleanup: } # else int -brHasBridge(const char *brname ATTRIBUTE_UNUSED) +brHasBridge(const char *brname) { - return EINVAL; + virReportSystemError(errno,
errno -> ENOSYS
+ _("Unable to check bridge %s"), brname); + return -1; } # endif
@@ -171,10 +199,11 @@ brDeleteBridge(const char *brname) int ret = -1;
if ((fd = brSetupControl(NULL, NULL))< 0) - return errno; + return -1;
if (ioctl(fd, SIOCBRDELBR, brname)< 0) { - ret = errno; + virReportSystemError(errno, + _("Unable to delete bridge %s"), brname); goto cleanup; }
@@ -188,6 +217,8 @@ cleanup: int brDeleteBridge(const char *brname ATTRIBUTE_UNUSED) { + virReportSystemError(errno, + _("Unable to delete bridge %s"), brname);
errno -> ENOSYS
return EINVAL; } # endif @@ -211,15 +242,17 @@ brAddInterface(const char *brname, struct ifreq ifr;
if ((fd = brSetupControl(brname,&ifr))< 0) - return errno; + return -1;
if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { - ret = errno; + virReportSystemError(errno, + _("Unable to get interface index for %s"), ifname);
I don't see an errno being defined for if_nametoindex in case of failure. Use ENODEV ?
goto cleanup; }
if (ioctl(fd, SIOCBRADDIF,&ifr)< 0) { - ret = errno; + virReportSystemError(errno, + _("Unable to add bridge %s port %s"), brname, ifname);
Unable to add interface %s to bridge %s ?
goto cleanup; }
@@ -230,10 +263,12 @@ cleanup: } # else int -brAddInterface(const char *brname ATTRIBUTE_UNUSED, - const char *ifname ATTRIBUTE_UNUSED) +brAddInterface(const char *brname, + const char *ifname) { - return EINVAL; + virReportSystemError(ENOSYS, + _("Unable to add bridge %s port %s"), brname, ifname); + return -1; } # endif
@@ -256,15 +291,18 @@ brDeleteInterface(const char *brname, struct ifreq ifr;
if ((fd = brSetupControl(brname,&ifr))< 0) - return errno; + return -1;
if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { - ret = errno; + virReportSystemError(errno, + _("Unable to get interface index for %s"), ifname); +
I don't see an errno being defined for if_nametoindex in case of failure. Use ENODEV ?
goto cleanup; }
if (ioctl(fd, SIOCBRDELIF,&ifr)< 0) { - ret = errno; + virReportSystemError(errno, + _("Unable to remove bridge %s port %s"), brname, ifname);
Unable to remove interface %s from bridge %s ?
goto cleanup; }
@@ -275,10 +313,12 @@ cleanup: } # else int -brDeleteInterface(const char *brname ATTRIBUTE_UNUSED, - const char *ifname ATTRIBUTE_UNUSED) +brDeleteInterface(const char *brname, + const char *ifname) { - return EINVAL; + virReportSystemError(errno, + _("Unable to remove bridge %s port %s"), brname, ifname); + return -1; } # endif
@@ -290,7 +330,7 @@ brDeleteInterface(const char *brname ATTRIBUTE_UNUSED, * This function sets the @macaddr for a given interface @ifname. This * gets rid of the kernel's automatically assigned random MAC. * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success or -1 on failure */ int brSetInterfaceMac(const char *ifname, @@ -301,18 +341,22 @@ brSetInterfaceMac(const char *ifname, struct ifreq ifr;
if ((fd = brSetupControl(ifname,&ifr))< 0) - return errno; + return -1;
/* To fill ifr.ifr_hdaddr.sa_family field */ if (ioctl(fd, SIOCGIFHWADDR,&ifr)< 0) { - ret = errno; + virReportSystemError(errno, + _("Cannot get interface MAC on '%s'"), + ifname); goto cleanup; }
memcpy(ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN);
if (ioctl(fd, SIOCSIFHWADDR,&ifr)< 0) { - ret = errno; + virReportSystemError(errno, + _("Cannot set interface MAC on '%s'"), + ifname); goto cleanup; }
@@ -329,8 +373,7 @@ cleanup: * * This function gets the @mtu value set for a given interface @ifname. * - * Returns the MTU value in case of success. - * On error, returns -1 and sets errno accordingly + * Returns the MTU value in case of success, or -1 on failure. */ static int ifGetMtu(const char *ifname) { @@ -341,8 +384,12 @@ static int ifGetMtu(const char *ifname) if ((fd = brSetupControl(ifname,&ifr))< 0) return -1;
- if (ioctl(fd, SIOCGIFMTU,&ifr)< 0) + if (ioctl(fd, SIOCGIFMTU,&ifr)< 0) { + virReportSystemError(errno, + _("Cannot get interface MTU on '%s'"), + ifname); goto cleanup; + }
ret = ifr.ifr_mtu;
@@ -359,7 +406,7 @@ cleanup: * This function sets the @mtu for a given interface @ifname. Typically * used on a tap device to set up for Jumbo Frames. * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success, or -1 on failure */ static int ifSetMtu(const char *ifname, int mtu) { @@ -368,12 +415,14 @@ static int ifSetMtu(const char *ifname, int mtu) struct ifreq ifr;
if ((fd = brSetupControl(ifname,&ifr))< 0) - return errno; + return -1;
ifr.ifr_mtu = mtu;
if (ioctl(fd, SIOCSIFMTU,&ifr)< 0) { - ret = errno; + virReportSystemError(errno, + _("Cannot set interface MTU on '%s'"), + ifname); goto cleanup; }
@@ -391,7 +440,7 @@ cleanup: * * Sets the interface mtu to the same MTU of the bridge * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success, or -1 on failure */ static int brSetInterfaceMtu(const char *brname, const char *ifname) @@ -399,7 +448,7 @@ static int brSetInterfaceMtu(const char *brname, int mtu = ifGetMtu(brname);
if (mtu< 0) - return errno; + return -1;
return ifSetMtu(ifname, mtu); } @@ -421,7 +470,7 @@ static int brSetInterfaceMtu(const char *brname, * kernel implements the TUNGETIFF ioctl(), which qemu needs to query * the supplied tapfd. * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 1 if VnetHdr is supported, 0 if not supported */ # ifdef IFF_VNET_HDR static int @@ -479,7 +528,7 @@ brProbeVnetHdr(int tapfd) * persistent and closed. The caller must use brDeleteTap to remove * a persistent TAP devices when it is no longer needed. * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success or -1 on failure */ int brAddTap(const char *brname, @@ -489,11 +538,8 @@ brAddTap(const char *brname, bool up, int *tapfd) { - errno = brCreateTap(ifname, vnet_hdr, tapfd); - - /* fd has been closed in brCreateTap() when it failed. */ - if (errno) - goto error; + if (brCreateTap(ifname, vnet_hdr, tapfd)< 0) + return -1;
/* We need to set the interface MAC before adding it * to the bridge, because the bridge assumes the lowest @@ -501,53 +547,69 @@ brAddTap(const char *brname, * seeing the kernel allocate random MAC for the TAP * device before we set our static MAC. */ - if ((errno = brSetInterfaceMac(*ifname, macaddr))) - goto close_fd; + if (brSetInterfaceMac(*ifname, macaddr)< 0) + goto error; + /* We need to set the interface MTU before adding it * to the bridge, because the bridge will have its * MTU adjusted automatically when we add the new interface. */ - if ((errno = brSetInterfaceMtu(brname, *ifname))) - goto close_fd; - if ((errno = brAddInterface(brname, *ifname))) - goto close_fd; - if (up&& ((errno = brSetInterfaceUp(*ifname, 1)))) - goto close_fd; + if (brSetInterfaceMtu(brname, *ifname)< 0) + goto error; + + if (brAddInterface(brname, *ifname)< 0) + goto error; + + if (brSetInterfaceUp(*ifname, up)< 0) + goto error;
return 0;
-close_fd: +error: if (tapfd) VIR_FORCE_CLOSE(*tapfd); -error: - return errno; + return -1; }
int brDeleteTap(const char *ifname) { struct ifreq try; int fd; + int ret = -1;
- if ((fd = open("/dev/net/tun", O_RDWR))< 0) - return errno; + if ((fd = open("/dev/net/tun", O_RDWR))< 0) { + virReportSystemError(errno, "%s", + _("Unable to open /dev/net/tun, is tun module loaded?")); + return -1; + }
memset(&try, 0, sizeof(struct ifreq)); try.ifr_flags = IFF_TAP|IFF_NO_PI;
if (virStrcpyStatic(try.ifr_name, ifname) == NULL) { - errno = EINVAL; - goto error; + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + ifname); + goto cleanup; }
- if (ioctl(fd, TUNSETIFF,&try) == 0) { - if ((errno = ioctl(fd, TUNSETPERSIST, 0))) - goto error; + if (ioctl(fd, TUNSETIFF,&try)< 0) { + virReportSystemError(errno, "%s", + _("Unable to associate TAP device"));
hm, 'Unable to set flags on TAP device' ?
+ goto cleanup; }
- error: - VIR_FORCE_CLOSE(fd); + if (ioctl(fd, TUNSETPERSIST, 0)< 0) { + virReportSystemError(errno, "%s", + _("Unable to make TAP device non-persistent")); + goto cleanup; + } + + ret = 0;
- return errno; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; }
@@ -558,7 +620,7 @@ int brDeleteTap(const char *ifname) * * Function to control if an interface is activated (up, 1) or not (down, 0) * - * Returns 0 in case of success or an errno code in case of failure. + * Returns 0 in case of success or -1 on error. */ int brSetInterfaceUp(const char *ifname, @@ -570,10 +632,12 @@ brSetInterfaceUp(const char *ifname, int ifflags;
if ((fd = brSetupControl(ifname,&ifr))< 0) - return errno; + return -1;
if (ioctl(fd, SIOCGIFFLAGS,&ifr)< 0) { - ret = errno; + virReportSystemError(errno, + _("Cannot get interface flags on '%s'"), + ifname); goto cleanup; }
@@ -585,7 +649,9 @@ brSetInterfaceUp(const char *ifname, if (ifr.ifr_flags != ifflags) { ifr.ifr_flags = ifflags; if (ioctl(fd, SIOCSIFFLAGS,&ifr)< 0) { - ret = errno; + virReportSystemError(errno, + _("Cannot set interface flags on '%s'"), + ifname); goto cleanup; } } @@ -615,10 +681,12 @@ brGetInterfaceUp(const char *ifname, struct ifreq ifr;
if ((fd = brSetupControl(ifname,&ifr))< 0) - return errno; + return -1;
if (ioctl(fd, SIOCGIFFLAGS,&ifr)< 0) { - ret = errno; + virReportSystemError(errno, + _("Cannot get interface flags on '%s'"), + ifname); goto cleanup; }
@@ -799,9 +867,13 @@ brCreateTap(char **ifname, { int fd; struct ifreq ifr; + int ret = -1;
- if ((fd = open("/dev/net/tun", O_RDWR))< 0) - return errno; + if ((fd = open("/dev/net/tun", O_RDWR))< 0) { + virReportSystemError(errno, "%s", + _("Unable to open /dev/net/tun, is tun module loaded?")); + return -1; + }
memset(&ifr, 0, sizeof(ifr));
@@ -813,29 +885,45 @@ brCreateTap(char **ifname, # endif
if (virStrcpyStatic(ifr.ifr_name, *ifname) == NULL) { - errno = EINVAL; - goto error; + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + *ifname); + goto cleanup; + }
- if (ioctl(fd, TUNSETIFF,&ifr)< 0) - goto error; + if (ioctl(fd, TUNSETIFF,&ifr)< 0) { + virReportSystemError(errno, + _("Unable to create tap device %s"), + NULLSTR(*ifname)); + goto cleanup; + }
if (!tapfd&& - (errno = ioctl(fd, TUNSETPERSIST, 1))) - goto error; + (errno = ioctl(fd, TUNSETPERSIST, 1))) { + virReportSystemError(errno, + _("Unable to set tap device %s to persistent"), + NULLSTR(*ifname)); + goto cleanup; + } + VIR_FREE(*ifname); - if (!(*ifname = strdup(ifr.ifr_name))) - goto error; - if(tapfd) + if (!(*ifname = strdup(ifr.ifr_name))) { + virReportOOMError(); + goto cleanup; + } + if (tapfd) *tapfd = fd; else VIR_FORCE_CLOSE(fd); - return 0;
- error: - VIR_FORCE_CLOSE(fd); + ret = 0;
- return errno; +cleanup: + if (ret< 0) + VIR_FORCE_CLOSE(fd); + + return ret; }
#endif /* WITH_BRIDGE */
Some nits above.

On Tue, Nov 08, 2011 at 09:09:31AM -0500, Stefan Berger wrote:
On 11/03/2011 01:29 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
Currently every caller of the brXXX APIs has to store the returned errno value and then raise an error message. This results in inconsistent error messages across drivers, additional burden on the callers and makes the error reporting inaccurate since it is hard to distinguish different scenarios from 1 errno value.
* src/util/bridge.c: Raise errors instead of returning errnos * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/uml/uml_conf.c, src/uml/uml_driver.c: Remove error reporting code --- po/POTFILES.in | 1 + src/lxc/lxc_driver.c | 7 +- src/network/bridge_driver.c | 78 +++----------- src/qemu/qemu_command.c | 23 +---- src/uml/uml_conf.c | 28 +----- src/uml/uml_driver.c | 14 +-- src/util/bridge.c | 262 +++++++++++++++++++++++++++++-------------- 7 files changed, 196 insertions(+), 217 deletions(-)
@@ -188,6 +217,8 @@ cleanup: int brDeleteBridge(const char *brname ATTRIBUTE_UNUSED) { + virReportSystemError(errno, + _("Unable to delete bridge %s"), brname);
errno -> ENOSYS
Fixed this and a few others, and the places where they reoccur in later patches.
@@ -211,15 +242,17 @@ brAddInterface(const char *brname, struct ifreq ifr;
if ((fd = brSetupControl(brname,&ifr))< 0) - return errno; + return -1;
if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { - ret = errno; + virReportSystemError(errno, + _("Unable to get interface index for %s"), ifname); I don't see an errno being defined for if_nametoindex in case of failure. Use ENODEV ?
Yeah I see it just returns 0, so I used ENODEV Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 11/03/2011 01:29 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
Currently every caller of the brXXX APIs has to store the returned errno value and then raise an error message. This results in inconsistent error messages across drivers, additional burden on the callers and makes the error reporting inaccurate since it is hard to distinguish different scenarios from 1 errno value.
While making the message more exact, it could also make it more difficult to determine the context of the error. Sometimes it's useful to have both (a drop-down list with a stack trace embedded into each error message would be so nice to have sometimes :-)

From: "Daniel P. Berrange" <berrange@redhat.com> The existing brXXX APIs in src/util/bridge.h are renamed to follow one of three different conventions - virNetDevXXX - operations for any type of interface - virNetDevBridgeXXX - operations for bridge interfaces - virNetDevTapXXX - operations for tap interfaces * src/util/bridge.h, src/util/bridge.c: Rename all APIs * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/uml/uml_conf.c, src/uml/uml_driver.c: Update for API renaming --- src/lxc/lxc_driver.c | 2 +- src/network/bridge_driver.c | 32 ++++---- src/qemu/qemu_command.c | 4 +- src/uml/uml_conf.c | 4 +- src/uml/uml_driver.c | 2 +- src/util/bridge.c | 196 +++++++++++++++++++----------------------- src/util/bridge.h | 74 ++++++++-------- 7 files changed, 148 insertions(+), 166 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 8ee1306..c75941f 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1269,7 +1269,7 @@ static int lxcSetupInterfaces(virConnectPtr conn, goto error_exit; } - if (brAddInterface(bridge, parentVeth) < 0) + if (virNetDevBridgeAddPort(bridge, parentVeth) < 0) goto error_exit; if (vethInterfaceUpOrDown(parentVeth, 1) < 0) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index d5d2472..bc9d2e1 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -211,7 +211,7 @@ networkFindActiveConfigs(struct network_driver *driver) { /* If bridge exists, then mark it active */ if (obj->def->bridge && - brHasBridge(obj->def->bridge) == 0) { + virNetDevExists(obj->def->bridge) == 0) { obj->active = 1; /* Try and read dnsmasq/radvd pids if any */ @@ -1677,8 +1677,8 @@ networkAddAddrToBridge(virNetworkObjPtr network, return -1; } - if (brAddInetAddress(network->def->bridge, - &ipdef->address, prefix) < 0) + if (virNetDevSetIPv4Addres(network->def->bridge, + &ipdef->address, prefix) < 0) return -1; return 0; @@ -1699,7 +1699,7 @@ networkStartNetworkVirtual(struct network_driver *driver, return -1; /* Create and configure the bridge device */ - if (brAddBridge(network->def->bridge) < 0) + if (virNetDevBridgeCreate(network->def->bridge) < 0) return -1; if (network->def->mac_specified) { @@ -1714,20 +1714,20 @@ networkStartNetworkVirtual(struct network_driver *driver, virReportOOMError(); goto err0; } - if (brAddTap(network->def->bridge, - &macTapIfName, network->def->mac, 0, false, NULL) < 0) { + if (virNetDevTapCreateInBridgePort(network->def->bridge, + &macTapIfName, network->def->mac, 0, false, NULL) < 0) { VIR_FREE(macTapIfName); goto err0; } } /* Set bridge options */ - if (brSetForwardDelay(network->def->bridge, + if (virNetDevBridgeSetSTPDelay(network->def->bridge, network->def->delay) < 0) goto err1; - if (brSetEnableSTP(network->def->bridge, - network->def->stp ? 1 : 0) < 0) + if (virNetDevBridgeSetSTP(network->def->bridge, + network->def->stp ? 1 : 0) < 0) goto err1; /* Disable IPv6 on the bridge if there are no IPv6 addresses @@ -1755,7 +1755,7 @@ networkStartNetworkVirtual(struct network_driver *driver, } /* Bring up the bridge interface */ - if (brSetInterfaceUp(network->def->bridge, 1) < 0) + if (virNetDevSetOnline(network->def->bridge, 1) < 0) goto err2; /* If forwardType != NONE, turn on global IP forwarding */ @@ -1804,7 +1804,7 @@ networkStartNetworkVirtual(struct network_driver *driver, err3: if (!save_err) save_err = virSaveLastError(); - ignore_value(brSetInterfaceUp(network->def->bridge, 0)); + ignore_value(virNetDevSetOnline(network->def->bridge, 0)); err2: if (!save_err) @@ -1815,13 +1815,13 @@ networkStartNetworkVirtual(struct network_driver *driver, if (!save_err) save_err = virSaveLastError(); - ignore_value(brDeleteTap(macTapIfName)); + ignore_value(virNetDevTapDelete(macTapIfName)); VIR_FREE(macTapIfName); err0: if (!save_err) save_err = virSaveLastError(); - ignore_value(brDeleteBridge(network->def->bridge)); + ignore_value(virNetDevBridgeDelete(network->def->bridge)); if (save_err) { virSetError(save_err); @@ -1859,16 +1859,16 @@ static int networkShutdownNetworkVirtual(struct network_driver *driver, if (!macTapIfName) { virReportOOMError(); } else { - ignore_value(brDeleteTap(macTapIfName)); + ignore_value(virNetDevTapDelete(macTapIfName)); VIR_FREE(macTapIfName); } } - ignore_value(brSetInterfaceUp(network->def->bridge, 0)); + ignore_value(virNetDevSetOnline(network->def->bridge, 0)); networkRemoveIptablesRules(driver, network); - ignore_value(brDeleteBridge(network->def->bridge)); + ignore_value(virNetDevBridgeDelete(network->def->bridge)); /* See if its still alive and really really kill it */ if (network->dnsmasqPid > 0 && diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6fbdc20..5680636 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -279,8 +279,8 @@ qemuNetworkIfaceConnect(virDomainDefPtr def, memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ - err = brAddTap(brname, &net->ifname, tapmac, - vnet_hdr, true, &tapfd); + err = virNetDevTapCreateInBridgePort(brname, &net->ifname, tapmac, + vnet_hdr, true, &tapfd); virDomainAuditNetDevice(def, net, "/dev/net/tun", tapfd >= 0); if (err < 0) { if (template_ifname) diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c index 477a178..9b6abe7 100644 --- a/src/uml/uml_conf.c +++ b/src/uml/uml_conf.c @@ -136,8 +136,8 @@ umlConnectTapDevice(virConnectPtr conn, memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ - if (brAddTap(bridge, &net->ifname, tapmac, - 0, true, NULL) < 0) { + if (virNetDevTapCreateInBridgePort(bridge, &net->ifname, tapmac, + 0, true, NULL) < 0) { if (template_ifname) VIR_FREE(net->ifname); goto error; diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 8ba06a5..4a417ab 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -962,7 +962,7 @@ static void umlCleanupTapDevices(virDomainObjPtr vm) { def->type != VIR_DOMAIN_NET_TYPE_NETWORK) continue; - ignore_value(brDeleteTap(def->ifname)); + ignore_value(virNetDevTapDelete(def->ifname)); } } diff --git a/src/util/bridge.c b/src/util/bridge.c index 351e482..a853c2a 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -58,10 +58,10 @@ # define VIR_FROM_THIS VIR_FROM_NONE -static int brSetupControlFull(const char *ifname, - struct ifreq *ifr, - int domain, - int type) +static int virNetDevSetupControlFull(const char *ifname, + struct ifreq *ifr, + int domain, + int type) { int fd; @@ -93,15 +93,15 @@ static int brSetupControlFull(const char *ifname, } -static int brSetupControl(const char *ifname, - struct ifreq *ifr) +static int virNetDevSetupControl(const char *ifname, + struct ifreq *ifr) { - return brSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); + return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); } /** - * brAddBridge: + * virNetDevBridgeCreate: * @brname: the bridge name * * This function register a new bridge @@ -109,13 +109,12 @@ static int brSetupControl(const char *ifname, * Returns 0 in case of success or -1 on failure */ # ifdef SIOCBRADDBR -int -brAddBridge(const char *brname) +int virNetDevBridgeCreate(const char *brname) { int fd = -1; int ret = -1; - if ((fd = brSetupControl(NULL, NULL)) < 0) + if ((fd = virNetDevSetupControl(NULL, NULL)) < 0) return -1; if (ioctl(fd, SIOCBRADDBR, brname) < 0) { @@ -131,7 +130,7 @@ cleanup: return ret; } # else -int brAddBridge(const char *brname) +int virNetDevBridgeCreate(const char *brname) { virReportSystemError(ENOSYS, _("Unable to create bridge %s"), brname); @@ -141,21 +140,20 @@ int brAddBridge(const char *brname) # ifdef SIOCBRDELBR /** - * brHasBridge: - * @brname + * virNetDevExists: + * @ifname * - * Check if the bridge @brname exists + * Check if the network device @ifname exists * * Returns 1 if it exists, 0 if it does not, -1 on error */ -int -brHasBridge(const char *brname) +int virNetDevExists(const char *ifname) { int fd = -1; int ret = -1; struct ifreq ifr; - if ((fd = brSetupControl(brname, &ifr)) < 0) + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) return -1; if (ioctl(fd, SIOCGIFFLAGS, &ifr)) { @@ -163,7 +161,7 @@ brHasBridge(const char *brname) ret = 0; else virReportSystemError(errno, - _("Unable to delete bridge %s"), brname); + _("Unable to check interface flags for %s"), ifname); goto cleanup; } @@ -174,17 +172,16 @@ cleanup: return ret; } # else -int -brHasBridge(const char *brname) +int virNetDevExists(const char *ifname) { virReportSystemError(errno, - _("Unable to check bridge %s"), brname); + _("Unable to check interface %s"), ifname); return -1; } # endif /** - * brDeleteBridge: + * virNetDevBridgeDelete: * @brname: the bridge name * * Remove a bridge from the layer. @@ -192,13 +189,12 @@ brHasBridge(const char *brname) * Returns 0 in case of success or an errno code in case of failure. */ # ifdef SIOCBRDELBR -int -brDeleteBridge(const char *brname) +int virNetDevBridgeDelete(const char *brname) { int fd = -1; int ret = -1; - if ((fd = brSetupControl(NULL, NULL)) < 0) + if ((fd = virNetDevSetupControl(NULL, NULL)) < 0) return -1; if (ioctl(fd, SIOCBRDELBR, brname) < 0) { @@ -214,8 +210,7 @@ cleanup: return ret; } # else -int -brDeleteBridge(const char *brname ATTRIBUTE_UNUSED) +int virNetDevBridgeDelete(const char *brname ATTRIBUTE_UNUSED) { virReportSystemError(errno, _("Unable to delete bridge %s"), brname); @@ -224,7 +219,7 @@ brDeleteBridge(const char *brname ATTRIBUTE_UNUSED) # endif /** - * brAddInterface: + * virNetDevBridgeAddPort: * @brname: the bridge name * @ifname: the network interface name * @@ -233,15 +228,14 @@ brDeleteBridge(const char *brname ATTRIBUTE_UNUSED) * Returns 0 in case of success or an errno code in case of failure. */ # ifdef SIOCBRADDIF -int -brAddInterface(const char *brname, - const char *ifname) +int virNetDevBridgeAddPort(const char *brname, + const char *ifname) { int fd = -1; int ret = -1; struct ifreq ifr; - if ((fd = brSetupControl(brname, &ifr)) < 0) + if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) return -1; if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { @@ -262,9 +256,8 @@ cleanup: return ret; } # else -int -brAddInterface(const char *brname, - const char *ifname) +int virNetDevBridgeAddPort(const char *brname, + const char *ifname) { virReportSystemError(ENOSYS, _("Unable to add bridge %s port %s"), brname, ifname); @@ -273,7 +266,7 @@ brAddInterface(const char *brname, # endif /** - * brDeleteInterface: + * virNetDevBridgeRemovePort: * @brname: the bridge name * @ifname: the network interface name * @@ -282,15 +275,14 @@ brAddInterface(const char *brname, * Returns 0 in case of success or an errno code in case of failure. */ # ifdef SIOCBRDELIF -int -brDeleteInterface(const char *brname, - const char *ifname) +int virNetDevBridgeRemovePort(const char *brname, + const char *ifname) { int fd = -1; int ret = -1; struct ifreq ifr; - if ((fd = brSetupControl(brname, &ifr)) < 0) + if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) return -1; if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { @@ -312,9 +304,8 @@ cleanup: return ret; } # else -int -brDeleteInterface(const char *brname, - const char *ifname) +int virNetDevBridgeRemovePort(const char *brname, + const char *ifname) { virReportSystemError(errno, _("Unable to remove bridge %s port %s"), brname, ifname); @@ -323,7 +314,7 @@ brDeleteInterface(const char *brname, # endif /** - * brSetInterfaceMac: + * virNetDevSetMAC: * @ifname: interface name to set MTU for * @macaddr: MAC address (VIR_MAC_BUFLEN in size) * @@ -332,15 +323,14 @@ brDeleteInterface(const char *brname, * * Returns 0 in case of success or -1 on failure */ -int -brSetInterfaceMac(const char *ifname, - const unsigned char *macaddr) +int virNetDevSetMAC(const char *ifname, + const unsigned char *macaddr) { int fd = -1; int ret = -1; struct ifreq ifr; - if ((fd = brSetupControl(ifname, &ifr)) < 0) + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) return -1; /* To fill ifr.ifr_hdaddr.sa_family field */ @@ -368,20 +358,20 @@ cleanup: } /** - * ifGetMtu + * virNetDevGetMTU: * @ifname: interface name get MTU for * * This function gets the @mtu value set for a given interface @ifname. * * Returns the MTU value in case of success, or -1 on failure. */ -static int ifGetMtu(const char *ifname) +static int virNetDevGetMTU(const char *ifname) { int fd = -1; int ret = -1; struct ifreq ifr; - if ((fd = brSetupControl(ifname, &ifr)) < 0) + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) return -1; if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { @@ -399,7 +389,7 @@ cleanup: } /** - * ifSetMtu: + * virNetDevSetMTU: * @ifname: interface name to set MTU for * @mtu: MTU value * @@ -408,13 +398,13 @@ cleanup: * * Returns 0 in case of success, or -1 on failure */ -static int ifSetMtu(const char *ifname, int mtu) +static int virNetDevSetMTU(const char *ifname, int mtu) { int fd = -1; int ret = -1; struct ifreq ifr; - if ((fd = brSetupControl(ifname, &ifr)) < 0) + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) return -1; ifr.ifr_mtu = mtu; @@ -442,19 +432,19 @@ cleanup: * * Returns 0 in case of success, or -1 on failure */ -static int brSetInterfaceMtu(const char *brname, - const char *ifname) +static int virNetDevSetMTUFromDevice(const char *brname, + const char *ifname) { - int mtu = ifGetMtu(brname); + int mtu = virNetDevGetMTU(brname); if (mtu < 0) return -1; - return ifSetMtu(ifname, mtu); + return virNetDevSetMTU(ifname, mtu); } /** - * brProbeVnetHdr: + * virNetDevProbeVnetHdr: * @tapfd: a tun/tap file descriptor * * Check whether it is safe to enable the IFF_VNET_HDR flag on the @@ -474,7 +464,7 @@ static int brSetInterfaceMtu(const char *brname, */ # ifdef IFF_VNET_HDR static int -brProbeVnetHdr(int tapfd) +virNetDevProbeVnetHdr(int tapfd) { # if defined(IFF_VNET_HDR) && defined(TUNGETFEATURES) && defined(TUNGETIFF) unsigned int features; @@ -530,15 +520,14 @@ brProbeVnetHdr(int tapfd) * * Returns 0 in case of success or -1 on failure */ -int -brAddTap(const char *brname, - char **ifname, - const unsigned char *macaddr, - int vnet_hdr, - bool up, - int *tapfd) +int virNetDevTapCreateInBridgePort(const char *brname, + char **ifname, + const unsigned char *macaddr, + int vnet_hdr, + bool up, + int *tapfd) { - if (brCreateTap(ifname, vnet_hdr, tapfd) < 0) + if (virNetDevTapCreate(ifname, vnet_hdr, tapfd) < 0) return -1; /* We need to set the interface MAC before adding it @@ -547,20 +536,20 @@ brAddTap(const char *brname, * seeing the kernel allocate random MAC for the TAP * device before we set our static MAC. */ - if (brSetInterfaceMac(*ifname, macaddr) < 0) + if (virNetDevSetMAC(*ifname, macaddr) < 0) goto error; /* We need to set the interface MTU before adding it * to the bridge, because the bridge will have its * MTU adjusted automatically when we add the new interface. */ - if (brSetInterfaceMtu(brname, *ifname) < 0) + if (virNetDevSetMTUFromDevice(brname, *ifname) < 0) goto error; - if (brAddInterface(brname, *ifname) < 0) + if (virNetDevBridgeAddPort(brname, *ifname) < 0) goto error; - if (brSetInterfaceUp(*ifname, up) < 0) + if (virNetDevSetOnline(*ifname, up) < 0) goto error; return 0; @@ -571,7 +560,7 @@ error: return -1; } -int brDeleteTap(const char *ifname) +int virNetDevTapDelete(const char *ifname) { struct ifreq try; int fd; @@ -614,7 +603,7 @@ cleanup: /** - * brSetInterfaceUp: + * virNetDevSetOnline: * @ifname: the interface name * @up: 1 for up, 0 for down * @@ -622,16 +611,15 @@ cleanup: * * Returns 0 in case of success or -1 on error. */ -int -brSetInterfaceUp(const char *ifname, - int up) +int virNetDevSetOnline(const char *ifname, + int up) { int fd = -1; int ret = -1; struct ifreq ifr; int ifflags; - if ((fd = brSetupControl(ifname, &ifr)) < 0) + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) return -1; if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { @@ -664,7 +652,7 @@ cleanup: } /** - * brGetInterfaceUp: + * virNetDevIsOnline: * @ifname: the interface name * @up: where to store the status * @@ -672,15 +660,14 @@ cleanup: * * Returns 0 in case of success or an errno code in case of failure. */ -int -brGetInterfaceUp(const char *ifname, - int *up) +int virNetDevIsOnline(const char *ifname, + int *up) { int fd = -1; int ret = -1; struct ifreq ifr; - if ((fd = brSetupControl(ifname, &ifr)) < 0) + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) return -1; if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { @@ -699,7 +686,7 @@ cleanup: } /** - * brAddInetAddress: + * virNetDevSetIPv4Addres: * @ifname: the interface name * @addr: the IP address (IPv4 or IPv6) * @prefix: number of 1 bits in the netmask @@ -711,10 +698,9 @@ cleanup: * Returns 0 in case of success or -1 in case of error. */ -int -brAddInetAddress(const char *ifname, - virSocketAddr *addr, - unsigned int prefix) +int virNetDevSetIPv4Addres(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) { virCommandPtr cmd = NULL; char *addrstr = NULL, *bcaststr = NULL; @@ -748,7 +734,7 @@ cleanup: } /** - * brDelInetAddress: + * virNetDevClearIPv4Address: * @ifname: the interface name * @addr: the IP address (IPv4 or IPv6) * @prefix: number of 1 bits in the netmask @@ -758,10 +744,9 @@ cleanup: * Returns 0 in case of success or -1 in case of error. */ -int -brDelInetAddress(const char *ifname, - virSocketAddr *addr, - unsigned int prefix) +int virNetDevClearIPv4Address(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) { virCommandPtr cmd = NULL; char *addrstr; @@ -785,7 +770,7 @@ cleanup: } /** - * brSetForwardDelay: + * virNetDevBridgeSetSTPDelay: * @brname: the bridge name * @delay: delay in seconds * @@ -794,9 +779,8 @@ cleanup: * Returns 0 in case of success or -1 on failure */ -int -brSetForwardDelay(const char *brname, - int delay) +int virNetDevBridgeSetSTPDelay(const char *brname, + int delay) { virCommandPtr cmd; int ret = -1; @@ -815,7 +799,7 @@ cleanup: } /** - * brSetEnableSTP: + * virNetDevBridgeSetSTP: * @brname: the bridge name * @enable: 1 to enable, 0 to disable * @@ -824,9 +808,8 @@ cleanup: * * Returns 0 in case of success or -1 on failure */ -int -brSetEnableSTP(const char *brname, - int enable) +int virNetDevBridgeSetSTP(const char *brname, + int enable) { virCommandPtr cmd; int ret = -1; @@ -860,10 +843,9 @@ cleanup: * Returns 0 in case of success or an errno code in case of failure. */ -int -brCreateTap(char **ifname, - int vnet_hdr ATTRIBUTE_UNUSED, - int *tapfd) +int virNetDevTapCreate(char **ifname, + int vnet_hdr ATTRIBUTE_UNUSED, + int *tapfd) { int fd; struct ifreq ifr; @@ -880,7 +862,7 @@ brCreateTap(char **ifname, ifr.ifr_flags = IFF_TAP|IFF_NO_PI; # ifdef IFF_VNET_HDR - if (vnet_hdr && brProbeVnetHdr(fd)) + if (vnet_hdr && virNetDevProbeVnetHdr(fd)) ifr.ifr_flags |= IFF_VNET_HDR; # endif diff --git a/src/util/bridge.h b/src/util/bridge.h index 2bfc4b4..44b6631 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -42,19 +42,19 @@ */ # define BR_INET_ADDR_MAXLEN INET_ADDRSTRLEN -int brAddBridge (const char *brname) +int virNetDevBridgeCreate(const char *brname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brDeleteBridge (const char *brname) +int virNetDevBridgeDelete(const char *brname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brHasBridge (const char *brname) +int virNetDevExists(const char *brname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brAddInterface (const char *brname, - const char *ifname) +int virNetDevBridgeAddPort(const char *brname, + const char *ifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int brDeleteInterface (const char *brname, - const char *ifname) +int virNetDevBridgeRemovePort(const char *brname, + const char *ifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; enum { @@ -62,55 +62,55 @@ enum { BR_TAP_PERSIST = (1 << 1), }; -int brAddTap (const char *brname, - char **ifname, - const unsigned char *macaddr, - int vnet_hdr, - bool up, - int *tapfd) +int virNetDevTapCreateInBridgePort(const char *brname, + char **ifname, + const unsigned char *macaddr, + int vnet_hdr, + bool up, + int *tapfd) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_RETURN_CHECK; -int brDeleteTap (const char *ifname) +int virNetDevTapDelete(const char *ifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brSetInterfaceUp (const char *ifname, - int up) +int virNetDevSetOnline(const char *ifname, + int up) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brGetInterfaceUp (const char *ifname, - int *up) +int virNetDevIsOnline(const char *ifname, + int *up) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int brAddInetAddress (const char *ifname, - virSocketAddr *addr, - unsigned int prefix) +int virNetDevSetIPv4Addres(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int brDelInetAddress (const char *ifname, - virSocketAddr *addr, - unsigned int prefix) +int virNetDevClearIPv4Address(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int brSetForwardDelay (const char *brname, - int delay) +int virNetDevBridgeSetSTPDelay(const char *brname, + int delay) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brGetForwardDelay (const char *brname, - int *delay) +int virNetDevBridgeGetSTPDelay(const char *brname, + int *delay) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int brSetEnableSTP (const char *brname, - int enable) +int virNetDevBridgeSetSTP(const char *brname, + int enable) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brGetEnableSTP (const char *brname, - int *enable) +int virNetDevBridgeGetSTP(const char *brname, + int *enable) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int brCreateTap (char **ifname, - int vnet_hdr, - int *tapfd) +int virNetDevTapCreate(char **ifname, + int vnet_hdr, + int *tapfd) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brSetInterfaceMac (const char *ifname, - const unsigned char *macaddr) +int virNetDevSetMAC(const char *ifname, + const unsigned char *macaddr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; # endif /* WITH_BRIDGE */ -- 1.7.6.4

On 11/03/2011 01:29 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
The existing brXXX APIs in src/util/bridge.h are renamed to follow one of three different conventions
- virNetDevXXX - operations for any type of interface - virNetDevBridgeXXX - operations for bridge interfaces - virNetDevTapXXX - operations for tap interfaces
* src/util/bridge.h, src/util/bridge.c: Rename all APIs * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/uml/uml_conf.c, src/uml/uml_driver.c: Update for API renaming --- src/lxc/lxc_driver.c | 2 +- src/network/bridge_driver.c | 32 ++++---- src/qemu/qemu_command.c | 4 +- src/uml/uml_conf.c | 4 +- src/uml/uml_driver.c | 2 +- src/util/bridge.c | 196 +++++++++++++++++++----------------------- src/util/bridge.h | 74 ++++++++-------- 7 files changed, 148 insertions(+), 166 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 8ee1306..c75941f 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1269,7 +1269,7 @@ static int lxcSetupInterfaces(virConnectPtr conn, goto error_exit; }
- if (brAddInterface(bridge, parentVeth)< 0) + if (virNetDevBridgeAddPort(bridge, parentVeth)< 0) goto error_exit;
if (vethInterfaceUpOrDown(parentVeth, 1)< 0) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index d5d2472..bc9d2e1 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -211,7 +211,7 @@ networkFindActiveConfigs(struct network_driver *driver) {
/* If bridge exists, then mark it active */ if (obj->def->bridge&& - brHasBridge(obj->def->bridge) == 0) { + virNetDevExists(obj->def->bridge) == 0) { obj->active = 1;
/* Try and read dnsmasq/radvd pids if any */ @@ -1677,8 +1677,8 @@ networkAddAddrToBridge(virNetworkObjPtr network, return -1; }
- if (brAddInetAddress(network->def->bridge, -&ipdef->address, prefix)< 0) + if (virNetDevSetIPv4Addres(network->def->bridge, +&ipdef->address, prefix)< 0)
Addres -> Address
return -1;
return 0; @@ -1699,7 +1699,7 @@ networkStartNetworkVirtual(struct network_driver *driver, return -1;
/* Create and configure the bridge device */ - if (brAddBridge(network->def->bridge)< 0) + if (virNetDevBridgeCreate(network->def->bridge)< 0) return -1;
if (network->def->mac_specified) { @@ -1714,20 +1714,20 @@ networkStartNetworkVirtual(struct network_driver *driver, virReportOOMError(); goto err0; } - if (brAddTap(network->def->bridge, -&macTapIfName, network->def->mac, 0, false, NULL)< 0) { + if (virNetDevTapCreateInBridgePort(network->def->bridge, +&macTapIfName, network->def->mac, 0, false, NULL)< 0) { VIR_FREE(macTapIfName); goto err0; } }
/* Set bridge options */ - if (brSetForwardDelay(network->def->bridge, + if (virNetDevBridgeSetSTPDelay(network->def->bridge, network->def->delay)< 0) goto err1;
- if (brSetEnableSTP(network->def->bridge, - network->def->stp ? 1 : 0)< 0) + if (virNetDevBridgeSetSTP(network->def->bridge, + network->def->stp ? 1 : 0)< 0) goto err1;
/* Disable IPv6 on the bridge if there are no IPv6 addresses @@ -1755,7 +1755,7 @@ networkStartNetworkVirtual(struct network_driver *driver, }
/* Bring up the bridge interface */ - if (brSetInterfaceUp(network->def->bridge, 1)< 0) + if (virNetDevSetOnline(network->def->bridge, 1)< 0) goto err2;
/* If forwardType != NONE, turn on global IP forwarding */ @@ -1804,7 +1804,7 @@ networkStartNetworkVirtual(struct network_driver *driver, err3: if (!save_err) save_err = virSaveLastError(); - ignore_value(brSetInterfaceUp(network->def->bridge, 0)); + ignore_value(virNetDevSetOnline(network->def->bridge, 0));
err2: if (!save_err) @@ -1815,13 +1815,13 @@ networkStartNetworkVirtual(struct network_driver *driver, if (!save_err) save_err = virSaveLastError();
- ignore_value(brDeleteTap(macTapIfName)); + ignore_value(virNetDevTapDelete(macTapIfName)); VIR_FREE(macTapIfName);
err0: if (!save_err) save_err = virSaveLastError(); - ignore_value(brDeleteBridge(network->def->bridge)); + ignore_value(virNetDevBridgeDelete(network->def->bridge));
if (save_err) { virSetError(save_err); @@ -1859,16 +1859,16 @@ static int networkShutdownNetworkVirtual(struct network_driver *driver, if (!macTapIfName) { virReportOOMError(); } else { - ignore_value(brDeleteTap(macTapIfName)); + ignore_value(virNetDevTapDelete(macTapIfName)); VIR_FREE(macTapIfName); } }
- ignore_value(brSetInterfaceUp(network->def->bridge, 0)); + ignore_value(virNetDevSetOnline(network->def->bridge, 0));
networkRemoveIptablesRules(driver, network);
- ignore_value(brDeleteBridge(network->def->bridge)); + ignore_value(virNetDevBridgeDelete(network->def->bridge));
/* See if its still alive and really really kill it */ if (network->dnsmasqPid> 0&& diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6fbdc20..5680636 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -279,8 +279,8 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ - err = brAddTap(brname,&net->ifname, tapmac, - vnet_hdr, true,&tapfd); + err = virNetDevTapCreateInBridgePort(brname,&net->ifname, tapmac, + vnet_hdr, true,&tapfd); virDomainAuditNetDevice(def, net, "/dev/net/tun", tapfd>= 0); if (err< 0) { if (template_ifname) diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c index 477a178..9b6abe7 100644 --- a/src/uml/uml_conf.c +++ b/src/uml/uml_conf.c @@ -136,8 +136,8 @@ umlConnectTapDevice(virConnectPtr conn,
memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ - if (brAddTap(bridge,&net->ifname, tapmac, - 0, true, NULL)< 0) { + if (virNetDevTapCreateInBridgePort(bridge,&net->ifname, tapmac, + 0, true, NULL)< 0) { if (template_ifname) VIR_FREE(net->ifname); goto error; diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 8ba06a5..4a417ab 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -962,7 +962,7 @@ static void umlCleanupTapDevices(virDomainObjPtr vm) { def->type != VIR_DOMAIN_NET_TYPE_NETWORK) continue;
- ignore_value(brDeleteTap(def->ifname)); + ignore_value(virNetDevTapDelete(def->ifname)); } }
diff --git a/src/util/bridge.c b/src/util/bridge.c index 351e482..a853c2a 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -58,10 +58,10 @@
# define VIR_FROM_THIS VIR_FROM_NONE
-static int brSetupControlFull(const char *ifname, - struct ifreq *ifr, - int domain, - int type) +static int virNetDevSetupControlFull(const char *ifname, + struct ifreq *ifr, + int domain, + int type) { int fd;
@@ -93,15 +93,15 @@ static int brSetupControlFull(const char *ifname, }
-static int brSetupControl(const char *ifname, - struct ifreq *ifr) +static int virNetDevSetupControl(const char *ifname, + struct ifreq *ifr) { - return brSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); + return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); }
/** - * brAddBridge: + * virNetDevBridgeCreate: * @brname: the bridge name * * This function register a new bridge @@ -109,13 +109,12 @@ static int brSetupControl(const char *ifname, * Returns 0 in case of success or -1 on failure */ # ifdef SIOCBRADDBR -int -brAddBridge(const char *brname) +int virNetDevBridgeCreate(const char *brname) { int fd = -1; int ret = -1;
- if ((fd = brSetupControl(NULL, NULL))< 0) + if ((fd = virNetDevSetupControl(NULL, NULL))< 0) return -1;
if (ioctl(fd, SIOCBRADDBR, brname)< 0) { @@ -131,7 +130,7 @@ cleanup: return ret; } # else -int brAddBridge(const char *brname) +int virNetDevBridgeCreate(const char *brname) { virReportSystemError(ENOSYS, _("Unable to create bridge %s"), brname); @@ -141,21 +140,20 @@ int brAddBridge(const char *brname)
# ifdef SIOCBRDELBR /** - * brHasBridge: - * @brname + * virNetDevExists: + * @ifname * - * Check if the bridge @brname exists + * Check if the network device @ifname exists * * Returns 1 if it exists, 0 if it does not, -1 on error */ -int -brHasBridge(const char *brname) +int virNetDevExists(const char *ifname) { int fd = -1; int ret = -1; struct ifreq ifr;
- if ((fd = brSetupControl(brname,&ifr))< 0) + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) return -1;
if (ioctl(fd, SIOCGIFFLAGS,&ifr)) { @@ -163,7 +161,7 @@ brHasBridge(const char *brname) ret = 0; else virReportSystemError(errno, - _("Unable to delete bridge %s"), brname); + _("Unable to check interface flags for %s"), ifname); goto cleanup; }
@@ -174,17 +172,16 @@ cleanup: return ret; } # else -int -brHasBridge(const char *brname) +int virNetDevExists(const char *ifname) { virReportSystemError(errno, - _("Unable to check bridge %s"), brname); + _("Unable to check interface %s"), ifname); return -1; } # endif
/** - * brDeleteBridge: + * virNetDevBridgeDelete: * @brname: the bridge name * * Remove a bridge from the layer. @@ -192,13 +189,12 @@ brHasBridge(const char *brname) * Returns 0 in case of success or an errno code in case of failure. */ # ifdef SIOCBRDELBR -int -brDeleteBridge(const char *brname) +int virNetDevBridgeDelete(const char *brname) { int fd = -1; int ret = -1;
- if ((fd = brSetupControl(NULL, NULL))< 0) + if ((fd = virNetDevSetupControl(NULL, NULL))< 0) return -1;
if (ioctl(fd, SIOCBRDELBR, brname)< 0) { @@ -214,8 +210,7 @@ cleanup: return ret; } # else -int -brDeleteBridge(const char *brname ATTRIBUTE_UNUSED) +int virNetDevBridgeDelete(const char *brname ATTRIBUTE_UNUSED) { virReportSystemError(errno, _("Unable to delete bridge %s"), brname); @@ -224,7 +219,7 @@ brDeleteBridge(const char *brname ATTRIBUTE_UNUSED) # endif
/** - * brAddInterface: + * virNetDevBridgeAddPort: * @brname: the bridge name * @ifname: the network interface name * @@ -233,15 +228,14 @@ brDeleteBridge(const char *brname ATTRIBUTE_UNUSED) * Returns 0 in case of success or an errno code in case of failure. */ # ifdef SIOCBRADDIF -int -brAddInterface(const char *brname, - const char *ifname) +int virNetDevBridgeAddPort(const char *brname, + const char *ifname) { int fd = -1; int ret = -1; struct ifreq ifr;
- if ((fd = brSetupControl(brname,&ifr))< 0) + if ((fd = virNetDevSetupControl(brname,&ifr))< 0) return -1;
if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { @@ -262,9 +256,8 @@ cleanup: return ret; } # else -int -brAddInterface(const char *brname, - const char *ifname) +int virNetDevBridgeAddPort(const char *brname, + const char *ifname) { virReportSystemError(ENOSYS, _("Unable to add bridge %s port %s"), brname, ifname); @@ -273,7 +266,7 @@ brAddInterface(const char *brname, # endif
/** - * brDeleteInterface: + * virNetDevBridgeRemovePort: * @brname: the bridge name * @ifname: the network interface name * @@ -282,15 +275,14 @@ brAddInterface(const char *brname, * Returns 0 in case of success or an errno code in case of failure. */ # ifdef SIOCBRDELIF -int -brDeleteInterface(const char *brname, - const char *ifname) +int virNetDevBridgeRemovePort(const char *brname, + const char *ifname) { int fd = -1; int ret = -1; struct ifreq ifr;
- if ((fd = brSetupControl(brname,&ifr))< 0) + if ((fd = virNetDevSetupControl(brname,&ifr))< 0) return -1;
if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { @@ -312,9 +304,8 @@ cleanup: return ret; } # else -int -brDeleteInterface(const char *brname, - const char *ifname) +int virNetDevBridgeRemovePort(const char *brname, + const char *ifname) { virReportSystemError(errno, _("Unable to remove bridge %s port %s"), brname, ifname); @@ -323,7 +314,7 @@ brDeleteInterface(const char *brname, # endif
/** - * brSetInterfaceMac: + * virNetDevSetMAC: * @ifname: interface name to set MTU for * @macaddr: MAC address (VIR_MAC_BUFLEN in size) * @@ -332,15 +323,14 @@ brDeleteInterface(const char *brname, * * Returns 0 in case of success or -1 on failure */ -int -brSetInterfaceMac(const char *ifname, - const unsigned char *macaddr) +int virNetDevSetMAC(const char *ifname, + const unsigned char *macaddr) { int fd = -1; int ret = -1; struct ifreq ifr;
- if ((fd = brSetupControl(ifname,&ifr))< 0) + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) return -1;
/* To fill ifr.ifr_hdaddr.sa_family field */ @@ -368,20 +358,20 @@ cleanup: }
/** - * ifGetMtu + * virNetDevGetMTU: * @ifname: interface name get MTU for * * This function gets the @mtu value set for a given interface @ifname. * * Returns the MTU value in case of success, or -1 on failure. */ -static int ifGetMtu(const char *ifname) +static int virNetDevGetMTU(const char *ifname) { int fd = -1; int ret = -1; struct ifreq ifr;
- if ((fd = brSetupControl(ifname,&ifr))< 0) + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) return -1;
if (ioctl(fd, SIOCGIFMTU,&ifr)< 0) { @@ -399,7 +389,7 @@ cleanup: }
/** - * ifSetMtu: + * virNetDevSetMTU: * @ifname: interface name to set MTU for * @mtu: MTU value * @@ -408,13 +398,13 @@ cleanup: * * Returns 0 in case of success, or -1 on failure */ -static int ifSetMtu(const char *ifname, int mtu) +static int virNetDevSetMTU(const char *ifname, int mtu) { int fd = -1; int ret = -1; struct ifreq ifr;
- if ((fd = brSetupControl(ifname,&ifr))< 0) + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) return -1;
ifr.ifr_mtu = mtu; @@ -442,19 +432,19 @@ cleanup: * * Returns 0 in case of success, or -1 on failure */ -static int brSetInterfaceMtu(const char *brname, - const char *ifname) +static int virNetDevSetMTUFromDevice(const char *brname, + const char *ifname) { - int mtu = ifGetMtu(brname); + int mtu = virNetDevGetMTU(brname);
if (mtu< 0) return -1;
- return ifSetMtu(ifname, mtu); + return virNetDevSetMTU(ifname, mtu); }
/** - * brProbeVnetHdr: + * virNetDevProbeVnetHdr: * @tapfd: a tun/tap file descriptor * * Check whether it is safe to enable the IFF_VNET_HDR flag on the @@ -474,7 +464,7 @@ static int brSetInterfaceMtu(const char *brname, */ # ifdef IFF_VNET_HDR static int -brProbeVnetHdr(int tapfd) +virNetDevProbeVnetHdr(int tapfd) { # if defined(IFF_VNET_HDR)&& defined(TUNGETFEATURES)&& defined(TUNGETIFF) unsigned int features; @@ -530,15 +520,14 @@ brProbeVnetHdr(int tapfd) * * Returns 0 in case of success or -1 on failure */ -int -brAddTap(const char *brname, - char **ifname, - const unsigned char *macaddr, - int vnet_hdr, - bool up, - int *tapfd) +int virNetDevTapCreateInBridgePort(const char *brname, + char **ifname, + const unsigned char *macaddr, + int vnet_hdr, + bool up, + int *tapfd) { - if (brCreateTap(ifname, vnet_hdr, tapfd)< 0) + if (virNetDevTapCreate(ifname, vnet_hdr, tapfd)< 0) return -1;
/* We need to set the interface MAC before adding it @@ -547,20 +536,20 @@ brAddTap(const char *brname, * seeing the kernel allocate random MAC for the TAP * device before we set our static MAC. */ - if (brSetInterfaceMac(*ifname, macaddr)< 0) + if (virNetDevSetMAC(*ifname, macaddr)< 0) goto error;
/* We need to set the interface MTU before adding it * to the bridge, because the bridge will have its * MTU adjusted automatically when we add the new interface. */ - if (brSetInterfaceMtu(brname, *ifname)< 0) + if (virNetDevSetMTUFromDevice(brname, *ifname)< 0) goto error;
- if (brAddInterface(brname, *ifname)< 0) + if (virNetDevBridgeAddPort(brname, *ifname)< 0) goto error;
- if (brSetInterfaceUp(*ifname, up)< 0) + if (virNetDevSetOnline(*ifname, up)< 0) goto error;
return 0; @@ -571,7 +560,7 @@ error: return -1; }
-int brDeleteTap(const char *ifname) +int virNetDevTapDelete(const char *ifname) { struct ifreq try; int fd; @@ -614,7 +603,7 @@ cleanup:
/** - * brSetInterfaceUp: + * virNetDevSetOnline: * @ifname: the interface name * @up: 1 for up, 0 for down * @@ -622,16 +611,15 @@ cleanup: * * Returns 0 in case of success or -1 on error. */ -int -brSetInterfaceUp(const char *ifname, - int up) +int virNetDevSetOnline(const char *ifname, + int up) { int fd = -1; int ret = -1; struct ifreq ifr; int ifflags;
- if ((fd = brSetupControl(ifname,&ifr))< 0) + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) return -1;
if (ioctl(fd, SIOCGIFFLAGS,&ifr)< 0) { @@ -664,7 +652,7 @@ cleanup: }
/** - * brGetInterfaceUp: + * virNetDevIsOnline: * @ifname: the interface name * @up: where to store the status * @@ -672,15 +660,14 @@ cleanup: * * Returns 0 in case of success or an errno code in case of failure. */ -int -brGetInterfaceUp(const char *ifname, - int *up) +int virNetDevIsOnline(const char *ifname, + int *up) { int fd = -1; int ret = -1; struct ifreq ifr;
- if ((fd = brSetupControl(ifname,&ifr))< 0) + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) return -1;
if (ioctl(fd, SIOCGIFFLAGS,&ifr)< 0) { @@ -699,7 +686,7 @@ cleanup: }
/** - * brAddInetAddress: + * virNetDevSetIPv4Addres: * @ifname: the interface name * @addr: the IP address (IPv4 or IPv6) * @prefix: number of 1 bits in the netmask @@ -711,10 +698,9 @@ cleanup: * Returns 0 in case of success or -1 in case of error. */
-int -brAddInetAddress(const char *ifname, - virSocketAddr *addr, - unsigned int prefix) +int virNetDevSetIPv4Addres(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) { virCommandPtr cmd = NULL; char *addrstr = NULL, *bcaststr = NULL; @@ -748,7 +734,7 @@ cleanup: }
/** - * brDelInetAddress: + * virNetDevClearIPv4Address: * @ifname: the interface name * @addr: the IP address (IPv4 or IPv6) * @prefix: number of 1 bits in the netmask @@ -758,10 +744,9 @@ cleanup: * Returns 0 in case of success or -1 in case of error. */
-int -brDelInetAddress(const char *ifname, - virSocketAddr *addr, - unsigned int prefix) +int virNetDevClearIPv4Address(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) { virCommandPtr cmd = NULL; char *addrstr; @@ -785,7 +770,7 @@ cleanup: }
/** - * brSetForwardDelay: + * virNetDevBridgeSetSTPDelay: * @brname: the bridge name * @delay: delay in seconds * @@ -794,9 +779,8 @@ cleanup: * Returns 0 in case of success or -1 on failure */
-int -brSetForwardDelay(const char *brname, - int delay) +int virNetDevBridgeSetSTPDelay(const char *brname, + int delay) { virCommandPtr cmd; int ret = -1; @@ -815,7 +799,7 @@ cleanup: }
/** - * brSetEnableSTP: + * virNetDevBridgeSetSTP: * @brname: the bridge name * @enable: 1 to enable, 0 to disable * @@ -824,9 +808,8 @@ cleanup: * * Returns 0 in case of success or -1 on failure */ -int -brSetEnableSTP(const char *brname, - int enable) +int virNetDevBridgeSetSTP(const char *brname, + int enable) { virCommandPtr cmd; int ret = -1; @@ -860,10 +843,9 @@ cleanup: * Returns 0 in case of success or an errno code in case of failure. */
-int -brCreateTap(char **ifname, - int vnet_hdr ATTRIBUTE_UNUSED, - int *tapfd) +int virNetDevTapCreate(char **ifname, + int vnet_hdr ATTRIBUTE_UNUSED, + int *tapfd) { int fd; struct ifreq ifr; @@ -880,7 +862,7 @@ brCreateTap(char **ifname, ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
# ifdef IFF_VNET_HDR - if (vnet_hdr&& brProbeVnetHdr(fd)) + if (vnet_hdr&& virNetDevProbeVnetHdr(fd)) ifr.ifr_flags |= IFF_VNET_HDR; # endif
diff --git a/src/util/bridge.h b/src/util/bridge.h index 2bfc4b4..44b6631 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -42,19 +42,19 @@ */ # define BR_INET_ADDR_MAXLEN INET_ADDRSTRLEN
-int brAddBridge (const char *brname) +int virNetDevBridgeCreate(const char *brname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brDeleteBridge (const char *brname) +int virNetDevBridgeDelete(const char *brname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brHasBridge (const char *brname) +int virNetDevExists(const char *brname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
-int brAddInterface (const char *brname, - const char *ifname) +int virNetDevBridgeAddPort(const char *brname, + const char *ifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
-int brDeleteInterface (const char *brname, - const char *ifname) +int virNetDevBridgeRemovePort(const char *brname, + const char *ifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
enum { @@ -62,55 +62,55 @@ enum { BR_TAP_PERSIST = (1<< 1), };
-int brAddTap (const char *brname, - char **ifname, - const unsigned char *macaddr, - int vnet_hdr, - bool up, - int *tapfd) +int virNetDevTapCreateInBridgePort(const char *brname, + char **ifname, + const unsigned char *macaddr, + int vnet_hdr, + bool up, + int *tapfd) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_RETURN_CHECK;
-int brDeleteTap (const char *ifname) +int virNetDevTapDelete(const char *ifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
-int brSetInterfaceUp (const char *ifname, - int up) +int virNetDevSetOnline(const char *ifname, + int up) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brGetInterfaceUp (const char *ifname, - int *up) +int virNetDevIsOnline(const char *ifname, + int *up) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
-int brAddInetAddress (const char *ifname, - virSocketAddr *addr, - unsigned int prefix) +int virNetDevSetIPv4Addres(const char *ifname,
Addres->Address
+ virSocketAddr *addr, + unsigned int prefix) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int brDelInetAddress (const char *ifname, - virSocketAddr *addr, - unsigned int prefix) +int virNetDevClearIPv4Address(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
-int brSetForwardDelay (const char *brname, - int delay) +int virNetDevBridgeSetSTPDelay(const char *brname, + int delay) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brGetForwardDelay (const char *brname, - int *delay) +int virNetDevBridgeGetSTPDelay(const char *brname, + int *delay) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int brSetEnableSTP (const char *brname, - int enable) +int virNetDevBridgeSetSTP(const char *brname, + int enable) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int brGetEnableSTP (const char *brname, - int *enable) +int virNetDevBridgeGetSTP(const char *brname, + int *enable) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
-int brCreateTap (char **ifname, - int vnet_hdr, - int *tapfd) +int virNetDevTapCreate(char **ifname, + int vnet_hdr, + int *tapfd) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
-int brSetInterfaceMac (const char *ifname, - const unsigned char *macaddr) +int virNetDevSetMAC(const char *ifname, + const unsigned char *macaddr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
# endif /* WITH_BRIDGE */ ACK with nit fixed.

On Tue, Nov 08, 2011 at 09:17:21AM -0500, Stefan Berger wrote:
On 11/03/2011 01:29 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
The existing brXXX APIs in src/util/bridge.h are renamed to follow one of three different conventions
- virNetDevXXX - operations for any type of interface - virNetDevBridgeXXX - operations for bridge interfaces - virNetDevTapXXX - operations for tap interfaces
* src/util/bridge.h, src/util/bridge.c: Rename all APIs * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/uml/uml_conf.c, src/uml/uml_driver.c: Update for API renaming --- src/lxc/lxc_driver.c | 2 +- src/network/bridge_driver.c | 32 ++++---- src/qemu/qemu_command.c | 4 +- src/uml/uml_conf.c | 4 +- src/uml/uml_driver.c | 2 +- src/util/bridge.c | 196 +++++++++++++++++++----------------------- src/util/bridge.h | 74 ++++++++-------- 7 files changed, 148 insertions(+), 166 deletions(-)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
-int brAddInetAddress (const char *ifname, - virSocketAddr *addr, - unsigned int prefix) +int virNetDevSetIPv4Addres(const char *ifname,
Addres->Address
Yes, and i've fixed it in later patches in the series where we move the functions to new files too. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: "Daniel P. Berrange" <berrange@redhat.com> * src/util/bridge.c, src/util/bridge.h: s/int/bool/ in virNetDevSetOnline and virNetDevBridgeSetSTP --- src/util/bridge.c | 18 +++++++++--------- src/util/bridge.h | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/util/bridge.c b/src/util/bridge.c index a853c2a..1584052 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -605,14 +605,14 @@ cleanup: /** * virNetDevSetOnline: * @ifname: the interface name - * @up: 1 for up, 0 for down + * @online: true for up, false for down * - * Function to control if an interface is activated (up, 1) or not (down, 0) + * Function to control if an interface is activated (up, true) or not (down, false) * * Returns 0 in case of success or -1 on error. */ int virNetDevSetOnline(const char *ifname, - int up) + bool online) { int fd = -1; int ret = -1; @@ -629,7 +629,7 @@ int virNetDevSetOnline(const char *ifname, goto cleanup; } - if (up) + if (online) ifflags = ifr.ifr_flags | IFF_UP; else ifflags = ifr.ifr_flags & ~IFF_UP; @@ -654,14 +654,14 @@ cleanup: /** * virNetDevIsOnline: * @ifname: the interface name - * @up: where to store the status + * @online: where to store the status * - * Function to query if an interface is activated (1) or not (0) + * Function to query if an interface is activated (true) or not (false) * * Returns 0 in case of success or an errno code in case of failure. */ int virNetDevIsOnline(const char *ifname, - int *up) + bool *online) { int fd = -1; int ret = -1; @@ -677,7 +677,7 @@ int virNetDevIsOnline(const char *ifname, goto cleanup; } - *up = (ifr.ifr_flags & IFF_UP) ? 1 : 0; + *online = (ifr.ifr_flags & IFF_UP) ? true : false; ret = 0; cleanup: @@ -809,7 +809,7 @@ cleanup: * Returns 0 in case of success or -1 on failure */ int virNetDevBridgeSetSTP(const char *brname, - int enable) + bool enable) { virCommandPtr cmd; int ret = -1; diff --git a/src/util/bridge.h b/src/util/bridge.h index 44b6631..2de7259 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -76,10 +76,10 @@ int virNetDevTapDelete(const char *ifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virNetDevSetOnline(const char *ifname, - int up) + bool online) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virNetDevIsOnline(const char *ifname, - int *up) + bool *online) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevSetIPv4Addres(const char *ifname, @@ -98,10 +98,10 @@ int virNetDevBridgeGetSTPDelay(const char *brname, int *delay) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevBridgeSetSTP(const char *brname, - int enable) + bool enable) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virNetDevBridgeGetSTP(const char *brname, - int *enable) + bool *enable) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevTapCreate(char **ifname, -- 1.7.6.4

On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
* src/util/bridge.c, src/util/bridge.h: s/int/bool/ in virNetDevSetOnline and virNetDevBridgeSetSTP --- src/util/bridge.c | 18 +++++++++--------- src/util/bridge.h | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/src/util/bridge.c b/src/util/bridge.c index a853c2a..1584052 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -605,14 +605,14 @@ cleanup: /** * virNetDevSetOnline: * @ifname: the interface name - * @up: 1 for up, 0 for down + * @online: true for up, false for down * - * Function to control if an interface is activated (up, 1) or not (down, 0) + * Function to control if an interface is activated (up, true) or not (down, false) * * Returns 0 in case of success or -1 on error. */ int virNetDevSetOnline(const char *ifname, - int up) + bool online) { int fd = -1; int ret = -1; @@ -629,7 +629,7 @@ int virNetDevSetOnline(const char *ifname, goto cleanup; }
- if (up) + if (online) ifflags = ifr.ifr_flags | IFF_UP; else ifflags = ifr.ifr_flags& ~IFF_UP; @@ -654,14 +654,14 @@ cleanup: /** * virNetDevIsOnline: * @ifname: the interface name - * @up: where to store the status + * @online: where to store the status * - * Function to query if an interface is activated (1) or not (0) + * Function to query if an interface is activated (true) or not (false) * * Returns 0 in case of success or an errno code in case of failure. */ int virNetDevIsOnline(const char *ifname, - int *up) + bool *online) { int fd = -1; int ret = -1; @@ -677,7 +677,7 @@ int virNetDevIsOnline(const char *ifname, goto cleanup; }
- *up = (ifr.ifr_flags& IFF_UP) ? 1 : 0; + *online = (ifr.ifr_flags& IFF_UP) ? true : false; ret = 0;
cleanup: @@ -809,7 +809,7 @@ cleanup: * Returns 0 in case of success or -1 on failure */ int virNetDevBridgeSetSTP(const char *brname, - int enable) + bool enable) { virCommandPtr cmd; int ret = -1; diff --git a/src/util/bridge.h b/src/util/bridge.h index 44b6631..2de7259 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -76,10 +76,10 @@ int virNetDevTapDelete(const char *ifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
int virNetDevSetOnline(const char *ifname, - int up) + bool online) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virNetDevIsOnline(const char *ifname, - int *up) + bool *online) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int virNetDevSetIPv4Addres(const char *ifname, @@ -98,10 +98,10 @@ int virNetDevBridgeGetSTPDelay(const char *brname, int *delay) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevBridgeSetSTP(const char *brname, - int enable) + bool enable) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virNetDevBridgeGetSTP(const char *brname, - int *enable) + bool *enable) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int virNetDevTapCreate(char **ifname, Hm, would have thought to see the callers being changed as well...

On Tue, Nov 08, 2011 at 09:21:19AM -0500, Stefan Berger wrote:
On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
* src/util/bridge.c, src/util/bridge.h: s/int/bool/ in virNetDevSetOnline and virNetDevBridgeSetSTP --- src/util/bridge.c | 18 +++++++++--------- src/util/bridge.h | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-)
@@ -98,10 +98,10 @@ int virNetDevBridgeGetSTPDelay(const char *brname, int *delay) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevBridgeSetSTP(const char *brname, - int enable) + bool enable) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virNetDevBridgeGetSTP(const char *brname, - int *enable) + bool *enable) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int virNetDevTapCreate(char **ifname, Hm, would have thought to see the callers being changed as well...
Yes, there was one caller which needed to change from 0/1 to false/true Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: "Daniel P. Berrange" <berrange@redhat.com> The MTU management APIs are useful to other code inside libvirt, so should be exposed as non-static APIs. * src/util/bridge.c, src/util/bridge.h: Expose virNetDevSetMTU, virNetDevSetMTUFromDevice & virNetDevGetMTU --- src/util/bridge.c | 18 +++++++++--------- src/util/bridge.h | 8 ++++++++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/util/bridge.c b/src/util/bridge.c index 1584052..247ce93 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -365,7 +365,7 @@ cleanup: * * Returns the MTU value in case of success, or -1 on failure. */ -static int virNetDevGetMTU(const char *ifname) +int virNetDevGetMTU(const char *ifname) { int fd = -1; int ret = -1; @@ -398,7 +398,7 @@ cleanup: * * Returns 0 in case of success, or -1 on failure */ -static int virNetDevSetMTU(const char *ifname, int mtu) +int virNetDevSetMTU(const char *ifname, int mtu) { int fd = -1; int ret = -1; @@ -424,18 +424,18 @@ cleanup: } /** - * brSetInterfaceMtu - * @brname: name of the bridge interface + * virNetDevSetMTUFromDevice: * @ifname: name of the interface whose MTU we want to set + * @otherifname: name of the interface whose MTU we want to copy * - * Sets the interface mtu to the same MTU of the bridge + * Sets the interface mtu to the same MTU as another interface * * Returns 0 in case of success, or -1 on failure */ -static int virNetDevSetMTUFromDevice(const char *brname, - const char *ifname) +int virNetDevSetMTUFromDevice(const char *ifname, + const char *otherifname) { - int mtu = virNetDevGetMTU(brname); + int mtu = virNetDevGetMTU(otherifname); if (mtu < 0) return -1; @@ -543,7 +543,7 @@ int virNetDevTapCreateInBridgePort(const char *brname, * to the bridge, because the bridge will have its * MTU adjusted automatically when we add the new interface. */ - if (virNetDevSetMTUFromDevice(brname, *ifname) < 0) + if (virNetDevSetMTUFromDevice(*ifname, brname) < 0) goto error; if (virNetDevBridgeAddPort(brname, *ifname) < 0) diff --git a/src/util/bridge.h b/src/util/bridge.h index 2de7259..0cc89c0 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -112,6 +112,14 @@ int virNetDevTapCreate(char **ifname, int virNetDevSetMAC(const char *ifname, const unsigned char *macaddr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetMTU(const char *ifname, + int mtu) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetMTUFromDevice(const char *ifname, + const char *otherifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetMTU(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; # endif /* WITH_BRIDGE */ -- 1.7.6.4

On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
The MTU management APIs are useful to other code inside libvirt, so should be exposed as non-static APIs.
* src/util/bridge.c, src/util/bridge.h: Expose virNetDevSetMTU, virNetDevSetMTUFromDevice& virNetDevGetMTU --- src/util/bridge.c | 18 +++++++++--------- src/util/bridge.h | 8 ++++++++ 2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/src/util/bridge.c b/src/util/bridge.c index 1584052..247ce93 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -365,7 +365,7 @@ cleanup: * * Returns the MTU value in case of success, or -1 on failure. */ -static int virNetDevGetMTU(const char *ifname) +int virNetDevGetMTU(const char *ifname) { int fd = -1; int ret = -1; @@ -398,7 +398,7 @@ cleanup: * * Returns 0 in case of success, or -1 on failure */ -static int virNetDevSetMTU(const char *ifname, int mtu) +int virNetDevSetMTU(const char *ifname, int mtu) { int fd = -1; int ret = -1; @@ -424,18 +424,18 @@ cleanup: }
/** - * brSetInterfaceMtu - * @brname: name of the bridge interface + * virNetDevSetMTUFromDevice: * @ifname: name of the interface whose MTU we want to set + * @otherifname: name of the interface whose MTU we want to copy * - * Sets the interface mtu to the same MTU of the bridge + * Sets the interface mtu to the same MTU as another interface * * Returns 0 in case of success, or -1 on failure */ -static int virNetDevSetMTUFromDevice(const char *brname, - const char *ifname) +int virNetDevSetMTUFromDevice(const char *ifname, + const char *otherifname) { - int mtu = virNetDevGetMTU(brname); + int mtu = virNetDevGetMTU(otherifname);
if (mtu< 0) return -1; @@ -543,7 +543,7 @@ int virNetDevTapCreateInBridgePort(const char *brname, * to the bridge, because the bridge will have its * MTU adjusted automatically when we add the new interface. */ - if (virNetDevSetMTUFromDevice(brname, *ifname)< 0) + if (virNetDevSetMTUFromDevice(*ifname, brname)< 0) goto error;
if (virNetDevBridgeAddPort(brname, *ifname)< 0) diff --git a/src/util/bridge.h b/src/util/bridge.h index 2de7259..0cc89c0 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -112,6 +112,14 @@ int virNetDevTapCreate(char **ifname, int virNetDevSetMAC(const char *ifname, const unsigned char *macaddr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetMTU(const char *ifname, + int mtu) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetMTUFromDevice(const char *ifname, + const char *otherifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetMTU(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
# endif /* WITH_BRIDGE */
ACK

From: "Daniel P. Berrange" <berrange@redhat.com> * src/util/bridge.c, src/util/bridge.h: Add virNetDevGetMAC --- src/util/bridge.c | 35 +++++++++++++++++++++++++++++++++++ src/util/bridge.h | 3 +++ 2 files changed, 38 insertions(+), 0 deletions(-) diff --git a/src/util/bridge.c b/src/util/bridge.c index 247ce93..3a7012c 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -358,6 +358,41 @@ cleanup: } /** + * virNetDevGetMAC: + * @ifname: interface name to set MTU for + * @macaddr: MAC address (VIR_MAC_BUFLEN in size) + * + * This function gets the @macaddr for a given interface @ifname. + * + * Returns 0 in case of success or -1 on failure + */ +int virNetDevGetMAC(const char *ifname, + unsigned char *macaddr) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { + virReportSystemError(errno, + _("Cannot get interface MAC on '%s'"), + ifname); + goto cleanup; + } + + memcpy(macaddr, ifr.ifr_hwaddr.sa_data, VIR_MAC_BUFLEN); + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + +/** * virNetDevGetMTU: * @ifname: interface name get MTU for * diff --git a/src/util/bridge.h b/src/util/bridge.h index 0cc89c0..7504925 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -112,6 +112,9 @@ int virNetDevTapCreate(char **ifname, int virNetDevSetMAC(const char *ifname, const unsigned char *macaddr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetMAC(const char *ifname, + unsigned char *macaddr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevSetMTU(const char *ifname, int mtu) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -- 1.7.6.4

On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
* src/util/bridge.c, src/util/bridge.h: Add virNetDevGetMAC --- src/util/bridge.c | 35 +++++++++++++++++++++++++++++++++++ src/util/bridge.h | 3 +++ 2 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/src/util/bridge.c b/src/util/bridge.c index 247ce93..3a7012c 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -358,6 +358,41 @@ cleanup: }
/** + * virNetDevGetMAC: + * @ifname: interface name to set MTU for + * @macaddr: MAC address (VIR_MAC_BUFLEN in size) + * + * This function gets the @macaddr for a given interface @ifname. + * + * Returns 0 in case of success or -1 on failure + */ +int virNetDevGetMAC(const char *ifname, + unsigned char *macaddr) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) + return -1; + + if (ioctl(fd, SIOCGIFHWADDR,&ifr)< 0) { + virReportSystemError(errno, + _("Cannot get interface MAC on '%s'"), + ifname); + goto cleanup; + } + + memcpy(macaddr, ifr.ifr_hwaddr.sa_data, VIR_MAC_BUFLEN); + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + +/** * virNetDevGetMTU: * @ifname: interface name get MTU for * diff --git a/src/util/bridge.h b/src/util/bridge.h index 0cc89c0..7504925 100644 --- a/src/util/bridge.h +++ b/src/util/bridge.h @@ -112,6 +112,9 @@ int virNetDevTapCreate(char **ifname, int virNetDevSetMAC(const char *ifname, const unsigned char *macaddr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetMAC(const char *ifname, + unsigned char *macaddr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevSetMTU(const char *ifname, int mtu) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; I like the short patches :-)
ACK

From: "Daniel P. Berrange" <berrange@redhat.com> Convert the virNetDevBridgeSetSTP and virNetDevBridgeSetSTPDelay to use ioctls instead of spawning brctl. Implement the virNetDevBridgeGetSTP and virNetDevBridgeGetSTPDelay methods which were declared in the header but never existed * src/util/bridge.c: Convert to use bridge ioctls instead of brctl --- configure.ac | 2 - libvirt.spec.in | 2 - src/util/bridge.c | 199 +++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 184 insertions(+), 19 deletions(-) diff --git a/configure.ac b/configure.ac index 5753c08..0ce020d 100644 --- a/configure.ac +++ b/configure.ac @@ -197,8 +197,6 @@ AC_DEFINE_UNQUOTED([DNSMASQ],["$DNSMASQ"], [Location or name of the dnsmasq program]) AC_DEFINE_UNQUOTED([RADVD],["$RADVD"], [Location or name of the radvd program]) -AC_DEFINE_UNQUOTED([BRCTL],["$BRCTL"], - [Location or name of the brctl program (see bridge-utils)]) AC_DEFINE_UNQUOTED([TC],["$TC"], [Location or name of the tc profram (see iproute2)]) if test -n "$UDEVADM"; then diff --git a/libvirt.spec.in b/libvirt.spec.in index 261f34c..eda0bcc 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -251,7 +251,6 @@ Requires: %{name}-client = %{version}-%{release} # Used by many of the drivers, so turn it on whenever the # daemon is present %if %{with_libvirtd} -Requires: bridge-utils # for modprobe of pci devices Requires: module-init-tools # for /sbin/ip & /sbin/tc @@ -380,7 +379,6 @@ BuildRequires: radvd %if %{with_nwfilter} BuildRequires: ebtables %endif -BuildRequires: bridge-utils BuildRequires: module-init-tools %if %{with_sasl} BuildRequires: cyrus-sasl-devel diff --git a/src/util/bridge.c b/src/util/bridge.c index 3a7012c..0265e81 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -52,6 +52,7 @@ # include "logging.h" # include "network.h" # include "virterror_internal.h" +# include "intprops.h" # define JIFFIES_TO_MS(j) (((j)*1000)/HZ) # define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000) @@ -99,6 +100,112 @@ static int virNetDevSetupControl(const char *ifname, return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); } +# define SYSFS_NET_DIR "/sys/class/net" +/* + * Bridge parameters can be set via sysfs on newish kernels, + * or by ioctl on older kernels. Perhaps we could just use + * ioctl for every kernel, but its not clear what the long + * term lifespan of the ioctl interface is... + */ +static int virNetDevBridgeSet(const char *brname, + const char *paramname, /* sysfs param name */ + unsigned long value, /* new value */ + int fd, /* control socket */ + struct ifreq *ifr) /* pre-filled bridge name */ +{ + char *path = NULL; + int ret = -1; + + if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname) < 0) { + virReportOOMError(); + return -1; + } + + if (virFileExists(path)) { + char valuestr[INT_BUFSIZE_BOUND(value)]; + snprintf(valuestr, sizeof(valuestr), "%lu", value); + if (virFileWriteStr(path, valuestr, 0) < 0) { + virReportSystemError(errno, + _("Unable to set bridge %s %s"), brname, paramname); + goto cleanup; + } + } else { + unsigned long paramid; + if (STREQ(paramname, "stp_state")) { + paramid = BRCTL_SET_BRIDGE_STP_STATE; + } else if (STREQ(paramname, "forward_delay")) { + paramid = BRCTL_SET_BRIDGE_FORWARD_DELAY; + } else { + virReportSystemError(EINVAL, + _("Unable to set bridge %s %s"), brname, paramname); + goto cleanup; + } + unsigned long args[] = { paramid, value, 0, 0 }; + ifr->ifr_data = (char*)&args; + if (ioctl(fd, SIOCDEVPRIVATE, ifr) < 0) { + virReportSystemError(errno, + _("Unable to set bridge %s %s"), brname, paramname); + goto cleanup; + } + } + + ret = 0; +cleanup: + VIR_FREE(path); + return ret; +} + + +static int virNetDevBridgeGet(const char *brname, + const char *paramname, /* sysfs param name */ + unsigned long *value, /* current value */ + int fd, /* control socket */ + struct ifreq *ifr) /* pre-filled bridge name */ +{ + char *path = NULL; + int ret = -1; + + if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname) < 0) { + virReportOOMError(); + return -1; + } + + if (virFileExists(path)) { + char *valuestr; + if (virFileReadAll(path, INT_BUFSIZE_BOUND(unsigned long), &valuestr) < 0) + goto cleanup; + + if (virStrToLong_ul(valuestr, NULL, 10, value) < 0) { + virReportSystemError(EINVAL, + _("Unable to get bridge %s %s"), brname, paramname); + } + } else { + struct __bridge_info info; + unsigned long args[] = { BRCTL_GET_BRIDGE_INFO, (unsigned long)&info, 0, 0 }; + ifr->ifr_data = (char*)&args; + if (ioctl(fd, SIOCDEVPRIVATE, ifr) < 0) { + virReportSystemError(errno, + _("Unable to get bridge %s %s"), brname, paramname); + goto cleanup; + } + + if (STREQ(paramname, "stp_state")) { + *value = info.stp_enabled; + } else if (STREQ(paramname, "forward_delay")) { + *value = info.forward_delay; + } else { + virReportSystemError(EINVAL, + _("Unable to get bridge %s %s"), brname, paramname); + goto cleanup; + } + } + + ret = 0; +cleanup: + VIR_FREE(path); + return ret; +} + /** * virNetDevBridgeCreate: @@ -817,22 +924,54 @@ cleanup: int virNetDevBridgeSetSTPDelay(const char *brname, int delay) { - virCommandPtr cmd; + int fd = -1; int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) + goto cleanup; - cmd = virCommandNew(BRCTL); - virCommandAddArgList(cmd, "setfd", brname, NULL); - virCommandAddArgFormat(cmd, "%d", delay); + ret = virNetDevBridgeSet(brname, "stp_state", MS_TO_JIFFIES(delay), + fd, &ifr); - if (virCommandRun(cmd, NULL) < 0) +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + + +/** + * virNetDevBridgeGetSTPDelay: + * @brname: the bridge device name + * @delayms: the forward delay in milliseconds + * + * Retrives the forward delay for the bridge device @brname + * storing it in @delayms. The forward delay is only meaningful + * if STP is enabled + * + * Returns 0 on success, -1 on error+ + */ +int virNetDevBridgeGetSTPDelay(const char *brname, + int *delayms) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + unsigned long i; + + if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) goto cleanup; - ret = 0; + ret = virNetDevBridgeGet(brname, "stp_state", &i, + fd, &ifr); + *delayms = JIFFIES_TO_MS(i); + cleanup: - virCommandFree(cmd); + VIR_FORCE_CLOSE(fd); return ret; } + /** * virNetDevBridgeSetSTP: * @brname: the bridge name @@ -846,23 +985,53 @@ cleanup: int virNetDevBridgeSetSTP(const char *brname, bool enable) { - virCommandPtr cmd; + int fd = -1; int ret = -1; + struct ifreq ifr; - cmd = virCommandNew(BRCTL); - virCommandAddArgList(cmd, "stp", brname, - enable ? "on" : "off", - NULL); + if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) + goto cleanup; - if (virCommandRun(cmd, NULL) < 0) + ret = virNetDevBridgeSet(brname, "stp_state", enable ? 1 : 0, + fd, &ifr); + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + + +/** + * virNetDevBridgeGetSTP: + * @brname: the bridge device name + * @enabled: returns the STP state + * + * Determine the state of the spanning tree protocol on + * the device @brname, returning the state in @enabled + * + * Returns 0 on success, -1 on error + */ +int virNetDevBridgeGetSTP(const char *brname, + bool *enabled) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + unsigned long i; + + if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) goto cleanup; - ret = 0; + ret = virNetDevBridgeGet(brname, "stp_state", &i, + fd, &ifr); + *enabled = i ? true : false; + cleanup: - virCommandFree(cmd); + VIR_FORCE_CLOSE(fd); return ret; } + /** * brCreateTap: * @ifname: the interface name -- 1.7.6.4

On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
Convert the virNetDevBridgeSetSTP and virNetDevBridgeSetSTPDelay to use ioctls instead of spawning brctl.
Implement the virNetDevBridgeGetSTP and virNetDevBridgeGetSTPDelay methods which were declared in the header but never existed
* src/util/bridge.c: Convert to use bridge ioctls instead of brctl --- configure.ac | 2 - libvirt.spec.in | 2 - src/util/bridge.c | 199 +++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 184 insertions(+), 19 deletions(-)
diff --git a/configure.ac b/configure.ac index 5753c08..0ce020d 100644 --- a/configure.ac +++ b/configure.ac @@ -197,8 +197,6 @@ AC_DEFINE_UNQUOTED([DNSMASQ],["$DNSMASQ"], [Location or name of the dnsmasq program]) AC_DEFINE_UNQUOTED([RADVD],["$RADVD"], [Location or name of the radvd program]) -AC_DEFINE_UNQUOTED([BRCTL],["$BRCTL"], - [Location or name of the brctl program (see bridge-utils)]) AC_DEFINE_UNQUOTED([TC],["$TC"], [Location or name of the tc profram (see iproute2)]) if test -n "$UDEVADM"; then diff --git a/libvirt.spec.in b/libvirt.spec.in index 261f34c..eda0bcc 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -251,7 +251,6 @@ Requires: %{name}-client = %{version}-%{release} # Used by many of the drivers, so turn it on whenever the # daemon is present %if %{with_libvirtd} -Requires: bridge-utils # for modprobe of pci devices Requires: module-init-tools # for /sbin/ip& /sbin/tc @@ -380,7 +379,6 @@ BuildRequires: radvd %if %{with_nwfilter} BuildRequires: ebtables %endif -BuildRequires: bridge-utils BuildRequires: module-init-tools %if %{with_sasl} BuildRequires: cyrus-sasl-devel diff --git a/src/util/bridge.c b/src/util/bridge.c index 3a7012c..0265e81 100644 --- a/src/util/bridge.c +++ b/src/util/bridge.c @@ -52,6 +52,7 @@ # include "logging.h" # include "network.h" # include "virterror_internal.h" +# include "intprops.h"
# define JIFFIES_TO_MS(j) (((j)*1000)/HZ) # define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000) @@ -99,6 +100,112 @@ static int virNetDevSetupControl(const char *ifname, return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); }
+# define SYSFS_NET_DIR "/sys/class/net" +/* + * Bridge parameters can be set via sysfs on newish kernels, + * or by ioctl on older kernels. Perhaps we could just use + * ioctl for every kernel, but its not clear what the long + * term lifespan of the ioctl interface is... + */ +static int virNetDevBridgeSet(const char *brname, + const char *paramname, /* sysfs param name */ + unsigned long value, /* new value */ + int fd, /* control socket */ + struct ifreq *ifr) /* pre-filled bridge name */ +{ + char *path = NULL; + int ret = -1; + + if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname)< 0) { + virReportOOMError(); + return -1; + } + + if (virFileExists(path)) { + char valuestr[INT_BUFSIZE_BOUND(value)]; + snprintf(valuestr, sizeof(valuestr), "%lu", value); + if (virFileWriteStr(path, valuestr, 0)< 0) { + virReportSystemError(errno, + _("Unable to set bridge %s %s"), brname, paramname); + goto cleanup; + } + } else { + unsigned long paramid; + if (STREQ(paramname, "stp_state")) { + paramid = BRCTL_SET_BRIDGE_STP_STATE; + } else if (STREQ(paramname, "forward_delay")) { + paramid = BRCTL_SET_BRIDGE_FORWARD_DELAY; + } else { + virReportSystemError(EINVAL, + _("Unable to set bridge %s %s"), brname, paramname); + goto cleanup; + } + unsigned long args[] = { paramid, value, 0, 0 }; + ifr->ifr_data = (char*)&args; + if (ioctl(fd, SIOCDEVPRIVATE, ifr)< 0) { + virReportSystemError(errno, + _("Unable to set bridge %s %s"), brname, paramname); + goto cleanup; + } + } + + ret = 0; +cleanup: + VIR_FREE(path); + return ret; +} + + +static int virNetDevBridgeGet(const char *brname, + const char *paramname, /* sysfs param name */ + unsigned long *value, /* current value */ + int fd, /* control socket */ + struct ifreq *ifr) /* pre-filled bridge name */ +{ + char *path = NULL; + int ret = -1; + + if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname)< 0) { + virReportOOMError(); + return -1; + } + + if (virFileExists(path)) { + char *valuestr; + if (virFileReadAll(path, INT_BUFSIZE_BOUND(unsigned long),&valuestr)< 0) + goto cleanup; + + if (virStrToLong_ul(valuestr, NULL, 10, value)< 0) { + virReportSystemError(EINVAL, + _("Unable to get bridge %s %s"), brname, paramname); + } + } else { + struct __bridge_info info; + unsigned long args[] = { BRCTL_GET_BRIDGE_INFO, (unsigned long)&info, 0, 0 }; + ifr->ifr_data = (char*)&args; + if (ioctl(fd, SIOCDEVPRIVATE, ifr)< 0) { + virReportSystemError(errno, + _("Unable to get bridge %s %s"), brname, paramname); + goto cleanup; + } + + if (STREQ(paramname, "stp_state")) { + *value = info.stp_enabled; + } else if (STREQ(paramname, "forward_delay")) { + *value = info.forward_delay; + } else { + virReportSystemError(EINVAL, + _("Unable to get bridge %s %s"), brname, paramname); + goto cleanup; + } + } + + ret = 0; +cleanup: + VIR_FREE(path); + return ret; +} +
/** * virNetDevBridgeCreate: @@ -817,22 +924,54 @@ cleanup: int virNetDevBridgeSetSTPDelay(const char *brname, int delay) { - virCommandPtr cmd; + int fd = -1; Also applicable for the other patches, the initialization to -1 doesn't seem necessary. int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(brname,&ifr))< 0) + goto cleanup;
- cmd = virCommandNew(BRCTL); - virCommandAddArgList(cmd, "setfd", brname, NULL); - virCommandAddArgFormat(cmd, "%d", delay); + ret = virNetDevBridgeSet(brname, "stp_state", MS_TO_JIFFIES(delay), + fd,&ifr);
- if (virCommandRun(cmd, NULL)< 0) +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + + +/** + * virNetDevBridgeGetSTPDelay: + * @brname: the bridge device name + * @delayms: the forward delay in milliseconds + * + * Retrives the forward delay for the bridge device @brname + * storing it in @delayms. The forward delay is only meaningful + * if STP is enabled + * + * Returns 0 on success, -1 on error+ + */ +int virNetDevBridgeGetSTPDelay(const char *brname, + int *delayms) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + unsigned long i; + + if ((fd = virNetDevSetupControl(brname,&ifr))< 0) goto cleanup;
- ret = 0; + ret = virNetDevBridgeGet(brname, "stp_state",&i, + fd,&ifr); + *delayms = JIFFIES_TO_MS(i); + cleanup: - virCommandFree(cmd); + VIR_FORCE_CLOSE(fd); return ret; }
+ /** * virNetDevBridgeSetSTP: * @brname: the bridge name @@ -846,23 +985,53 @@ cleanup: int virNetDevBridgeSetSTP(const char *brname, bool enable) { - virCommandPtr cmd; + int fd = -1; int ret = -1; + struct ifreq ifr;
- cmd = virCommandNew(BRCTL); - virCommandAddArgList(cmd, "stp", brname, - enable ? "on" : "off", - NULL); + if ((fd = virNetDevSetupControl(brname,&ifr))< 0) + goto cleanup;
- if (virCommandRun(cmd, NULL)< 0) + ret = virNetDevBridgeSet(brname, "stp_state", enable ? 1 : 0, + fd,&ifr); + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + + +/** + * virNetDevBridgeGetSTP: + * @brname: the bridge device name + * @enabled: returns the STP state + * + * Determine the state of the spanning tree protocol on + * the device @brname, returning the state in @enabled + * + * Returns 0 on success, -1 on error + */ +int virNetDevBridgeGetSTP(const char *brname, + bool *enabled) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + unsigned long i; + + if ((fd = virNetDevSetupControl(brname,&ifr))< 0) goto cleanup;
- ret = 0; + ret = virNetDevBridgeGet(brname, "stp_state",&i, + fd,&ifr); + *enabled = i ? true : false; + cleanup: - virCommandFree(cmd); + VIR_FORCE_CLOSE(fd); return ret; }
+ /** * brCreateTap: * @ifname: the interface name ACK

On Tue, Nov 08, 2011 at 09:48:34AM -0500, Stefan Berger wrote:
On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
Convert the virNetDevBridgeSetSTP and virNetDevBridgeSetSTPDelay to use ioctls instead of spawning brctl.
Implement the virNetDevBridgeGetSTP and virNetDevBridgeGetSTPDelay methods which were declared in the header but never existed
* src/util/bridge.c: Convert to use bridge ioctls instead of brctl --- configure.ac | 2 - libvirt.spec.in | 2 - src/util/bridge.c | 199 +++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 184 insertions(+), 19 deletions(-)
@@ -817,22 +924,54 @@ cleanup: int virNetDevBridgeSetSTPDelay(const char *brname, int delay) { - virCommandPtr cmd; + int fd = -1;
Also applicable for the other patches, the initialization to -1 doesn't seem necessary.
I prefer to be overly cautious when declaring file descriptor variables. Even though the current code will always initialize FD, someone might come along later and refactor the method, resulting in code which needs the -1 initialization at declaration. GCC is not entirely reliable at detecting use of uninitialized variables. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: "Daniel P. Berrange" <berrange@redhat.com> Following the renaming of the bridge management APIs, we can now split the source file into 3 corresponding pieces * src/util/virnetdev.c: APIs for any type of network interface * src/util/virnetdevbridge.c: APIs for bridge interfaces * src/util/virnetdevtap.c: APIs for TAP interfaces * src/util/virnetdev.c, src/util/virnetdev.h, src/util/virnetdevbridge.c, src/util/virnetdevbridge.h, src/util/virnetdevtap.c, src/util/virnetdevtap.h: Copied from bridge.{c,h} * src/util/bridge.c, src/util/bridge.h: Split into 3 pieces * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/openvz/openvz_driver.c, src/qemu/qemu_command.c, src/qemu/qemu_conf.h, src/uml/uml_conf.c, src/uml/uml_conf.h, src/uml/uml_driver.c: Update #include directives --- configure.ac | 3 +- po/POTFILES.in | 4 +- src/Makefile.am | 6 +- src/lxc/lxc_driver.c | 2 +- src/network/bridge_driver.c | 5 +- src/openvz/openvz_driver.c | 1 - src/qemu/qemu_command.c | 1 + src/qemu/qemu_conf.h | 1 - src/uml/uml_conf.c | 2 +- src/uml/uml_conf.h | 1 - src/uml/uml_driver.c | 1 + src/util/bridge.c | 1115 ------------------------------------------- src/util/bridge.h | 129 ----- src/util/virnetdev.c | 524 ++++++++++++++++++++ src/util/virnetdev.h | 63 +++ src/util/virnetdevbridge.c | 527 ++++++++++++++++++++ src/util/virnetdevbridge.h | 54 ++ src/util/virnetdevtap.c | 300 ++++++++++++ src/util/virnetdevtap.h | 45 ++ 19 files changed, 1530 insertions(+), 1254 deletions(-) delete mode 100644 src/util/bridge.c delete mode 100644 src/util/bridge.h create mode 100644 src/util/virnetdev.c create mode 100644 src/util/virnetdev.h create mode 100644 src/util/virnetdevbridge.c create mode 100644 src/util/virnetdevbridge.h create mode 100644 src/util/virnetdevtap.c create mode 100644 src/util/virnetdevtap.h diff --git a/configure.ac b/configure.ac index 0ce020d..c2746d8 100644 --- a/configure.ac +++ b/configure.ac @@ -150,7 +150,8 @@ LIBS=$old_libs dnl Availability of various common headers (non-fatal if missing). AC_CHECK_HEADERS([pwd.h paths.h regex.h sys/un.h \ sys/poll.h syslog.h mntent.h net/ethernet.h linux/magic.h \ - sys/un.h sys/syscall.h netinet/tcp.h ifaddrs.h libtasn1.h]) + sys/un.h sys/syscall.h netinet/tcp.h ifaddrs.h libtasn1.h \ + net/if.h]) dnl Our only use of libtasn1.h is in the testsuite, and can be skipped dnl if the header is not present. Assume -ltasn1 is present if the diff --git a/po/POTFILES.in b/po/POTFILES.in index bd1d7bd..a3685e8 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -102,7 +102,6 @@ src/test/test_driver.c src/uml/uml_conf.c src/uml/uml_driver.c src/util/authhelper.c -src/util/bridge.c src/util/cgroup.c src/util/command.c src/util/conf.c @@ -127,6 +126,9 @@ src/util/sysinfo.c src/util/util.c src/util/viraudit.c src/util/virfile.c +src/util/virnetdev.c +src/util/virnetdevbridge.c +src/util/virnetdevtap.c src/util/virpidfile.c src/util/virterror.c src/util/xml.c diff --git a/src/Makefile.am b/src/Makefile.am index bf26b19..f742f2a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -52,7 +52,6 @@ augeastest_DATA = UTIL_SOURCES = \ util/authhelper.c util/authhelper.h \ util/bitmap.c util/bitmap.h \ - util/bridge.c util/bridge.h \ util/buf.c util/buf.h \ util/command.c util/command.h \ util/conf.c util/conf.h \ @@ -91,7 +90,10 @@ UTIL_SOURCES = \ util/xml.c util/xml.h \ util/virterror.c util/virterror_internal.h \ util/virkeycode.c util/virkeycode.h \ - util/virkeymaps.h + util/virkeymaps.h \ + util/virnetdev.h util/virnetdev.c \ + util/virnetdevbridge.h util/virnetdevbridge.c \ + util/virnetdevtap.h util/virnetdevtap.c EXTRA_DIST += $(srcdir)/util/virkeymaps.h $(srcdir)/util/keymaps.csv \ $(srcdir)/util/virkeycode-mapgen.py diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index c75941f..5701467 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -43,7 +43,7 @@ #include "lxc_driver.h" #include "memory.h" #include "util.h" -#include "bridge.h" +#include "virnetdevbridge.h" #include "veth.h" #include "nodeinfo.h" #include "uuid.h" diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index bc9d2e1..bc3a18f 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -42,6 +42,7 @@ #include <stdio.h> #include <sys/wait.h> #include <sys/ioctl.h> +#include <net/if.h> #include "virterror_internal.h" #include "datatypes.h" @@ -55,13 +56,15 @@ #include "memory.h" #include "uuid.h" #include "iptables.h" -#include "bridge.h" #include "interface.h" #include "logging.h" #include "dnsmasq.h" #include "util/network.h" #include "configmake.h" #include "ignore-value.h" +#include "virnetdev.h" +#include "virnetdevbridge.h" +#include "virnetdevtap.h" #define NETWORK_PID_DIR LOCALSTATEDIR "/run/libvirt/network" #define NETWORK_STATE_DIR LOCALSTATEDIR "/lib/libvirt/network" diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 69ff444..12867d3 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -54,7 +54,6 @@ #include "openvz_conf.h" #include "nodeinfo.h" #include "memory.h" -#include "bridge.h" #include "virfile.h" #include "logging.h" #include "command.h" diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5680636..7c9e60b 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -38,6 +38,7 @@ #include "domain_audit.h" #include "domain_conf.h" #include "network/bridge_driver.h" +#include "virnetdevtap.h" #include <sys/utsname.h> #include <sys/stat.h> diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 1ba2002..bbe7e74 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -28,7 +28,6 @@ # include "ebtables.h" # include "internal.h" -# include "bridge.h" # include "capabilities.h" # include "network_conf.h" # include "domain_conf.h" diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c index 9b6abe7..3089abb 100644 --- a/src/uml/uml_conf.c +++ b/src/uml/uml_conf.c @@ -43,11 +43,11 @@ #include "util.h" #include "memory.h" #include "nodeinfo.h" -#include "bridge.h" #include "logging.h" #include "domain_nwfilter.h" #include "virfile.h" #include "command.h" +#include "virnetdevtap.h" #define VIR_FROM_THIS VIR_FROM_UML diff --git a/src/uml/uml_conf.h b/src/uml/uml_conf.h index 01695c7..383ae66 100644 --- a/src/uml/uml_conf.h +++ b/src/uml/uml_conf.h @@ -25,7 +25,6 @@ # define __UML_CONF_H # include "internal.h" -# include "bridge.h" # include "capabilities.h" # include "network_conf.h" # include "domain_conf.h" diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 4a417ab..c5587d0 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -62,6 +62,7 @@ #include "virfile.h" #include "fdstream.h" #include "configmake.h" +#include "virnetdevtap.h" #define VIR_FROM_THIS VIR_FROM_UML diff --git a/src/util/bridge.c b/src/util/bridge.c deleted file mode 100644 index 0265e81..0000000 --- a/src/util/bridge.c +++ /dev/null @@ -1,1115 +0,0 @@ -/* - * Copyright (C) 2007, 2009, 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Authors: - * Mark McLoughlin <markmc@redhat.com> - */ - -#include <config.h> - -#if defined(WITH_BRIDGE) - -# include "bridge.h" -# include "virfile.h" - -# include <stdlib.h> -# include <stdio.h> -# include <string.h> -# include <unistd.h> -# include <fcntl.h> -# include <errno.h> -# include <arpa/inet.h> -# include <sys/types.h> -# include <sys/socket.h> -# include <sys/ioctl.h> -# include <paths.h> -# include <sys/wait.h> - -# include <linux/param.h> /* HZ */ -# include <linux/sockios.h> /* SIOCBRADDBR etc. */ -# include <linux/if_bridge.h> /* SYSFS_BRIDGE_ATTR */ -# include <linux/if_tun.h> /* IFF_TUN, IFF_NO_PI */ -# include <net/if_arp.h> /* ARPHRD_ETHER */ - -# include "internal.h" -# include "command.h" -# include "memory.h" -# include "util.h" -# include "logging.h" -# include "network.h" -# include "virterror_internal.h" -# include "intprops.h" - -# define JIFFIES_TO_MS(j) (((j)*1000)/HZ) -# define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000) - -# define VIR_FROM_THIS VIR_FROM_NONE - -static int virNetDevSetupControlFull(const char *ifname, - struct ifreq *ifr, - int domain, - int type) -{ - int fd; - - if (ifname && ifr) { - memset(ifr, 0, sizeof(*ifr)); - - if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) { - virReportSystemError(ERANGE, - _("Network interface name '%s' is too long"), - ifname); - return -1; - } - } - - if ((fd = socket(domain, type, 0)) < 0) { - virReportSystemError(errno, "%s", - _("Cannot open network interface control socket")); - return -1; - } - - if (virSetInherit(fd, false) < 0) { - virReportSystemError(errno, "%s", - _("Cannot set close-on-exec flag for socket")); - VIR_FORCE_CLOSE(fd); - return -1; - } - - return fd; -} - - -static int virNetDevSetupControl(const char *ifname, - struct ifreq *ifr) -{ - return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); -} - -# define SYSFS_NET_DIR "/sys/class/net" -/* - * Bridge parameters can be set via sysfs on newish kernels, - * or by ioctl on older kernels. Perhaps we could just use - * ioctl for every kernel, but its not clear what the long - * term lifespan of the ioctl interface is... - */ -static int virNetDevBridgeSet(const char *brname, - const char *paramname, /* sysfs param name */ - unsigned long value, /* new value */ - int fd, /* control socket */ - struct ifreq *ifr) /* pre-filled bridge name */ -{ - char *path = NULL; - int ret = -1; - - if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname) < 0) { - virReportOOMError(); - return -1; - } - - if (virFileExists(path)) { - char valuestr[INT_BUFSIZE_BOUND(value)]; - snprintf(valuestr, sizeof(valuestr), "%lu", value); - if (virFileWriteStr(path, valuestr, 0) < 0) { - virReportSystemError(errno, - _("Unable to set bridge %s %s"), brname, paramname); - goto cleanup; - } - } else { - unsigned long paramid; - if (STREQ(paramname, "stp_state")) { - paramid = BRCTL_SET_BRIDGE_STP_STATE; - } else if (STREQ(paramname, "forward_delay")) { - paramid = BRCTL_SET_BRIDGE_FORWARD_DELAY; - } else { - virReportSystemError(EINVAL, - _("Unable to set bridge %s %s"), brname, paramname); - goto cleanup; - } - unsigned long args[] = { paramid, value, 0, 0 }; - ifr->ifr_data = (char*)&args; - if (ioctl(fd, SIOCDEVPRIVATE, ifr) < 0) { - virReportSystemError(errno, - _("Unable to set bridge %s %s"), brname, paramname); - goto cleanup; - } - } - - ret = 0; -cleanup: - VIR_FREE(path); - return ret; -} - - -static int virNetDevBridgeGet(const char *brname, - const char *paramname, /* sysfs param name */ - unsigned long *value, /* current value */ - int fd, /* control socket */ - struct ifreq *ifr) /* pre-filled bridge name */ -{ - char *path = NULL; - int ret = -1; - - if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname) < 0) { - virReportOOMError(); - return -1; - } - - if (virFileExists(path)) { - char *valuestr; - if (virFileReadAll(path, INT_BUFSIZE_BOUND(unsigned long), &valuestr) < 0) - goto cleanup; - - if (virStrToLong_ul(valuestr, NULL, 10, value) < 0) { - virReportSystemError(EINVAL, - _("Unable to get bridge %s %s"), brname, paramname); - } - } else { - struct __bridge_info info; - unsigned long args[] = { BRCTL_GET_BRIDGE_INFO, (unsigned long)&info, 0, 0 }; - ifr->ifr_data = (char*)&args; - if (ioctl(fd, SIOCDEVPRIVATE, ifr) < 0) { - virReportSystemError(errno, - _("Unable to get bridge %s %s"), brname, paramname); - goto cleanup; - } - - if (STREQ(paramname, "stp_state")) { - *value = info.stp_enabled; - } else if (STREQ(paramname, "forward_delay")) { - *value = info.forward_delay; - } else { - virReportSystemError(EINVAL, - _("Unable to get bridge %s %s"), brname, paramname); - goto cleanup; - } - } - - ret = 0; -cleanup: - VIR_FREE(path); - return ret; -} - - -/** - * virNetDevBridgeCreate: - * @brname: the bridge name - * - * This function register a new bridge - * - * Returns 0 in case of success or -1 on failure - */ -# ifdef SIOCBRADDBR -int virNetDevBridgeCreate(const char *brname) -{ - int fd = -1; - int ret = -1; - - if ((fd = virNetDevSetupControl(NULL, NULL)) < 0) - return -1; - - if (ioctl(fd, SIOCBRADDBR, brname) < 0) { - virReportSystemError(errno, - _("Unable to create bridge %s"), brname); - goto cleanup; - } - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} -# else -int virNetDevBridgeCreate(const char *brname) -{ - virReportSystemError(ENOSYS, - _("Unable to create bridge %s"), brname); - return -1; -} -# endif - -# ifdef SIOCBRDELBR -/** - * virNetDevExists: - * @ifname - * - * Check if the network device @ifname exists - * - * Returns 1 if it exists, 0 if it does not, -1 on error - */ -int virNetDevExists(const char *ifname) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) - return -1; - - if (ioctl(fd, SIOCGIFFLAGS, &ifr)) { - if (errno == ENODEV) - ret = 0; - else - virReportSystemError(errno, - _("Unable to check interface flags for %s"), ifname); - goto cleanup; - } - - ret = 1; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} -# else -int virNetDevExists(const char *ifname) -{ - virReportSystemError(errno, - _("Unable to check interface %s"), ifname); - return -1; -} -# endif - -/** - * virNetDevBridgeDelete: - * @brname: the bridge name - * - * Remove a bridge from the layer. - * - * Returns 0 in case of success or an errno code in case of failure. - */ -# ifdef SIOCBRDELBR -int virNetDevBridgeDelete(const char *brname) -{ - int fd = -1; - int ret = -1; - - if ((fd = virNetDevSetupControl(NULL, NULL)) < 0) - return -1; - - if (ioctl(fd, SIOCBRDELBR, brname) < 0) { - virReportSystemError(errno, - _("Unable to delete bridge %s"), brname); - goto cleanup; - } - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} -# else -int virNetDevBridgeDelete(const char *brname ATTRIBUTE_UNUSED) -{ - virReportSystemError(errno, - _("Unable to delete bridge %s"), brname); - return EINVAL; -} -# endif - -/** - * virNetDevBridgeAddPort: - * @brname: the bridge name - * @ifname: the network interface name - * - * Adds an interface to a bridge - * - * Returns 0 in case of success or an errno code in case of failure. - */ -# ifdef SIOCBRADDIF -int virNetDevBridgeAddPort(const char *brname, - const char *ifname) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) - return -1; - - if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { - virReportSystemError(errno, - _("Unable to get interface index for %s"), ifname); - goto cleanup; - } - - if (ioctl(fd, SIOCBRADDIF, &ifr) < 0) { - virReportSystemError(errno, - _("Unable to add bridge %s port %s"), brname, ifname); - goto cleanup; - } - - ret = 0; -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} -# else -int virNetDevBridgeAddPort(const char *brname, - const char *ifname) -{ - virReportSystemError(ENOSYS, - _("Unable to add bridge %s port %s"), brname, ifname); - return -1; -} -# endif - -/** - * virNetDevBridgeRemovePort: - * @brname: the bridge name - * @ifname: the network interface name - * - * Removes an interface from a bridge - * - * Returns 0 in case of success or an errno code in case of failure. - */ -# ifdef SIOCBRDELIF -int virNetDevBridgeRemovePort(const char *brname, - const char *ifname) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) - return -1; - - if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { - virReportSystemError(errno, - _("Unable to get interface index for %s"), ifname); - - goto cleanup; - } - - if (ioctl(fd, SIOCBRDELIF, &ifr) < 0) { - virReportSystemError(errno, - _("Unable to remove bridge %s port %s"), brname, ifname); - goto cleanup; - } - - ret = 0; -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} -# else -int virNetDevBridgeRemovePort(const char *brname, - const char *ifname) -{ - virReportSystemError(errno, - _("Unable to remove bridge %s port %s"), brname, ifname); - return -1; -} -# endif - -/** - * virNetDevSetMAC: - * @ifname: interface name to set MTU for - * @macaddr: MAC address (VIR_MAC_BUFLEN in size) - * - * This function sets the @macaddr for a given interface @ifname. This - * gets rid of the kernel's automatically assigned random MAC. - * - * Returns 0 in case of success or -1 on failure - */ -int virNetDevSetMAC(const char *ifname, - const unsigned char *macaddr) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) - return -1; - - /* To fill ifr.ifr_hdaddr.sa_family field */ - if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { - virReportSystemError(errno, - _("Cannot get interface MAC on '%s'"), - ifname); - goto cleanup; - } - - memcpy(ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN); - - if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) { - virReportSystemError(errno, - _("Cannot set interface MAC on '%s'"), - ifname); - goto cleanup; - } - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - -/** - * virNetDevGetMAC: - * @ifname: interface name to set MTU for - * @macaddr: MAC address (VIR_MAC_BUFLEN in size) - * - * This function gets the @macaddr for a given interface @ifname. - * - * Returns 0 in case of success or -1 on failure - */ -int virNetDevGetMAC(const char *ifname, - unsigned char *macaddr) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) - return -1; - - if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { - virReportSystemError(errno, - _("Cannot get interface MAC on '%s'"), - ifname); - goto cleanup; - } - - memcpy(macaddr, ifr.ifr_hwaddr.sa_data, VIR_MAC_BUFLEN); - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - -/** - * virNetDevGetMTU: - * @ifname: interface name get MTU for - * - * This function gets the @mtu value set for a given interface @ifname. - * - * Returns the MTU value in case of success, or -1 on failure. - */ -int virNetDevGetMTU(const char *ifname) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) - return -1; - - if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { - virReportSystemError(errno, - _("Cannot get interface MTU on '%s'"), - ifname); - goto cleanup; - } - - ret = ifr.ifr_mtu; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - -/** - * virNetDevSetMTU: - * @ifname: interface name to set MTU for - * @mtu: MTU value - * - * This function sets the @mtu for a given interface @ifname. Typically - * used on a tap device to set up for Jumbo Frames. - * - * Returns 0 in case of success, or -1 on failure - */ -int virNetDevSetMTU(const char *ifname, int mtu) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) - return -1; - - ifr.ifr_mtu = mtu; - - if (ioctl(fd, SIOCSIFMTU, &ifr) < 0) { - virReportSystemError(errno, - _("Cannot set interface MTU on '%s'"), - ifname); - goto cleanup; - } - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - -/** - * virNetDevSetMTUFromDevice: - * @ifname: name of the interface whose MTU we want to set - * @otherifname: name of the interface whose MTU we want to copy - * - * Sets the interface mtu to the same MTU as another interface - * - * Returns 0 in case of success, or -1 on failure - */ -int virNetDevSetMTUFromDevice(const char *ifname, - const char *otherifname) -{ - int mtu = virNetDevGetMTU(otherifname); - - if (mtu < 0) - return -1; - - return virNetDevSetMTU(ifname, mtu); -} - -/** - * virNetDevProbeVnetHdr: - * @tapfd: a tun/tap file descriptor - * - * Check whether it is safe to enable the IFF_VNET_HDR flag on the - * tap interface. - * - * Setting IFF_VNET_HDR enables QEMU's virtio_net driver to allow - * guests to pass larger (GSO) packets, with partial checksums, to - * the host. This greatly increases the achievable throughput. - * - * It is only useful to enable this when we're setting up a virtio - * interface. And it is only *safe* to enable it when we know for - * sure that a) qemu has support for IFF_VNET_HDR and b) the running - * kernel implements the TUNGETIFF ioctl(), which qemu needs to query - * the supplied tapfd. - * - * Returns 1 if VnetHdr is supported, 0 if not supported - */ -# ifdef IFF_VNET_HDR -static int -virNetDevProbeVnetHdr(int tapfd) -{ -# if defined(IFF_VNET_HDR) && defined(TUNGETFEATURES) && defined(TUNGETIFF) - unsigned int features; - struct ifreq dummy; - - if (ioctl(tapfd, TUNGETFEATURES, &features) != 0) { - VIR_INFO("Not enabling IFF_VNET_HDR; " - "TUNGETFEATURES ioctl() not implemented"); - return 0; - } - - if (!(features & IFF_VNET_HDR)) { - VIR_INFO("Not enabling IFF_VNET_HDR; " - "TUNGETFEATURES ioctl() reports no IFF_VNET_HDR"); - return 0; - } - - /* The kernel will always return -1 at this point. - * If TUNGETIFF is not implemented then errno == EBADFD. - */ - if (ioctl(tapfd, TUNGETIFF, &dummy) != -1 || errno != EBADFD) { - VIR_INFO("Not enabling IFF_VNET_HDR; " - "TUNGETIFF ioctl() not implemented"); - return 0; - } - - VIR_INFO("Enabling IFF_VNET_HDR"); - - return 1; -# else - (void) tapfd; - VIR_INFO("Not enabling IFF_VNET_HDR; disabled at build time"); - return 0; -# endif -} -# endif - -/** - * brAddTap: - * @brname: the bridge name - * @ifname: the interface name (or name template) - * @macaddr: desired MAC address (VIR_MAC_BUFLEN long) - * @vnet_hdr: whether to try enabling IFF_VNET_HDR - * @tapfd: file descriptor return value for the new tap device - * - * This function creates a new tap device on a bridge. @ifname can be either - * a fixed name or a name template with '%d' for dynamic name allocation. - * in either case the final name for the bridge will be stored in @ifname. - * If the @tapfd parameter is supplied, the open tap device file - * descriptor will be returned, otherwise the TAP device will be made - * persistent and closed. The caller must use brDeleteTap to remove - * a persistent TAP devices when it is no longer needed. - * - * Returns 0 in case of success or -1 on failure - */ -int virNetDevTapCreateInBridgePort(const char *brname, - char **ifname, - const unsigned char *macaddr, - int vnet_hdr, - bool up, - int *tapfd) -{ - if (virNetDevTapCreate(ifname, vnet_hdr, tapfd) < 0) - return -1; - - /* We need to set the interface MAC before adding it - * to the bridge, because the bridge assumes the lowest - * MAC of all enslaved interfaces & we don't want it - * seeing the kernel allocate random MAC for the TAP - * device before we set our static MAC. - */ - if (virNetDevSetMAC(*ifname, macaddr) < 0) - goto error; - - /* We need to set the interface MTU before adding it - * to the bridge, because the bridge will have its - * MTU adjusted automatically when we add the new interface. - */ - if (virNetDevSetMTUFromDevice(*ifname, brname) < 0) - goto error; - - if (virNetDevBridgeAddPort(brname, *ifname) < 0) - goto error; - - if (virNetDevSetOnline(*ifname, up) < 0) - goto error; - - return 0; - -error: - if (tapfd) - VIR_FORCE_CLOSE(*tapfd); - return -1; -} - -int virNetDevTapDelete(const char *ifname) -{ - struct ifreq try; - int fd; - int ret = -1; - - if ((fd = open("/dev/net/tun", O_RDWR)) < 0) { - virReportSystemError(errno, "%s", - _("Unable to open /dev/net/tun, is tun module loaded?")); - return -1; - } - - memset(&try, 0, sizeof(struct ifreq)); - try.ifr_flags = IFF_TAP|IFF_NO_PI; - - if (virStrcpyStatic(try.ifr_name, ifname) == NULL) { - virReportSystemError(ERANGE, - _("Network interface name '%s' is too long"), - ifname); - goto cleanup; - } - - if (ioctl(fd, TUNSETIFF, &try) < 0) { - virReportSystemError(errno, "%s", - _("Unable to associate TAP device")); - goto cleanup; - } - - if (ioctl(fd, TUNSETPERSIST, 0) < 0) { - virReportSystemError(errno, "%s", - _("Unable to make TAP device non-persistent")); - goto cleanup; - } - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - - -/** - * virNetDevSetOnline: - * @ifname: the interface name - * @online: true for up, false for down - * - * Function to control if an interface is activated (up, true) or not (down, false) - * - * Returns 0 in case of success or -1 on error. - */ -int virNetDevSetOnline(const char *ifname, - bool online) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - int ifflags; - - if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) - return -1; - - if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { - virReportSystemError(errno, - _("Cannot get interface flags on '%s'"), - ifname); - goto cleanup; - } - - if (online) - ifflags = ifr.ifr_flags | IFF_UP; - else - ifflags = ifr.ifr_flags & ~IFF_UP; - - if (ifr.ifr_flags != ifflags) { - ifr.ifr_flags = ifflags; - if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { - virReportSystemError(errno, - _("Cannot set interface flags on '%s'"), - ifname); - goto cleanup; - } - } - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - -/** - * virNetDevIsOnline: - * @ifname: the interface name - * @online: where to store the status - * - * Function to query if an interface is activated (true) or not (false) - * - * Returns 0 in case of success or an errno code in case of failure. - */ -int virNetDevIsOnline(const char *ifname, - bool *online) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) - return -1; - - if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { - virReportSystemError(errno, - _("Cannot get interface flags on '%s'"), - ifname); - goto cleanup; - } - - *online = (ifr.ifr_flags & IFF_UP) ? true : false; - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - -/** - * virNetDevSetIPv4Addres: - * @ifname: the interface name - * @addr: the IP address (IPv4 or IPv6) - * @prefix: number of 1 bits in the netmask - * - * Add an IP address to an interface. This function *does not* remove - * any previously added IP addresses - that must be done separately with - * brDelInetAddress. - * - * Returns 0 in case of success or -1 in case of error. - */ - -int virNetDevSetIPv4Addres(const char *ifname, - virSocketAddr *addr, - unsigned int prefix) -{ - virCommandPtr cmd = NULL; - char *addrstr = NULL, *bcaststr = NULL; - virSocketAddr broadcast; - int ret = -1; - - if (!(addrstr = virSocketFormatAddr(addr))) - goto cleanup; - /* format up a broadcast address if this is IPv4 */ - if ((VIR_SOCKET_IS_FAMILY(addr, AF_INET)) && - ((virSocketAddrBroadcastByPrefix(addr, prefix, &broadcast) < 0) || - !(bcaststr = virSocketFormatAddr(&broadcast)))) { - goto cleanup; - } - cmd = virCommandNew(IP_PATH); - virCommandAddArgList(cmd, "addr", "add", NULL); - virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); - if (bcaststr) - virCommandAddArgList(cmd, "broadcast", bcaststr, NULL); - virCommandAddArgList(cmd, "dev", ifname, NULL); - - if (virCommandRun(cmd, NULL) < 0) - goto cleanup; - - ret = 0; -cleanup: - VIR_FREE(addrstr); - VIR_FREE(bcaststr); - virCommandFree(cmd); - return ret; -} - -/** - * virNetDevClearIPv4Address: - * @ifname: the interface name - * @addr: the IP address (IPv4 or IPv6) - * @prefix: number of 1 bits in the netmask - * - * Delete an IP address from an interface. - * - * Returns 0 in case of success or -1 in case of error. - */ - -int virNetDevClearIPv4Address(const char *ifname, - virSocketAddr *addr, - unsigned int prefix) -{ - virCommandPtr cmd = NULL; - char *addrstr; - int ret = -1; - - if (!(addrstr = virSocketFormatAddr(addr))) - goto cleanup; - cmd = virCommandNew(IP_PATH); - virCommandAddArgList(cmd, "addr", "del", NULL); - virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); - virCommandAddArgList(cmd, "dev", ifname, NULL); - - if (virCommandRun(cmd, NULL) < 0) - goto cleanup; - - ret = 0; -cleanup: - VIR_FREE(addrstr); - virCommandFree(cmd); - return ret; -} - -/** - * virNetDevBridgeSetSTPDelay: - * @brname: the bridge name - * @delay: delay in seconds - * - * Set the bridge forward delay - * - * Returns 0 in case of success or -1 on failure - */ - -int virNetDevBridgeSetSTPDelay(const char *brname, - int delay) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) - goto cleanup; - - ret = virNetDevBridgeSet(brname, "stp_state", MS_TO_JIFFIES(delay), - fd, &ifr); - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - - -/** - * virNetDevBridgeGetSTPDelay: - * @brname: the bridge device name - * @delayms: the forward delay in milliseconds - * - * Retrives the forward delay for the bridge device @brname - * storing it in @delayms. The forward delay is only meaningful - * if STP is enabled - * - * Returns 0 on success, -1 on error+ - */ -int virNetDevBridgeGetSTPDelay(const char *brname, - int *delayms) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - unsigned long i; - - if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) - goto cleanup; - - ret = virNetDevBridgeGet(brname, "stp_state", &i, - fd, &ifr); - *delayms = JIFFIES_TO_MS(i); - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - - -/** - * virNetDevBridgeSetSTP: - * @brname: the bridge name - * @enable: 1 to enable, 0 to disable - * - * Control whether the bridge participates in the spanning tree protocol, - * in general don't disable it without good reasons. - * - * Returns 0 in case of success or -1 on failure - */ -int virNetDevBridgeSetSTP(const char *brname, - bool enable) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) - goto cleanup; - - ret = virNetDevBridgeSet(brname, "stp_state", enable ? 1 : 0, - fd, &ifr); - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - - -/** - * virNetDevBridgeGetSTP: - * @brname: the bridge device name - * @enabled: returns the STP state - * - * Determine the state of the spanning tree protocol on - * the device @brname, returning the state in @enabled - * - * Returns 0 on success, -1 on error - */ -int virNetDevBridgeGetSTP(const char *brname, - bool *enabled) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - unsigned long i; - - if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) - goto cleanup; - - ret = virNetDevBridgeGet(brname, "stp_state", &i, - fd, &ifr); - *enabled = i ? true : false; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - - -/** - * brCreateTap: - * @ifname: the interface name - * @vnet_hr: whether to try enabling IFF_VNET_HDR - * @tapfd: file descriptor return value for the new tap device - * - * Creates a tap interface. - * If the @tapfd parameter is supplied, the open tap device file - * descriptor will be returned, otherwise the TAP device will be made - * persistent and closed. The caller must use brDeleteTap to remove - * a persistent TAP devices when it is no longer needed. - * - * Returns 0 in case of success or an errno code in case of failure. - */ - -int virNetDevTapCreate(char **ifname, - int vnet_hdr ATTRIBUTE_UNUSED, - int *tapfd) -{ - int fd; - struct ifreq ifr; - int ret = -1; - - if ((fd = open("/dev/net/tun", O_RDWR)) < 0) { - virReportSystemError(errno, "%s", - _("Unable to open /dev/net/tun, is tun module loaded?")); - return -1; - } - - memset(&ifr, 0, sizeof(ifr)); - - ifr.ifr_flags = IFF_TAP|IFF_NO_PI; - -# ifdef IFF_VNET_HDR - if (vnet_hdr && virNetDevProbeVnetHdr(fd)) - ifr.ifr_flags |= IFF_VNET_HDR; -# endif - - if (virStrcpyStatic(ifr.ifr_name, *ifname) == NULL) { - virReportSystemError(ERANGE, - _("Network interface name '%s' is too long"), - *ifname); - goto cleanup; - - } - - if (ioctl(fd, TUNSETIFF, &ifr) < 0) { - virReportSystemError(errno, - _("Unable to create tap device %s"), - NULLSTR(*ifname)); - goto cleanup; - } - - if (!tapfd && - (errno = ioctl(fd, TUNSETPERSIST, 1))) { - virReportSystemError(errno, - _("Unable to set tap device %s to persistent"), - NULLSTR(*ifname)); - goto cleanup; - } - - VIR_FREE(*ifname); - if (!(*ifname = strdup(ifr.ifr_name))) { - virReportOOMError(); - goto cleanup; - } - if (tapfd) - *tapfd = fd; - else - VIR_FORCE_CLOSE(fd); - - ret = 0; - -cleanup: - if (ret < 0) - VIR_FORCE_CLOSE(fd); - - return ret; -} - -#endif /* WITH_BRIDGE */ diff --git a/src/util/bridge.h b/src/util/bridge.h deleted file mode 100644 index 7504925..0000000 --- a/src/util/bridge.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2007 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Authors: - * Mark McLoughlin <markmc@redhat.com> - */ - -#ifndef __QEMUD_BRIDGE_H__ -# define __QEMUD_BRIDGE_H__ - -# include <config.h> - -# if defined(WITH_BRIDGE) - -# include <net/if.h> -# include <netinet/in.h> -# include "network.h" - -/** - * BR_IFNAME_MAXLEN: - * maximum size in byte of the name for an interface - */ -# define BR_IFNAME_MAXLEN IF_NAMESIZE - -/** - * BR_INET_ADDR_MAXLEN: - * maximum size in bytes for an inet addess name - */ -# define BR_INET_ADDR_MAXLEN INET_ADDRSTRLEN - -int virNetDevBridgeCreate(const char *brname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevBridgeDelete(const char *brname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevExists(const char *brname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -int virNetDevBridgeAddPort(const char *brname, - const char *ifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -int virNetDevBridgeRemovePort(const char *brname, - const char *ifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -enum { - BR_TAP_VNET_HDR = (1 << 0), - BR_TAP_PERSIST = (1 << 1), -}; - -int virNetDevTapCreateInBridgePort(const char *brname, - char **ifname, - const unsigned char *macaddr, - int vnet_hdr, - bool up, - int *tapfd) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) - ATTRIBUTE_RETURN_CHECK; - - -int virNetDevTapDelete(const char *ifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -int virNetDevSetOnline(const char *ifname, - bool online) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevIsOnline(const char *ifname, - bool *online) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -int virNetDevSetIPv4Addres(const char *ifname, - virSocketAddr *addr, - unsigned int prefix) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int virNetDevClearIPv4Address(const char *ifname, - virSocketAddr *addr, - unsigned int prefix) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -int virNetDevBridgeSetSTPDelay(const char *brname, - int delay) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevBridgeGetSTPDelay(const char *brname, - int *delay) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int virNetDevBridgeSetSTP(const char *brname, - bool enable) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevBridgeGetSTP(const char *brname, - bool *enable) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -int virNetDevTapCreate(char **ifname, - int vnet_hdr, - int *tapfd) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -int virNetDevSetMAC(const char *ifname, - const unsigned char *macaddr) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int virNetDevGetMAC(const char *ifname, - unsigned char *macaddr) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int virNetDevSetMTU(const char *ifname, - int mtu) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevSetMTUFromDevice(const char *ifname, - const char *otherifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int virNetDevGetMTU(const char *ifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -# endif /* WITH_BRIDGE */ - -#endif /* __QEMUD_BRIDGE_H__ */ diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c new file mode 100644 index 0000000..6eb5fe7 --- /dev/null +++ b/src/util/virnetdev.c @@ -0,0 +1,524 @@ +/* + * Copyright (C) 2007-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin <markmc@redhat.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#include <config.h> + +#include "virnetdev.h" +#include "virfile.h" +#include "virterror_internal.h" +#include "command.h" +#include "memory.h" + +#include <sys/ioctl.h> +#ifdef HAVE_NET_IF_H +# include <net/if.h> +#endif + +#define VIR_FROM_THIS VIR_FROM_NONE + +#ifdef HAVE_NET_IF_H +static int virNetDevSetupControlFull(const char *ifname, + struct ifreq *ifr, + int domain, + int type) +{ + int fd; + + memset(ifr, 0, sizeof(*ifr)); + + if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) { + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + ifname); + return -1; + } + + if ((fd = socket(domain, type, 0)) < 0) { + virReportSystemError(errno, "%s", + _("Cannot open network interface control socket")); + return -1; + } + + if (virSetInherit(fd, false) < 0) { + virReportSystemError(errno, "%s", + _("Cannot set close-on-exec flag for socket")); + VIR_FORCE_CLOSE(fd); + return -1; + } + + return fd; +} + + +static int virNetDevSetupControl(const char *ifname, + struct ifreq *ifr) +{ + return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); +} +#endif + + +#ifdef SIOCGIFFLAGS +/** + * virNetDevExists: + * @ifname + * + * Check if the network device @ifname exists + * + * Returns 1 if it exists, 0 if it does not, -1 on error + */ +int virNetDevExists(const char *ifname) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + if (ioctl(fd, SIOCGIFFLAGS, &ifr)) { + if (errno == ENODEV) + ret = 0; + else + virReportSystemError(errno, + _("Unable to check interface flags for %s"), ifname); + goto cleanup; + } + + ret = 1; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevExists(const char *ifname) +{ + virReportSystemError(errno, + _("Unable to check interface %s"), ifname); + return -1; +} +#endif + + +#ifdef SIOCGIFHWADDR +/** + * virNetDevSetMAC: + * @ifname: interface name to set MTU for + * @macaddr: MAC address (VIR_MAC_BUFLEN in size) + * + * This function sets the @macaddr for a given interface @ifname. This + * gets rid of the kernel's automatically assigned random MAC. + * + * Returns 0 in case of success or -1 on failure + */ +int virNetDevSetMAC(const char *ifname, + const unsigned char *macaddr) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + /* To fill ifr.ifr_hdaddr.sa_family field */ + if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { + virReportSystemError(errno, + _("Cannot get interface MAC on '%s'"), + ifname); + goto cleanup; + } + + memcpy(ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN); + + if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) { + virReportSystemError(errno, + _("Cannot set interface MAC on '%s'"), + ifname); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevSetMAC(const char *ifname, + const unsigned char *macaddr ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Cannot set interface MAC on '%s'"), + ifname); + return -1; +} +#endif + + +#ifdef SIOCGIFHWADDR +/** + * virNetDevGetMAC: + * @ifname: interface name to set MTU for + * @macaddr: MAC address (VIR_MAC_BUFLEN in size) + * + * This function gets the @macaddr for a given interface @ifname. + * + * Returns 0 in case of success or -1 on failure + */ +int virNetDevGetMAC(const char *ifname, + unsigned char *macaddr) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { + virReportSystemError(errno, + _("Cannot get interface MAC on '%s'"), + ifname); + goto cleanup; + } + + memcpy(macaddr, ifr.ifr_hwaddr.sa_data, VIR_MAC_BUFLEN); + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevGetMAC(const char *ifname, + unsigned char *macaddr ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Cannot get interface MAC on '%s'"), + ifname); + return -1; +} +#endif + + +#ifdef SIOCGIFMTU +/** + * virNetDevGetMTU: + * @ifname: interface name get MTU for + * + * This function gets the @mtu value set for a given interface @ifname. + * + * Returns the MTU value in case of success, or -1 on failure. + */ +int virNetDevGetMTU(const char *ifname) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { + virReportSystemError(errno, + _("Cannot get interface MTU on '%s'"), + ifname); + goto cleanup; + } + + ret = ifr.ifr_mtu; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevGetMTU(const char *ifname) +{ + virReportSystemError(ENOSYS, + _("Cannot get interface MTU on '%s'"), + ifname); + return -1; +} +#endif + + +#ifdef SIOCSIFMTU +/** + * virNetDevSetMTU: + * @ifname: interface name to set MTU for + * @mtu: MTU value + * + * This function sets the @mtu for a given interface @ifname. Typically + * used on a tap device to set up for Jumbo Frames. + * + * Returns 0 in case of success, or -1 on failure + */ +int virNetDevSetMTU(const char *ifname, int mtu) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + ifr.ifr_mtu = mtu; + + if (ioctl(fd, SIOCSIFMTU, &ifr) < 0) { + virReportSystemError(errno, + _("Cannot set interface MTU on '%s'"), + ifname); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevSetMTU(const char *ifname, int mtu ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Cannot set interface MTU on '%s'"), + ifname); + return -1; +} +#endif + + +/** + * virNetDevSetMTUFromDevice: + * @ifname: name of the interface whose MTU we want to set + * @otherifname: name of the interface whose MTU we want to copy + * + * Sets the interface mtu to the same MTU as another interface + * + * Returns 0 in case of success, or -1 on failure + */ +int virNetDevSetMTUFromDevice(const char *ifname, + const char *otherifname) +{ + int mtu = virNetDevGetMTU(otherifname); + + if (mtu < 0) + return -1; + + return virNetDevSetMTU(ifname, mtu); +} + + +#ifdef SIOCSIFFLAGS +/** + * virNetDevSetOnline: + * @ifname: the interface name + * @online: true for up, false for down + * + * Function to control if an interface is activated (up, true) or not (down, false) + * + * Returns 0 in case of success or -1 on error. + */ +int virNetDevSetOnline(const char *ifname, + bool online) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + int ifflags; + + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + virReportSystemError(errno, + _("Cannot get interface flags on '%s'"), + ifname); + goto cleanup; + } + + if (online) + ifflags = ifr.ifr_flags | IFF_UP; + else + ifflags = ifr.ifr_flags & ~IFF_UP; + + if (ifr.ifr_flags != ifflags) { + ifr.ifr_flags = ifflags; + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { + virReportSystemError(errno, + _("Cannot set interface flags on '%s'"), + ifname); + goto cleanup; + } + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevSetOnline(const char *ifname, + bool online ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Cannot set interface flags on '%s'"), + ifname); + return -1; +} +#endif + + +#ifdef SIOCGIFFLAGS +/** + * virNetDevIsOnline: + * @ifname: the interface name + * @online: where to store the status + * + * Function to query if an interface is activated (true) or not (false) + * + * Returns 0 in case of success or an errno code in case of failure. + */ +int virNetDevIsOnline(const char *ifname, + bool *online) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { + virReportSystemError(errno, + _("Cannot get interface flags on '%s'"), + ifname); + goto cleanup; + } + + *online = (ifr.ifr_flags & IFF_UP) ? true : false; + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevIsOnline(const char *ifname, + bool *online ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Cannot get interface flags on '%s'"), + ifname); + return -1; +} +#endif + + +/** + * virNetDevSetIPv4Addres: + * @ifname: the interface name + * @addr: the IP address (IPv4 or IPv6) + * @prefix: number of 1 bits in the netmask + * + * Add an IP address to an interface. This function *does not* remove + * any previously added IP addresses - that must be done separately with + * brDelInetAddress. + * + * Returns 0 in case of success or -1 in case of error. + */ + +int virNetDevSetIPv4Addres(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) +{ + virCommandPtr cmd = NULL; + char *addrstr = NULL, *bcaststr = NULL; + virSocketAddr broadcast; + int ret = -1; + + if (!(addrstr = virSocketFormatAddr(addr))) + goto cleanup; + /* format up a broadcast address if this is IPv4 */ + if ((VIR_SOCKET_IS_FAMILY(addr, AF_INET)) && + ((virSocketAddrBroadcastByPrefix(addr, prefix, &broadcast) < 0) || + !(bcaststr = virSocketFormatAddr(&broadcast)))) { + goto cleanup; + } + cmd = virCommandNew(IP_PATH); + virCommandAddArgList(cmd, "addr", "add", NULL); + virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); + if (bcaststr) + virCommandAddArgList(cmd, "broadcast", bcaststr, NULL); + virCommandAddArgList(cmd, "dev", ifname, NULL); + + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + ret = 0; +cleanup: + VIR_FREE(addrstr); + VIR_FREE(bcaststr); + virCommandFree(cmd); + return ret; +} + +/** + * virNetDevClearIPv4Address: + * @ifname: the interface name + * @addr: the IP address (IPv4 or IPv6) + * @prefix: number of 1 bits in the netmask + * + * Delete an IP address from an interface. + * + * Returns 0 in case of success or -1 in case of error. + */ + +int virNetDevClearIPv4Address(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) +{ + virCommandPtr cmd = NULL; + char *addrstr; + int ret = -1; + + if (!(addrstr = virSocketFormatAddr(addr))) + goto cleanup; + cmd = virCommandNew(IP_PATH); + virCommandAddArgList(cmd, "addr", "del", NULL); + virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); + virCommandAddArgList(cmd, "dev", ifname, NULL); + + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + ret = 0; +cleanup: + VIR_FREE(addrstr); + virCommandFree(cmd); + return ret; +} diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h new file mode 100644 index 0000000..cae98b7 --- /dev/null +++ b/src/util/virnetdev.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin <markmc@redhat.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#ifndef __VIR_NETDEV_H__ +# define __VIR_NETDEV_H__ + +# include "network.h" + +int virNetDevExists(const char *brname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +int virNetDevSetOnline(const char *ifname, + bool online) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevIsOnline(const char *ifname, + bool *online) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int virNetDevSetIPv4Addres(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevClearIPv4Address(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + + +int virNetDevSetMAC(const char *ifname, + const unsigned char *macaddr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetMAC(const char *ifname, + unsigned char *macaddr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetMTU(const char *ifname, + int mtu) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetMTUFromDevice(const char *ifname, + const char *otherifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetMTU(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +#endif /* __VIR_NETDEV_H__ */ diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c new file mode 100644 index 0000000..701d9ff --- /dev/null +++ b/src/util/virnetdevbridge.c @@ -0,0 +1,527 @@ +/* + * Copyright (C) 2007-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin <markmc@redhat.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#include <config.h> + +#include "virnetdevbridge.h" +#include "virterror_internal.h" +#include "util.h" +#include "virfile.h" +#include "memory.h" +#include "intprops.h" + +#include <sys/ioctl.h> +#ifdef HAVE_NET_IF_H +# include <net/if.h> +#endif +#ifdef __linux__ +# include <linux/sockios.h> +# include <linux/param.h> /* HZ */ +# include <linux/if_bridge.h> /* SYSFS_BRIDGE_ATTR */ + +# define JIFFIES_TO_MS(j) (((j)*1000)/HZ) +# define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000) +#endif + +#define VIR_FROM_THIS VIR_FROM_NONE + + +#ifdef HAVE_NET_IF_H +static int virNetDevSetupControlFull(const char *ifname, + struct ifreq *ifr, + int domain, + int type) +{ + int fd; + + if (ifname && ifr) { + memset(ifr, 0, sizeof(*ifr)); + + if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) { + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + ifname); + return -1; + } + } + + if ((fd = socket(domain, type, 0)) < 0) { + virReportSystemError(errno, "%s", + _("Cannot open network interface control socket")); + return -1; + } + + if (virSetInherit(fd, false) < 0) { + virReportSystemError(errno, "%s", + _("Cannot set close-on-exec flag for socket")); + VIR_FORCE_CLOSE(fd); + return -1; + } + + return fd; +} + + +static int virNetDevSetupControl(const char *ifname, + struct ifreq *ifr) +{ + return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); +} +#endif + +#ifdef __linux__ +# define SYSFS_NET_DIR "/sys/class/net" +/* + * Bridge parameters can be set via sysfs on newish kernels, + * or by ioctl on older kernels. Perhaps we could just use + * ioctl for every kernel, but its not clear what the long + * term lifespan of the ioctl interface is... + */ +static int virNetDevBridgeSet(const char *brname, + const char *paramname, /* sysfs param name */ + unsigned long value, /* new value */ + int fd, /* control socket */ + struct ifreq *ifr) /* pre-filled bridge name */ +{ + char *path = NULL; + int ret = -1; + + if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname) < 0) { + virReportOOMError(); + return -1; + } + + if (virFileExists(path)) { + char valuestr[INT_BUFSIZE_BOUND(value)]; + snprintf(valuestr, sizeof(valuestr), "%lu", value); + if (virFileWriteStr(path, valuestr, 0) < 0) { + virReportSystemError(errno, + _("Unable to set bridge %s %s"), brname, paramname); + goto cleanup; + } + } else { + unsigned long paramid; + if (STREQ(paramname, "stp_state")) { + paramid = BRCTL_SET_BRIDGE_STP_STATE; + } else if (STREQ(paramname, "forward_delay")) { + paramid = BRCTL_SET_BRIDGE_FORWARD_DELAY; + } else { + virReportSystemError(EINVAL, + _("Unable to set bridge %s %s"), brname, paramname); + goto cleanup; + } + unsigned long args[] = { paramid, value, 0, 0 }; + ifr->ifr_data = (char*)&args; + if (ioctl(fd, SIOCDEVPRIVATE, ifr) < 0) { + virReportSystemError(errno, + _("Unable to set bridge %s %s"), brname, paramname); + goto cleanup; + } + } + + ret = 0; +cleanup: + VIR_FREE(path); + return ret; +} + + +static int virNetDevBridgeGet(const char *brname, + const char *paramname, /* sysfs param name */ + unsigned long *value, /* current value */ + int fd, /* control socket */ + struct ifreq *ifr) /* pre-filled bridge name */ +{ + char *path = NULL; + int ret = -1; + + if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname) < 0) { + virReportOOMError(); + return -1; + } + + if (virFileExists(path)) { + char *valuestr; + if (virFileReadAll(path, INT_BUFSIZE_BOUND(unsigned long), &valuestr) < 0) + goto cleanup; + + if (virStrToLong_ul(valuestr, NULL, 10, value) < 0) { + virReportSystemError(EINVAL, + _("Unable to get bridge %s %s"), brname, paramname); + } + } else { + struct __bridge_info info; + unsigned long args[] = { BRCTL_GET_BRIDGE_INFO, (unsigned long)&info, 0, 0 }; + ifr->ifr_data = (char*)&args; + if (ioctl(fd, SIOCDEVPRIVATE, ifr) < 0) { + virReportSystemError(errno, + _("Unable to get bridge %s %s"), brname, paramname); + goto cleanup; + } + + if (STREQ(paramname, "stp_state")) { + *value = info.stp_enabled; + } else if (STREQ(paramname, "forward_delay")) { + *value = info.forward_delay; + } else { + virReportSystemError(EINVAL, + _("Unable to get bridge %s %s"), brname, paramname); + goto cleanup; + } + } + + ret = 0; +cleanup: + VIR_FREE(path); + return ret; +} +#endif /* __linux__ */ + + +/** + * virNetDevBridgeCreate: + * @brname: the bridge name + * + * This function register a new bridge + * + * Returns 0 in case of success or -1 on failure + */ +#ifdef SIOCBRADDBR +int virNetDevBridgeCreate(const char *brname) +{ + int fd = -1; + int ret = -1; + + if ((fd = virNetDevSetupControl(NULL, NULL)) < 0) + return -1; + + if (ioctl(fd, SIOCBRADDBR, brname) < 0) { + virReportSystemError(errno, + _("Unable to create bridge %s"), brname); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevBridgeCreate(const char *brname) +{ + virReportSystemError(ENOSYS, + _("Unable to create bridge %s"), brname); + return -1; +} +#endif + +/** + * virNetDevBridgeDelete: + * @brname: the bridge name + * + * Remove a bridge from the layer. + * + * Returns 0 in case of success or an errno code in case of failure. + */ +#ifdef SIOCBRDELBR +int virNetDevBridgeDelete(const char *brname) +{ + int fd = -1; + int ret = -1; + + if ((fd = virNetDevSetupControl(NULL, NULL)) < 0) + return -1; + + if (ioctl(fd, SIOCBRDELBR, brname) < 0) { + virReportSystemError(errno, + _("Unable to delete bridge %s"), brname); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevBridgeDelete(const char *brname ATTRIBUTE_UNUSED) +{ + virReportSystemError(errno, + _("Unable to delete bridge %s"), brname); + return EINVAL; +} +#endif + +/** + * virNetDevBridgeAddPort: + * @brname: the bridge name + * @ifname: the network interface name + * + * Adds an interface to a bridge + * + * Returns 0 in case of success or an errno code in case of failure. + */ +#ifdef SIOCBRADDIF +int virNetDevBridgeAddPort(const char *brname, + const char *ifname) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) + return -1; + + if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { + virReportSystemError(errno, + _("Unable to get interface index for %s"), ifname); + goto cleanup; + } + + if (ioctl(fd, SIOCBRADDIF, &ifr) < 0) { + virReportSystemError(errno, + _("Unable to add bridge %s port %s"), brname, ifname); + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevBridgeAddPort(const char *brname, + const char *ifname) +{ + virReportSystemError(ENOSYS, + _("Unable to add bridge %s port %s"), brname, ifname); + return -1; +} +#endif + +/** + * virNetDevBridgeRemovePort: + * @brname: the bridge name + * @ifname: the network interface name + * + * Removes an interface from a bridge + * + * Returns 0 in case of success or an errno code in case of failure. + */ +#ifdef SIOCBRDELIF +int virNetDevBridgeRemovePort(const char *brname, + const char *ifname) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) + return -1; + + if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { + virReportSystemError(errno, + _("Unable to get interface index for %s"), ifname); + + goto cleanup; + } + + if (ioctl(fd, SIOCBRDELIF, &ifr) < 0) { + virReportSystemError(errno, + _("Unable to remove bridge %s port %s"), brname, ifname); + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevBridgeRemovePort(const char *brname, + const char *ifname) +{ + virReportSystemError(errno, + _("Unable to remove bridge %s port %s"), brname, ifname); + return -1; +} +#endif + + +#ifdef __linux__ +/** + * virNetDevBridgeSetSTPDelay: + * @brname: the bridge name + * @delay: delay in seconds + * + * Set the bridge forward delay + * + * Returns 0 in case of success or -1 on failure + */ + +int virNetDevBridgeSetSTPDelay(const char *brname, + int delay) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) + goto cleanup; + + ret = virNetDevBridgeSet(brname, "stp_state", MS_TO_JIFFIES(delay), + fd, &ifr); + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + + +/** + * virNetDevBridgeGetSTPDelay: + * @brname: the bridge device name + * @delayms: the forward delay in milliseconds + * + * Retrives the forward delay for the bridge device @brname + * storing it in @delayms. The forward delay is only meaningful + * if STP is enabled + * + * Returns 0 on success, -1 on error+ + */ +int virNetDevBridgeGetSTPDelay(const char *brname, + int *delayms) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + unsigned long i; + + if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) + goto cleanup; + + ret = virNetDevBridgeGet(brname, "stp_state", &i, + fd, &ifr); + *delayms = JIFFIES_TO_MS(i); + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + + +/** + * virNetDevBridgeSetSTP: + * @brname: the bridge name + * @enable: 1 to enable, 0 to disable + * + * Control whether the bridge participates in the spanning tree protocol, + * in general don't disable it without good reasons. + * + * Returns 0 in case of success or -1 on failure + */ +int virNetDevBridgeSetSTP(const char *brname, + bool enable) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) + goto cleanup; + + ret = virNetDevBridgeSet(brname, "stp_state", enable ? 1 : 0, + fd, &ifr); + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + + +/** + * virNetDevBridgeGetSTP: + * @brname: the bridge device name + * @enabled: returns the STP state + * + * Determine the state of the spanning tree protocol on + * the device @brname, returning the state in @enabled + * + * Returns 0 on success, -1 on error + */ +int virNetDevBridgeGetSTP(const char *brname, + bool *enabled) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + unsigned long i; + + if ((fd = virNetDevSetupControl(brname, &ifr)) < 0) + goto cleanup; + + ret = virNetDevBridgeGet(brname, "stp_state", &i, + fd, &ifr); + *enabled = i ? true : false; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else /* !__linux__ */ +int virNetDevBridgeSetSTPDelay(const char *brname, + int delay ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Unable to set STP delay on %s on this platform"), + brname); + return -1; +} +int virNetDevBridgeGetSTPDelay(const char *brname, + int *delay ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Unable to get STP delay on %s on this platform"), + brname); + return -1; +} + +int virNetDevBridgeSetSTP(const char *brname, + bool enable ATTRIBUTE_UNUSED) + +{ + virReportSystemError(ENOSYS, + _("Unable to set STP on %s on this platform"), + brname); + return -1; +} +int virNetDevBridgeGetSTP(const char *brname, + bool *enable ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Unable to get STP on %s on this platform"), + brname); + return -1; +} +#endif /* __linux__ */ diff --git a/src/util/virnetdevbridge.h b/src/util/virnetdevbridge.h new file mode 100644 index 0000000..98fc1d2 --- /dev/null +++ b/src/util/virnetdevbridge.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2007-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin <markmc@redhat.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#ifndef __VIR_NETDEV_BRIDGE_H__ +# define __VIR_NETDEV_BRIDGE_H__ + +# include "internal.h" + +int virNetDevBridgeCreate(const char *brname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBridgeDelete(const char *brname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +int virNetDevBridgeAddPort(const char *brname, + const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int virNetDevBridgeRemovePort(const char *brname, + const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int virNetDevBridgeSetSTPDelay(const char *brname, + int delay) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBridgeGetSTPDelay(const char *brname, + int *delay) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevBridgeSetSTP(const char *brname, + bool enable) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBridgeGetSTP(const char *brname, + bool *enable) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +#endif /* __VIR_NETDEV_BRIDGE_H__ */ diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c new file mode 100644 index 0000000..5c60925 --- /dev/null +++ b/src/util/virnetdevtap.c @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2007-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin <markmc@redhat.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#include <config.h> + +#include "virnetdevtap.h" +#include "virnetdev.h" +#include "virnetdevbridge.h" +#include "virterror_internal.h" +#include "virfile.h" +#include "virterror_internal.h" +#include "memory.h" +#include "logging.h" + +#include <sys/ioctl.h> +#ifdef HAVE_NET_IF_H +# include <net/if.h> +#endif +#include <fcntl.h> +#ifdef __linux__ +# include <linux/if_tun.h> /* IFF_TUN, IFF_NO_PI */ +#endif + +#define VIR_FROM_THIS VIR_FROM_NONE + +/** + * virNetDevProbeVnetHdr: + * @tapfd: a tun/tap file descriptor + * + * Check whether it is safe to enable the IFF_VNET_HDR flag on the + * tap interface. + * + * Setting IFF_VNET_HDR enables QEMU's virtio_net driver to allow + * guests to pass larger (GSO) packets, with partial checksums, to + * the host. This greatly increases the achievable throughput. + * + * It is only useful to enable this when we're setting up a virtio + * interface. And it is only *safe* to enable it when we know for + * sure that a) qemu has support for IFF_VNET_HDR and b) the running + * kernel implements the TUNGETIFF ioctl(), which qemu needs to query + * the supplied tapfd. + * + * Returns 1 if VnetHdr is supported, 0 if not supported + */ +#ifdef IFF_VNET_HDR +static int +virNetDevProbeVnetHdr(int tapfd) +{ +# if defined(IFF_VNET_HDR) && defined(TUNGETFEATURES) && defined(TUNGETIFF) + unsigned int features; + struct ifreq dummy; + + if (ioctl(tapfd, TUNGETFEATURES, &features) != 0) { + VIR_INFO("Not enabling IFF_VNET_HDR; " + "TUNGETFEATURES ioctl() not implemented"); + return 0; + } + + if (!(features & IFF_VNET_HDR)) { + VIR_INFO("Not enabling IFF_VNET_HDR; " + "TUNGETFEATURES ioctl() reports no IFF_VNET_HDR"); + return 0; + } + + /* The kernel will always return -1 at this point. + * If TUNGETIFF is not implemented then errno == EBADFD. + */ + if (ioctl(tapfd, TUNGETIFF, &dummy) != -1 || errno != EBADFD) { + VIR_INFO("Not enabling IFF_VNET_HDR; " + "TUNGETIFF ioctl() not implemented"); + return 0; + } + + VIR_INFO("Enabling IFF_VNET_HDR"); + + return 1; +# else + (void) tapfd; + VIR_INFO("Not enabling IFF_VNET_HDR; disabled at build time"); + return 0; +# endif +} +#endif + + +#ifdef TUNSETIFF +/** + * brCreateTap: + * @ifname: the interface name + * @vnet_hr: whether to try enabling IFF_VNET_HDR + * @tapfd: file descriptor return value for the new tap device + * + * Creates a tap interface. + * If the @tapfd parameter is supplied, the open tap device file + * descriptor will be returned, otherwise the TAP device will be made + * persistent and closed. The caller must use brDeleteTap to remove + * a persistent TAP devices when it is no longer needed. + * + * Returns 0 in case of success or an errno code in case of failure. + */ +int virNetDevTapCreate(char **ifname, + int vnet_hdr ATTRIBUTE_UNUSED, + int *tapfd) +{ + int fd; + struct ifreq ifr; + int ret = -1; + + if ((fd = open("/dev/net/tun", O_RDWR)) < 0) { + virReportSystemError(errno, "%s", + _("Unable to open /dev/net/tun, is tun module loaded?")); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; + +# ifdef IFF_VNET_HDR + if (vnet_hdr && virNetDevProbeVnetHdr(fd)) + ifr.ifr_flags |= IFF_VNET_HDR; +# endif + + if (virStrcpyStatic(ifr.ifr_name, *ifname) == NULL) { + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + *ifname); + goto cleanup; + + } + + if (ioctl(fd, TUNSETIFF, &ifr) < 0) { + virReportSystemError(errno, + _("Unable to create tap device %s"), + NULLSTR(*ifname)); + goto cleanup; + } + + if (!tapfd && + (errno = ioctl(fd, TUNSETPERSIST, 1))) { + virReportSystemError(errno, + _("Unable to set tap device %s to persistent"), + NULLSTR(*ifname)); + goto cleanup; + } + + VIR_FREE(*ifname); + if (!(*ifname = strdup(ifr.ifr_name))) { + virReportOOMError(); + goto cleanup; + } + if (tapfd) + *tapfd = fd; + else + VIR_FORCE_CLOSE(fd); + + ret = 0; + +cleanup: + if (ret < 0) + VIR_FORCE_CLOSE(fd); + + return ret; +} + + +int virNetDevTapDelete(const char *ifname) +{ + struct ifreq try; + int fd; + int ret = -1; + + if ((fd = open("/dev/net/tun", O_RDWR)) < 0) { + virReportSystemError(errno, "%s", + _("Unable to open /dev/net/tun, is tun module loaded?")); + return -1; + } + + memset(&try, 0, sizeof(struct ifreq)); + try.ifr_flags = IFF_TAP|IFF_NO_PI; + + if (virStrcpyStatic(try.ifr_name, ifname) == NULL) { + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + ifname); + goto cleanup; + } + + if (ioctl(fd, TUNSETIFF, &try) < 0) { + virReportSystemError(errno, "%s", + _("Unable to associate TAP device")); + goto cleanup; + } + + if (ioctl(fd, TUNSETPERSIST, 0) < 0) { + virReportSystemError(errno, "%s", + _("Unable to make TAP device non-persistent")); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else /* ! TUNSETIFF */ +int virNetDevTapCreate(char **ifname ATTRIBUTE_UNUSED, + int vnet_hdr ATTRIBUTE_UNUSED, + int *tapfd ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to create TAP devices on this platform")); + return -1; +} +int virNetDevTapDelete(const char *ifname ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to delete TAP devices on this platform")); + return -1; +} +#endif /* ! TUNSETIFF */ + + +/** + * virNetDevTapCreateInBridgePort: + * @brname: the bridge name + * @ifname: the interface name (or name template) + * @macaddr: desired MAC address (VIR_MAC_BUFLEN long) + * @vnet_hdr: whether to try enabling IFF_VNET_HDR + * @tapfd: file descriptor return value for the new tap device + * + * This function creates a new tap device on a bridge. @ifname can be either + * a fixed name or a name template with '%d' for dynamic name allocation. + * in either case the final name for the bridge will be stored in @ifname. + * If the @tapfd parameter is supplied, the open tap device file + * descriptor will be returned, otherwise the TAP device will be made + * persistent and closed. The caller must use brDeleteTap to remove + * a persistent TAP devices when it is no longer needed. + * + * Returns 0 in case of success or -1 on failure + */ +int virNetDevTapCreateInBridgePort(const char *brname, + char **ifname, + const unsigned char *macaddr, + int vnet_hdr, + bool up, + int *tapfd) +{ + if (virNetDevTapCreate(ifname, vnet_hdr, tapfd) < 0) + return -1; + + /* We need to set the interface MAC before adding it + * to the bridge, because the bridge assumes the lowest + * MAC of all enslaved interfaces & we don't want it + * seeing the kernel allocate random MAC for the TAP + * device before we set our static MAC. + */ + if (virNetDevSetMAC(*ifname, macaddr) < 0) + goto error; + + /* We need to set the interface MTU before adding it + * to the bridge, because the bridge will have its + * MTU adjusted automatically when we add the new interface. + */ + if (virNetDevSetMTUFromDevice(*ifname, brname) < 0) + goto error; + + if (virNetDevBridgeAddPort(brname, *ifname) < 0) + goto error; + + if (virNetDevSetOnline(*ifname, up) < 0) + goto error; + + return 0; + + error: + VIR_FORCE_CLOSE(*tapfd); + + return errno; +} diff --git a/src/util/virnetdevtap.h b/src/util/virnetdevtap.h new file mode 100644 index 0000000..fb35ac5 --- /dev/null +++ b/src/util/virnetdevtap.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2007-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin <markmc@redhat.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#ifndef __VIR_NETDEV_TAP_H__ +# define __VIR_NETDEV_TAP_H__ + +# include "internal.h" + +int virNetDevTapCreate(char **ifname, + int vnet_hdr, + int *tapfd) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +int virNetDevTapDelete(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +int virNetDevTapCreateInBridgePort(const char *brname, + char **ifname, + const unsigned char *macaddr, + int vnet_hdr, + bool up, + int *tapfd) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_RETURN_CHECK; + +#endif /* __VIR_NETDEV_TAP_H__ */ -- 1.7.6.4

On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
Following the renaming of the bridge management APIs, we can now split the source file into 3 corresponding pieces
* src/util/virnetdev.c: APIs for any type of network interface * src/util/virnetdevbridge.c: APIs for bridge interfaces * src/util/virnetdevtap.c: APIs for TAP interfaces
* src/util/virnetdev.c, src/util/virnetdev.h, src/util/virnetdevbridge.c, src/util/virnetdevbridge.h, src/util/virnetdevtap.c, src/util/virnetdevtap.h: Copied from bridge.{c,h} * src/util/bridge.c, src/util/bridge.h: Split into 3 pieces * src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/openvz/openvz_driver.c, src/qemu/qemu_command.c, src/qemu/qemu_conf.h, src/uml/uml_conf.c, src/uml/uml_conf.h, src/uml/uml_driver.c: Update #include directives --- configure.ac | 3 +- po/POTFILES.in | 4 +- src/Makefile.am | 6 +- src/lxc/lxc_driver.c | 2 +- src/network/bridge_driver.c | 5 +- src/openvz/openvz_driver.c | 1 - src/qemu/qemu_command.c | 1 + src/qemu/qemu_conf.h | 1 - src/uml/uml_conf.c | 2 +- src/uml/uml_conf.h | 1 - src/uml/uml_driver.c | 1 + src/util/bridge.c | 1115 ------------------------------------------- src/util/bridge.h | 129 ----- src/util/virnetdev.c | 524 ++++++++++++++++++++ src/util/virnetdev.h | 63 +++ src/util/virnetdevbridge.c | 527 ++++++++++++++++++++ src/util/virnetdevbridge.h | 54 ++ src/util/virnetdevtap.c | 300 ++++++++++++ src/util/virnetdevtap.h | 45 ++ 19 files changed, 1530 insertions(+), 1254 deletions(-) delete mode 100644 src/util/bridge.c delete mode 100644 src/util/bridge.h create mode 100644 src/util/virnetdev.c create mode 100644 src/util/virnetdev.h create mode 100644 src/util/virnetdevbridge.c create mode 100644 src/util/virnetdevbridge.h create mode 100644 src/util/virnetdevtap.c create mode 100644 src/util/virnetdevtap.h
diff --git a/configure.ac b/configure.ac index 0ce020d..c2746d8 100644 --- a/configure.ac +++ b/configure.ac @@ -150,7 +150,8 @@ LIBS=$old_libs dnl Availability of various common headers (non-fatal if missing). AC_CHECK_HEADERS([pwd.h paths.h regex.h sys/un.h \ sys/poll.h syslog.h mntent.h net/ethernet.h linux/magic.h \ - sys/un.h sys/syscall.h netinet/tcp.h ifaddrs.h libtasn1.h]) + sys/un.h sys/syscall.h netinet/tcp.h ifaddrs.h libtasn1.h \ + net/if.h])
dnl Our only use of libtasn1.h is in the testsuite, and can be skipped dnl if the header is not present. Assume -ltasn1 is present if the diff --git a/po/POTFILES.in b/po/POTFILES.in index bd1d7bd..a3685e8 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -102,7 +102,6 @@ src/test/test_driver.c src/uml/uml_conf.c src/uml/uml_driver.c src/util/authhelper.c -src/util/bridge.c src/util/cgroup.c src/util/command.c src/util/conf.c @@ -127,6 +126,9 @@ src/util/sysinfo.c src/util/util.c src/util/viraudit.c src/util/virfile.c +src/util/virnetdev.c +src/util/virnetdevbridge.c +src/util/virnetdevtap.c src/util/virpidfile.c src/util/virterror.c src/util/xml.c diff --git a/src/Makefile.am b/src/Makefile.am index bf26b19..f742f2a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -52,7 +52,6 @@ augeastest_DATA = UTIL_SOURCES = \ util/authhelper.c util/authhelper.h \ util/bitmap.c util/bitmap.h \ - util/bridge.c util/bridge.h \ util/buf.c util/buf.h \ util/command.c util/command.h \ util/conf.c util/conf.h \ @@ -91,7 +90,10 @@ UTIL_SOURCES = \ util/xml.c util/xml.h \ util/virterror.c util/virterror_internal.h \ util/virkeycode.c util/virkeycode.h \ - util/virkeymaps.h + util/virkeymaps.h \ + util/virnetdev.h util/virnetdev.c \ + util/virnetdevbridge.h util/virnetdevbridge.c \ + util/virnetdevtap.h util/virnetdevtap.c
EXTRA_DIST += $(srcdir)/util/virkeymaps.h $(srcdir)/util/keymaps.csv \ $(srcdir)/util/virkeycode-mapgen.py diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index c75941f..5701467 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -43,7 +43,7 @@ #include "lxc_driver.h" #include "memory.h" #include "util.h" -#include "bridge.h" +#include "virnetdevbridge.h" #include "veth.h" #include "nodeinfo.h" #include "uuid.h" diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index bc9d2e1..bc3a18f 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -42,6 +42,7 @@ #include<stdio.h> #include<sys/wait.h> #include<sys/ioctl.h> +#include<net/if.h>
#include "virterror_internal.h" #include "datatypes.h" @@ -55,13 +56,15 @@ #include "memory.h" #include "uuid.h" #include "iptables.h" -#include "bridge.h" #include "interface.h" #include "logging.h" #include "dnsmasq.h" #include "util/network.h" #include "configmake.h" #include "ignore-value.h" +#include "virnetdev.h" +#include "virnetdevbridge.h" +#include "virnetdevtap.h"
#define NETWORK_PID_DIR LOCALSTATEDIR "/run/libvirt/network" #define NETWORK_STATE_DIR LOCALSTATEDIR "/lib/libvirt/network" diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 69ff444..12867d3 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -54,7 +54,6 @@ #include "openvz_conf.h" #include "nodeinfo.h" #include "memory.h" -#include "bridge.h" #include "virfile.h" #include "logging.h" #include "command.h" diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5680636..7c9e60b 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -38,6 +38,7 @@ #include "domain_audit.h" #include "domain_conf.h" #include "network/bridge_driver.h" +#include "virnetdevtap.h"
#include<sys/utsname.h> #include<sys/stat.h> diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 1ba2002..bbe7e74 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -28,7 +28,6 @@
# include "ebtables.h" # include "internal.h" -# include "bridge.h" # include "capabilities.h" # include "network_conf.h" # include "domain_conf.h" diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c index 9b6abe7..3089abb 100644 --- a/src/uml/uml_conf.c +++ b/src/uml/uml_conf.c @@ -43,11 +43,11 @@ #include "util.h" #include "memory.h" #include "nodeinfo.h" -#include "bridge.h" #include "logging.h" #include "domain_nwfilter.h" #include "virfile.h" #include "command.h" +#include "virnetdevtap.h"
#define VIR_FROM_THIS VIR_FROM_UML
diff --git a/src/uml/uml_conf.h b/src/uml/uml_conf.h index 01695c7..383ae66 100644 --- a/src/uml/uml_conf.h +++ b/src/uml/uml_conf.h @@ -25,7 +25,6 @@ # define __UML_CONF_H
# include "internal.h" -# include "bridge.h" # include "capabilities.h" # include "network_conf.h" # include "domain_conf.h" diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 4a417ab..c5587d0 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -62,6 +62,7 @@ #include "virfile.h" #include "fdstream.h" #include "configmake.h" +#include "virnetdevtap.h"
#define VIR_FROM_THIS VIR_FROM_UML
diff --git a/src/util/bridge.c b/src/util/bridge.c deleted file mode 100644 index 0265e81..0000000 --- a/src/util/bridge.c +++ /dev/null @@ -1,1115 +0,0 @@ -/* - * Copyright (C) 2007, 2009, 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Authors: - * Mark McLoughlin<markmc@redhat.com> - */ - -#include<config.h> - -#if defined(WITH_BRIDGE) - -# include "bridge.h" -# include "virfile.h" - -# include<stdlib.h> -# include<stdio.h> -# include<string.h> -# include<unistd.h> -# include<fcntl.h> -# include<errno.h> -# include<arpa/inet.h> -# include<sys/types.h> -# include<sys/socket.h> -# include<sys/ioctl.h> -# include<paths.h> -# include<sys/wait.h> - -# include<linux/param.h> /* HZ */ -# include<linux/sockios.h> /* SIOCBRADDBR etc. */ -# include<linux/if_bridge.h> /* SYSFS_BRIDGE_ATTR */ -# include<linux/if_tun.h> /* IFF_TUN, IFF_NO_PI */ -# include<net/if_arp.h> /* ARPHRD_ETHER */ - -# include "internal.h" -# include "command.h" -# include "memory.h" -# include "util.h" -# include "logging.h" -# include "network.h" -# include "virterror_internal.h" -# include "intprops.h" - -# define JIFFIES_TO_MS(j) (((j)*1000)/HZ) -# define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000) - -# define VIR_FROM_THIS VIR_FROM_NONE - -static int virNetDevSetupControlFull(const char *ifname, - struct ifreq *ifr, - int domain, - int type) -{ - int fd; - - if (ifname&& ifr) { - memset(ifr, 0, sizeof(*ifr)); - - if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) { - virReportSystemError(ERANGE, - _("Network interface name '%s' is too long"), - ifname); - return -1; - } - } - - if ((fd = socket(domain, type, 0))< 0) { - virReportSystemError(errno, "%s", - _("Cannot open network interface control socket")); - return -1; - } - - if (virSetInherit(fd, false)< 0) { - virReportSystemError(errno, "%s", - _("Cannot set close-on-exec flag for socket")); - VIR_FORCE_CLOSE(fd); - return -1; - } - - return fd; -} - - -static int virNetDevSetupControl(const char *ifname, - struct ifreq *ifr) -{ - return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); -} - -# define SYSFS_NET_DIR "/sys/class/net" -/* - * Bridge parameters can be set via sysfs on newish kernels, - * or by ioctl on older kernels. Perhaps we could just use - * ioctl for every kernel, but its not clear what the long - * term lifespan of the ioctl interface is... - */ -static int virNetDevBridgeSet(const char *brname, - const char *paramname, /* sysfs param name */ - unsigned long value, /* new value */ - int fd, /* control socket */ - struct ifreq *ifr) /* pre-filled bridge name */ -{ - char *path = NULL; - int ret = -1; - - if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname)< 0) { - virReportOOMError(); - return -1; - } - - if (virFileExists(path)) { - char valuestr[INT_BUFSIZE_BOUND(value)]; - snprintf(valuestr, sizeof(valuestr), "%lu", value); - if (virFileWriteStr(path, valuestr, 0)< 0) { - virReportSystemError(errno, - _("Unable to set bridge %s %s"), brname, paramname); - goto cleanup; - } - } else { - unsigned long paramid; - if (STREQ(paramname, "stp_state")) { - paramid = BRCTL_SET_BRIDGE_STP_STATE; - } else if (STREQ(paramname, "forward_delay")) { - paramid = BRCTL_SET_BRIDGE_FORWARD_DELAY; - } else { - virReportSystemError(EINVAL, - _("Unable to set bridge %s %s"), brname, paramname); - goto cleanup; - } - unsigned long args[] = { paramid, value, 0, 0 }; - ifr->ifr_data = (char*)&args; - if (ioctl(fd, SIOCDEVPRIVATE, ifr)< 0) { - virReportSystemError(errno, - _("Unable to set bridge %s %s"), brname, paramname); - goto cleanup; - } - } - - ret = 0; -cleanup: - VIR_FREE(path); - return ret; -} - - -static int virNetDevBridgeGet(const char *brname, - const char *paramname, /* sysfs param name */ - unsigned long *value, /* current value */ - int fd, /* control socket */ - struct ifreq *ifr) /* pre-filled bridge name */ -{ - char *path = NULL; - int ret = -1; - - if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname)< 0) { - virReportOOMError(); - return -1; - } - - if (virFileExists(path)) { - char *valuestr; - if (virFileReadAll(path, INT_BUFSIZE_BOUND(unsigned long),&valuestr)< 0) - goto cleanup; - - if (virStrToLong_ul(valuestr, NULL, 10, value)< 0) { - virReportSystemError(EINVAL, - _("Unable to get bridge %s %s"), brname, paramname); - } - } else { - struct __bridge_info info; - unsigned long args[] = { BRCTL_GET_BRIDGE_INFO, (unsigned long)&info, 0, 0 }; - ifr->ifr_data = (char*)&args; - if (ioctl(fd, SIOCDEVPRIVATE, ifr)< 0) { - virReportSystemError(errno, - _("Unable to get bridge %s %s"), brname, paramname); - goto cleanup; - } - - if (STREQ(paramname, "stp_state")) { - *value = info.stp_enabled; - } else if (STREQ(paramname, "forward_delay")) { - *value = info.forward_delay; - } else { - virReportSystemError(EINVAL, - _("Unable to get bridge %s %s"), brname, paramname); - goto cleanup; - } - } - - ret = 0; -cleanup: - VIR_FREE(path); - return ret; -} - - -/** - * virNetDevBridgeCreate: - * @brname: the bridge name - * - * This function register a new bridge - * - * Returns 0 in case of success or -1 on failure - */ -# ifdef SIOCBRADDBR -int virNetDevBridgeCreate(const char *brname) -{ - int fd = -1; - int ret = -1; - - if ((fd = virNetDevSetupControl(NULL, NULL))< 0) - return -1; - - if (ioctl(fd, SIOCBRADDBR, brname)< 0) { - virReportSystemError(errno, - _("Unable to create bridge %s"), brname); - goto cleanup; - } - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} -# else -int virNetDevBridgeCreate(const char *brname) -{ - virReportSystemError(ENOSYS, - _("Unable to create bridge %s"), brname); - return -1; -} -# endif - -# ifdef SIOCBRDELBR -/** - * virNetDevExists: - * @ifname - * - * Check if the network device @ifname exists - * - * Returns 1 if it exists, 0 if it does not, -1 on error - */ -int virNetDevExists(const char *ifname) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) - return -1; - - if (ioctl(fd, SIOCGIFFLAGS,&ifr)) { - if (errno == ENODEV) - ret = 0; - else - virReportSystemError(errno, - _("Unable to check interface flags for %s"), ifname); - goto cleanup; - } - - ret = 1; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} -# else -int virNetDevExists(const char *ifname) -{ - virReportSystemError(errno, - _("Unable to check interface %s"), ifname); - return -1; -} -# endif - -/** - * virNetDevBridgeDelete: - * @brname: the bridge name - * - * Remove a bridge from the layer. - * - * Returns 0 in case of success or an errno code in case of failure. - */ -# ifdef SIOCBRDELBR -int virNetDevBridgeDelete(const char *brname) -{ - int fd = -1; - int ret = -1; - - if ((fd = virNetDevSetupControl(NULL, NULL))< 0) - return -1; - - if (ioctl(fd, SIOCBRDELBR, brname)< 0) { - virReportSystemError(errno, - _("Unable to delete bridge %s"), brname); - goto cleanup; - } - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} -# else -int virNetDevBridgeDelete(const char *brname ATTRIBUTE_UNUSED) -{ - virReportSystemError(errno, - _("Unable to delete bridge %s"), brname); - return EINVAL; -} -# endif - -/** - * virNetDevBridgeAddPort: - * @brname: the bridge name - * @ifname: the network interface name - * - * Adds an interface to a bridge - * - * Returns 0 in case of success or an errno code in case of failure. - */ -# ifdef SIOCBRADDIF -int virNetDevBridgeAddPort(const char *brname, - const char *ifname) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(brname,&ifr))< 0) - return -1; - - if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { - virReportSystemError(errno, - _("Unable to get interface index for %s"), ifname); - goto cleanup; - } - - if (ioctl(fd, SIOCBRADDIF,&ifr)< 0) { - virReportSystemError(errno, - _("Unable to add bridge %s port %s"), brname, ifname); - goto cleanup; - } - - ret = 0; -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} -# else -int virNetDevBridgeAddPort(const char *brname, - const char *ifname) -{ - virReportSystemError(ENOSYS, - _("Unable to add bridge %s port %s"), brname, ifname); - return -1; -} -# endif - -/** - * virNetDevBridgeRemovePort: - * @brname: the bridge name - * @ifname: the network interface name - * - * Removes an interface from a bridge - * - * Returns 0 in case of success or an errno code in case of failure. - */ -# ifdef SIOCBRDELIF -int virNetDevBridgeRemovePort(const char *brname, - const char *ifname) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(brname,&ifr))< 0) - return -1; - - if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { - virReportSystemError(errno, - _("Unable to get interface index for %s"), ifname); - - goto cleanup; - } - - if (ioctl(fd, SIOCBRDELIF,&ifr)< 0) { - virReportSystemError(errno, - _("Unable to remove bridge %s port %s"), brname, ifname); - goto cleanup; - } - - ret = 0; -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} -# else -int virNetDevBridgeRemovePort(const char *brname, - const char *ifname) -{ - virReportSystemError(errno, - _("Unable to remove bridge %s port %s"), brname, ifname); - return -1; -} -# endif - -/** - * virNetDevSetMAC: - * @ifname: interface name to set MTU for - * @macaddr: MAC address (VIR_MAC_BUFLEN in size) - * - * This function sets the @macaddr for a given interface @ifname. This - * gets rid of the kernel's automatically assigned random MAC. - * - * Returns 0 in case of success or -1 on failure - */ -int virNetDevSetMAC(const char *ifname, - const unsigned char *macaddr) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) - return -1; - - /* To fill ifr.ifr_hdaddr.sa_family field */ - if (ioctl(fd, SIOCGIFHWADDR,&ifr)< 0) { - virReportSystemError(errno, - _("Cannot get interface MAC on '%s'"), - ifname); - goto cleanup; - } - - memcpy(ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN); - - if (ioctl(fd, SIOCSIFHWADDR,&ifr)< 0) { - virReportSystemError(errno, - _("Cannot set interface MAC on '%s'"), - ifname); - goto cleanup; - } - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - -/** - * virNetDevGetMAC: - * @ifname: interface name to set MTU for - * @macaddr: MAC address (VIR_MAC_BUFLEN in size) - * - * This function gets the @macaddr for a given interface @ifname. - * - * Returns 0 in case of success or -1 on failure - */ -int virNetDevGetMAC(const char *ifname, - unsigned char *macaddr) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) - return -1; - - if (ioctl(fd, SIOCGIFHWADDR,&ifr)< 0) { - virReportSystemError(errno, - _("Cannot get interface MAC on '%s'"), - ifname); - goto cleanup; - } - - memcpy(macaddr, ifr.ifr_hwaddr.sa_data, VIR_MAC_BUFLEN); - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - -/** - * virNetDevGetMTU: - * @ifname: interface name get MTU for - * - * This function gets the @mtu value set for a given interface @ifname. - * - * Returns the MTU value in case of success, or -1 on failure. - */ -int virNetDevGetMTU(const char *ifname) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) - return -1; - - if (ioctl(fd, SIOCGIFMTU,&ifr)< 0) { - virReportSystemError(errno, - _("Cannot get interface MTU on '%s'"), - ifname); - goto cleanup; - } - - ret = ifr.ifr_mtu; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - -/** - * virNetDevSetMTU: - * @ifname: interface name to set MTU for - * @mtu: MTU value - * - * This function sets the @mtu for a given interface @ifname. Typically - * used on a tap device to set up for Jumbo Frames. - * - * Returns 0 in case of success, or -1 on failure - */ -int virNetDevSetMTU(const char *ifname, int mtu) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) - return -1; - - ifr.ifr_mtu = mtu; - - if (ioctl(fd, SIOCSIFMTU,&ifr)< 0) { - virReportSystemError(errno, - _("Cannot set interface MTU on '%s'"), - ifname); - goto cleanup; - } - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - -/** - * virNetDevSetMTUFromDevice: - * @ifname: name of the interface whose MTU we want to set - * @otherifname: name of the interface whose MTU we want to copy - * - * Sets the interface mtu to the same MTU as another interface - * - * Returns 0 in case of success, or -1 on failure - */ -int virNetDevSetMTUFromDevice(const char *ifname, - const char *otherifname) -{ - int mtu = virNetDevGetMTU(otherifname); - - if (mtu< 0) - return -1; - - return virNetDevSetMTU(ifname, mtu); -} - -/** - * virNetDevProbeVnetHdr: - * @tapfd: a tun/tap file descriptor - * - * Check whether it is safe to enable the IFF_VNET_HDR flag on the - * tap interface. - * - * Setting IFF_VNET_HDR enables QEMU's virtio_net driver to allow - * guests to pass larger (GSO) packets, with partial checksums, to - * the host. This greatly increases the achievable throughput. - * - * It is only useful to enable this when we're setting up a virtio - * interface. And it is only *safe* to enable it when we know for - * sure that a) qemu has support for IFF_VNET_HDR and b) the running - * kernel implements the TUNGETIFF ioctl(), which qemu needs to query - * the supplied tapfd. - * - * Returns 1 if VnetHdr is supported, 0 if not supported - */ -# ifdef IFF_VNET_HDR -static int -virNetDevProbeVnetHdr(int tapfd) -{ -# if defined(IFF_VNET_HDR)&& defined(TUNGETFEATURES)&& defined(TUNGETIFF) - unsigned int features; - struct ifreq dummy; - - if (ioctl(tapfd, TUNGETFEATURES,&features) != 0) { - VIR_INFO("Not enabling IFF_VNET_HDR; " - "TUNGETFEATURES ioctl() not implemented"); - return 0; - } - - if (!(features& IFF_VNET_HDR)) { - VIR_INFO("Not enabling IFF_VNET_HDR; " - "TUNGETFEATURES ioctl() reports no IFF_VNET_HDR"); - return 0; - } - - /* The kernel will always return -1 at this point. - * If TUNGETIFF is not implemented then errno == EBADFD. - */ - if (ioctl(tapfd, TUNGETIFF,&dummy) != -1 || errno != EBADFD) { - VIR_INFO("Not enabling IFF_VNET_HDR; " - "TUNGETIFF ioctl() not implemented"); - return 0; - } - - VIR_INFO("Enabling IFF_VNET_HDR"); - - return 1; -# else - (void) tapfd; - VIR_INFO("Not enabling IFF_VNET_HDR; disabled at build time"); - return 0; -# endif -} -# endif - -/** - * brAddTap: - * @brname: the bridge name - * @ifname: the interface name (or name template) - * @macaddr: desired MAC address (VIR_MAC_BUFLEN long) - * @vnet_hdr: whether to try enabling IFF_VNET_HDR - * @tapfd: file descriptor return value for the new tap device - * - * This function creates a new tap device on a bridge. @ifname can be either - * a fixed name or a name template with '%d' for dynamic name allocation. - * in either case the final name for the bridge will be stored in @ifname. - * If the @tapfd parameter is supplied, the open tap device file - * descriptor will be returned, otherwise the TAP device will be made - * persistent and closed. The caller must use brDeleteTap to remove - * a persistent TAP devices when it is no longer needed. - * - * Returns 0 in case of success or -1 on failure - */ -int virNetDevTapCreateInBridgePort(const char *brname, - char **ifname, - const unsigned char *macaddr, - int vnet_hdr, - bool up, - int *tapfd) -{ - if (virNetDevTapCreate(ifname, vnet_hdr, tapfd)< 0) - return -1; - - /* We need to set the interface MAC before adding it - * to the bridge, because the bridge assumes the lowest - * MAC of all enslaved interfaces& we don't want it - * seeing the kernel allocate random MAC for the TAP - * device before we set our static MAC. - */ - if (virNetDevSetMAC(*ifname, macaddr)< 0) - goto error; - - /* We need to set the interface MTU before adding it - * to the bridge, because the bridge will have its - * MTU adjusted automatically when we add the new interface. - */ - if (virNetDevSetMTUFromDevice(*ifname, brname)< 0) - goto error; - - if (virNetDevBridgeAddPort(brname, *ifname)< 0) - goto error; - - if (virNetDevSetOnline(*ifname, up)< 0) - goto error; - - return 0; - -error: - if (tapfd) - VIR_FORCE_CLOSE(*tapfd); - return -1; -} - -int virNetDevTapDelete(const char *ifname) -{ - struct ifreq try; - int fd; - int ret = -1; - - if ((fd = open("/dev/net/tun", O_RDWR))< 0) { - virReportSystemError(errno, "%s", - _("Unable to open /dev/net/tun, is tun module loaded?")); - return -1; - } - - memset(&try, 0, sizeof(struct ifreq)); - try.ifr_flags = IFF_TAP|IFF_NO_PI; - - if (virStrcpyStatic(try.ifr_name, ifname) == NULL) { - virReportSystemError(ERANGE, - _("Network interface name '%s' is too long"), - ifname); - goto cleanup; - } - - if (ioctl(fd, TUNSETIFF,&try)< 0) { - virReportSystemError(errno, "%s", - _("Unable to associate TAP device")); - goto cleanup; - } - - if (ioctl(fd, TUNSETPERSIST, 0)< 0) { - virReportSystemError(errno, "%s", - _("Unable to make TAP device non-persistent")); - goto cleanup; - } - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - - -/** - * virNetDevSetOnline: - * @ifname: the interface name - * @online: true for up, false for down - * - * Function to control if an interface is activated (up, true) or not (down, false) - * - * Returns 0 in case of success or -1 on error. - */ -int virNetDevSetOnline(const char *ifname, - bool online) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - int ifflags; - - if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) - return -1; - - if (ioctl(fd, SIOCGIFFLAGS,&ifr)< 0) { - virReportSystemError(errno, - _("Cannot get interface flags on '%s'"), - ifname); - goto cleanup; - } - - if (online) - ifflags = ifr.ifr_flags | IFF_UP; - else - ifflags = ifr.ifr_flags& ~IFF_UP; - - if (ifr.ifr_flags != ifflags) { - ifr.ifr_flags = ifflags; - if (ioctl(fd, SIOCSIFFLAGS,&ifr)< 0) { - virReportSystemError(errno, - _("Cannot set interface flags on '%s'"), - ifname); - goto cleanup; - } - } - - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - -/** - * virNetDevIsOnline: - * @ifname: the interface name - * @online: where to store the status - * - * Function to query if an interface is activated (true) or not (false) - * - * Returns 0 in case of success or an errno code in case of failure. - */ -int virNetDevIsOnline(const char *ifname, - bool *online) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) - return -1; - - if (ioctl(fd, SIOCGIFFLAGS,&ifr)< 0) { - virReportSystemError(errno, - _("Cannot get interface flags on '%s'"), - ifname); - goto cleanup; - } - - *online = (ifr.ifr_flags& IFF_UP) ? true : false; - ret = 0; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - -/** - * virNetDevSetIPv4Addres: - * @ifname: the interface name - * @addr: the IP address (IPv4 or IPv6) - * @prefix: number of 1 bits in the netmask - * - * Add an IP address to an interface. This function *does not* remove - * any previously added IP addresses - that must be done separately with - * brDelInetAddress. - * - * Returns 0 in case of success or -1 in case of error. - */ - -int virNetDevSetIPv4Addres(const char *ifname, - virSocketAddr *addr, - unsigned int prefix) -{ - virCommandPtr cmd = NULL; - char *addrstr = NULL, *bcaststr = NULL; - virSocketAddr broadcast; - int ret = -1; - - if (!(addrstr = virSocketFormatAddr(addr))) - goto cleanup; - /* format up a broadcast address if this is IPv4 */ - if ((VIR_SOCKET_IS_FAMILY(addr, AF_INET))&& - ((virSocketAddrBroadcastByPrefix(addr, prefix,&broadcast)< 0) || - !(bcaststr = virSocketFormatAddr(&broadcast)))) { - goto cleanup; - } - cmd = virCommandNew(IP_PATH); - virCommandAddArgList(cmd, "addr", "add", NULL); - virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); - if (bcaststr) - virCommandAddArgList(cmd, "broadcast", bcaststr, NULL); - virCommandAddArgList(cmd, "dev", ifname, NULL); - - if (virCommandRun(cmd, NULL)< 0) - goto cleanup; - - ret = 0; -cleanup: - VIR_FREE(addrstr); - VIR_FREE(bcaststr); - virCommandFree(cmd); - return ret; -} - -/** - * virNetDevClearIPv4Address: - * @ifname: the interface name - * @addr: the IP address (IPv4 or IPv6) - * @prefix: number of 1 bits in the netmask - * - * Delete an IP address from an interface. - * - * Returns 0 in case of success or -1 in case of error. - */ - -int virNetDevClearIPv4Address(const char *ifname, - virSocketAddr *addr, - unsigned int prefix) -{ - virCommandPtr cmd = NULL; - char *addrstr; - int ret = -1; - - if (!(addrstr = virSocketFormatAddr(addr))) - goto cleanup; - cmd = virCommandNew(IP_PATH); - virCommandAddArgList(cmd, "addr", "del", NULL); - virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); - virCommandAddArgList(cmd, "dev", ifname, NULL); - - if (virCommandRun(cmd, NULL)< 0) - goto cleanup; - - ret = 0; -cleanup: - VIR_FREE(addrstr); - virCommandFree(cmd); - return ret; -} - -/** - * virNetDevBridgeSetSTPDelay: - * @brname: the bridge name - * @delay: delay in seconds - * - * Set the bridge forward delay - * - * Returns 0 in case of success or -1 on failure - */ - -int virNetDevBridgeSetSTPDelay(const char *brname, - int delay) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(brname,&ifr))< 0) - goto cleanup; - - ret = virNetDevBridgeSet(brname, "stp_state", MS_TO_JIFFIES(delay), - fd,&ifr); - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - - -/** - * virNetDevBridgeGetSTPDelay: - * @brname: the bridge device name - * @delayms: the forward delay in milliseconds - * - * Retrives the forward delay for the bridge device @brname - * storing it in @delayms. The forward delay is only meaningful - * if STP is enabled - * - * Returns 0 on success, -1 on error+ - */ -int virNetDevBridgeGetSTPDelay(const char *brname, - int *delayms) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - unsigned long i; - - if ((fd = virNetDevSetupControl(brname,&ifr))< 0) - goto cleanup; - - ret = virNetDevBridgeGet(brname, "stp_state",&i, - fd,&ifr); - *delayms = JIFFIES_TO_MS(i); - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - - -/** - * virNetDevBridgeSetSTP: - * @brname: the bridge name - * @enable: 1 to enable, 0 to disable - * - * Control whether the bridge participates in the spanning tree protocol, - * in general don't disable it without good reasons. - * - * Returns 0 in case of success or -1 on failure - */ -int virNetDevBridgeSetSTP(const char *brname, - bool enable) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - - if ((fd = virNetDevSetupControl(brname,&ifr))< 0) - goto cleanup; - - ret = virNetDevBridgeSet(brname, "stp_state", enable ? 1 : 0, - fd,&ifr); - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - - -/** - * virNetDevBridgeGetSTP: - * @brname: the bridge device name - * @enabled: returns the STP state - * - * Determine the state of the spanning tree protocol on - * the device @brname, returning the state in @enabled - * - * Returns 0 on success, -1 on error - */ -int virNetDevBridgeGetSTP(const char *brname, - bool *enabled) -{ - int fd = -1; - int ret = -1; - struct ifreq ifr; - unsigned long i; - - if ((fd = virNetDevSetupControl(brname,&ifr))< 0) - goto cleanup; - - ret = virNetDevBridgeGet(brname, "stp_state",&i, - fd,&ifr); - *enabled = i ? true : false; - -cleanup: - VIR_FORCE_CLOSE(fd); - return ret; -} - - -/** - * brCreateTap: - * @ifname: the interface name - * @vnet_hr: whether to try enabling IFF_VNET_HDR - * @tapfd: file descriptor return value for the new tap device - * - * Creates a tap interface. - * If the @tapfd parameter is supplied, the open tap device file - * descriptor will be returned, otherwise the TAP device will be made - * persistent and closed. The caller must use brDeleteTap to remove - * a persistent TAP devices when it is no longer needed. - * - * Returns 0 in case of success or an errno code in case of failure. - */ - -int virNetDevTapCreate(char **ifname, - int vnet_hdr ATTRIBUTE_UNUSED, - int *tapfd) -{ - int fd; - struct ifreq ifr; - int ret = -1; - - if ((fd = open("/dev/net/tun", O_RDWR))< 0) { - virReportSystemError(errno, "%s", - _("Unable to open /dev/net/tun, is tun module loaded?")); - return -1; - } - - memset(&ifr, 0, sizeof(ifr)); - - ifr.ifr_flags = IFF_TAP|IFF_NO_PI; - -# ifdef IFF_VNET_HDR - if (vnet_hdr&& virNetDevProbeVnetHdr(fd)) - ifr.ifr_flags |= IFF_VNET_HDR; -# endif - - if (virStrcpyStatic(ifr.ifr_name, *ifname) == NULL) { - virReportSystemError(ERANGE, - _("Network interface name '%s' is too long"), - *ifname); - goto cleanup; - - } - - if (ioctl(fd, TUNSETIFF,&ifr)< 0) { - virReportSystemError(errno, - _("Unable to create tap device %s"), - NULLSTR(*ifname)); - goto cleanup; - } - - if (!tapfd&& - (errno = ioctl(fd, TUNSETPERSIST, 1))) { - virReportSystemError(errno, - _("Unable to set tap device %s to persistent"), - NULLSTR(*ifname)); - goto cleanup; - } - - VIR_FREE(*ifname); - if (!(*ifname = strdup(ifr.ifr_name))) { - virReportOOMError(); - goto cleanup; - } - if (tapfd) - *tapfd = fd; - else - VIR_FORCE_CLOSE(fd); - - ret = 0; - -cleanup: - if (ret< 0) - VIR_FORCE_CLOSE(fd); - - return ret; -} - -#endif /* WITH_BRIDGE */ diff --git a/src/util/bridge.h b/src/util/bridge.h deleted file mode 100644 index 7504925..0000000 --- a/src/util/bridge.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2007 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Authors: - * Mark McLoughlin<markmc@redhat.com> - */ - -#ifndef __QEMUD_BRIDGE_H__ -# define __QEMUD_BRIDGE_H__ - -# include<config.h> - -# if defined(WITH_BRIDGE) - -# include<net/if.h> -# include<netinet/in.h> -# include "network.h" - -/** - * BR_IFNAME_MAXLEN: - * maximum size in byte of the name for an interface - */ -# define BR_IFNAME_MAXLEN IF_NAMESIZE - -/** - * BR_INET_ADDR_MAXLEN: - * maximum size in bytes for an inet addess name - */ -# define BR_INET_ADDR_MAXLEN INET_ADDRSTRLEN - -int virNetDevBridgeCreate(const char *brname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevBridgeDelete(const char *brname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevExists(const char *brname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -int virNetDevBridgeAddPort(const char *brname, - const char *ifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -int virNetDevBridgeRemovePort(const char *brname, - const char *ifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -enum { - BR_TAP_VNET_HDR = (1<< 0), - BR_TAP_PERSIST = (1<< 1), -}; - -int virNetDevTapCreateInBridgePort(const char *brname, - char **ifname, - const unsigned char *macaddr, - int vnet_hdr, - bool up, - int *tapfd) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) - ATTRIBUTE_RETURN_CHECK; - - -int virNetDevTapDelete(const char *ifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -int virNetDevSetOnline(const char *ifname, - bool online) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevIsOnline(const char *ifname, - bool *online) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -int virNetDevSetIPv4Addres(const char *ifname, - virSocketAddr *addr, - unsigned int prefix) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int virNetDevClearIPv4Address(const char *ifname, - virSocketAddr *addr, - unsigned int prefix) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -int virNetDevBridgeSetSTPDelay(const char *brname, - int delay) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevBridgeGetSTPDelay(const char *brname, - int *delay) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int virNetDevBridgeSetSTP(const char *brname, - bool enable) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevBridgeGetSTP(const char *brname, - bool *enable) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -int virNetDevTapCreate(char **ifname, - int vnet_hdr, - int *tapfd) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -int virNetDevSetMAC(const char *ifname, - const unsigned char *macaddr) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int virNetDevGetMAC(const char *ifname, - unsigned char *macaddr) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int virNetDevSetMTU(const char *ifname, - int mtu) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevSetMTUFromDevice(const char *ifname, - const char *otherifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int virNetDevGetMTU(const char *ifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -# endif /* WITH_BRIDGE */ - -#endif /* __QEMUD_BRIDGE_H__ */ diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c new file mode 100644 index 0000000..6eb5fe7 --- /dev/null +++ b/src/util/virnetdev.c @@ -0,0 +1,524 @@ +/* + * Copyright (C) 2007-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin<markmc@redhat.com> + * Daniel P. Berrange<berrange@redhat.com> + */ + +#include<config.h> + +#include "virnetdev.h" +#include "virfile.h" +#include "virterror_internal.h" +#include "command.h" +#include "memory.h" + +#include<sys/ioctl.h> +#ifdef HAVE_NET_IF_H +# include<net/if.h> +#endif + +#define VIR_FROM_THIS VIR_FROM_NONE + +#ifdef HAVE_NET_IF_H +static int virNetDevSetupControlFull(const char *ifname, + struct ifreq *ifr, + int domain, + int type) +{ + int fd; + + memset(ifr, 0, sizeof(*ifr)); + + if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) { + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + ifname); + return -1; + } + + if ((fd = socket(domain, type, 0))< 0) { + virReportSystemError(errno, "%s", + _("Cannot open network interface control socket")); + return -1; + } + + if (virSetInherit(fd, false)< 0) { + virReportSystemError(errno, "%s", + _("Cannot set close-on-exec flag for socket")); + VIR_FORCE_CLOSE(fd); + return -1; + } + + return fd; +} + + +static int virNetDevSetupControl(const char *ifname, + struct ifreq *ifr) +{ + return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); +} +#endif + + +#ifdef SIOCGIFFLAGS +/** + * virNetDevExists: + * @ifname + * + * Check if the network device @ifname exists + * + * Returns 1 if it exists, 0 if it does not, -1 on error + */ +int virNetDevExists(const char *ifname) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) + return -1; + + if (ioctl(fd, SIOCGIFFLAGS,&ifr)) { + if (errno == ENODEV) + ret = 0; + else + virReportSystemError(errno, + _("Unable to check interface flags for %s"), ifname); + goto cleanup; + } + + ret = 1; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevExists(const char *ifname) +{ + virReportSystemError(errno, ENOSYS + _("Unable to check interface %s"), ifname); + return -1; +} +#endif + + +#ifdef SIOCGIFHWADDR +/** + * virNetDevSetMAC: + * @ifname: interface name to set MTU for + * @macaddr: MAC address (VIR_MAC_BUFLEN in size) + * + * This function sets the @macaddr for a given interface @ifname. This + * gets rid of the kernel's automatically assigned random MAC. + * + * Returns 0 in case of success or -1 on failure + */ +int virNetDevSetMAC(const char *ifname, + const unsigned char *macaddr) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) + return -1; + + /* To fill ifr.ifr_hdaddr.sa_family field */ + if (ioctl(fd, SIOCGIFHWADDR,&ifr)< 0) { + virReportSystemError(errno, + _("Cannot get interface MAC on '%s'"), + ifname); + goto cleanup; + } + + memcpy(ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN); + + if (ioctl(fd, SIOCSIFHWADDR,&ifr)< 0) { + virReportSystemError(errno, + _("Cannot set interface MAC on '%s'"), + ifname); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevSetMAC(const char *ifname, + const unsigned char *macaddr ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Cannot set interface MAC on '%s'"), + ifname); + return -1; +} +#endif + + +#ifdef SIOCGIFHWADDR +/** + * virNetDevGetMAC: + * @ifname: interface name to set MTU for + * @macaddr: MAC address (VIR_MAC_BUFLEN in size) + * + * This function gets the @macaddr for a given interface @ifname. + * + * Returns 0 in case of success or -1 on failure + */ +int virNetDevGetMAC(const char *ifname, + unsigned char *macaddr) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) + return -1; + + if (ioctl(fd, SIOCGIFHWADDR,&ifr)< 0) { + virReportSystemError(errno, + _("Cannot get interface MAC on '%s'"), + ifname); + goto cleanup; + } + + memcpy(macaddr, ifr.ifr_hwaddr.sa_data, VIR_MAC_BUFLEN); + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevGetMAC(const char *ifname, + unsigned char *macaddr ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Cannot get interface MAC on '%s'"), + ifname); + return -1; +} +#endif + + +#ifdef SIOCGIFMTU +/** + * virNetDevGetMTU: + * @ifname: interface name get MTU for + * + * This function gets the @mtu value set for a given interface @ifname. + * + * Returns the MTU value in case of success, or -1 on failure. + */ +int virNetDevGetMTU(const char *ifname) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) + return -1; + + if (ioctl(fd, SIOCGIFMTU,&ifr)< 0) { + virReportSystemError(errno, + _("Cannot get interface MTU on '%s'"), + ifname); + goto cleanup; + } + + ret = ifr.ifr_mtu; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevGetMTU(const char *ifname) +{ + virReportSystemError(ENOSYS, + _("Cannot get interface MTU on '%s'"), + ifname); + return -1; +} +#endif + + +#ifdef SIOCSIFMTU +/** + * virNetDevSetMTU: + * @ifname: interface name to set MTU for + * @mtu: MTU value + * + * This function sets the @mtu for a given interface @ifname. Typically + * used on a tap device to set up for Jumbo Frames. + * + * Returns 0 in case of success, or -1 on failure + */ +int virNetDevSetMTU(const char *ifname, int mtu) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) + return -1; + + ifr.ifr_mtu = mtu; + + if (ioctl(fd, SIOCSIFMTU,&ifr)< 0) { + virReportSystemError(errno, + _("Cannot set interface MTU on '%s'"), + ifname); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevSetMTU(const char *ifname, int mtu ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Cannot set interface MTU on '%s'"), + ifname); + return -1; +} +#endif + + +/** + * virNetDevSetMTUFromDevice: + * @ifname: name of the interface whose MTU we want to set + * @otherifname: name of the interface whose MTU we want to copy + * + * Sets the interface mtu to the same MTU as another interface + * + * Returns 0 in case of success, or -1 on failure + */ +int virNetDevSetMTUFromDevice(const char *ifname, + const char *otherifname) +{ + int mtu = virNetDevGetMTU(otherifname); + + if (mtu< 0) + return -1; + + return virNetDevSetMTU(ifname, mtu); +} + + +#ifdef SIOCSIFFLAGS +/** + * virNetDevSetOnline: + * @ifname: the interface name + * @online: true for up, false for down + * + * Function to control if an interface is activated (up, true) or not (down, false) + * + * Returns 0 in case of success or -1 on error. + */ +int virNetDevSetOnline(const char *ifname, + bool online) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + int ifflags; + + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) + return -1; + + if (ioctl(fd, SIOCGIFFLAGS,&ifr)< 0) { + virReportSystemError(errno, + _("Cannot get interface flags on '%s'"), + ifname); + goto cleanup; + } + + if (online) + ifflags = ifr.ifr_flags | IFF_UP; + else + ifflags = ifr.ifr_flags& ~IFF_UP; + + if (ifr.ifr_flags != ifflags) { + ifr.ifr_flags = ifflags; + if (ioctl(fd, SIOCSIFFLAGS,&ifr)< 0) { + virReportSystemError(errno, + _("Cannot set interface flags on '%s'"), + ifname); + goto cleanup; + } + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevSetOnline(const char *ifname, + bool online ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Cannot set interface flags on '%s'"), + ifname); + return -1; +} +#endif + + +#ifdef SIOCGIFFLAGS +/** + * virNetDevIsOnline: + * @ifname: the interface name + * @online: where to store the status + * + * Function to query if an interface is activated (true) or not (false) + * + * Returns 0 in case of success or an errno code in case of failure. + */ +int virNetDevIsOnline(const char *ifname, + bool *online) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname,&ifr))< 0) + return -1; + + if (ioctl(fd, SIOCGIFFLAGS,&ifr)< 0) { + virReportSystemError(errno, + _("Cannot get interface flags on '%s'"), + ifname); + goto cleanup; + } + + *online = (ifr.ifr_flags& IFF_UP) ? true : false; + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevIsOnline(const char *ifname, + bool *online ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Cannot get interface flags on '%s'"), + ifname); + return -1; +} +#endif + + +/** + * virNetDevSetIPv4Addres: + * @ifname: the interface name + * @addr: the IP address (IPv4 or IPv6) + * @prefix: number of 1 bits in the netmask + * + * Add an IP address to an interface. This function *does not* remove + * any previously added IP addresses - that must be done separately with + * brDelInetAddress. + * + * Returns 0 in case of success or -1 in case of error. + */ + +int virNetDevSetIPv4Addres(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) +{ + virCommandPtr cmd = NULL; + char *addrstr = NULL, *bcaststr = NULL; + virSocketAddr broadcast; + int ret = -1; + + if (!(addrstr = virSocketFormatAddr(addr))) + goto cleanup; + /* format up a broadcast address if this is IPv4 */ + if ((VIR_SOCKET_IS_FAMILY(addr, AF_INET))&& + ((virSocketAddrBroadcastByPrefix(addr, prefix,&broadcast)< 0) || + !(bcaststr = virSocketFormatAddr(&broadcast)))) { + goto cleanup; + } + cmd = virCommandNew(IP_PATH); + virCommandAddArgList(cmd, "addr", "add", NULL); + virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); + if (bcaststr) + virCommandAddArgList(cmd, "broadcast", bcaststr, NULL); + virCommandAddArgList(cmd, "dev", ifname, NULL); + + if (virCommandRun(cmd, NULL)< 0) + goto cleanup; + + ret = 0; +cleanup: + VIR_FREE(addrstr); + VIR_FREE(bcaststr); + virCommandFree(cmd); + return ret; +} + +/** + * virNetDevClearIPv4Address: + * @ifname: the interface name + * @addr: the IP address (IPv4 or IPv6) + * @prefix: number of 1 bits in the netmask + * + * Delete an IP address from an interface. + * + * Returns 0 in case of success or -1 in case of error. + */ + +int virNetDevClearIPv4Address(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) +{ + virCommandPtr cmd = NULL; + char *addrstr; + int ret = -1; + + if (!(addrstr = virSocketFormatAddr(addr))) + goto cleanup; + cmd = virCommandNew(IP_PATH); + virCommandAddArgList(cmd, "addr", "del", NULL); + virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix); + virCommandAddArgList(cmd, "dev", ifname, NULL); + + if (virCommandRun(cmd, NULL)< 0) + goto cleanup; + + ret = 0; +cleanup: + VIR_FREE(addrstr); + virCommandFree(cmd); + return ret; +} diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h new file mode 100644 index 0000000..cae98b7 --- /dev/null +++ b/src/util/virnetdev.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin<markmc@redhat.com> + * Daniel P. Berrange<berrange@redhat.com> + */ + +#ifndef __VIR_NETDEV_H__ +# define __VIR_NETDEV_H__ + +# include "network.h" + +int virNetDevExists(const char *brname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +int virNetDevSetOnline(const char *ifname, + bool online) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevIsOnline(const char *ifname, + bool *online) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int virNetDevSetIPv4Addres(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevClearIPv4Address(const char *ifname, + virSocketAddr *addr, + unsigned int prefix) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + + +int virNetDevSetMAC(const char *ifname, + const unsigned char *macaddr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetMAC(const char *ifname, + unsigned char *macaddr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetMTU(const char *ifname, + int mtu) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetMTUFromDevice(const char *ifname, + const char *otherifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetMTU(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +#endif /* __VIR_NETDEV_H__ */ diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c new file mode 100644 index 0000000..701d9ff --- /dev/null +++ b/src/util/virnetdevbridge.c @@ -0,0 +1,527 @@ +/* + * Copyright (C) 2007-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin<markmc@redhat.com> + * Daniel P. Berrange<berrange@redhat.com> + */ + +#include<config.h> + +#include "virnetdevbridge.h" +#include "virterror_internal.h" +#include "util.h" +#include "virfile.h" +#include "memory.h" +#include "intprops.h" + +#include<sys/ioctl.h> +#ifdef HAVE_NET_IF_H +# include<net/if.h> +#endif +#ifdef __linux__ +# include<linux/sockios.h> +# include<linux/param.h> /* HZ */ +# include<linux/if_bridge.h> /* SYSFS_BRIDGE_ATTR */ + +# define JIFFIES_TO_MS(j) (((j)*1000)/HZ) +# define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000) +#endif + +#define VIR_FROM_THIS VIR_FROM_NONE + + +#ifdef HAVE_NET_IF_H +static int virNetDevSetupControlFull(const char *ifname, + struct ifreq *ifr, + int domain, + int type) +{ + int fd; + + if (ifname&& ifr) { + memset(ifr, 0, sizeof(*ifr)); + + if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) { + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + ifname); + return -1; + } + } + + if ((fd = socket(domain, type, 0))< 0) { + virReportSystemError(errno, "%s", + _("Cannot open network interface control socket")); + return -1; + } + + if (virSetInherit(fd, false)< 0) { + virReportSystemError(errno, "%s", + _("Cannot set close-on-exec flag for socket")); + VIR_FORCE_CLOSE(fd); + return -1; + } + + return fd; +} + + +static int virNetDevSetupControl(const char *ifname, + struct ifreq *ifr) +{ + return virNetDevSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM); +} +#endif + +#ifdef __linux__ +# define SYSFS_NET_DIR "/sys/class/net" +/* + * Bridge parameters can be set via sysfs on newish kernels, + * or by ioctl on older kernels. Perhaps we could just use + * ioctl for every kernel, but its not clear what the long + * term lifespan of the ioctl interface is... + */ +static int virNetDevBridgeSet(const char *brname, + const char *paramname, /* sysfs param name */ + unsigned long value, /* new value */ + int fd, /* control socket */ + struct ifreq *ifr) /* pre-filled bridge name */ +{ + char *path = NULL; + int ret = -1; + + if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname)< 0) { + virReportOOMError(); + return -1; + } + + if (virFileExists(path)) { + char valuestr[INT_BUFSIZE_BOUND(value)]; + snprintf(valuestr, sizeof(valuestr), "%lu", value); + if (virFileWriteStr(path, valuestr, 0)< 0) { + virReportSystemError(errno, + _("Unable to set bridge %s %s"), brname, paramname); + goto cleanup; + } + } else { + unsigned long paramid; + if (STREQ(paramname, "stp_state")) { + paramid = BRCTL_SET_BRIDGE_STP_STATE; + } else if (STREQ(paramname, "forward_delay")) { + paramid = BRCTL_SET_BRIDGE_FORWARD_DELAY; + } else { + virReportSystemError(EINVAL, + _("Unable to set bridge %s %s"), brname, paramname); + goto cleanup; + } + unsigned long args[] = { paramid, value, 0, 0 }; + ifr->ifr_data = (char*)&args; + if (ioctl(fd, SIOCDEVPRIVATE, ifr)< 0) { + virReportSystemError(errno, + _("Unable to set bridge %s %s"), brname, paramname); + goto cleanup; + } + } + + ret = 0; +cleanup: + VIR_FREE(path); + return ret; +} + + +static int virNetDevBridgeGet(const char *brname, + const char *paramname, /* sysfs param name */ + unsigned long *value, /* current value */ + int fd, /* control socket */ + struct ifreq *ifr) /* pre-filled bridge name */ +{ + char *path = NULL; + int ret = -1; + + if (virAsprintf(&path, "%s/%s/bridge/%s", SYSFS_NET_DIR, brname, paramname)< 0) { + virReportOOMError(); + return -1; + } + + if (virFileExists(path)) { + char *valuestr; + if (virFileReadAll(path, INT_BUFSIZE_BOUND(unsigned long),&valuestr)< 0) + goto cleanup; + + if (virStrToLong_ul(valuestr, NULL, 10, value)< 0) { + virReportSystemError(EINVAL, + _("Unable to get bridge %s %s"), brname, paramname); + } + } else { + struct __bridge_info info; + unsigned long args[] = { BRCTL_GET_BRIDGE_INFO, (unsigned long)&info, 0, 0 }; + ifr->ifr_data = (char*)&args; + if (ioctl(fd, SIOCDEVPRIVATE, ifr)< 0) { + virReportSystemError(errno, + _("Unable to get bridge %s %s"), brname, paramname); + goto cleanup; + } + + if (STREQ(paramname, "stp_state")) { + *value = info.stp_enabled; + } else if (STREQ(paramname, "forward_delay")) { + *value = info.forward_delay; + } else { + virReportSystemError(EINVAL, + _("Unable to get bridge %s %s"), brname, paramname); + goto cleanup; + } + } + + ret = 0; +cleanup: + VIR_FREE(path); + return ret; +} +#endif /* __linux__ */ + + +/** + * virNetDevBridgeCreate: + * @brname: the bridge name + * + * This function register a new bridge + * + * Returns 0 in case of success or -1 on failure + */ +#ifdef SIOCBRADDBR +int virNetDevBridgeCreate(const char *brname) +{ + int fd = -1; + int ret = -1; + + if ((fd = virNetDevSetupControl(NULL, NULL))< 0) + return -1; + + if (ioctl(fd, SIOCBRADDBR, brname)< 0) { + virReportSystemError(errno, + _("Unable to create bridge %s"), brname); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevBridgeCreate(const char *brname) +{ + virReportSystemError(ENOSYS, + _("Unable to create bridge %s"), brname); + return -1; +} +#endif + +/** + * virNetDevBridgeDelete: + * @brname: the bridge name + * + * Remove a bridge from the layer. + * + * Returns 0 in case of success or an errno code in case of failure. + */ +#ifdef SIOCBRDELBR +int virNetDevBridgeDelete(const char *brname) +{ + int fd = -1; + int ret = -1; + + if ((fd = virNetDevSetupControl(NULL, NULL))< 0) + return -1; + + if (ioctl(fd, SIOCBRDELBR, brname)< 0) { + virReportSystemError(errno, + _("Unable to delete bridge %s"), brname); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevBridgeDelete(const char *brname ATTRIBUTE_UNUSED) +{ + virReportSystemError(errno, + _("Unable to delete bridge %s"), brname); + return EINVAL; +} +#endif + +/** + * virNetDevBridgeAddPort: + * @brname: the bridge name + * @ifname: the network interface name + * + * Adds an interface to a bridge + * + * Returns 0 in case of success or an errno code in case of failure. + */ +#ifdef SIOCBRADDIF +int virNetDevBridgeAddPort(const char *brname, + const char *ifname) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(brname,&ifr))< 0) + return -1; + + if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { + virReportSystemError(errno, + _("Unable to get interface index for %s"), ifname); + goto cleanup; + } + + if (ioctl(fd, SIOCBRADDIF,&ifr)< 0) { + virReportSystemError(errno, + _("Unable to add bridge %s port %s"), brname, ifname); + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevBridgeAddPort(const char *brname, + const char *ifname) +{ + virReportSystemError(ENOSYS, + _("Unable to add bridge %s port %s"), brname, ifname); + return -1; +} +#endif + +/** + * virNetDevBridgeRemovePort: + * @brname: the bridge name + * @ifname: the network interface name + * + * Removes an interface from a bridge + * + * Returns 0 in case of success or an errno code in case of failure. + */ +#ifdef SIOCBRDELIF +int virNetDevBridgeRemovePort(const char *brname, + const char *ifname) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(brname,&ifr))< 0) + return -1; + + if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) { + virReportSystemError(errno, + _("Unable to get interface index for %s"), ifname); + + goto cleanup; + } + + if (ioctl(fd, SIOCBRDELIF,&ifr)< 0) { + virReportSystemError(errno, + _("Unable to remove bridge %s port %s"), brname, ifname); + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevBridgeRemovePort(const char *brname, + const char *ifname) +{ + virReportSystemError(errno, + _("Unable to remove bridge %s port %s"), brname, ifname); + return -1; +} +#endif + + +#ifdef __linux__ +/** + * virNetDevBridgeSetSTPDelay: + * @brname: the bridge name + * @delay: delay in seconds + * + * Set the bridge forward delay + * + * Returns 0 in case of success or -1 on failure + */ + +int virNetDevBridgeSetSTPDelay(const char *brname, + int delay) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(brname,&ifr))< 0) + goto cleanup; + + ret = virNetDevBridgeSet(brname, "stp_state", MS_TO_JIFFIES(delay), + fd,&ifr); + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + + +/** + * virNetDevBridgeGetSTPDelay: + * @brname: the bridge device name + * @delayms: the forward delay in milliseconds + * + * Retrives the forward delay for the bridge device @brname + * storing it in @delayms. The forward delay is only meaningful + * if STP is enabled + * + * Returns 0 on success, -1 on error+ + */ +int virNetDevBridgeGetSTPDelay(const char *brname, + int *delayms) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + unsigned long i; + + if ((fd = virNetDevSetupControl(brname,&ifr))< 0) + goto cleanup; + + ret = virNetDevBridgeGet(brname, "stp_state",&i, + fd,&ifr); + *delayms = JIFFIES_TO_MS(i); + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + + +/** + * virNetDevBridgeSetSTP: + * @brname: the bridge name + * @enable: 1 to enable, 0 to disable + * + * Control whether the bridge participates in the spanning tree protocol, + * in general don't disable it without good reasons. + * + * Returns 0 in case of success or -1 on failure + */ +int virNetDevBridgeSetSTP(const char *brname, + bool enable) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(brname,&ifr))< 0) + goto cleanup; + + ret = virNetDevBridgeSet(brname, "stp_state", enable ? 1 : 0, + fd,&ifr); + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + + +/** + * virNetDevBridgeGetSTP: + * @brname: the bridge device name + * @enabled: returns the STP state + * + * Determine the state of the spanning tree protocol on + * the device @brname, returning the state in @enabled + * + * Returns 0 on success, -1 on error + */ +int virNetDevBridgeGetSTP(const char *brname, + bool *enabled) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + unsigned long i; + + if ((fd = virNetDevSetupControl(brname,&ifr))< 0) + goto cleanup; + + ret = virNetDevBridgeGet(brname, "stp_state",&i, + fd,&ifr); + *enabled = i ? true : false; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else /* !__linux__ */ +int virNetDevBridgeSetSTPDelay(const char *brname, + int delay ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Unable to set STP delay on %s on this platform"), + brname); + return -1; +} +int virNetDevBridgeGetSTPDelay(const char *brname, + int *delay ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Unable to get STP delay on %s on this platform"), + brname); + return -1; +} + +int virNetDevBridgeSetSTP(const char *brname, + bool enable ATTRIBUTE_UNUSED) + +{ + virReportSystemError(ENOSYS, + _("Unable to set STP on %s on this platform"), + brname); + return -1; +} +int virNetDevBridgeGetSTP(const char *brname, + bool *enable ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("Unable to get STP on %s on this platform"), + brname); + return -1; +} +#endif /* __linux__ */ diff --git a/src/util/virnetdevbridge.h b/src/util/virnetdevbridge.h new file mode 100644 index 0000000..98fc1d2 --- /dev/null +++ b/src/util/virnetdevbridge.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2007-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin<markmc@redhat.com> + * Daniel P. Berrange<berrange@redhat.com> + */ + +#ifndef __VIR_NETDEV_BRIDGE_H__ +# define __VIR_NETDEV_BRIDGE_H__ + +# include "internal.h" + +int virNetDevBridgeCreate(const char *brname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBridgeDelete(const char *brname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +int virNetDevBridgeAddPort(const char *brname, + const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int virNetDevBridgeRemovePort(const char *brname, + const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int virNetDevBridgeSetSTPDelay(const char *brname, + int delay) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBridgeGetSTPDelay(const char *brname, + int *delay) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevBridgeSetSTP(const char *brname, + bool enable) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBridgeGetSTP(const char *brname, + bool *enable) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +#endif /* __VIR_NETDEV_BRIDGE_H__ */ diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c new file mode 100644 index 0000000..5c60925 --- /dev/null +++ b/src/util/virnetdevtap.c @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2007-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin<markmc@redhat.com> + * Daniel P. Berrange<berrange@redhat.com> + */ + +#include<config.h> + +#include "virnetdevtap.h" +#include "virnetdev.h" +#include "virnetdevbridge.h" +#include "virterror_internal.h" +#include "virfile.h" +#include "virterror_internal.h" +#include "memory.h" +#include "logging.h" + +#include<sys/ioctl.h> +#ifdef HAVE_NET_IF_H +# include<net/if.h> +#endif +#include<fcntl.h> +#ifdef __linux__ +# include<linux/if_tun.h> /* IFF_TUN, IFF_NO_PI */ +#endif + +#define VIR_FROM_THIS VIR_FROM_NONE + +/** + * virNetDevProbeVnetHdr: + * @tapfd: a tun/tap file descriptor + * + * Check whether it is safe to enable the IFF_VNET_HDR flag on the + * tap interface. + * + * Setting IFF_VNET_HDR enables QEMU's virtio_net driver to allow + * guests to pass larger (GSO) packets, with partial checksums, to + * the host. This greatly increases the achievable throughput. + * + * It is only useful to enable this when we're setting up a virtio + * interface. And it is only *safe* to enable it when we know for + * sure that a) qemu has support for IFF_VNET_HDR and b) the running + * kernel implements the TUNGETIFF ioctl(), which qemu needs to query + * the supplied tapfd. + * + * Returns 1 if VnetHdr is supported, 0 if not supported + */ +#ifdef IFF_VNET_HDR +static int +virNetDevProbeVnetHdr(int tapfd) +
I guess other network devices than taps can also use this function, so it doesn't need Tap in the name of the function. Maybe move it into the virnetdev.c file ?
{ +# if defined(IFF_VNET_HDR)&& defined(TUNGETFEATURES)&& defined(TUNGETIFF) + unsigned int features; + struct ifreq dummy; + + if (ioctl(tapfd, TUNGETFEATURES,&features) != 0) { + VIR_INFO("Not enabling IFF_VNET_HDR; " + "TUNGETFEATURES ioctl() not implemented"); + return 0; + } + + if (!(features& IFF_VNET_HDR)) { + VIR_INFO("Not enabling IFF_VNET_HDR; " + "TUNGETFEATURES ioctl() reports no IFF_VNET_HDR"); + return 0; + } + + /* The kernel will always return -1 at this point. + * If TUNGETIFF is not implemented then errno == EBADFD. + */ + if (ioctl(tapfd, TUNGETIFF,&dummy) != -1 || errno != EBADFD) { + VIR_INFO("Not enabling IFF_VNET_HDR; " + "TUNGETIFF ioctl() not implemented"); + return 0; + } + + VIR_INFO("Enabling IFF_VNET_HDR"); + + return 1; +# else + (void) tapfd; + VIR_INFO("Not enabling IFF_VNET_HDR; disabled at build time"); + return 0; +# endif +} +#endif + + +#ifdef TUNSETIFF +/** + * brCreateTap: + * @ifname: the interface name + * @vnet_hr: whether to try enabling IFF_VNET_HDR + * @tapfd: file descriptor return value for the new tap device + * + * Creates a tap interface. + * If the @tapfd parameter is supplied, the open tap device file + * descriptor will be returned, otherwise the TAP device will be made + * persistent and closed. The caller must use brDeleteTap to remove + * a persistent TAP devices when it is no longer needed. + * + * Returns 0 in case of success or an errno code in case of failure. + */ +int virNetDevTapCreate(char **ifname, + int vnet_hdr ATTRIBUTE_UNUSED, + int *tapfd) +{ + int fd; + struct ifreq ifr; + int ret = -1; + + if ((fd = open("/dev/net/tun", O_RDWR))< 0) { + virReportSystemError(errno, "%s", + _("Unable to open /dev/net/tun, is tun module loaded?")); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; + +# ifdef IFF_VNET_HDR + if (vnet_hdr&& virNetDevProbeVnetHdr(fd)) + ifr.ifr_flags |= IFF_VNET_HDR; +# endif + + if (virStrcpyStatic(ifr.ifr_name, *ifname) == NULL) { + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + *ifname); + goto cleanup; + + } + + if (ioctl(fd, TUNSETIFF,&ifr)< 0) { + virReportSystemError(errno, + _("Unable to create tap device %s"), + NULLSTR(*ifname)); + goto cleanup; + } + + if (!tapfd&& + (errno = ioctl(fd, TUNSETPERSIST, 1))) { + virReportSystemError(errno, + _("Unable to set tap device %s to persistent"), + NULLSTR(*ifname)); + goto cleanup; + } + + VIR_FREE(*ifname); + if (!(*ifname = strdup(ifr.ifr_name))) { + virReportOOMError(); + goto cleanup; + } + if (tapfd) + *tapfd = fd; + else + VIR_FORCE_CLOSE(fd); + + ret = 0; + +cleanup: + if (ret< 0) + VIR_FORCE_CLOSE(fd); + + return ret; +} + + +int virNetDevTapDelete(const char *ifname) +{ + struct ifreq try; + int fd; + int ret = -1; + + if ((fd = open("/dev/net/tun", O_RDWR))< 0) { + virReportSystemError(errno, "%s", + _("Unable to open /dev/net/tun, is tun module loaded?")); + return -1; + } + + memset(&try, 0, sizeof(struct ifreq)); + try.ifr_flags = IFF_TAP|IFF_NO_PI; + + if (virStrcpyStatic(try.ifr_name, ifname) == NULL) { + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + ifname); + goto cleanup; + } + + if (ioctl(fd, TUNSETIFF,&try)< 0) { + virReportSystemError(errno, "%s", + _("Unable to associate TAP device")); + goto cleanup; + } + + if (ioctl(fd, TUNSETPERSIST, 0)< 0) { + virReportSystemError(errno, "%s", + _("Unable to make TAP device non-persistent")); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else /* ! TUNSETIFF */ +int virNetDevTapCreate(char **ifname ATTRIBUTE_UNUSED, + int vnet_hdr ATTRIBUTE_UNUSED, + int *tapfd ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to create TAP devices on this platform")); + return -1; +} +int virNetDevTapDelete(const char *ifname ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to delete TAP devices on this platform")); + return -1; +} +#endif /* ! TUNSETIFF */ + + +/** + * virNetDevTapCreateInBridgePort: + * @brname: the bridge name + * @ifname: the interface name (or name template) + * @macaddr: desired MAC address (VIR_MAC_BUFLEN long) + * @vnet_hdr: whether to try enabling IFF_VNET_HDR + * @tapfd: file descriptor return value for the new tap device + * + * This function creates a new tap device on a bridge. @ifname can be either + * a fixed name or a name template with '%d' for dynamic name allocation. + * in either case the final name for the bridge will be stored in @ifname. + * If the @tapfd parameter is supplied, the open tap device file + * descriptor will be returned, otherwise the TAP device will be made + * persistent and closed. The caller must use brDeleteTap to remove + * a persistent TAP devices when it is no longer needed. + * + * Returns 0 in case of success or -1 on failure + */ +int virNetDevTapCreateInBridgePort(const char *brname, + char **ifname, + const unsigned char *macaddr, + int vnet_hdr, + bool up, + int *tapfd) +{ + if (virNetDevTapCreate(ifname, vnet_hdr, tapfd)< 0) + return -1; + + /* We need to set the interface MAC before adding it + * to the bridge, because the bridge assumes the lowest + * MAC of all enslaved interfaces& we don't want it + * seeing the kernel allocate random MAC for the TAP + * device before we set our static MAC. + */ + if (virNetDevSetMAC(*ifname, macaddr)< 0) + goto error; + + /* We need to set the interface MTU before adding it + * to the bridge, because the bridge will have its + * MTU adjusted automatically when we add the new interface. + */ + if (virNetDevSetMTUFromDevice(*ifname, brname)< 0) + goto error; + + if (virNetDevBridgeAddPort(brname, *ifname)< 0) + goto error; + + if (virNetDevSetOnline(*ifname, up)< 0) + goto error; + + return 0; + + error: + VIR_FORCE_CLOSE(*tapfd); + + return errno; +} diff --git a/src/util/virnetdevtap.h b/src/util/virnetdevtap.h new file mode 100644 index 0000000..fb35ac5 --- /dev/null +++ b/src/util/virnetdevtap.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2007-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin<markmc@redhat.com> + * Daniel P. Berrange<berrange@redhat.com> + */ + +#ifndef __VIR_NETDEV_TAP_H__ +# define __VIR_NETDEV_TAP_H__ + +# include "internal.h" + +int virNetDevTapCreate(char **ifname, + int vnet_hdr, + int *tapfd) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +int virNetDevTapDelete(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +int virNetDevTapCreateInBridgePort(const char *brname, + char **ifname, + const unsigned char *macaddr, + int vnet_hdr, + bool up, + int *tapfd) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_RETURN_CHECK; + +#endif /* __VIR_NETDEV_TAP_H__ */ ACK with nits addressed...
Stefan

From: "Daniel P. Berrange" <berrange@redhat.com> The socket address APIs in src/util/network.h either take the form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr. Sanitize this so everything is virSocketAddrXXXX, and ensure that the virSocketAddr parameter is always the first one. * src/util/network.c, src/util/network.h: Santize socket address API naming * src/conf/domain_conf.c, src/conf/network_conf.c, src/conf/nwfilter_conf.c, src/network/bridge_driver.c, src/nwfilter/nwfilter_ebiptables_driver.c, src/nwfilter/nwfilter_learnipaddr.c, src/qemu/qemu_command.c, src/rpc/virnetsocket.c, src/util/dnsmasq.c, src/util/iptables.c, src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for API renaming --- src/conf/domain_conf.c | 12 ++-- src/conf/network_conf.c | 66 ++++++++++---------- src/conf/nwfilter_conf.c | 16 ++--- src/libvirt_private.syms | 18 +++--- src/network/bridge_driver.c | 42 +++++++------- src/nwfilter/nwfilter_ebiptables_driver.c | 4 +- src/nwfilter/nwfilter_learnipaddr.c | 2 +- src/qemu/qemu_command.c | 4 +- src/rpc/virnetsocket.c | 6 +- src/util/dnsmasq.c | 4 +- src/util/iptables.c | 20 +++--- src/util/network.c | 93 ++++++++++++++--------------- src/util/network.h | 46 +++++++------- src/util/virnetdev.c | 8 +- src/vbox/vbox_tmpl.c | 10 ++-- tests/sockettest.c | 20 +++--- tests/virnetsockettest.c | 1 + tests/virnettlscontexttest.c | 6 +- 18 files changed, 188 insertions(+), 190 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 238edfd..2b235c8 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3685,7 +3685,7 @@ virDomainChrDefParseTargetXML(virCapsPtr caps, goto error; } - if (virSocketParseAddr(addrStr, def->target.addr, AF_UNSPEC) < 0) + if (virSocketAddrParse(def->target.addr, addrStr, AF_UNSPEC) < 0) goto error; if (def->target.addr->data.stor.ss_family != AF_INET) { @@ -3709,7 +3709,7 @@ virDomainChrDefParseTargetXML(virCapsPtr caps, goto error; } - virSocketSetPort(def->target.addr, port); + virSocketAddrSetPort(def->target.addr, port); break; case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO: @@ -8378,8 +8378,8 @@ static bool virDomainChannelDefCheckABIStability(virDomainChrDefPtr src, case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD: if (memcmp(src->target.addr, dst->target.addr, sizeof(*src->target.addr)) != 0) { - char *saddr = virSocketFormatAddrFull(src->target.addr, true, ":"); - char *daddr = virSocketFormatAddrFull(dst->target.addr, true, ":"); + char *saddr = virSocketAddrFormatFull(src->target.addr, true, ":"); + char *daddr = virSocketAddrFormatFull(dst->target.addr, true, ":"); virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target channel addr %s does not match source %s"), NULLSTR(daddr), NULLSTR(saddr)); @@ -10034,14 +10034,14 @@ virDomainChrDefFormat(virBufferPtr buf, switch (def->targetType) { case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD: { - int port = virSocketGetPort(def->target.addr); + int port = virSocketAddrGetPort(def->target.addr); if (port < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to format guestfwd port")); return -1; } - const char *addr = virSocketFormatAddr(def->target.addr); + const char *addr = virSocketAddrFormat(def->target.addr); if (addr == NULL) return -1; diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index f7369e8..8dca618 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -286,7 +286,7 @@ virNetworkDefGetIpByIndex(const virNetworkDefPtr def, /* find the nth ip of type "family" */ for (ii = 0; ii < def->nips; ii++) { - if (VIR_SOCKET_IS_FAMILY(&def->ips[ii].address, family) + if (VIR_SOCKET_ADDR_IS_FAMILY(&def->ips[ii].address, family) && (n-- <= 0)) { return &def->ips[ii]; } @@ -302,9 +302,9 @@ int virNetworkIpDefPrefix(const virNetworkIpDefPtr def) { if (def->prefix > 0) { return def->prefix; - } else if (VIR_SOCKET_HAS_ADDR(&def->netmask)) { - return virSocketGetNumNetmaskBits(&def->netmask); - } else if (VIR_SOCKET_IS_FAMILY(&def->address, AF_INET)) { + } else if (VIR_SOCKET_ADDR_VALID(&def->netmask)) { + return virSocketAddrGetNumNetmaskBits(&def->netmask); + } else if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) { /* Return the natural prefix for the network's ip address. * On Linux we could use the IN_CLASSx() macros, but those * aren't guaranteed on all platforms, so we just deal with @@ -323,7 +323,7 @@ int virNetworkIpDefPrefix(const virNetworkIpDefPtr def) return 24; } return -1; - } else if (VIR_SOCKET_IS_FAMILY(&def->address, AF_INET6)) { + } else if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) { return 64; } return -1; @@ -336,13 +336,13 @@ int virNetworkIpDefPrefix(const virNetworkIpDefPtr def) int virNetworkIpDefNetmask(const virNetworkIpDefPtr def, virSocketAddrPtr netmask) { - if (VIR_SOCKET_IS_FAMILY(&def->netmask, AF_INET)) { + if (VIR_SOCKET_ADDR_IS_FAMILY(&def->netmask, AF_INET)) { *netmask = def->netmask; return 0; } return virSocketAddrPrefixToNetmask(virNetworkIpDefPrefix(def), netmask, - VIR_SOCKET_FAMILY(&def->address)); + VIR_SOCKET_ADDR_FAMILY(&def->address)); } @@ -372,18 +372,18 @@ virNetworkDHCPRangeDefParseXML(const char *networkName, continue; } - if (virSocketParseAddr(start, &saddr, AF_UNSPEC) < 0) { + if (virSocketAddrParse(&saddr, start, AF_UNSPEC) < 0) { VIR_FREE(start); VIR_FREE(end); return -1; } - if (virSocketParseAddr(end, &eaddr, AF_UNSPEC) < 0) { + if (virSocketAddrParse(&eaddr, end, AF_UNSPEC) < 0) { VIR_FREE(start); VIR_FREE(end); return -1; } - range = virSocketGetRange(&saddr, &eaddr); + range = virSocketAddrGetRange(&saddr, &eaddr); if (range < 0) { virNetworkReportError(VIR_ERR_XML_ERROR, _("Invalid dhcp range '%s' to '%s' in network '%s'"), @@ -434,7 +434,7 @@ virNetworkDHCPRangeDefParseXML(const char *networkName, } ip = virXMLPropString(cur, "ip"); if ((ip == NULL) || - (virSocketParseAddr(ip, &inaddr, AF_UNSPEC) < 0)) { + (virSocketAddrParse(&inaddr, ip, AF_UNSPEC) < 0)) { virNetworkReportError(VIR_ERR_XML_ERROR, _("Missing IP address in static host definition for network '%s'"), networkName); @@ -469,7 +469,7 @@ virNetworkDHCPRangeDefParseXML(const char *networkName, server = virXMLPropString(cur, "server"); if (server && - virSocketParseAddr(server, &inaddr, AF_UNSPEC) < 0) { + virSocketAddrParse(&inaddr, server, AF_UNSPEC) < 0) { VIR_FREE(file); VIR_FREE(server); return -1; @@ -504,7 +504,7 @@ virNetworkDNSHostsDefParseXML(virNetworkDNSDefPtr def, } if (!(ip = virXMLPropString(node, "ip")) || - (virSocketParseAddr(ip, &inaddr, AF_UNSPEC) < 0)) { + (virSocketAddrParse(&inaddr, ip, AF_UNSPEC) < 0)) { virNetworkReportError(VIR_ERR_XML_DETAIL, _("Missing IP address in DNS host definition")); VIR_FREE(ip); @@ -649,7 +649,7 @@ virNetworkIPParseXML(const char *networkName, netmask = virXPathString("string(./@netmask)", ctxt); if (address) { - if (virSocketParseAddr(address, &def->address, AF_UNSPEC) < 0) { + if (virSocketAddrParse(&def->address, address, AF_UNSPEC) < 0) { virNetworkReportError(VIR_ERR_XML_ERROR, _("Bad address '%s' in definition of network '%s'"), address, networkName); @@ -660,22 +660,22 @@ virNetworkIPParseXML(const char *networkName, /* validate family vs. address */ if (def->family == NULL) { - if (!(VIR_SOCKET_IS_FAMILY(&def->address, AF_INET) || - VIR_SOCKET_IS_FAMILY(&def->address, AF_UNSPEC))) { + if (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) || + VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_UNSPEC))) { virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("no family specified for non-IPv4 address address '%s' in network '%s'"), address, networkName); goto error; } } else if (STREQ(def->family, "ipv4")) { - if (!VIR_SOCKET_IS_FAMILY(&def->address, AF_INET)) { + if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) { virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("family 'ipv4' specified for non-IPv4 address '%s' in network '%s'"), address, networkName); goto error; } } else if (STREQ(def->family, "ipv6")) { - if (!VIR_SOCKET_IS_FAMILY(&def->address, AF_INET6)) { + if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) { virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("family 'ipv6' specified for non-IPv6 address '%s' in network '%s'"), address, networkName); @@ -698,7 +698,7 @@ virNetworkIPParseXML(const char *networkName, goto error; } - if (!VIR_SOCKET_IS_FAMILY(&def->address, AF_INET)) { + if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) { virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("netmask not supported for address '%s' in network '%s' (IPv4 only)"), address, networkName); @@ -713,10 +713,10 @@ virNetworkIPParseXML(const char *networkName, goto error; } - if (virSocketParseAddr(netmask, &def->netmask, AF_UNSPEC) < 0) + if (virSocketAddrParse(&def->netmask, netmask, AF_UNSPEC) < 0) goto error; - if (!VIR_SOCKET_IS_FAMILY(&def->netmask, AF_INET)) { + if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->netmask, AF_INET)) { virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("network '%s' has invalid netmask '%s' for address '%s' (both must be IPv4)"), networkName, netmask, address); @@ -724,7 +724,7 @@ virNetworkIPParseXML(const char *networkName, } } - if (VIR_SOCKET_IS_FAMILY(&def->address, AF_INET)) { + if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) { /* parse IPv4-related info */ cur = node->children; while (cur != NULL) { @@ -1151,7 +1151,7 @@ virNetworkDNSDefFormat(virBufferPtr buf, int ii, j; for (ii = 0 ; ii < def->nhosts; ii++) { - char *ip = virSocketFormatAddr(&def->hosts[ii].ip); + char *ip = virSocketAddrFormat(&def->hosts[ii].ip); virBufferAsprintf(buf, " <host ip='%s'>\n", ip); @@ -1180,15 +1180,15 @@ virNetworkIpDefFormat(virBufferPtr buf, if (def->family) { virBufferAsprintf(buf, " family='%s'", def->family); } - if (VIR_SOCKET_HAS_ADDR(&def->address)) { - char *addr = virSocketFormatAddr(&def->address); + if (VIR_SOCKET_ADDR_VALID(&def->address)) { + char *addr = virSocketAddrFormat(&def->address); if (!addr) goto error; virBufferAsprintf(buf, " address='%s'", addr); VIR_FREE(addr); } - if (VIR_SOCKET_HAS_ADDR(&def->netmask)) { - char *addr = virSocketFormatAddr(&def->netmask); + if (VIR_SOCKET_ADDR_VALID(&def->netmask)) { + char *addr = virSocketAddrFormat(&def->netmask); if (!addr) goto error; virBufferAsprintf(buf, " netmask='%s'", addr); @@ -1207,10 +1207,10 @@ virNetworkIpDefFormat(virBufferPtr buf, int ii; virBufferAddLit(buf, " <dhcp>\n"); for (ii = 0 ; ii < def->nranges ; ii++) { - char *saddr = virSocketFormatAddr(&def->ranges[ii].start); + char *saddr = virSocketAddrFormat(&def->ranges[ii].start); if (!saddr) goto error; - char *eaddr = virSocketFormatAddr(&def->ranges[ii].end); + char *eaddr = virSocketAddrFormat(&def->ranges[ii].end); if (!eaddr) { VIR_FREE(saddr); goto error; @@ -1226,8 +1226,8 @@ virNetworkIpDefFormat(virBufferPtr buf, virBufferAsprintf(buf, "mac='%s' ", def->hosts[ii].mac); if (def->hosts[ii].name) virBufferAsprintf(buf, "name='%s' ", def->hosts[ii].name); - if (VIR_SOCKET_HAS_ADDR(&def->hosts[ii].ip)) { - char *ipaddr = virSocketFormatAddr(&def->hosts[ii].ip); + if (VIR_SOCKET_ADDR_VALID(&def->hosts[ii].ip)) { + char *ipaddr = virSocketAddrFormat(&def->hosts[ii].ip); if (!ipaddr) goto error; virBufferAsprintf(buf, "ip='%s' ", ipaddr); @@ -1238,8 +1238,8 @@ virNetworkIpDefFormat(virBufferPtr buf, if (def->bootfile) { virBufferEscapeString(buf, " <bootp file='%s' ", def->bootfile); - if (VIR_SOCKET_HAS_ADDR(&def->bootserver)) { - char *ipaddr = virSocketFormatAddr(&def->bootserver); + if (VIR_SOCKET_ADDR_VALID(&def->bootserver)) { + char *ipaddr = virSocketAddrFormat(&def->bootserver); if (!ipaddr) goto error; virBufferEscapeString(buf, "server='%s' ", ipaddr); diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index 6c3e1cf..55ab68b 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -1523,8 +1523,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr node, break; case DATATYPE_IPADDR: - if (virSocketParseIpv4Addr(prop, - &item->u.ipaddr) < 0) + if (virSocketAddrParseIPv4(&item->u.ipaddr, prop) < 0) rc = -1; found = 1; break; @@ -1539,10 +1538,10 @@ virNWFilterRuleDetailsParse(xmlNodePtr node, } else rc = -1; } else { - if (virSocketParseIpv4Addr(prop, &ipaddr) < 0) { + if (virSocketAddrParseIPv4(&ipaddr, prop) < 0) { rc = -1; } else { - int_val = virSocketGetNumNetmaskBits(&ipaddr); + int_val = virSocketAddrGetNumNetmaskBits(&ipaddr); if (int_val >= 0) item->u.u8 = int_val; else @@ -1571,8 +1570,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr node, break; case DATATYPE_IPV6ADDR: - if (virSocketParseIpv6Addr(prop, - &item->u.ipaddr) < 0) + if (virSocketAddrParseIPv6(&item->u.ipaddr, prop) < 0) rc = -1; found = 1; break; @@ -1587,10 +1585,10 @@ virNWFilterRuleDetailsParse(xmlNodePtr node, } else rc = -1; } else { - if (virSocketParseIpv6Addr(prop, &ipaddr) < 0) { + if (virSocketAddrParseIPv6(&ipaddr, prop) < 0) { rc = -1; } else { - int_val = virSocketGetNumNetmaskBits(&ipaddr); + int_val = virSocketAddrGetNumNetmaskBits(&ipaddr); if (int_val >= 0) item->u.u8 = int_val; else @@ -2596,7 +2594,7 @@ virNWFilterObjDeleteDef(virNWFilterObjPtr nwfilter) static void virNWIPAddressFormat(virBufferPtr buf, virSocketAddrPtr ipaddr) { - char *output = virSocketFormatAddr(ipaddr); + char *output = virSocketAddrFormat(ipaddr); if (output) { virBufferAdd(buf, output, -1); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6a1562e..fa8ac93 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -773,19 +773,19 @@ virBandwidthEnable; virBandwidthEqual; virSocketAddrBroadcast; virSocketAddrBroadcastByPrefix; +virSocketAddrCheckNetmask; +virSocketAddrFormat; +virSocketAddrFormatFull; +virSocketAddrGetPort; +virSocketAddrGetRange; virSocketAddrIsNetmask; virSocketAddrMask; virSocketAddrMaskByPrefix; +virSocketAddrParse; +virSocketAddrParseIPv4; +virSocketAddrParseIPv6; virSocketAddrPrefixToNetmask; -virSocketCheckNetmask; -virSocketFormatAddr; -virSocketFormatAddrFull; -virSocketGetPort; -virSocketGetRange; -virSocketParseAddr; -virSocketParseIpv4Addr; -virSocketParseIpv6Addr; -virSocketSetPort; +virSocketAddrSetPort; virVirtualPortProfileEqual; virVirtualPortProfileFormat; virVirtualPortProfileParseXML; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index bc3a18f..bd8f0b3 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -432,7 +432,7 @@ networkBuildDnsmasqHostsfile(dnsmasqContext *dctx, for (i = 0; i < ipdef->nhosts; i++) { virNetworkDHCPHostDefPtr host = &(ipdef->hosts[i]); - if ((host->mac) && VIR_SOCKET_HAS_ADDR(&host->ip)) + if ((host->mac) && VIR_SOCKET_ADDR_VALID(&host->ip)) if (dnsmasqAddDhcpHost(dctx, host->mac, &host->ip, host->name) < 0) return -1; } @@ -440,7 +440,7 @@ networkBuildDnsmasqHostsfile(dnsmasqContext *dctx, if (dnsdef) { for (i = 0; i < dnsdef->nhosts; i++) { virNetworkDNSHostsDefPtr host = &(dnsdef->hosts[i]); - if (VIR_SOCKET_HAS_ADDR(&host->ip)) { + if (VIR_SOCKET_ADDR_VALID(&host->ip)) { for (j = 0; j < host->nnames; j++) if (dnsmasqAddHost(dctx, &host->ip, host->names[j]) < 0) return -1; @@ -543,7 +543,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, for (ii = 0; (tmpipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii)); ii++) { - char *ipaddr = virSocketFormatAddr(&tmpipdef->address); + char *ipaddr = virSocketAddrFormat(&tmpipdef->address); if (!ipaddr) goto cleanup; virCommandAddArgList(cmd, "--listen-address", ipaddr, NULL); @@ -552,10 +552,10 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, if (ipdef) { for (r = 0 ; r < ipdef->nranges ; r++) { - char *saddr = virSocketFormatAddr(&ipdef->ranges[r].start); + char *saddr = virSocketAddrFormat(&ipdef->ranges[r].start); if (!saddr) goto cleanup; - char *eaddr = virSocketFormatAddr(&ipdef->ranges[r].end); + char *eaddr = virSocketAddrFormat(&ipdef->ranges[r].end); if (!eaddr) { VIR_FREE(saddr); goto cleanup; @@ -564,8 +564,8 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, virCommandAddArgFormat(cmd, "%s,%s", saddr, eaddr); VIR_FREE(saddr); VIR_FREE(eaddr); - nbleases += virSocketGetRange(&ipdef->ranges[r].start, - &ipdef->ranges[r].end); + nbleases += virSocketAddrGetRange(&ipdef->ranges[r].start, + &ipdef->ranges[r].end); } /* @@ -574,7 +574,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, * dnsmasq. */ if (!ipdef->nranges && ipdef->nhosts) { - char *bridgeaddr = virSocketFormatAddr(&ipdef->address); + char *bridgeaddr = virSocketAddrFormat(&ipdef->address); if (!bridgeaddr) goto cleanup; virCommandAddArg(cmd, "--dhcp-range"); @@ -615,8 +615,8 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, } if (ipdef->bootfile) { virCommandAddArg(cmd, "--dhcp-boot"); - if (VIR_SOCKET_HAS_ADDR(&ipdef->bootserver)) { - char *bootserver = virSocketFormatAddr(&ipdef->bootserver); + if (VIR_SOCKET_ADDR_VALID(&ipdef->bootserver)) { + char *bootserver = virSocketAddrFormat(&ipdef->bootserver); if (!bootserver) goto cleanup; @@ -815,7 +815,7 @@ networkStartRadvd(virNetworkObjPtr network) network->def->bridge); goto cleanup; } - if (!(netaddr = virSocketFormatAddr(&ipdef->address))) + if (!(netaddr = virSocketAddrFormat(&ipdef->address))) goto cleanup; virBufferAsprintf(&configbuf, " prefix %s/%d\n" @@ -1389,9 +1389,9 @@ networkAddIpSpecificIptablesRules(struct network_driver *driver, */ if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) { - if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) return networkAddMasqueradingIptablesRules(driver, network, ipdef); - else if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET6)) + else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) return networkAddRoutingIptablesRules(driver, network, ipdef); } else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE) { return networkAddRoutingIptablesRules(driver, network, ipdef); @@ -1405,9 +1405,9 @@ networkRemoveIpSpecificIptablesRules(struct network_driver *driver, virNetworkIpDefPtr ipdef) { if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) { - if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) networkRemoveMasqueradingIptablesRules(driver, network, ipdef); - else if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET6)) + else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) networkRemoveRoutingIptablesRules(driver, network, ipdef); } else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE) { networkRemoveRoutingIptablesRules(driver, network, ipdef); @@ -1746,9 +1746,9 @@ networkStartNetworkVirtual(struct network_driver *driver, for (ii = 0; (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii)); ii++) { - if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) v4present = true; - if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET6)) + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) v6present = true; /* Add the IP address/netmask to the bridge */ @@ -2302,7 +2302,7 @@ static virNetworkPtr networkDefine(virConnectPtr conn, const char *xml) { for (ii = 0; (ipdef = virNetworkDefGetIpByIndex(def, AF_UNSPEC, ii)); ii++) { - if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) { + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) { if (ipdef->nranges || ipdef->nhosts) { if (ipv4def) { networkReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -2366,10 +2366,10 @@ static int networkUndefine(virNetworkPtr net) { for (ii = 0; (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii)); ii++) { - if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) { + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) { if (ipdef->nranges || ipdef->nhosts) dhcp_present = true; - } else if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET6)) { + } else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) { v6present = true; } } @@ -3165,7 +3165,7 @@ networkGetNetworkAddress(const char *netname, char **netaddr) } if (addrptr && - (*netaddr = virSocketFormatAddr(addrptr))) { + (*netaddr = virSocketAddrFormat(addrptr))) { ret = 0; } diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index f87cfa1..28f7288 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -196,7 +196,7 @@ _printDataType(virNWFilterHashTablePtr vars, switch (item->datatype) { case DATATYPE_IPADDR: - data = virSocketFormatAddr(&item->u.ipaddr); + data = virSocketAddrFormat(&item->u.ipaddr); if (!data) return 1; if (snprintf(buf, bufsize, "%s", data) >= bufsize) { @@ -209,7 +209,7 @@ _printDataType(virNWFilterHashTablePtr vars, break; case DATATYPE_IPV6ADDR: - data = virSocketFormatAddr(&item->u.ipaddr); + data = virSocketAddrFormat(&item->u.ipaddr); if (!data) return 1; diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c index 034eedb..68bdcfc 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -630,7 +630,7 @@ learnIPAddressThread(void *arg) sa.data.inet4.sin_addr.s_addr = vmaddr; char *inetaddr; - if ((inetaddr = virSocketFormatAddr(&sa))!= NULL) { + if ((inetaddr = virSocketAddrFormat(&sa))!= NULL) { virNWFilterAddIpAddrForIfname(req->ifname, inetaddr); ret = virNWFilterInstantiateFilterLate(NULL, diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 7c9e60b..fba9ace 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4440,10 +4440,10 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, devstr); VIR_FREE(devstr); - addr = virSocketFormatAddr(channel->target.addr); + addr = virSocketAddrFormat(channel->target.addr); if (!addr) goto error; - port = virSocketGetPort(channel->target.addr); + port = virSocketAddrGetPort(channel->target.addr); virCommandAddArg(cmd, "-netdev"); virCommandAddArgFormat(cmd, diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index d832c53..3c9f327 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -163,11 +163,11 @@ static virNetSocketPtr virNetSocketNew(virSocketAddrPtr localAddr, if (localAddr && - !(sock->localAddrStr = virSocketFormatAddrFull(localAddr, true, ";"))) + !(sock->localAddrStr = virSocketAddrFormatFull(localAddr, true, ";"))) goto error; if (remoteAddr && - !(sock->remoteAddrStr = virSocketFormatAddrFull(remoteAddr, true, ";"))) + !(sock->remoteAddrStr = virSocketAddrFormatFull(remoteAddr, true, ";"))) goto error; sock->client = isClient; @@ -809,7 +809,7 @@ int virNetSocketGetPort(virNetSocketPtr sock) { int port; virMutexLock(&sock->lock); - port = virSocketGetPort(&sock->localAddr); + port = virSocketAddrGetPort(&sock->localAddr); virMutexUnlock(&sock->lock); return port; } diff --git a/src/util/dnsmasq.c b/src/util/dnsmasq.c index d76cf65..b5f90a6 100644 --- a/src/util/dnsmasq.c +++ b/src/util/dnsmasq.c @@ -95,7 +95,7 @@ addnhostsAdd(dnsmasqAddnHostsfile *addnhostsfile, int idx = -1; int i; - if (!(ipstr = virSocketFormatAddr(ip))) + if (!(ipstr = virSocketAddrFormat(ip))) return -1; for (i = 0; i < addnhostsfile->nhosts; i++) { @@ -300,7 +300,7 @@ hostsfileAdd(dnsmasqHostsfile *hostsfile, if (VIR_REALLOC_N(hostsfile->hosts, hostsfile->nhosts + 1) < 0) goto alloc_error; - if (!(ipstr = virSocketFormatAddr(ip))) + if (!(ipstr = virSocketAddrFormat(ip))) return -1; if (name) { diff --git a/src/util/iptables.c b/src/util/iptables.c index 76d412c..452d717 100644 --- a/src/util/iptables.c +++ b/src/util/iptables.c @@ -291,8 +291,8 @@ static char *iptablesFormatNetwork(virSocketAddr *netaddr, char *netstr; char *ret; - if (!(VIR_SOCKET_IS_FAMILY(netaddr, AF_INET) || - VIR_SOCKET_IS_FAMILY(netaddr, AF_INET6))) { + if (!(VIR_SOCKET_ADDR_IS_FAMILY(netaddr, AF_INET) || + VIR_SOCKET_ADDR_IS_FAMILY(netaddr, AF_INET6))) { iptablesError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Only IPv4 or IPv6 addresses can be used with iptables")); return NULL; @@ -304,7 +304,7 @@ static char *iptablesFormatNetwork(virSocketAddr *netaddr, return NULL; } - netstr = virSocketFormatAddr(&network); + netstr = virSocketAddrFormat(&network); if (!netstr) return NULL; @@ -336,7 +336,7 @@ iptablesForwardAllowOut(iptablesContext *ctx, if (physdev && physdev[0]) { ret = iptablesAddRemoveRule(ctx->forward_filter, - VIR_SOCKET_FAMILY(netaddr), + VIR_SOCKET_ADDR_FAMILY(netaddr), action, "--source", networkstr, "--in-interface", iface, @@ -345,7 +345,7 @@ iptablesForwardAllowOut(iptablesContext *ctx, NULL); } else { ret = iptablesAddRemoveRule(ctx->forward_filter, - VIR_SOCKET_FAMILY(netaddr), + VIR_SOCKET_ADDR_FAMILY(netaddr), action, "--source", networkstr, "--in-interface", iface, @@ -422,7 +422,7 @@ iptablesForwardAllowRelatedIn(iptablesContext *ctx, if (physdev && physdev[0]) { ret = iptablesAddRemoveRule(ctx->forward_filter, - VIR_SOCKET_FAMILY(netaddr), + VIR_SOCKET_ADDR_FAMILY(netaddr), action, "--destination", networkstr, "--in-interface", physdev, @@ -433,7 +433,7 @@ iptablesForwardAllowRelatedIn(iptablesContext *ctx, NULL); } else { ret = iptablesAddRemoveRule(ctx->forward_filter, - VIR_SOCKET_FAMILY(netaddr), + VIR_SOCKET_ADDR_FAMILY(netaddr), action, "--destination", networkstr, "--out-interface", iface, @@ -510,7 +510,7 @@ iptablesForwardAllowIn(iptablesContext *ctx, if (physdev && physdev[0]) { ret = iptablesAddRemoveRule(ctx->forward_filter, - VIR_SOCKET_FAMILY(netaddr), + VIR_SOCKET_ADDR_FAMILY(netaddr), action, "--destination", networkstr, "--in-interface", physdev, @@ -519,7 +519,7 @@ iptablesForwardAllowIn(iptablesContext *ctx, NULL); } else { ret = iptablesAddRemoveRule(ctx->forward_filter, - VIR_SOCKET_FAMILY(netaddr), + VIR_SOCKET_ADDR_FAMILY(netaddr), action, "--destination", networkstr, "--out-interface", iface, @@ -761,7 +761,7 @@ iptablesForwardMasquerade(iptablesContext *ctx, if (!(networkstr = iptablesFormatNetwork(netaddr, prefix))) return -1; - if (!VIR_SOCKET_IS_FAMILY(netaddr, AF_INET)) { + if (!VIR_SOCKET_ADDR_IS_FAMILY(netaddr, AF_INET)) { /* Higher level code *should* guaranteee it's impossible to get here. */ iptablesError(VIR_ERR_INTERNAL_ERROR, _("Attempted to NAT '%s'. NAT is only supported for IPv4."), diff --git a/src/util/network.c b/src/util/network.c index edf9c50..087df22 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -27,12 +27,12 @@ * Helpers to extract the IP arrays from the virSocketAddrPtr * That part is the less portable of the module */ -typedef unsigned char virIPv4Addr[4]; -typedef virIPv4Addr *virIPv4AddrPtr; -typedef unsigned short virIPv6Addr[8]; -typedef virIPv6Addr *virIPv6AddrPtr; +typedef unsigned char virSocketAddrIPv4[4]; +typedef virSocketAddrIPv4 *virSocketAddrIPv4Ptr; +typedef unsigned short virSocketAddrIPv6[8]; +typedef virSocketAddrIPv6 *virSocketAddrIPv6Ptr; -static int getIPv4Addr(virSocketAddrPtr addr, virIPv4AddrPtr tab) { +static int virSocketAddrGetIPv4Addr(virSocketAddrPtr addr, virSocketAddrIPv4Ptr tab) { unsigned long val; int i; @@ -49,7 +49,7 @@ static int getIPv4Addr(virSocketAddrPtr addr, virIPv4AddrPtr tab) { return(0); } -static int getIPv6Addr(virSocketAddrPtr addr, virIPv6AddrPtr tab) { +static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr tab) { int i; if ((addr == NULL) || (tab == NULL) || (addr->data.stor.ss_family != AF_INET6)) @@ -64,7 +64,7 @@ static int getIPv6Addr(virSocketAddrPtr addr, virIPv6AddrPtr tab) { } /** - * virSocketParseAddr: + * virSocketAddrParse: * @val: a numeric network address IPv4 or IPv6 * @addr: where to store the return value, optional. * @family: address family to pass down to getaddrinfo @@ -74,8 +74,7 @@ static int getIPv6Addr(virSocketAddrPtr addr, virIPv6AddrPtr tab) { * * Returns the length of the network address or -1 in case of error. */ -int -virSocketParseAddr(const char *val, virSocketAddrPtr addr, int family) { +int virSocketAddrParse(virSocketAddrPtr addr, const char *val, int family) { int len; struct addrinfo hints; struct addrinfo *res = NULL; @@ -114,7 +113,7 @@ virSocketParseAddr(const char *val, virSocketAddrPtr addr, int family) { } /* - * virSocketParseIpv4Addr: + * virSocketAddrParseIPv4: * @val: an IPv4 numeric address * @addr: the location to store the result * @@ -123,12 +122,12 @@ virSocketParseAddr(const char *val, virSocketAddrPtr addr, int family) { * Returns the length of the network address or -1 in case of error. */ int -virSocketParseIpv4Addr(const char *val, virSocketAddrPtr addr) { - return(virSocketParseAddr(val, addr, AF_INET)); +virSocketAddrParseIPv4(virSocketAddrPtr addr, const char *val) { + return virSocketAddrParse(addr, val, AF_INET); } /* - * virSocketParseIpv6Addr: + * virSocketAddrParseIPv6: * @val: an IPv6 numeric address * @addr: the location to store the result * @@ -137,12 +136,12 @@ virSocketParseIpv4Addr(const char *val, virSocketAddrPtr addr) { * Returns the length of the network address or -1 in case of error. */ int -virSocketParseIpv6Addr(const char *val, virSocketAddrPtr addr) { - return(virSocketParseAddr(val, addr, AF_INET6)); +virSocketAddrParseIPv6(virSocketAddrPtr addr, const char *val) { + return virSocketAddrParse(addr, val, AF_INET6); } /* - * virSocketFormatAddr: + * virSocketAddrFormat: * @addr: an initialized virSocketAddrPtr * * Returns a string representation of the given address @@ -150,13 +149,13 @@ virSocketParseIpv6Addr(const char *val, virSocketAddrPtr addr) { * Caller must free the returned string */ char * -virSocketFormatAddr(virSocketAddrPtr addr) { - return virSocketFormatAddrFull(addr, false, NULL); +virSocketAddrFormat(virSocketAddrPtr addr) { + return virSocketAddrFormatFull(addr, false, NULL); } /* - * virSocketFormatAddrFull: + * virSocketAddrFormatFull: * @addr: an initialized virSocketAddrPtr * @withService: if true, then service info is appended * @separator: separator between hostname & service. @@ -166,7 +165,7 @@ virSocketFormatAddr(virSocketAddrPtr addr) { * Caller must free the returned string */ char * -virSocketFormatAddrFull(virSocketAddrPtr addr, +virSocketAddrFormatFull(virSocketAddrPtr addr, bool withService, const char *separator) { @@ -221,7 +220,7 @@ no_memory: /* - * virSocketSetPort: + * virSocketAddrSetPort: * @addr: an initialized virSocketAddrPtr * @port: the port number to set * @@ -230,7 +229,7 @@ no_memory: * Returns 0 on success, -1 on failure */ int -virSocketSetPort(virSocketAddrPtr addr, int port) { +virSocketAddrSetPort(virSocketAddrPtr addr, int port) { if (addr == NULL) return -1; @@ -259,7 +258,7 @@ virSocketSetPort(virSocketAddrPtr addr, int port) { * Returns -1 if @addr is invalid */ int -virSocketGetPort(virSocketAddrPtr addr) { +virSocketAddrGetPort(virSocketAddrPtr addr) { if (addr == NULL) return -1; @@ -283,7 +282,7 @@ virSocketGetPort(virSocketAddrPtr addr) { * Returns 0 in case of success and -1 in case of error */ int virSocketAddrIsNetmask(virSocketAddrPtr netmask) { - int n = virSocketGetNumNetmaskBits(netmask); + int n = virSocketAddrGetNumNetmaskBits(netmask); if (n < 0) return -1; return 0; @@ -429,8 +428,8 @@ virSocketAddrBroadcastByPrefix(const virSocketAddrPtr addr, * Returns 1 in case of success and 0 in case of failure and * -1 in case of error */ -int virSocketCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2, - virSocketAddrPtr netmask) { +int virSocketAddrCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2, + virSocketAddrPtr netmask) { int i; if ((addr1 == NULL) || (addr2 == NULL) || (netmask == NULL)) @@ -443,11 +442,11 @@ int virSocketCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2, return(-1); if (addr1->data.stor.ss_family == AF_INET) { - virIPv4Addr t1, t2, tm; + virSocketAddrIPv4 t1, t2, tm; - if ((getIPv4Addr(addr1, &t1) < 0) || - (getIPv4Addr(addr2, &t2) < 0) || - (getIPv4Addr(netmask, &tm) < 0)) + if ((virSocketAddrGetIPv4Addr(addr1, &t1) < 0) || + (virSocketAddrGetIPv4Addr(addr2, &t2) < 0) || + (virSocketAddrGetIPv4Addr(netmask, &tm) < 0)) return(-1); for (i = 0;i < 4;i++) { @@ -456,11 +455,11 @@ int virSocketCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2, } } else if (addr1->data.stor.ss_family == AF_INET6) { - virIPv6Addr t1, t2, tm; + virSocketAddrIPv6 t1, t2, tm; - if ((getIPv6Addr(addr1, &t1) < 0) || - (getIPv6Addr(addr2, &t2) < 0) || - (getIPv6Addr(netmask, &tm) < 0)) + if ((virSocketAddrGetIPv6Addr(addr1, &t1) < 0) || + (virSocketAddrGetIPv6Addr(addr2, &t2) < 0) || + (virSocketAddrGetIPv6Addr(netmask, &tm) < 0)) return(-1); for (i = 0;i < 8;i++) { @@ -486,7 +485,7 @@ int virSocketCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2, * * Returns the size of the range or -1 in case of failure */ -int virSocketGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { +int virSocketAddrGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { int ret = 0, i; if ((start == NULL) || (end == NULL)) @@ -495,10 +494,10 @@ int virSocketGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { return(-1); if (start->data.stor.ss_family == AF_INET) { - virIPv4Addr t1, t2; + virSocketAddrIPv4 t1, t2; - if ((getIPv4Addr(start, &t1) < 0) || - (getIPv4Addr(end, &t2) < 0)) + if ((virSocketAddrGetIPv4Addr(start, &t1) < 0) || + (virSocketAddrGetIPv4Addr(end, &t2) < 0)) return(-1); for (i = 0;i < 2;i++) { @@ -510,10 +509,10 @@ int virSocketGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { return(-1); ret++; } else if (start->data.stor.ss_family == AF_INET6) { - virIPv6Addr t1, t2; + virSocketAddrIPv6 t1, t2; - if ((getIPv6Addr(start, &t1) < 0) || - (getIPv6Addr(end, &t2) < 0)) + if ((virSocketAddrGetIPv6Addr(start, &t1) < 0) || + (virSocketAddrGetIPv6Addr(end, &t2) < 0)) return(-1); for (i = 0;i < 7;i++) { @@ -532,7 +531,7 @@ int virSocketGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { /** - * virGetNumNetmaskBits + * virSocketAddrGetNumNetmaskBits * @netmask: the presumed netmask * * Get the number of netmask bits in a netmask. @@ -540,16 +539,16 @@ int virSocketGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { * Returns the number of bits in the netmask or -1 if an error occurred * or the netmask is invalid. */ -int virSocketGetNumNetmaskBits(const virSocketAddrPtr netmask) +int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask) { int i, j; int c = 0; if (netmask->data.stor.ss_family == AF_INET) { - virIPv4Addr tm; + virSocketAddrIPv4 tm; uint8_t bit; - if (getIPv4Addr(netmask, &tm) < 0) + if (virSocketAddrGetIPv4Addr(netmask, &tm) < 0) return -1; for (i = 0; i < 4; i++) @@ -580,10 +579,10 @@ int virSocketGetNumNetmaskBits(const virSocketAddrPtr netmask) return c; } else if (netmask->data.stor.ss_family == AF_INET6) { - virIPv6Addr tm; + virSocketAddrIPv6 tm; uint16_t bit; - if (getIPv6Addr(netmask, &tm) < 0) + if (virSocketAddrGetIPv6Addr(netmask, &tm) < 0) return -1; for (i = 0; i < 8; i++) diff --git a/src/util/network.h b/src/util/network.h index 835934f..a2c68e9 100644 --- a/src/util/network.h +++ b/src/util/network.h @@ -37,13 +37,13 @@ typedef struct { socklen_t len; } virSocketAddr; -# define VIR_SOCKET_HAS_ADDR(s) \ +# define VIR_SOCKET_ADDR_VALID(s) \ ((s)->data.sa.sa_family != AF_UNSPEC) -# define VIR_SOCKET_IS_FAMILY(s, f) \ +# define VIR_SOCKET_ADDR_IS_FAMILY(s, f) \ ((s)->data.sa.sa_family == f) -# define VIR_SOCKET_FAMILY(s) \ +# define VIR_SOCKET_ADDR_FAMILY(s) \ ((s)->data.sa.sa_family) typedef virSocketAddr *virSocketAddrPtr; @@ -62,36 +62,36 @@ typedef struct { typedef virBandwidth *virBandwidthPtr; -int virSocketParseAddr (const char *val, - virSocketAddrPtr addr, - int hint); +int virSocketAddrParse(virSocketAddrPtr addr, + const char *val, + int family); -int virSocketParseIpv4Addr(const char *val, - virSocketAddrPtr addr); +int virSocketAddrParseIPv4(virSocketAddrPtr addr, + const char *val); -int virSocketParseIpv6Addr(const char *val, - virSocketAddrPtr addr); +int virSocketAddrParseIPv6(virSocketAddrPtr addr, + const char *val); -char * virSocketFormatAddr(virSocketAddrPtr addr); -char * virSocketFormatAddrFull(virSocketAddrPtr addr, +char * virSocketAddrFormat(virSocketAddrPtr addr); +char * virSocketAddrFormatFull(virSocketAddrPtr addr, bool withService, const char *separator); -int virSocketSetPort(virSocketAddrPtr addr, int port); +int virSocketAddrSetPort(virSocketAddrPtr addr, int port); -int virSocketGetPort(virSocketAddrPtr addr); +int virSocketAddrGetPort(virSocketAddrPtr addr); -int virSocketGetRange (virSocketAddrPtr start, - virSocketAddrPtr end); +int virSocketAddrGetRange(virSocketAddrPtr start, + virSocketAddrPtr end); int virSocketAddrIsNetmask(virSocketAddrPtr netmask); -int virSocketCheckNetmask (virSocketAddrPtr addr1, - virSocketAddrPtr addr2, - virSocketAddrPtr netmask); -int virSocketAddrMask (const virSocketAddrPtr addr, - const virSocketAddrPtr netmask, - virSocketAddrPtr network); +int virSocketAddrCheckNetmask(virSocketAddrPtr addr1, + virSocketAddrPtr addr2, + virSocketAddrPtr netmask); +int virSocketAddrMask(const virSocketAddrPtr addr, + const virSocketAddrPtr netmask, + virSocketAddrPtr network); int virSocketAddrMaskByPrefix(const virSocketAddrPtr addr, unsigned int prefix, virSocketAddrPtr network); @@ -102,7 +102,7 @@ int virSocketAddrBroadcastByPrefix(const virSocketAddrPtr addr, unsigned int prefix, virSocketAddrPtr broadcast); -int virSocketGetNumNetmaskBits(const virSocketAddrPtr netmask); +int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask); int virSocketAddrPrefixToNetmask(unsigned int prefix, virSocketAddrPtr netmask, int family); diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 6eb5fe7..c9fb6a1 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -461,12 +461,12 @@ int virNetDevSetIPv4Addres(const char *ifname, virSocketAddr broadcast; int ret = -1; - if (!(addrstr = virSocketFormatAddr(addr))) + if (!(addrstr = virSocketAddrFormat(addr))) goto cleanup; /* format up a broadcast address if this is IPv4 */ - if ((VIR_SOCKET_IS_FAMILY(addr, AF_INET)) && + if ((VIR_SOCKET_ADDR_IS_FAMILY(addr, AF_INET)) && ((virSocketAddrBroadcastByPrefix(addr, prefix, &broadcast) < 0) || - !(bcaststr = virSocketFormatAddr(&broadcast)))) { + !(bcaststr = virSocketAddrFormat(&broadcast)))) { goto cleanup; } cmd = virCommandNew(IP_PATH); @@ -506,7 +506,7 @@ int virNetDevClearIPv4Address(const char *ifname, char *addrstr; int ret = -1; - if (!(addrstr = virSocketFormatAddr(addr))) + if (!(addrstr = virSocketAddrFormat(addr))) goto cleanup; cmd = virCommandNew(IP_PATH); virCommandAddArgList(cmd, "addr", "del", NULL); diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 3f3353f..3338c05 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -792,7 +792,7 @@ vboxSocketFormatAddrUtf16(vboxGlobalData *data, virSocketAddrPtr addr) char *utf8 = NULL; PRUnichar *utf16 = NULL; - utf8 = virSocketFormatAddr(addr); + utf8 = virSocketAddrFormat(addr); if (utf8 == NULL) { return NULL; @@ -813,7 +813,7 @@ vboxSocketParseAddrUtf16(vboxGlobalData *data, const PRUnichar *utf16, VBOX_UTF16_TO_UTF8(utf16, &utf8); - if (virSocketParseAddr(utf8, addr, AF_UNSPEC) < 0) { + if (virSocketAddrParse(addr, utf8, AF_UNSPEC) < 0) { goto cleanup; } @@ -7679,8 +7679,8 @@ static virNetworkPtr vboxNetworkDefineCreateXML(virConnectPtr conn, const char * * with contigious address space from start to end */ if ((ipdef->nranges >= 1) && - VIR_SOCKET_HAS_ADDR(&ipdef->ranges[0].start) && - VIR_SOCKET_HAS_ADDR(&ipdef->ranges[0].end)) { + VIR_SOCKET_ADDR_VALID(&ipdef->ranges[0].start) && + VIR_SOCKET_ADDR_VALID(&ipdef->ranges[0].end)) { IDHCPServer *dhcpServer = NULL; data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj, @@ -7741,7 +7741,7 @@ static virNetworkPtr vboxNetworkDefineCreateXML(virConnectPtr conn, const char * } if ((ipdef->nhosts >= 1) && - VIR_SOCKET_HAS_ADDR(&ipdef->hosts[0].ip)) { + VIR_SOCKET_ADDR_VALID(&ipdef->hosts[0].ip)) { PRUnichar *ipAddressUtf16 = NULL; PRUnichar *networkMaskUtf16 = NULL; diff --git a/tests/sockettest.c b/tests/sockettest.c index b9e37ab..bcc2800 100644 --- a/tests/sockettest.c +++ b/tests/sockettest.c @@ -25,7 +25,7 @@ #include <stdlib.h> #include <string.h> -#include "network.h" +#include "virsocketaddr.h" #include "testutils.h" #include "logging.h" #include "memory.h" @@ -40,7 +40,7 @@ static int testParse(virSocketAddr *addr, const char *addrstr, int family, bool { int rc; - rc = virSocketParseAddr(addrstr, addr, family); + rc = virSocketAddrParse(addr, addrstr, family); if (rc < 0) return pass ? -1 : 0; @@ -52,7 +52,7 @@ static int testFormat(virSocketAddr *addr, const char *addrstr, bool pass) { char *newaddrstr; - newaddrstr = virSocketFormatAddr(addr); + newaddrstr = virSocketAddrFormat(addr); if (!newaddrstr) return pass ? -1 : 0; @@ -95,12 +95,12 @@ static int testRange(const char *saddrstr, const char *eaddrstr, int size, bool virSocketAddr saddr; virSocketAddr eaddr; - if (virSocketParseAddr(saddrstr, &saddr, AF_UNSPEC) < 0) + if (virSocketAddrParse(&saddr, saddrstr, AF_UNSPEC) < 0) return -1; - if (virSocketParseAddr(eaddrstr, &eaddr, AF_UNSPEC) < 0) + if (virSocketAddrParse(&eaddr, eaddrstr, AF_UNSPEC) < 0) return -1; - int gotsize = virSocketGetRange(&saddr, &eaddr); + int gotsize = virSocketAddrGetRange(&saddr, &eaddr); VIR_DEBUG("Size want %d vs got %d", size, gotsize); if (gotsize < 0 || gotsize != size) { return pass ? -1 : 0; @@ -129,14 +129,14 @@ static int testNetmask(const char *addr1str, const char *addr2str, virSocketAddr addr2; virSocketAddr netmask; - if (virSocketParseAddr(addr1str, &addr1, AF_UNSPEC) < 0) + if (virSocketAddrParse(&addr1, addr1str, AF_UNSPEC) < 0) return -1; - if (virSocketParseAddr(addr2str, &addr2, AF_UNSPEC) < 0) + if (virSocketAddrParse(&addr2, addr2str, AF_UNSPEC) < 0) return -1; - if (virSocketParseAddr(netmaskstr, &netmask, AF_UNSPEC) < 0) + if (virSocketAddrParse(&netmask, netmaskstr, AF_UNSPEC) < 0) return -1; - int ret = virSocketCheckNetmask(&addr1, &addr2, &netmask); + int ret = virSocketAddrCheckNetmask(&addr1, &addr2, &netmask); if (ret <= 0) { return pass ? -1 : 0; diff --git a/tests/virnetsockettest.c b/tests/virnetsockettest.c index 16713e8..44d6f65 100644 --- a/tests/virnetsockettest.c +++ b/tests/virnetsockettest.c @@ -25,6 +25,7 @@ #ifdef HAVE_IFADDRS_H # include <ifaddrs.h> #endif +#include <netdb.h> #include "testutils.h" #include "util.h" diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c index ece611a..51f75b4 100644 --- a/tests/virnettlscontexttest.c +++ b/tests/virnettlscontexttest.c @@ -33,7 +33,7 @@ #include "logging.h" #include "virfile.h" #include "command.h" -#include "network.h" +#include "virsocketaddr.h" #include "gnutls_1_0_compat.h" #if !defined WIN32 && HAVE_LIBTASN1_H && !defined GNUTLS_1_0_COMPAT @@ -231,7 +231,7 @@ testTLSGenerateCert(struct testTLSCertReq *req) virSocketAddr addr; char *data; int len; - if (virSocketParseAddr(req->ipaddr1, &addr, 0) < 0) { + if (virSocketAddrParse(&addr, req->ipaddr1, 0) < 0) { VIR_WARN("Cannot parse %s", req->ipaddr1); abort(); } @@ -254,7 +254,7 @@ testTLSGenerateCert(struct testTLSCertReq *req) virSocketAddr addr; char *data; int len; - if (virSocketParseAddr(req->ipaddr2, &addr, 0) < 0) { + if (virSocketAddrParse(&addr, req->ipaddr2, 0) < 0) { VIR_WARN("Cannot parse %s", req->ipaddr2); abort(); } -- 1.7.6.4

On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
The socket address APIs in src/util/network.h either take the form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket address API naming * src/conf/domain_conf.c, src/conf/network_conf.c, src/conf/nwfilter_conf.c, src/network/bridge_driver.c, src/nwfilter/nwfilter_ebiptables_driver.c, src/nwfilter/nwfilter_learnipaddr.c, src/qemu/qemu_command.c, src/rpc/virnetsocket.c, src/util/dnsmasq.c, src/util/iptables.c, src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for API renaming --- src/conf/domain_conf.c | 12 ++-- src/conf/network_conf.c | 66 ++++++++++---------- src/conf/nwfilter_conf.c | 16 ++--- src/libvirt_private.syms | 18 +++--- src/network/bridge_driver.c | 42 +++++++------- src/nwfilter/nwfilter_ebiptables_driver.c | 4 +- src/nwfilter/nwfilter_learnipaddr.c | 2 +- src/qemu/qemu_command.c | 4 +- src/rpc/virnetsocket.c | 6 +- src/util/dnsmasq.c | 4 +- src/util/iptables.c | 20 +++--- src/util/network.c | 93 ++++++++++++++--------------- src/util/network.h | 46 +++++++------- src/util/virnetdev.c | 8 +- src/vbox/vbox_tmpl.c | 10 ++-- tests/sockettest.c | 20 +++--- tests/virnetsockettest.c | 1 + tests/virnettlscontexttest.c | 6 +- 18 files changed, 188 insertions(+), 190 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 238edfd..2b235c8 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3685,7 +3685,7 @@ virDomainChrDefParseTargetXML(virCapsPtr caps, goto error; }
- if (virSocketParseAddr(addrStr, def->target.addr, AF_UNSPEC)< 0) + if (virSocketAddrParse(def->target.addr, addrStr, AF_UNSPEC)< 0) goto error;
if (def->target.addr->data.stor.ss_family != AF_INET) { @@ -3709,7 +3709,7 @@ virDomainChrDefParseTargetXML(virCapsPtr caps, goto error; }
- virSocketSetPort(def->target.addr, port); + virSocketAddrSetPort(def->target.addr, port); break;
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO: @@ -8378,8 +8378,8 @@ static bool virDomainChannelDefCheckABIStability(virDomainChrDefPtr src, case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD: if (memcmp(src->target.addr, dst->target.addr, sizeof(*src->target.addr)) != 0) { - char *saddr = virSocketFormatAddrFull(src->target.addr, true, ":"); - char *daddr = virSocketFormatAddrFull(dst->target.addr, true, ":"); + char *saddr = virSocketAddrFormatFull(src->target.addr, true, ":"); + char *daddr = virSocketAddrFormatFull(dst->target.addr, true, ":"); virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target channel addr %s does not match source %s"), NULLSTR(daddr), NULLSTR(saddr)); @@ -10034,14 +10034,14 @@ virDomainChrDefFormat(virBufferPtr buf,
switch (def->targetType) { case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD: { - int port = virSocketGetPort(def->target.addr); + int port = virSocketAddrGetPort(def->target.addr); if (port< 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to format guestfwd port")); return -1; }
- const char *addr = virSocketFormatAddr(def->target.addr); + const char *addr = virSocketAddrFormat(def->target.addr); if (addr == NULL) return -1;
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index f7369e8..8dca618 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -286,7 +286,7 @@ virNetworkDefGetIpByIndex(const virNetworkDefPtr def,
/* find the nth ip of type "family" */ for (ii = 0; ii< def->nips; ii++) { - if (VIR_SOCKET_IS_FAMILY(&def->ips[ii].address, family) + if (VIR_SOCKET_ADDR_IS_FAMILY(&def->ips[ii].address, family) && (n--<= 0)) { return&def->ips[ii]; } @@ -302,9 +302,9 @@ int virNetworkIpDefPrefix(const virNetworkIpDefPtr def) { if (def->prefix> 0) { return def->prefix; - } else if (VIR_SOCKET_HAS_ADDR(&def->netmask)) { - return virSocketGetNumNetmaskBits(&def->netmask); - } else if (VIR_SOCKET_IS_FAMILY(&def->address, AF_INET)) { + } else if (VIR_SOCKET_ADDR_VALID(&def->netmask)) { + return virSocketAddrGetNumNetmaskBits(&def->netmask); + } else if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) { /* Return the natural prefix for the network's ip address. * On Linux we could use the IN_CLASSx() macros, but those * aren't guaranteed on all platforms, so we just deal with @@ -323,7 +323,7 @@ int virNetworkIpDefPrefix(const virNetworkIpDefPtr def) return 24; } return -1; - } else if (VIR_SOCKET_IS_FAMILY(&def->address, AF_INET6)) { + } else if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) { return 64; } return -1; @@ -336,13 +336,13 @@ int virNetworkIpDefPrefix(const virNetworkIpDefPtr def) int virNetworkIpDefNetmask(const virNetworkIpDefPtr def, virSocketAddrPtr netmask) { - if (VIR_SOCKET_IS_FAMILY(&def->netmask, AF_INET)) { + if (VIR_SOCKET_ADDR_IS_FAMILY(&def->netmask, AF_INET)) { *netmask = def->netmask; return 0; }
return virSocketAddrPrefixToNetmask(virNetworkIpDefPrefix(def), netmask, - VIR_SOCKET_FAMILY(&def->address)); + VIR_SOCKET_ADDR_FAMILY(&def->address)); }
@@ -372,18 +372,18 @@ virNetworkDHCPRangeDefParseXML(const char *networkName, continue; }
- if (virSocketParseAddr(start,&saddr, AF_UNSPEC)< 0) { + if (virSocketAddrParse(&saddr, start, AF_UNSPEC)< 0) { VIR_FREE(start); VIR_FREE(end); return -1; } - if (virSocketParseAddr(end,&eaddr, AF_UNSPEC)< 0) { + if (virSocketAddrParse(&eaddr, end, AF_UNSPEC)< 0) { VIR_FREE(start); VIR_FREE(end); return -1; }
- range = virSocketGetRange(&saddr,&eaddr); + range = virSocketAddrGetRange(&saddr,&eaddr); if (range< 0) { virNetworkReportError(VIR_ERR_XML_ERROR, _("Invalid dhcp range '%s' to '%s' in network '%s'"), @@ -434,7 +434,7 @@ virNetworkDHCPRangeDefParseXML(const char *networkName, } ip = virXMLPropString(cur, "ip"); if ((ip == NULL) || - (virSocketParseAddr(ip,&inaddr, AF_UNSPEC)< 0)) { + (virSocketAddrParse(&inaddr, ip, AF_UNSPEC)< 0)) { virNetworkReportError(VIR_ERR_XML_ERROR, _("Missing IP address in static host definition for network '%s'"), networkName); @@ -469,7 +469,7 @@ virNetworkDHCPRangeDefParseXML(const char *networkName, server = virXMLPropString(cur, "server");
if (server&& - virSocketParseAddr(server,&inaddr, AF_UNSPEC)< 0) { + virSocketAddrParse(&inaddr, server, AF_UNSPEC)< 0) { VIR_FREE(file); VIR_FREE(server); return -1; @@ -504,7 +504,7 @@ virNetworkDNSHostsDefParseXML(virNetworkDNSDefPtr def, }
if (!(ip = virXMLPropString(node, "ip")) || - (virSocketParseAddr(ip,&inaddr, AF_UNSPEC)< 0)) { + (virSocketAddrParse(&inaddr, ip, AF_UNSPEC)< 0)) { virNetworkReportError(VIR_ERR_XML_DETAIL, _("Missing IP address in DNS host definition")); VIR_FREE(ip); @@ -649,7 +649,7 @@ virNetworkIPParseXML(const char *networkName, netmask = virXPathString("string(./@netmask)", ctxt);
if (address) { - if (virSocketParseAddr(address,&def->address, AF_UNSPEC)< 0) { + if (virSocketAddrParse(&def->address, address, AF_UNSPEC)< 0) { virNetworkReportError(VIR_ERR_XML_ERROR, _("Bad address '%s' in definition of network '%s'"), address, networkName); @@ -660,22 +660,22 @@ virNetworkIPParseXML(const char *networkName,
/* validate family vs. address */ if (def->family == NULL) { - if (!(VIR_SOCKET_IS_FAMILY(&def->address, AF_INET) || - VIR_SOCKET_IS_FAMILY(&def->address, AF_UNSPEC))) { + if (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) || + VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_UNSPEC))) { virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("no family specified for non-IPv4 address address '%s' in network '%s'"), address, networkName); goto error; } } else if (STREQ(def->family, "ipv4")) { - if (!VIR_SOCKET_IS_FAMILY(&def->address, AF_INET)) { + if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) { virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("family 'ipv4' specified for non-IPv4 address '%s' in network '%s'"), address, networkName); goto error; } } else if (STREQ(def->family, "ipv6")) { - if (!VIR_SOCKET_IS_FAMILY(&def->address, AF_INET6)) { + if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) { virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("family 'ipv6' specified for non-IPv6 address '%s' in network '%s'"), address, networkName); @@ -698,7 +698,7 @@ virNetworkIPParseXML(const char *networkName, goto error; }
- if (!VIR_SOCKET_IS_FAMILY(&def->address, AF_INET)) { + if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) { virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("netmask not supported for address '%s' in network '%s' (IPv4 only)"), address, networkName); @@ -713,10 +713,10 @@ virNetworkIPParseXML(const char *networkName, goto error; }
- if (virSocketParseAddr(netmask,&def->netmask, AF_UNSPEC)< 0) + if (virSocketAddrParse(&def->netmask, netmask, AF_UNSPEC)< 0) goto error;
- if (!VIR_SOCKET_IS_FAMILY(&def->netmask, AF_INET)) { + if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->netmask, AF_INET)) { virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("network '%s' has invalid netmask '%s' for address '%s' (both must be IPv4)"), networkName, netmask, address); @@ -724,7 +724,7 @@ virNetworkIPParseXML(const char *networkName, } }
- if (VIR_SOCKET_IS_FAMILY(&def->address, AF_INET)) { + if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) { /* parse IPv4-related info */ cur = node->children; while (cur != NULL) { @@ -1151,7 +1151,7 @@ virNetworkDNSDefFormat(virBufferPtr buf, int ii, j;
for (ii = 0 ; ii< def->nhosts; ii++) { - char *ip = virSocketFormatAddr(&def->hosts[ii].ip); + char *ip = virSocketAddrFormat(&def->hosts[ii].ip);
virBufferAsprintf(buf, "<host ip='%s'>\n", ip);
@@ -1180,15 +1180,15 @@ virNetworkIpDefFormat(virBufferPtr buf, if (def->family) { virBufferAsprintf(buf, " family='%s'", def->family); } - if (VIR_SOCKET_HAS_ADDR(&def->address)) { - char *addr = virSocketFormatAddr(&def->address); + if (VIR_SOCKET_ADDR_VALID(&def->address)) { + char *addr = virSocketAddrFormat(&def->address); if (!addr) goto error; virBufferAsprintf(buf, " address='%s'", addr); VIR_FREE(addr); } - if (VIR_SOCKET_HAS_ADDR(&def->netmask)) { - char *addr = virSocketFormatAddr(&def->netmask); + if (VIR_SOCKET_ADDR_VALID(&def->netmask)) { + char *addr = virSocketAddrFormat(&def->netmask); if (!addr) goto error; virBufferAsprintf(buf, " netmask='%s'", addr); @@ -1207,10 +1207,10 @@ virNetworkIpDefFormat(virBufferPtr buf, int ii; virBufferAddLit(buf, "<dhcp>\n"); for (ii = 0 ; ii< def->nranges ; ii++) { - char *saddr = virSocketFormatAddr(&def->ranges[ii].start); + char *saddr = virSocketAddrFormat(&def->ranges[ii].start); if (!saddr) goto error; - char *eaddr = virSocketFormatAddr(&def->ranges[ii].end); + char *eaddr = virSocketAddrFormat(&def->ranges[ii].end); if (!eaddr) { VIR_FREE(saddr); goto error; @@ -1226,8 +1226,8 @@ virNetworkIpDefFormat(virBufferPtr buf, virBufferAsprintf(buf, "mac='%s' ", def->hosts[ii].mac); if (def->hosts[ii].name) virBufferAsprintf(buf, "name='%s' ", def->hosts[ii].name); - if (VIR_SOCKET_HAS_ADDR(&def->hosts[ii].ip)) { - char *ipaddr = virSocketFormatAddr(&def->hosts[ii].ip); + if (VIR_SOCKET_ADDR_VALID(&def->hosts[ii].ip)) { + char *ipaddr = virSocketAddrFormat(&def->hosts[ii].ip); if (!ipaddr) goto error; virBufferAsprintf(buf, "ip='%s' ", ipaddr); @@ -1238,8 +1238,8 @@ virNetworkIpDefFormat(virBufferPtr buf, if (def->bootfile) { virBufferEscapeString(buf, "<bootp file='%s' ", def->bootfile); - if (VIR_SOCKET_HAS_ADDR(&def->bootserver)) { - char *ipaddr = virSocketFormatAddr(&def->bootserver); + if (VIR_SOCKET_ADDR_VALID(&def->bootserver)) { + char *ipaddr = virSocketAddrFormat(&def->bootserver); if (!ipaddr) goto error; virBufferEscapeString(buf, "server='%s' ", ipaddr); diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index 6c3e1cf..55ab68b 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -1523,8 +1523,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr node, break;
case DATATYPE_IPADDR: - if (virSocketParseIpv4Addr(prop, -&item->u.ipaddr)< 0) + if (virSocketAddrParseIPv4(&item->u.ipaddr, prop)< 0) rc = -1; found = 1; break; @@ -1539,10 +1538,10 @@ virNWFilterRuleDetailsParse(xmlNodePtr node, } else rc = -1; } else { - if (virSocketParseIpv4Addr(prop,&ipaddr)< 0) { + if (virSocketAddrParseIPv4(&ipaddr, prop)< 0) { rc = -1; } else { - int_val = virSocketGetNumNetmaskBits(&ipaddr); + int_val = virSocketAddrGetNumNetmaskBits(&ipaddr); if (int_val>= 0) item->u.u8 = int_val; else @@ -1571,8 +1570,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr node, break;
case DATATYPE_IPV6ADDR: - if (virSocketParseIpv6Addr(prop, -&item->u.ipaddr)< 0) + if (virSocketAddrParseIPv6(&item->u.ipaddr, prop)< 0) rc = -1; found = 1; break; @@ -1587,10 +1585,10 @@ virNWFilterRuleDetailsParse(xmlNodePtr node, } else rc = -1; } else { - if (virSocketParseIpv6Addr(prop,&ipaddr)< 0) { + if (virSocketAddrParseIPv6(&ipaddr, prop)< 0) { rc = -1; } else { - int_val = virSocketGetNumNetmaskBits(&ipaddr); + int_val = virSocketAddrGetNumNetmaskBits(&ipaddr); if (int_val>= 0) item->u.u8 = int_val; else @@ -2596,7 +2594,7 @@ virNWFilterObjDeleteDef(virNWFilterObjPtr nwfilter) static void virNWIPAddressFormat(virBufferPtr buf, virSocketAddrPtr ipaddr) { - char *output = virSocketFormatAddr(ipaddr); + char *output = virSocketAddrFormat(ipaddr);
if (output) { virBufferAdd(buf, output, -1); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6a1562e..fa8ac93 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -773,19 +773,19 @@ virBandwidthEnable; virBandwidthEqual; virSocketAddrBroadcast; virSocketAddrBroadcastByPrefix; +virSocketAddrCheckNetmask; +virSocketAddrFormat; +virSocketAddrFormatFull; +virSocketAddrGetPort; +virSocketAddrGetRange; virSocketAddrIsNetmask; virSocketAddrMask; virSocketAddrMaskByPrefix; +virSocketAddrParse; +virSocketAddrParseIPv4; +virSocketAddrParseIPv6; virSocketAddrPrefixToNetmask; -virSocketCheckNetmask; -virSocketFormatAddr; -virSocketFormatAddrFull; -virSocketGetPort; -virSocketGetRange; -virSocketParseAddr; -virSocketParseIpv4Addr; -virSocketParseIpv6Addr; -virSocketSetPort; +virSocketAddrSetPort; virVirtualPortProfileEqual; virVirtualPortProfileFormat; virVirtualPortProfileParseXML; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index bc3a18f..bd8f0b3 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -432,7 +432,7 @@ networkBuildDnsmasqHostsfile(dnsmasqContext *dctx,
for (i = 0; i< ipdef->nhosts; i++) { virNetworkDHCPHostDefPtr host =&(ipdef->hosts[i]); - if ((host->mac)&& VIR_SOCKET_HAS_ADDR(&host->ip)) + if ((host->mac)&& VIR_SOCKET_ADDR_VALID(&host->ip)) if (dnsmasqAddDhcpHost(dctx, host->mac,&host->ip, host->name)< 0) return -1; } @@ -440,7 +440,7 @@ networkBuildDnsmasqHostsfile(dnsmasqContext *dctx, if (dnsdef) { for (i = 0; i< dnsdef->nhosts; i++) { virNetworkDNSHostsDefPtr host =&(dnsdef->hosts[i]); - if (VIR_SOCKET_HAS_ADDR(&host->ip)) { + if (VIR_SOCKET_ADDR_VALID(&host->ip)) { for (j = 0; j< host->nnames; j++) if (dnsmasqAddHost(dctx,&host->ip, host->names[j])< 0) return -1; @@ -543,7 +543,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, for (ii = 0; (tmpipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii)); ii++) { - char *ipaddr = virSocketFormatAddr(&tmpipdef->address); + char *ipaddr = virSocketAddrFormat(&tmpipdef->address); if (!ipaddr) goto cleanup; virCommandAddArgList(cmd, "--listen-address", ipaddr, NULL); @@ -552,10 +552,10 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
if (ipdef) { for (r = 0 ; r< ipdef->nranges ; r++) { - char *saddr = virSocketFormatAddr(&ipdef->ranges[r].start); + char *saddr = virSocketAddrFormat(&ipdef->ranges[r].start); if (!saddr) goto cleanup; - char *eaddr = virSocketFormatAddr(&ipdef->ranges[r].end); + char *eaddr = virSocketAddrFormat(&ipdef->ranges[r].end); if (!eaddr) { VIR_FREE(saddr); goto cleanup; @@ -564,8 +564,8 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, virCommandAddArgFormat(cmd, "%s,%s", saddr, eaddr); VIR_FREE(saddr); VIR_FREE(eaddr); - nbleases += virSocketGetRange(&ipdef->ranges[r].start, -&ipdef->ranges[r].end); + nbleases += virSocketAddrGetRange(&ipdef->ranges[r].start, +&ipdef->ranges[r].end); }
/* @@ -574,7 +574,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, * dnsmasq. */ if (!ipdef->nranges&& ipdef->nhosts) { - char *bridgeaddr = virSocketFormatAddr(&ipdef->address); + char *bridgeaddr = virSocketAddrFormat(&ipdef->address); if (!bridgeaddr) goto cleanup; virCommandAddArg(cmd, "--dhcp-range"); @@ -615,8 +615,8 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, } if (ipdef->bootfile) { virCommandAddArg(cmd, "--dhcp-boot"); - if (VIR_SOCKET_HAS_ADDR(&ipdef->bootserver)) { - char *bootserver = virSocketFormatAddr(&ipdef->bootserver); + if (VIR_SOCKET_ADDR_VALID(&ipdef->bootserver)) { + char *bootserver = virSocketAddrFormat(&ipdef->bootserver);
if (!bootserver) goto cleanup; @@ -815,7 +815,7 @@ networkStartRadvd(virNetworkObjPtr network) network->def->bridge); goto cleanup; } - if (!(netaddr = virSocketFormatAddr(&ipdef->address))) + if (!(netaddr = virSocketAddrFormat(&ipdef->address))) goto cleanup; virBufferAsprintf(&configbuf, " prefix %s/%d\n" @@ -1389,9 +1389,9 @@ networkAddIpSpecificIptablesRules(struct network_driver *driver, */
if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) { - if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) return networkAddMasqueradingIptablesRules(driver, network, ipdef); - else if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET6)) + else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) return networkAddRoutingIptablesRules(driver, network, ipdef); } else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE) { return networkAddRoutingIptablesRules(driver, network, ipdef); @@ -1405,9 +1405,9 @@ networkRemoveIpSpecificIptablesRules(struct network_driver *driver, virNetworkIpDefPtr ipdef) { if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) { - if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) networkRemoveMasqueradingIptablesRules(driver, network, ipdef); - else if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET6)) + else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) networkRemoveRoutingIptablesRules(driver, network, ipdef); } else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE) { networkRemoveRoutingIptablesRules(driver, network, ipdef); @@ -1746,9 +1746,9 @@ networkStartNetworkVirtual(struct network_driver *driver, for (ii = 0; (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii)); ii++) { - if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) v4present = true; - if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET6)) + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) v6present = true;
/* Add the IP address/netmask to the bridge */ @@ -2302,7 +2302,7 @@ static virNetworkPtr networkDefine(virConnectPtr conn, const char *xml) { for (ii = 0; (ipdef = virNetworkDefGetIpByIndex(def, AF_UNSPEC, ii)); ii++) { - if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) { + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) { if (ipdef->nranges || ipdef->nhosts) { if (ipv4def) { networkReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -2366,10 +2366,10 @@ static int networkUndefine(virNetworkPtr net) { for (ii = 0; (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii)); ii++) { - if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) { + if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) { if (ipdef->nranges || ipdef->nhosts) dhcp_present = true; - } else if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET6)) { + } else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) { v6present = true; } } @@ -3165,7 +3165,7 @@ networkGetNetworkAddress(const char *netname, char **netaddr) }
if (addrptr&& - (*netaddr = virSocketFormatAddr(addrptr))) { + (*netaddr = virSocketAddrFormat(addrptr))) { ret = 0; }
diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index f87cfa1..28f7288 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -196,7 +196,7 @@ _printDataType(virNWFilterHashTablePtr vars,
switch (item->datatype) { case DATATYPE_IPADDR: - data = virSocketFormatAddr(&item->u.ipaddr); + data = virSocketAddrFormat(&item->u.ipaddr); if (!data) return 1; if (snprintf(buf, bufsize, "%s", data)>= bufsize) { @@ -209,7 +209,7 @@ _printDataType(virNWFilterHashTablePtr vars, break;
case DATATYPE_IPV6ADDR: - data = virSocketFormatAddr(&item->u.ipaddr); + data = virSocketAddrFormat(&item->u.ipaddr); if (!data) return 1;
diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c index 034eedb..68bdcfc 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -630,7 +630,7 @@ learnIPAddressThread(void *arg) sa.data.inet4.sin_addr.s_addr = vmaddr; char *inetaddr;
- if ((inetaddr = virSocketFormatAddr(&sa))!= NULL) { + if ((inetaddr = virSocketAddrFormat(&sa))!= NULL) { virNWFilterAddIpAddrForIfname(req->ifname, inetaddr);
ret = virNWFilterInstantiateFilterLate(NULL, diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 7c9e60b..fba9ace 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4440,10 +4440,10 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, devstr); VIR_FREE(devstr);
- addr = virSocketFormatAddr(channel->target.addr); + addr = virSocketAddrFormat(channel->target.addr); if (!addr) goto error; - port = virSocketGetPort(channel->target.addr); + port = virSocketAddrGetPort(channel->target.addr);
virCommandAddArg(cmd, "-netdev"); virCommandAddArgFormat(cmd, diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index d832c53..3c9f327 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -163,11 +163,11 @@ static virNetSocketPtr virNetSocketNew(virSocketAddrPtr localAddr,
if (localAddr&& - !(sock->localAddrStr = virSocketFormatAddrFull(localAddr, true, ";"))) + !(sock->localAddrStr = virSocketAddrFormatFull(localAddr, true, ";"))) goto error;
if (remoteAddr&& - !(sock->remoteAddrStr = virSocketFormatAddrFull(remoteAddr, true, ";"))) + !(sock->remoteAddrStr = virSocketAddrFormatFull(remoteAddr, true, ";"))) goto error;
sock->client = isClient; @@ -809,7 +809,7 @@ int virNetSocketGetPort(virNetSocketPtr sock) { int port; virMutexLock(&sock->lock); - port = virSocketGetPort(&sock->localAddr); + port = virSocketAddrGetPort(&sock->localAddr); virMutexUnlock(&sock->lock); return port; } diff --git a/src/util/dnsmasq.c b/src/util/dnsmasq.c index d76cf65..b5f90a6 100644 --- a/src/util/dnsmasq.c +++ b/src/util/dnsmasq.c @@ -95,7 +95,7 @@ addnhostsAdd(dnsmasqAddnHostsfile *addnhostsfile, int idx = -1; int i;
- if (!(ipstr = virSocketFormatAddr(ip))) + if (!(ipstr = virSocketAddrFormat(ip))) return -1;
for (i = 0; i< addnhostsfile->nhosts; i++) { @@ -300,7 +300,7 @@ hostsfileAdd(dnsmasqHostsfile *hostsfile, if (VIR_REALLOC_N(hostsfile->hosts, hostsfile->nhosts + 1)< 0) goto alloc_error;
- if (!(ipstr = virSocketFormatAddr(ip))) + if (!(ipstr = virSocketAddrFormat(ip))) return -1;
if (name) { diff --git a/src/util/iptables.c b/src/util/iptables.c index 76d412c..452d717 100644 --- a/src/util/iptables.c +++ b/src/util/iptables.c @@ -291,8 +291,8 @@ static char *iptablesFormatNetwork(virSocketAddr *netaddr, char *netstr; char *ret;
- if (!(VIR_SOCKET_IS_FAMILY(netaddr, AF_INET) || - VIR_SOCKET_IS_FAMILY(netaddr, AF_INET6))) { + if (!(VIR_SOCKET_ADDR_IS_FAMILY(netaddr, AF_INET) || + VIR_SOCKET_ADDR_IS_FAMILY(netaddr, AF_INET6))) { iptablesError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Only IPv4 or IPv6 addresses can be used with iptables")); return NULL; @@ -304,7 +304,7 @@ static char *iptablesFormatNetwork(virSocketAddr *netaddr, return NULL; }
- netstr = virSocketFormatAddr(&network); + netstr = virSocketAddrFormat(&network);
if (!netstr) return NULL; @@ -336,7 +336,7 @@ iptablesForwardAllowOut(iptablesContext *ctx,
if (physdev&& physdev[0]) { ret = iptablesAddRemoveRule(ctx->forward_filter, - VIR_SOCKET_FAMILY(netaddr), + VIR_SOCKET_ADDR_FAMILY(netaddr), action, "--source", networkstr, "--in-interface", iface, @@ -345,7 +345,7 @@ iptablesForwardAllowOut(iptablesContext *ctx, NULL); } else { ret = iptablesAddRemoveRule(ctx->forward_filter, - VIR_SOCKET_FAMILY(netaddr), + VIR_SOCKET_ADDR_FAMILY(netaddr), action, "--source", networkstr, "--in-interface", iface, @@ -422,7 +422,7 @@ iptablesForwardAllowRelatedIn(iptablesContext *ctx,
if (physdev&& physdev[0]) { ret = iptablesAddRemoveRule(ctx->forward_filter, - VIR_SOCKET_FAMILY(netaddr), + VIR_SOCKET_ADDR_FAMILY(netaddr), action, "--destination", networkstr, "--in-interface", physdev, @@ -433,7 +433,7 @@ iptablesForwardAllowRelatedIn(iptablesContext *ctx, NULL); } else { ret = iptablesAddRemoveRule(ctx->forward_filter, - VIR_SOCKET_FAMILY(netaddr), + VIR_SOCKET_ADDR_FAMILY(netaddr), action, "--destination", networkstr, "--out-interface", iface, @@ -510,7 +510,7 @@ iptablesForwardAllowIn(iptablesContext *ctx,
if (physdev&& physdev[0]) { ret = iptablesAddRemoveRule(ctx->forward_filter, - VIR_SOCKET_FAMILY(netaddr), + VIR_SOCKET_ADDR_FAMILY(netaddr), action, "--destination", networkstr, "--in-interface", physdev, @@ -519,7 +519,7 @@ iptablesForwardAllowIn(iptablesContext *ctx, NULL); } else { ret = iptablesAddRemoveRule(ctx->forward_filter, - VIR_SOCKET_FAMILY(netaddr), + VIR_SOCKET_ADDR_FAMILY(netaddr), action, "--destination", networkstr, "--out-interface", iface, @@ -761,7 +761,7 @@ iptablesForwardMasquerade(iptablesContext *ctx, if (!(networkstr = iptablesFormatNetwork(netaddr, prefix))) return -1;
- if (!VIR_SOCKET_IS_FAMILY(netaddr, AF_INET)) { + if (!VIR_SOCKET_ADDR_IS_FAMILY(netaddr, AF_INET)) { /* Higher level code *should* guaranteee it's impossible to get here. */ iptablesError(VIR_ERR_INTERNAL_ERROR, _("Attempted to NAT '%s'. NAT is only supported for IPv4."), diff --git a/src/util/network.c b/src/util/network.c index edf9c50..087df22 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -27,12 +27,12 @@ * Helpers to extract the IP arrays from the virSocketAddrPtr * That part is the less portable of the module */ -typedef unsigned char virIPv4Addr[4]; -typedef virIPv4Addr *virIPv4AddrPtr; -typedef unsigned short virIPv6Addr[8]; -typedef virIPv6Addr *virIPv6AddrPtr; +typedef unsigned char virSocketAddrIPv4[4]; +typedef virSocketAddrIPv4 *virSocketAddrIPv4Ptr; +typedef unsigned short virSocketAddrIPv6[8]; +typedef virSocketAddrIPv6 *virSocketAddrIPv6Ptr;
-static int getIPv4Addr(virSocketAddrPtr addr, virIPv4AddrPtr tab) { +static int virSocketAddrGetIPv4Addr(virSocketAddrPtr addr, virSocketAddrIPv4Ptr tab) { unsigned long val; int i;
@@ -49,7 +49,7 @@ static int getIPv4Addr(virSocketAddrPtr addr, virIPv4AddrPtr tab) { return(0); }
-static int getIPv6Addr(virSocketAddrPtr addr, virIPv6AddrPtr tab) { +static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr tab) { int i;
if ((addr == NULL) || (tab == NULL) || (addr->data.stor.ss_family != AF_INET6)) @@ -64,7 +64,7 @@ static int getIPv6Addr(virSocketAddrPtr addr, virIPv6AddrPtr tab) { }
/** - * virSocketParseAddr: + * virSocketAddrParse: * @val: a numeric network address IPv4 or IPv6 * @addr: where to store the return value, optional. * @family: address family to pass down to getaddrinfo @@ -74,8 +74,7 @@ static int getIPv6Addr(virSocketAddrPtr addr, virIPv6AddrPtr tab) { * * Returns the length of the network address or -1 in case of error. */ -int -virSocketParseAddr(const char *val, virSocketAddrPtr addr, int family) { +int virSocketAddrParse(virSocketAddrPtr addr, const char *val, int family) { int len; struct addrinfo hints; struct addrinfo *res = NULL; @@ -114,7 +113,7 @@ virSocketParseAddr(const char *val, virSocketAddrPtr addr, int family) { }
/* - * virSocketParseIpv4Addr: + * virSocketAddrParseIPv4: * @val: an IPv4 numeric address * @addr: the location to store the result * @@ -123,12 +122,12 @@ virSocketParseAddr(const char *val, virSocketAddrPtr addr, int family) { * Returns the length of the network address or -1 in case of error. */ int -virSocketParseIpv4Addr(const char *val, virSocketAddrPtr addr) { - return(virSocketParseAddr(val, addr, AF_INET)); +virSocketAddrParseIPv4(virSocketAddrPtr addr, const char *val) { + return virSocketAddrParse(addr, val, AF_INET); }
/* - * virSocketParseIpv6Addr: + * virSocketAddrParseIPv6: * @val: an IPv6 numeric address * @addr: the location to store the result * @@ -137,12 +136,12 @@ virSocketParseIpv4Addr(const char *val, virSocketAddrPtr addr) { * Returns the length of the network address or -1 in case of error. */ int -virSocketParseIpv6Addr(const char *val, virSocketAddrPtr addr) { - return(virSocketParseAddr(val, addr, AF_INET6)); +virSocketAddrParseIPv6(virSocketAddrPtr addr, const char *val) { + return virSocketAddrParse(addr, val, AF_INET6); }
/* - * virSocketFormatAddr: + * virSocketAddrFormat: * @addr: an initialized virSocketAddrPtr * * Returns a string representation of the given address @@ -150,13 +149,13 @@ virSocketParseIpv6Addr(const char *val, virSocketAddrPtr addr) { * Caller must free the returned string */ char * -virSocketFormatAddr(virSocketAddrPtr addr) { - return virSocketFormatAddrFull(addr, false, NULL); +virSocketAddrFormat(virSocketAddrPtr addr) { + return virSocketAddrFormatFull(addr, false, NULL); }
/* - * virSocketFormatAddrFull: + * virSocketAddrFormatFull: * @addr: an initialized virSocketAddrPtr * @withService: if true, then service info is appended * @separator: separator between hostname& service. @@ -166,7 +165,7 @@ virSocketFormatAddr(virSocketAddrPtr addr) { * Caller must free the returned string */ char * -virSocketFormatAddrFull(virSocketAddrPtr addr, +virSocketAddrFormatFull(virSocketAddrPtr addr, bool withService, const char *separator) { @@ -221,7 +220,7 @@ no_memory:
/* - * virSocketSetPort: + * virSocketAddrSetPort: * @addr: an initialized virSocketAddrPtr * @port: the port number to set * @@ -230,7 +229,7 @@ no_memory: * Returns 0 on success, -1 on failure */ int -virSocketSetPort(virSocketAddrPtr addr, int port) { +virSocketAddrSetPort(virSocketAddrPtr addr, int port) { if (addr == NULL) return -1;
@@ -259,7 +258,7 @@ virSocketSetPort(virSocketAddrPtr addr, int port) { * Returns -1 if @addr is invalid */ int -virSocketGetPort(virSocketAddrPtr addr) { +virSocketAddrGetPort(virSocketAddrPtr addr) { if (addr == NULL) return -1;
@@ -283,7 +282,7 @@ virSocketGetPort(virSocketAddrPtr addr) { * Returns 0 in case of success and -1 in case of error */ int virSocketAddrIsNetmask(virSocketAddrPtr netmask) { - int n = virSocketGetNumNetmaskBits(netmask); + int n = virSocketAddrGetNumNetmaskBits(netmask); if (n< 0) return -1; return 0; @@ -429,8 +428,8 @@ virSocketAddrBroadcastByPrefix(const virSocketAddrPtr addr, * Returns 1 in case of success and 0 in case of failure and * -1 in case of error */ -int virSocketCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2, - virSocketAddrPtr netmask) { +int virSocketAddrCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2, + virSocketAddrPtr netmask) { int i;
if ((addr1 == NULL) || (addr2 == NULL) || (netmask == NULL)) @@ -443,11 +442,11 @@ int virSocketCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2, return(-1);
if (addr1->data.stor.ss_family == AF_INET) { - virIPv4Addr t1, t2, tm; + virSocketAddrIPv4 t1, t2, tm;
- if ((getIPv4Addr(addr1,&t1)< 0) || - (getIPv4Addr(addr2,&t2)< 0) || - (getIPv4Addr(netmask,&tm)< 0)) + if ((virSocketAddrGetIPv4Addr(addr1,&t1)< 0) || + (virSocketAddrGetIPv4Addr(addr2,&t2)< 0) || + (virSocketAddrGetIPv4Addr(netmask,&tm)< 0)) return(-1);
for (i = 0;i< 4;i++) { @@ -456,11 +455,11 @@ int virSocketCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2, }
} else if (addr1->data.stor.ss_family == AF_INET6) { - virIPv6Addr t1, t2, tm; + virSocketAddrIPv6 t1, t2, tm;
- if ((getIPv6Addr(addr1,&t1)< 0) || - (getIPv6Addr(addr2,&t2)< 0) || - (getIPv6Addr(netmask,&tm)< 0)) + if ((virSocketAddrGetIPv6Addr(addr1,&t1)< 0) || + (virSocketAddrGetIPv6Addr(addr2,&t2)< 0) || + (virSocketAddrGetIPv6Addr(netmask,&tm)< 0)) return(-1);
for (i = 0;i< 8;i++) { @@ -486,7 +485,7 @@ int virSocketCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2, * * Returns the size of the range or -1 in case of failure */ -int virSocketGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { +int virSocketAddrGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { int ret = 0, i;
if ((start == NULL) || (end == NULL)) @@ -495,10 +494,10 @@ int virSocketGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { return(-1);
if (start->data.stor.ss_family == AF_INET) { - virIPv4Addr t1, t2; + virSocketAddrIPv4 t1, t2;
- if ((getIPv4Addr(start,&t1)< 0) || - (getIPv4Addr(end,&t2)< 0)) + if ((virSocketAddrGetIPv4Addr(start,&t1)< 0) || + (virSocketAddrGetIPv4Addr(end,&t2)< 0)) return(-1);
for (i = 0;i< 2;i++) { @@ -510,10 +509,10 @@ int virSocketGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { return(-1); ret++; } else if (start->data.stor.ss_family == AF_INET6) { - virIPv6Addr t1, t2; + virSocketAddrIPv6 t1, t2;
- if ((getIPv6Addr(start,&t1)< 0) || - (getIPv6Addr(end,&t2)< 0)) + if ((virSocketAddrGetIPv6Addr(start,&t1)< 0) || + (virSocketAddrGetIPv6Addr(end,&t2)< 0)) return(-1);
for (i = 0;i< 7;i++) { @@ -532,7 +531,7 @@ int virSocketGetRange(virSocketAddrPtr start, virSocketAddrPtr end) {
/** - * virGetNumNetmaskBits + * virSocketAddrGetNumNetmaskBits * @netmask: the presumed netmask * * Get the number of netmask bits in a netmask. @@ -540,16 +539,16 @@ int virSocketGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { * Returns the number of bits in the netmask or -1 if an error occurred * or the netmask is invalid. */ -int virSocketGetNumNetmaskBits(const virSocketAddrPtr netmask) +int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask) { int i, j; int c = 0;
if (netmask->data.stor.ss_family == AF_INET) { - virIPv4Addr tm; + virSocketAddrIPv4 tm; uint8_t bit;
- if (getIPv4Addr(netmask,&tm)< 0) + if (virSocketAddrGetIPv4Addr(netmask,&tm)< 0) return -1;
for (i = 0; i< 4; i++) @@ -580,10 +579,10 @@ int virSocketGetNumNetmaskBits(const virSocketAddrPtr netmask)
return c; } else if (netmask->data.stor.ss_family == AF_INET6) { - virIPv6Addr tm; + virSocketAddrIPv6 tm; uint16_t bit;
- if (getIPv6Addr(netmask,&tm)< 0) + if (virSocketAddrGetIPv6Addr(netmask,&tm)< 0) return -1;
for (i = 0; i< 8; i++) diff --git a/src/util/network.h b/src/util/network.h index 835934f..a2c68e9 100644 --- a/src/util/network.h +++ b/src/util/network.h @@ -37,13 +37,13 @@ typedef struct { socklen_t len; } virSocketAddr;
-# define VIR_SOCKET_HAS_ADDR(s) \ +# define VIR_SOCKET_ADDR_VALID(s) \ ((s)->data.sa.sa_family != AF_UNSPEC)
-# define VIR_SOCKET_IS_FAMILY(s, f) \ +# define VIR_SOCKET_ADDR_IS_FAMILY(s, f) \ ((s)->data.sa.sa_family == f)
-# define VIR_SOCKET_FAMILY(s) \ +# define VIR_SOCKET_ADDR_FAMILY(s) \ ((s)->data.sa.sa_family)
typedef virSocketAddr *virSocketAddrPtr; @@ -62,36 +62,36 @@ typedef struct {
typedef virBandwidth *virBandwidthPtr;
-int virSocketParseAddr (const char *val, - virSocketAddrPtr addr, - int hint); +int virSocketAddrParse(virSocketAddrPtr addr, + const char *val, + int family);
-int virSocketParseIpv4Addr(const char *val, - virSocketAddrPtr addr); +int virSocketAddrParseIPv4(virSocketAddrPtr addr, + const char *val);
-int virSocketParseIpv6Addr(const char *val, - virSocketAddrPtr addr); +int virSocketAddrParseIPv6(virSocketAddrPtr addr, + const char *val);
-char * virSocketFormatAddr(virSocketAddrPtr addr); -char * virSocketFormatAddrFull(virSocketAddrPtr addr, +char * virSocketAddrFormat(virSocketAddrPtr addr); +char * virSocketAddrFormatFull(virSocketAddrPtr addr, bool withService, const char *separator);
-int virSocketSetPort(virSocketAddrPtr addr, int port); +int virSocketAddrSetPort(virSocketAddrPtr addr, int port);
-int virSocketGetPort(virSocketAddrPtr addr); +int virSocketAddrGetPort(virSocketAddrPtr addr);
-int virSocketGetRange (virSocketAddrPtr start, - virSocketAddrPtr end); +int virSocketAddrGetRange(virSocketAddrPtr start, + virSocketAddrPtr end);
int virSocketAddrIsNetmask(virSocketAddrPtr netmask);
-int virSocketCheckNetmask (virSocketAddrPtr addr1, - virSocketAddrPtr addr2, - virSocketAddrPtr netmask); -int virSocketAddrMask (const virSocketAddrPtr addr, - const virSocketAddrPtr netmask, - virSocketAddrPtr network); +int virSocketAddrCheckNetmask(virSocketAddrPtr addr1, + virSocketAddrPtr addr2, + virSocketAddrPtr netmask); +int virSocketAddrMask(const virSocketAddrPtr addr, + const virSocketAddrPtr netmask, + virSocketAddrPtr network); int virSocketAddrMaskByPrefix(const virSocketAddrPtr addr, unsigned int prefix, virSocketAddrPtr network); @@ -102,7 +102,7 @@ int virSocketAddrBroadcastByPrefix(const virSocketAddrPtr addr, unsigned int prefix, virSocketAddrPtr broadcast);
-int virSocketGetNumNetmaskBits(const virSocketAddrPtr netmask); +int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask); int virSocketAddrPrefixToNetmask(unsigned int prefix, virSocketAddrPtr netmask, int family); diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 6eb5fe7..c9fb6a1 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -461,12 +461,12 @@ int virNetDevSetIPv4Addres(const char *ifname, virSocketAddr broadcast; int ret = -1;
- if (!(addrstr = virSocketFormatAddr(addr))) + if (!(addrstr = virSocketAddrFormat(addr))) goto cleanup; /* format up a broadcast address if this is IPv4 */ - if ((VIR_SOCKET_IS_FAMILY(addr, AF_INET))&& + if ((VIR_SOCKET_ADDR_IS_FAMILY(addr, AF_INET))&& ((virSocketAddrBroadcastByPrefix(addr, prefix,&broadcast)< 0) || - !(bcaststr = virSocketFormatAddr(&broadcast)))) { + !(bcaststr = virSocketAddrFormat(&broadcast)))) { goto cleanup; } cmd = virCommandNew(IP_PATH); @@ -506,7 +506,7 @@ int virNetDevClearIPv4Address(const char *ifname, char *addrstr; int ret = -1;
- if (!(addrstr = virSocketFormatAddr(addr))) + if (!(addrstr = virSocketAddrFormat(addr))) goto cleanup; cmd = virCommandNew(IP_PATH); virCommandAddArgList(cmd, "addr", "del", NULL); diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 3f3353f..3338c05 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -792,7 +792,7 @@ vboxSocketFormatAddrUtf16(vboxGlobalData *data, virSocketAddrPtr addr) char *utf8 = NULL; PRUnichar *utf16 = NULL;
- utf8 = virSocketFormatAddr(addr); + utf8 = virSocketAddrFormat(addr);
if (utf8 == NULL) { return NULL; @@ -813,7 +813,7 @@ vboxSocketParseAddrUtf16(vboxGlobalData *data, const PRUnichar *utf16,
VBOX_UTF16_TO_UTF8(utf16,&utf8);
- if (virSocketParseAddr(utf8, addr, AF_UNSPEC)< 0) { + if (virSocketAddrParse(addr, utf8, AF_UNSPEC)< 0) { goto cleanup; }
@@ -7679,8 +7679,8 @@ static virNetworkPtr vboxNetworkDefineCreateXML(virConnectPtr conn, const char * * with contigious address space from start to end */ if ((ipdef->nranges>= 1)&& - VIR_SOCKET_HAS_ADDR(&ipdef->ranges[0].start)&& - VIR_SOCKET_HAS_ADDR(&ipdef->ranges[0].end)) { + VIR_SOCKET_ADDR_VALID(&ipdef->ranges[0].start)&& + VIR_SOCKET_ADDR_VALID(&ipdef->ranges[0].end)) { IDHCPServer *dhcpServer = NULL;
data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj, @@ -7741,7 +7741,7 @@ static virNetworkPtr vboxNetworkDefineCreateXML(virConnectPtr conn, const char * }
if ((ipdef->nhosts>= 1)&& - VIR_SOCKET_HAS_ADDR(&ipdef->hosts[0].ip)) { + VIR_SOCKET_ADDR_VALID(&ipdef->hosts[0].ip)) { PRUnichar *ipAddressUtf16 = NULL; PRUnichar *networkMaskUtf16 = NULL;
diff --git a/tests/sockettest.c b/tests/sockettest.c index b9e37ab..bcc2800 100644 --- a/tests/sockettest.c +++ b/tests/sockettest.c @@ -25,7 +25,7 @@ #include<stdlib.h> #include<string.h>
-#include "network.h" +#include "virsocketaddr.h" #include "testutils.h" #include "logging.h" #include "memory.h" @@ -40,7 +40,7 @@ static int testParse(virSocketAddr *addr, const char *addrstr, int family, bool { int rc;
- rc = virSocketParseAddr(addrstr, addr, family); + rc = virSocketAddrParse(addr, addrstr, family);
if (rc< 0) return pass ? -1 : 0; @@ -52,7 +52,7 @@ static int testFormat(virSocketAddr *addr, const char *addrstr, bool pass) { char *newaddrstr;
- newaddrstr = virSocketFormatAddr(addr); + newaddrstr = virSocketAddrFormat(addr); if (!newaddrstr) return pass ? -1 : 0;
@@ -95,12 +95,12 @@ static int testRange(const char *saddrstr, const char *eaddrstr, int size, bool virSocketAddr saddr; virSocketAddr eaddr;
- if (virSocketParseAddr(saddrstr,&saddr, AF_UNSPEC)< 0) + if (virSocketAddrParse(&saddr, saddrstr, AF_UNSPEC)< 0) return -1; - if (virSocketParseAddr(eaddrstr,&eaddr, AF_UNSPEC)< 0) + if (virSocketAddrParse(&eaddr, eaddrstr, AF_UNSPEC)< 0) return -1;
- int gotsize = virSocketGetRange(&saddr,&eaddr); + int gotsize = virSocketAddrGetRange(&saddr,&eaddr); VIR_DEBUG("Size want %d vs got %d", size, gotsize); if (gotsize< 0 || gotsize != size) { return pass ? -1 : 0; @@ -129,14 +129,14 @@ static int testNetmask(const char *addr1str, const char *addr2str, virSocketAddr addr2; virSocketAddr netmask;
- if (virSocketParseAddr(addr1str,&addr1, AF_UNSPEC)< 0) + if (virSocketAddrParse(&addr1, addr1str, AF_UNSPEC)< 0) return -1; - if (virSocketParseAddr(addr2str,&addr2, AF_UNSPEC)< 0) + if (virSocketAddrParse(&addr2, addr2str, AF_UNSPEC)< 0) return -1; - if (virSocketParseAddr(netmaskstr,&netmask, AF_UNSPEC)< 0) + if (virSocketAddrParse(&netmask, netmaskstr, AF_UNSPEC)< 0) return -1;
- int ret = virSocketCheckNetmask(&addr1,&addr2,&netmask); + int ret = virSocketAddrCheckNetmask(&addr1,&addr2,&netmask);
if (ret<= 0) { return pass ? -1 : 0; diff --git a/tests/virnetsockettest.c b/tests/virnetsockettest.c index 16713e8..44d6f65 100644 --- a/tests/virnetsockettest.c +++ b/tests/virnetsockettest.c @@ -25,6 +25,7 @@ #ifdef HAVE_IFADDRS_H # include<ifaddrs.h> #endif +#include<netdb.h>
#include "testutils.h" #include "util.h" diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c index ece611a..51f75b4 100644 --- a/tests/virnettlscontexttest.c +++ b/tests/virnettlscontexttest.c @@ -33,7 +33,7 @@ #include "logging.h" #include "virfile.h" #include "command.h" -#include "network.h" +#include "virsocketaddr.h" #include "gnutls_1_0_compat.h"
#if !defined WIN32&& HAVE_LIBTASN1_H&& !defined GNUTLS_1_0_COMPAT @@ -231,7 +231,7 @@ testTLSGenerateCert(struct testTLSCertReq *req) virSocketAddr addr; char *data; int len; - if (virSocketParseAddr(req->ipaddr1,&addr, 0)< 0) { + if (virSocketAddrParse(&addr, req->ipaddr1, 0)< 0) { VIR_WARN("Cannot parse %s", req->ipaddr1); abort(); } @@ -254,7 +254,7 @@ testTLSGenerateCert(struct testTLSCertReq *req) virSocketAddr addr; char *data; int len; - if (virSocketParseAddr(req->ipaddr2,&addr, 0)< 0) { + if (virSocketAddrParse(&addr, req->ipaddr2, 0)< 0) { VIR_WARN("Cannot parse %s", req->ipaddr2); abort(); } ACK

"make check" fails to build after applying this patch: CC sockettest.o sockettest.c:28:27: fatal error: virsocketaddr.h: No such file or directory compilation terminated. On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
The socket address APIs in src/util/network.h either take the form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket address API naming * src/conf/domain_conf.c, src/conf/network_conf.c, src/conf/nwfilter_conf.c, src/network/bridge_driver.c, src/nwfilter/nwfilter_ebiptables_driver.c, src/nwfilter/nwfilter_learnipaddr.c, src/qemu/qemu_command.c, src/rpc/virnetsocket.c, src/util/dnsmasq.c, src/util/iptables.c, src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for API renaming --- src/conf/domain_conf.c | 12 ++-- src/conf/network_conf.c | 66 ++++++++++---------- src/conf/nwfilter_conf.c | 16 ++--- src/libvirt_private.syms | 18 +++--- src/network/bridge_driver.c | 42 +++++++------- src/nwfilter/nwfilter_ebiptables_driver.c | 4 +- src/nwfilter/nwfilter_learnipaddr.c | 2 +- src/qemu/qemu_command.c | 4 +- src/rpc/virnetsocket.c | 6 +- src/util/dnsmasq.c | 4 +- src/util/iptables.c | 20 +++--- src/util/network.c | 93 ++++++++++++++--------------- src/util/network.h | 46 +++++++------- src/util/virnetdev.c | 8 +- src/vbox/vbox_tmpl.c | 10 ++-- tests/sockettest.c | 20 +++--- tests/virnetsockettest.c | 1 + tests/virnettlscontexttest.c | 6 +- 18 files changed, 188 insertions(+), 190 deletions(-)
diff --git a/tests/sockettest.c b/tests/sockettest.c index b9e37ab..bcc2800 100644 --- a/tests/sockettest.c +++ b/tests/sockettest.c @@ -25,7 +25,7 @@ #include<stdlib.h> #include<string.h>
Here's the problem. util/network.[ch] split into multiple files in patch 13/33, but you've accidentally changed the name of the #include here in 09/33:
-#include "network.h" +#include "virsocketaddr.h" #include "testutils.h" #include "logging.h" #include "memory.h"
diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c index ece611a..51f75b4 100644 --- a/tests/virnettlscontexttest.c +++ b/tests/virnettlscontexttest.c @@ -33,7 +33,7 @@ #include "logging.h" #include "virfile.h" #include "command.h"
Same problem here:
-#include "network.h" +#include "virsocketaddr.h" #include "gnutls_1_0_compat.h"
ACK with those two #include lines changed back to network.h

On Tue, Nov 08, 2011 at 08:50:41PM -0500, Laine Stump wrote:
"make check" fails to build after applying this patch:
CC sockettest.o sockettest.c:28:27: fatal error: virsocketaddr.h: No such file or directory compilation terminated.
diff --git a/tests/sockettest.c b/tests/sockettest.c index b9e37ab..bcc2800 100644 --- a/tests/sockettest.c +++ b/tests/sockettest.c @@ -25,7 +25,7 @@ #include<stdlib.h> #include<string.h>
Here's the problem. util/network.[ch] split into multiple files in patch 13/33, but you've accidentally changed the name of the #include here in 09/33:
-#include "network.h" +#include "virsocketaddr.h" #include "testutils.h" #include "logging.h" #include "memory.h"
diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c index ece611a..51f75b4 100644 --- a/tests/virnettlscontexttest.c +++ b/tests/virnettlscontexttest.c @@ -33,7 +33,7 @@ #include "logging.h" #include "virfile.h" #include "command.h"
Same problem here:
-#include "network.h" +#include "virsocketaddr.h" #include "gnutls_1_0_compat.h"
ACK with those two #include lines changed back to network.h
Yes, I squashed a later patch into this one and squashed too much ! Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: "Daniel P. Berrange" <berrange@redhat.com> Rename virBandwidth to virNetDevBandwidth, and virRate to virNetDevBandwidthRate. * src/util/network.c, src/util/network.h: Rename bandwidth structs and APIs * src/conf/domain_conf.c, src/conf/domain_conf.h, src/conf/network_conf.c, src/conf/network_conf.h, src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/util/macvtap.c, src/util/macvtap.h, tools/virsh.c: Update for API changes. --- src/conf/domain_conf.c | 14 +++--- src/conf/domain_conf.h | 6 +- src/conf/network_conf.c | 12 ++-- src/conf/network_conf.h | 4 +- src/libvirt_private.syms | 14 +++--- src/lxc/lxc_driver.c | 4 +- src/network/bridge_driver.c | 17 ++----- src/qemu/qemu_command.c | 4 +- src/util/macvtap.c | 4 +- src/util/macvtap.h | 2 +- src/util/network.c | 115 +++++++++++++++++------------------------- src/util/network.h | 43 +++++++++------- tools/virsh.c | 4 +- 13 files changed, 110 insertions(+), 133 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2b235c8..ab7853d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -862,7 +862,7 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr def) break; } - virBandwidthDefFree(def->bandwidth); + virNetDevBandwidthFree(def->bandwidth); VIR_FREE(def); } @@ -921,7 +921,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def) VIR_FREE(def->filter); virNWFilterHashTableFree(def->filterparams); - virBandwidthDefFree(def->bandwidth); + virNetDevBandwidthFree(def->bandwidth); VIR_FREE(def); } @@ -3120,7 +3120,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node, bandwidth_node = virXPathNode("./bandwidth", ctxt); if (bandwidth_node && - !(actual->bandwidth = virBandwidthDefParseNode(bandwidth_node))) + !(actual->bandwidth = virNetDevBandwidthParse(bandwidth_node))) goto error; *def = actual; @@ -3278,7 +3278,7 @@ virDomainNetDefParseXML(virCapsPtr caps, if (virDomainActualNetDefParseXML(cur, ctxt, &actual) < 0) goto error; } else if (xmlStrEqual(cur->name, BAD_CAST "bandwidth")) { - if (!(def->bandwidth = virBandwidthDefParseNode(cur))) + if (!(def->bandwidth = virNetDevBandwidthParse(cur))) goto error; } } @@ -9729,7 +9729,7 @@ virDomainActualNetDefFormat(virBufferPtr buf, } virBufferAdjustIndent(buf, 8); - if (virBandwidthDefFormat(buf, def->bandwidth) < 0) + if (virNetDevBandwidthFormat(def->bandwidth, buf) < 0) goto error; virBufferAdjustIndent(buf, -8); @@ -9882,7 +9882,7 @@ virDomainNetDefFormat(virBufferPtr buf, virDomainNetInterfaceLinkStateTypeToString(def->linkstate)); virBufferAdjustIndent(buf, 6); - if (virBandwidthDefFormat(buf, def->bandwidth) < 0) + if (virNetDevBandwidthFormat(def->bandwidth, buf) < 0) return -1; virBufferAdjustIndent(buf, -6); @@ -13090,7 +13090,7 @@ virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface) return iface->data.network.actual->data.direct.virtPortProfile; } -virBandwidthPtr +virNetDevBandwidthPtr virDomainNetGetActualBandwidth(virDomainNetDefPtr iface) { if ((iface->type == VIR_DOMAIN_NET_TYPE_NETWORK) && diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 5ebb441..a3cb834 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -511,7 +511,7 @@ struct _virDomainActualNetDef { virVirtualPortProfileParamsPtr virtPortProfile; } direct; } data; - virBandwidthPtr bandwidth; + virNetDevBandwidthPtr bandwidth; }; /* Stores the virtual network interface configuration */ @@ -576,7 +576,7 @@ struct _virDomainNetDef { virDomainDeviceInfo info; char *filter; virNWFilterHashTablePtr filterparams; - virBandwidthPtr bandwidth; + virNetDevBandwidthPtr bandwidth; int linkstate; }; @@ -1797,7 +1797,7 @@ char *virDomainNetGetActualDirectDev(virDomainNetDefPtr iface); int virDomainNetGetActualDirectMode(virDomainNetDefPtr iface); virVirtualPortProfileParamsPtr virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface); -virBandwidthPtr +virNetDevBandwidthPtr virDomainNetGetActualBandwidth(virDomainNetDefPtr iface); int virDomainControllerInsert(virDomainDefPtr def, diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 8dca618..a70b5a2 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -92,7 +92,7 @@ virPortGroupDefClear(virPortGroupDefPtr def) { VIR_FREE(def->name); VIR_FREE(def->virtPortProfile); - virBandwidthDefFree(def->bandwidth); + virNetDevBandwidthFree(def->bandwidth); def->bandwidth = NULL; } @@ -171,7 +171,7 @@ void virNetworkDefFree(virNetworkDefPtr def) VIR_FREE(def->virtPortProfile); - virBandwidthDefFree(def->bandwidth); + virNetDevBandwidthFree(def->bandwidth); VIR_FREE(def); } @@ -797,7 +797,7 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def, bandwidth_node = virXPathNode("./bandwidth", ctxt); if (bandwidth_node && - !(def->bandwidth = virBandwidthDefParseNode(bandwidth_node))) { + !(def->bandwidth = virNetDevBandwidthParse(bandwidth_node))) { goto error; } @@ -863,7 +863,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) def->domain = virXPathString("string(./domain[1]/@name)", ctxt); if ((bandwidthNode = virXPathNode("./bandwidth", ctxt)) != NULL && - (def->bandwidth = virBandwidthDefParseNode(bandwidthNode)) == NULL) + (def->bandwidth = virNetDevBandwidthParse(bandwidthNode)) == NULL) goto error; /* Parse bridge information */ @@ -1269,7 +1269,7 @@ virPortGroupDefFormat(virBufferPtr buf, virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 4); virVirtualPortProfileFormat(buf, def->virtPortProfile); - virBandwidthDefFormat(buf, def->bandwidth); + virNetDevBandwidthFormat(def->bandwidth, buf); virBufferAdjustIndent(buf, -4); virBufferAddLit(buf, " </portgroup>\n"); } @@ -1344,7 +1344,7 @@ char *virNetworkDefFormat(const virNetworkDefPtr def) goto error; virBufferAdjustIndent(&buf, 2); - if (virBandwidthDefFormat(&buf, def->bandwidth) < 0) + if (virNetDevBandwidthFormat(def->bandwidth, &buf) < 0) goto error; virBufferAdjustIndent(&buf, -2); diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 869085e..2cfbe46 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -123,7 +123,7 @@ struct _virPortGroupDef { char *name; bool isDefault; virVirtualPortProfileParamsPtr virtPortProfile; - virBandwidthPtr bandwidth; + virNetDevBandwidthPtr bandwidth; }; typedef struct _virNetworkDef virNetworkDef; @@ -155,7 +155,7 @@ struct _virNetworkDef { size_t nPortGroups; virPortGroupDefPtr portGroups; - virBandwidthPtr bandwidth; + virNetDevBandwidthPtr bandwidth; }; typedef struct _virNetworkObj virNetworkObj; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fa8ac93..81de6b4 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -764,13 +764,13 @@ nlComm; # network.h -virBandwidthCopy; -virBandwidthDefFormat; -virBandwidthDefFree; -virBandwidthDefParseNode; -virBandwidthDisable; -virBandwidthEnable; -virBandwidthEqual; +virNetDevBandwidthClear; +virNetDevBandwidthCopy; +virNetDevBandwidthEqual; +virNetDevBandwidthFormat; +virNetDevBandwidthFree; +virNetDevBandwidthParse; +virNetDevBandwidthSet; virSocketAddrBroadcast; virSocketAddrBroadcastByPrefix; virSocketAddrCheckNetmask; diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 5701467..2c1154f 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1275,8 +1275,8 @@ static int lxcSetupInterfaces(virConnectPtr conn, if (vethInterfaceUpOrDown(parentVeth, 1) < 0) goto error_exit; - if (virBandwidthEnable(virDomainNetGetActualBandwidth(def->nets[i]), - def->nets[i]->ifname) < 0) { + if (virNetDevBandwidthSet(def->nets[i]->ifname, + virDomainNetGetActualBandwidth(def->nets[i])) < 0) { lxcError(VIR_ERR_INTERNAL_ERROR, _("cannot set bandwidth limits on %s"), def->nets[i]->ifname); diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index bd8f0b3..d213642 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -1778,7 +1778,7 @@ networkStartNetworkVirtual(struct network_driver *driver, if (v6present && networkStartRadvd(network) < 0) goto err4; - if (virBandwidthEnable(network->def->bandwidth, network->def->bridge) < 0) { + if (virNetDevBandwidthSet(network->def->bridge, network->def->bandwidth) < 0) { networkReportError(VIR_ERR_INTERNAL_ERROR, _("cannot set bandwidth limits on %s"), network->def->bridge); @@ -1790,10 +1790,7 @@ networkStartNetworkVirtual(struct network_driver *driver, return 0; err5: - if (virBandwidthDisable(network->def->bridge, true) < 0) { - VIR_WARN("Failed to disable QoS on %s", - network->def->bridge); - } + ignore_value(virNetDevBandwidthClear(network->def->bridge)); err4: if (!save_err) @@ -1836,10 +1833,7 @@ networkStartNetworkVirtual(struct network_driver *driver, static int networkShutdownNetworkVirtual(struct network_driver *driver, virNetworkObjPtr network) { - if (virBandwidthDisable(network->def->bridge, true) < 0) { - VIR_WARN("Failed to disable QoS on %s", - network->def->name); - } + ignore_value(virNetDevBandwidthClear(network->def->bridge)); if (network->radvdPid > 0) { char *radvdpidbase; @@ -2733,10 +2727,9 @@ networkAllocateActualDevice(virDomainNetDefPtr iface) goto cleanup; } - if (virBandwidthCopy(&iface->data.network.actual->bandwidth, - portgroup->bandwidth) < 0) { + if (virNetDevBandwidthCopy(&iface->data.network.actual->bandwidth, + portgroup->bandwidth) < 0) goto cleanup; - } } if ((netdef->forwardType == VIR_NETWORK_FORWARD_NONE) || diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index fba9ace..11ebb69 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -298,8 +298,8 @@ qemuNetworkIfaceConnect(virDomainDefPtr def, } if (tapfd >= 0 && - virBandwidthEnable(virDomainNetGetActualBandwidth(net), - net->ifname) < 0) { + virNetDevBandwidthSet(net->ifname, + virDomainNetGetActualBandwidth(net)) < 0) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("cannot set bandwidth limits on %s"), net->ifname); diff --git a/src/util/macvtap.c b/src/util/macvtap.c index 54dc670..cb13d2b 100644 --- a/src/util/macvtap.c +++ b/src/util/macvtap.c @@ -271,7 +271,7 @@ openMacvtapTap(const char *tgifname, char **res_ifname, enum virVMOperationType vmOp, char *stateDir, - virBandwidthPtr bandwidth) + virNetDevBandwidthPtr bandwidth) { const char *type = "macvtap"; int c, rc; @@ -364,7 +364,7 @@ create_name: } else goto disassociate_exit; - if (virBandwidthEnable(bandwidth, cr_ifname) < 0) { + if (virNetDevBandwidthSet(cr_ifname, bandwidth) < 0) { macvtapError(VIR_ERR_INTERNAL_ERROR, _("cannot set bandwidth limits on %s"), cr_ifname); diff --git a/src/util/macvtap.h b/src/util/macvtap.h index 2b2d835..330e5e2 100644 --- a/src/util/macvtap.h +++ b/src/util/macvtap.h @@ -63,7 +63,7 @@ int openMacvtapTap(const char *ifname, char **res_ifname, enum virVMOperationType vmop, char *stateDir, - virBandwidthPtr bandwidth); + virNetDevBandwidthPtr bandwidth); void delMacvtap(const char *ifname, const unsigned char *macaddress, diff --git a/src/util/network.c b/src/util/network.c index 087df22..1ecbce3 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -17,6 +17,7 @@ #include "util.h" #include "virterror_internal.h" #include "command.h" +#include "ignore-value.h" #define VIR_FROM_THIS VIR_FROM_NONE #define virSocketError(code, ...) \ @@ -918,7 +919,7 @@ virVirtualPortProfileFormat(virBufferPtr buf, } static int -virBandwidthParseChildDefNode(xmlNodePtr node, virRatePtr rate) +virNetDevBandwidthParseRate(xmlNodePtr node, virNetDevBandwidthRatePtr rate) { int ret = -1; char *average = NULL; @@ -973,17 +974,17 @@ cleanup: } /** - * virBandwidthDefParseNode: + * virNetDevBandwidthParse: * @node: XML node * * Parse bandwidth XML and return pointer to structure * * Returns !NULL on success, NULL on error. */ -virBandwidthPtr -virBandwidthDefParseNode(xmlNodePtr node) +virNetDevBandwidthPtr +virNetDevBandwidthParse(xmlNodePtr node) { - virBandwidthPtr def = NULL; + virNetDevBandwidthPtr def = NULL; xmlNodePtr cur = node->children; xmlNodePtr in = NULL, out = NULL; @@ -1028,7 +1029,7 @@ virBandwidthDefParseNode(xmlNodePtr node) goto error; } - if (virBandwidthParseChildDefNode(in, def->in) < 0) { + if (virNetDevBandwidthParseRate(in, def->in) < 0) { /* helper reported error for us */ goto error; } @@ -1040,7 +1041,7 @@ virBandwidthDefParseNode(xmlNodePtr node) goto error; } - if (virBandwidthParseChildDefNode(out, def->out) < 0) { + if (virNetDevBandwidthParseRate(out, def->out) < 0) { /* helper reported error for us */ goto error; } @@ -1049,12 +1050,12 @@ virBandwidthDefParseNode(xmlNodePtr node) return def; error: - virBandwidthDefFree(def); + virNetDevBandwidthFree(def); return NULL; } void -virBandwidthDefFree(virBandwidthPtr def) +virNetDevBandwidthFree(virNetDevBandwidthPtr def) { if (!def) return; @@ -1065,9 +1066,9 @@ virBandwidthDefFree(virBandwidthPtr def) } static int -virBandwidthChildDefFormat(virBufferPtr buf, - virRatePtr def, - const char *elem_name) +virNetDevBandwidthRateFormat(virNetDevBandwidthRatePtr def, + virBufferPtr buf, + const char *elem_name) { if (!buf || !elem_name) return -1; @@ -1090,9 +1091,9 @@ virBandwidthChildDefFormat(virBufferPtr buf, } /** - * virBandwidthDefFormat: - * @buf: Buffer to print to + * virNetDevBandwidthDefFormat: * @def: Data source + * @buf: Buffer to print to * * Formats bandwidth and prepend each line with @indent. * @buf may use auto-indentation. @@ -1100,8 +1101,7 @@ virBandwidthChildDefFormat(virBufferPtr buf, * Returns 0 on success, else -1. */ int -virBandwidthDefFormat(virBufferPtr buf, - virBandwidthPtr def) +virNetDevBandwidthFormat(virNetDevBandwidthPtr def, virBufferPtr buf) { int ret = -1; @@ -1114,8 +1114,8 @@ virBandwidthDefFormat(virBufferPtr buf, } virBufferAddLit(buf, "<bandwidth>\n"); - if (virBandwidthChildDefFormat(buf, def->in, "inbound") < 0 || - virBandwidthChildDefFormat(buf, def->out, "outbound") < 0) + if (virNetDevBandwidthRateFormat(def->in, buf, "inbound") < 0 || + virNetDevBandwidthRateFormat(def->out, buf, "outbound") < 0) goto cleanup; virBufferAddLit(buf, "</bandwidth>\n"); @@ -1126,9 +1126,9 @@ cleanup: } /** - * virBandwidthEnable: - * @bandwidth: rates to set - * @iface: on which interface + * virNetDevBandwidthSet: + * @ifname: on which interface + * @bandwidth: rates to set (may be NULL) * * This function enables QoS on specified interface * and set given traffic limits for both, incoming @@ -1138,8 +1138,8 @@ cleanup: * Return 0 on success, -1 otherwise. */ int -virBandwidthEnable(virBandwidthPtr bandwidth, - const char *iface) +virNetDevBandwidthSet(const char *ifname, + virNetDevBandwidthPtr bandwidth) { int ret = -1; virCommandPtr cmd = NULL; @@ -1147,17 +1147,13 @@ virBandwidthEnable(virBandwidthPtr bandwidth, char *peak = NULL; char *burst = NULL; - if (!iface) - return -1; - if (!bandwidth) { /* nothing to be enabled */ ret = 0; goto cleanup; } - if (virBandwidthDisable(iface, true) < 0) - goto cleanup; + ignore_value(virNetDevBandwidthClear(ifname)); if (bandwidth->in) { if (virAsprintf(&average, "%llukbps", bandwidth->in->average) < 0) @@ -1170,14 +1166,14 @@ virBandwidthEnable(virBandwidthPtr bandwidth, goto cleanup; cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "qdisc", "add", "dev", iface, "root", + virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, "root", "handle", "1:", "htb", "default", "1", NULL); if (virCommandRun(cmd, NULL) < 0) goto cleanup; virCommandFree(cmd); cmd = virCommandNew(TC); - virCommandAddArgList(cmd,"class", "add", "dev", iface, "parent", + virCommandAddArgList(cmd,"class", "add", "dev", ifname, "parent", "1:", "classid", "1:1", "htb", NULL); virCommandAddArgList(cmd, "rate", average, NULL); @@ -1191,7 +1187,7 @@ virBandwidthEnable(virBandwidthPtr bandwidth, virCommandFree(cmd); cmd = virCommandNew(TC); - virCommandAddArgList(cmd,"filter", "add", "dev", iface, "parent", + virCommandAddArgList(cmd,"filter", "add", "dev", ifname, "parent", "1:0", "protocol", "ip", "handle", "1", "fw", "flowid", "1", NULL); @@ -1212,7 +1208,7 @@ virBandwidthEnable(virBandwidthPtr bandwidth, virCommandFree(cmd); cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "qdisc", "add", "dev", iface, + virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, "ingress", NULL); if (virCommandRun(cmd, NULL) < 0) @@ -1220,7 +1216,7 @@ virBandwidthEnable(virBandwidthPtr bandwidth, virCommandFree(cmd); cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "filter", "add", "dev", iface, "parent", + virCommandAddArgList(cmd, "filter", "add", "dev", ifname, "parent", "ffff:", "protocol", "ip", "u32", "match", "ip", "src", "0.0.0.0/0", "police", "rate", average, "burst", burst, "mtu", burst, "drop", "flowid", @@ -1241,9 +1237,8 @@ cleanup: } /** - * virBandwidthDisable: - * @iface: on which interface - * @may_fail: should be unsuccessful disable considered fatal? + * virNetDevBandwidthClear: + * @ifname: on which interface * * This function tries to disable QoS on specified interface * by deleting root and ingress qdisc. However, this may fail @@ -1252,59 +1247,43 @@ cleanup: * Return 0 on success, -1 otherwise. */ int -virBandwidthDisable(const char *iface, - bool may_fail) +virNetDevBandwidthClear(const char *ifname) { - int ret = -1; - int status; + int ret = 0; virCommandPtr cmd = NULL; - if (!iface) - return -1; - cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "qdisc", "del", "dev", iface, "root", NULL); + virCommandAddArgList(cmd, "qdisc", "del", "dev", ifname, "root", NULL); - if ((virCommandRun(cmd, &status) < 0) || - (!may_fail && status)) - goto cleanup; + if (virCommandRun(cmd, NULL) < 0) + ret = -1; virCommandFree(cmd); cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "qdisc", "del", "dev", iface, "ingress", NULL); - - if ((virCommandRun(cmd, &status) < 0) || - (!may_fail && status)) - goto cleanup; - - ret = 0; + virCommandAddArgList(cmd, "qdisc", "del", "dev", ifname, "ingress", NULL); -cleanup: + if (virCommandRun(cmd, NULL) < 0) + ret = -1; virCommandFree(cmd); + return ret; } /* - * virBandwidthCopy: + * virNetDevBandwidthCopy: * @dest: destination - * @src: source + * @src: source (may be NULL) * * Returns -1 on OOM error (which gets reported), * 0 otherwise. */ int -virBandwidthCopy(virBandwidthPtr *dest, - const virBandwidthPtr src) +virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest, + const virNetDevBandwidthPtr src) { int ret = -1; - if (!dest) { - virSocketError(VIR_ERR_INVALID_ARG, "%s", - _("invalid argument supplied")); - return -1; - } - *dest = NULL; if (!src) { /* nothing to be copied */ @@ -1337,15 +1316,15 @@ virBandwidthCopy(virBandwidthPtr *dest, cleanup: if (ret < 0) { - virBandwidthDefFree(*dest); + virNetDevBandwidthFree(*dest); *dest = NULL; } return ret; } bool -virBandwidthEqual(virBandwidthPtr a, - virBandwidthPtr b) +virNetDevBandwidthEqual(virNetDevBandwidthPtr a, + virNetDevBandwidthPtr b) { if (!a && !b) return true; diff --git a/src/util/network.h b/src/util/network.h index a2c68e9..1f3a53f 100644 --- a/src/util/network.h +++ b/src/util/network.h @@ -48,19 +48,19 @@ typedef struct { typedef virSocketAddr *virSocketAddrPtr; -typedef struct { +typedef struct _virNetDevBandwidthRate virNetDevBandwidthRate; +typedef virNetDevBandwidthRate *virNetDevBandwidthRatePtr; +struct _virNetDevBandwidthRate { unsigned long long average; /* kbytes/s */ unsigned long long peak; /* kbytes/s */ unsigned long long burst; /* kbytes */ -} virRate; - -typedef virRate *virRatePtr; - -typedef struct { - virRatePtr in, out; -} virBandwidth; +}; -typedef virBandwidth *virBandwidthPtr; +typedef struct _virNetDevBandwidth virNetDevBandwidth; +typedef virNetDevBandwidth *virNetDevBandwidthPtr; +struct _virNetDevBandwidth { + virNetDevBandwidthRatePtr in, out; +}; int virSocketAddrParse(virSocketAddrPtr addr, const char *val, @@ -152,16 +152,21 @@ virVirtualPortProfileFormat(virBufferPtr buf, bool virVirtualPortProfileEqual(virVirtualPortProfileParamsPtr a, virVirtualPortProfileParamsPtr b); -virBandwidthPtr virBandwidthDefParseNode(xmlNodePtr node); -void virBandwidthDefFree(virBandwidthPtr def); -int virBandwidthDefFormat(virBufferPtr buf, - virBandwidthPtr def); - -int virBandwidthEnable(virBandwidthPtr bandwidth, const char *iface); -int virBandwidthDisable(const char *iface, bool may_fail); -int virBandwidthCopy(virBandwidthPtr *dest, const virBandwidthPtr src); - -bool virBandwidthEqual(virBandwidthPtr a, virBandwidthPtr b); +virNetDevBandwidthPtr virNetDevBandwidthParse(xmlNodePtr node) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +void virNetDevBandwidthFree(virNetDevBandwidthPtr def); +int virNetDevBandwidthFormat(virNetDevBandwidthPtr def, + virBufferPtr buf) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +int virNetDevBandwidthSet(const char *ifname, virNetDevBandwidthPtr bandwidth) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBandwidthClear(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest, const virNetDevBandwidthPtr src) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +bool virNetDevBandwidthEqual(virNetDevBandwidthPtr a, virNetDevBandwidthPtr b); #endif /* __VIR_NETWORK_H__ */ diff --git a/tools/virsh.c b/tools/virsh.c index 5544a41..d8261f7 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -11250,7 +11250,7 @@ static const vshCmdOptDef opts_attach_interface[] = { /* parse inbound and outbound which are in the format of * 'average,peak,burst', in which peak and burst are optional, * thus 'average,,burst' and 'average,peak' are also legal. */ -static int parseRateStr(const char *rateStr, virRatePtr rate) +static int parseRateStr(const char *rateStr, virNetDevBandwidthRatePtr rate) { const char *average = NULL; char *peak = NULL, *burst = NULL; @@ -11289,7 +11289,7 @@ cmdAttachInterface(vshControl *ctl, const vshCmd *cmd) const char *mac = NULL, *target = NULL, *script = NULL, *type = NULL, *source = NULL, *model = NULL, *inboundStr = NULL, *outboundStr = NULL; - virRate inbound, outbound; + virNetDevBandwidthRate inbound, outbound; int typ; int ret; bool functionReturn = false; -- 1.7.6.4

On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
Rename virBandwidth to virNetDevBandwidth, and virRate to virNetDevBandwidthRate.
* src/util/network.c, src/util/network.h: Rename bandwidth structs and APIs * src/conf/domain_conf.c, src/conf/domain_conf.h, src/conf/network_conf.c, src/conf/network_conf.h, src/lxc/lxc_driver.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/util/macvtap.c, src/util/macvtap.h, tools/virsh.c: Update for API changes. --- src/conf/domain_conf.c | 14 +++--- src/conf/domain_conf.h | 6 +- src/conf/network_conf.c | 12 ++-- src/conf/network_conf.h | 4 +- src/libvirt_private.syms | 14 +++--- src/lxc/lxc_driver.c | 4 +- src/network/bridge_driver.c | 17 ++----- src/qemu/qemu_command.c | 4 +- src/util/macvtap.c | 4 +- src/util/macvtap.h | 2 +- src/util/network.c | 115 +++++++++++++++++------------------------- src/util/network.h | 43 +++++++++------- tools/virsh.c | 4 +- 13 files changed, 110 insertions(+), 133 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2b235c8..ab7853d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -862,7 +862,7 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr def) break; }
- virBandwidthDefFree(def->bandwidth); + virNetDevBandwidthFree(def->bandwidth);
VIR_FREE(def); } @@ -921,7 +921,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def) VIR_FREE(def->filter); virNWFilterHashTableFree(def->filterparams);
- virBandwidthDefFree(def->bandwidth); + virNetDevBandwidthFree(def->bandwidth);
VIR_FREE(def); } @@ -3120,7 +3120,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
bandwidth_node = virXPathNode("./bandwidth", ctxt); if (bandwidth_node&& - !(actual->bandwidth = virBandwidthDefParseNode(bandwidth_node))) + !(actual->bandwidth = virNetDevBandwidthParse(bandwidth_node))) goto error;
*def = actual; @@ -3278,7 +3278,7 @@ virDomainNetDefParseXML(virCapsPtr caps, if (virDomainActualNetDefParseXML(cur, ctxt,&actual)< 0) goto error; } else if (xmlStrEqual(cur->name, BAD_CAST "bandwidth")) { - if (!(def->bandwidth = virBandwidthDefParseNode(cur))) + if (!(def->bandwidth = virNetDevBandwidthParse(cur))) goto error; } } @@ -9729,7 +9729,7 @@ virDomainActualNetDefFormat(virBufferPtr buf, }
virBufferAdjustIndent(buf, 8); - if (virBandwidthDefFormat(buf, def->bandwidth)< 0) + if (virNetDevBandwidthFormat(def->bandwidth, buf)< 0) goto error; virBufferAdjustIndent(buf, -8);
@@ -9882,7 +9882,7 @@ virDomainNetDefFormat(virBufferPtr buf, virDomainNetInterfaceLinkStateTypeToString(def->linkstate));
virBufferAdjustIndent(buf, 6); - if (virBandwidthDefFormat(buf, def->bandwidth)< 0) + if (virNetDevBandwidthFormat(def->bandwidth, buf)< 0) return -1; virBufferAdjustIndent(buf, -6);
@@ -13090,7 +13090,7 @@ virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface) return iface->data.network.actual->data.direct.virtPortProfile; }
-virBandwidthPtr +virNetDevBandwidthPtr virDomainNetGetActualBandwidth(virDomainNetDefPtr iface) { if ((iface->type == VIR_DOMAIN_NET_TYPE_NETWORK)&& diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 5ebb441..a3cb834 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -511,7 +511,7 @@ struct _virDomainActualNetDef { virVirtualPortProfileParamsPtr virtPortProfile; } direct; } data; - virBandwidthPtr bandwidth; + virNetDevBandwidthPtr bandwidth; };
/* Stores the virtual network interface configuration */ @@ -576,7 +576,7 @@ struct _virDomainNetDef { virDomainDeviceInfo info; char *filter; virNWFilterHashTablePtr filterparams; - virBandwidthPtr bandwidth; + virNetDevBandwidthPtr bandwidth; int linkstate; };
@@ -1797,7 +1797,7 @@ char *virDomainNetGetActualDirectDev(virDomainNetDefPtr iface); int virDomainNetGetActualDirectMode(virDomainNetDefPtr iface); virVirtualPortProfileParamsPtr virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface); -virBandwidthPtr +virNetDevBandwidthPtr virDomainNetGetActualBandwidth(virDomainNetDefPtr iface);
int virDomainControllerInsert(virDomainDefPtr def, diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 8dca618..a70b5a2 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -92,7 +92,7 @@ virPortGroupDefClear(virPortGroupDefPtr def) { VIR_FREE(def->name); VIR_FREE(def->virtPortProfile); - virBandwidthDefFree(def->bandwidth); + virNetDevBandwidthFree(def->bandwidth); def->bandwidth = NULL; }
@@ -171,7 +171,7 @@ void virNetworkDefFree(virNetworkDefPtr def)
VIR_FREE(def->virtPortProfile);
- virBandwidthDefFree(def->bandwidth); + virNetDevBandwidthFree(def->bandwidth);
VIR_FREE(def); } @@ -797,7 +797,7 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
bandwidth_node = virXPathNode("./bandwidth", ctxt); if (bandwidth_node&& - !(def->bandwidth = virBandwidthDefParseNode(bandwidth_node))) { + !(def->bandwidth = virNetDevBandwidthParse(bandwidth_node))) { goto error; }
@@ -863,7 +863,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) def->domain = virXPathString("string(./domain[1]/@name)", ctxt);
if ((bandwidthNode = virXPathNode("./bandwidth", ctxt)) != NULL&& - (def->bandwidth = virBandwidthDefParseNode(bandwidthNode)) == NULL) + (def->bandwidth = virNetDevBandwidthParse(bandwidthNode)) == NULL) goto error;
/* Parse bridge information */ @@ -1269,7 +1269,7 @@ virPortGroupDefFormat(virBufferPtr buf, virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 4); virVirtualPortProfileFormat(buf, def->virtPortProfile); - virBandwidthDefFormat(buf, def->bandwidth); + virNetDevBandwidthFormat(def->bandwidth, buf); virBufferAdjustIndent(buf, -4); virBufferAddLit(buf, "</portgroup>\n"); } @@ -1344,7 +1344,7 @@ char *virNetworkDefFormat(const virNetworkDefPtr def) goto error;
virBufferAdjustIndent(&buf, 2); - if (virBandwidthDefFormat(&buf, def->bandwidth)< 0) + if (virNetDevBandwidthFormat(def->bandwidth,&buf)< 0) goto error; virBufferAdjustIndent(&buf, -2);
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 869085e..2cfbe46 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -123,7 +123,7 @@ struct _virPortGroupDef { char *name; bool isDefault; virVirtualPortProfileParamsPtr virtPortProfile; - virBandwidthPtr bandwidth; + virNetDevBandwidthPtr bandwidth; };
typedef struct _virNetworkDef virNetworkDef; @@ -155,7 +155,7 @@ struct _virNetworkDef {
size_t nPortGroups; virPortGroupDefPtr portGroups; - virBandwidthPtr bandwidth; + virNetDevBandwidthPtr bandwidth; };
typedef struct _virNetworkObj virNetworkObj; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fa8ac93..81de6b4 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -764,13 +764,13 @@ nlComm;
# network.h -virBandwidthCopy; -virBandwidthDefFormat; -virBandwidthDefFree; -virBandwidthDefParseNode; -virBandwidthDisable; -virBandwidthEnable; -virBandwidthEqual; +virNetDevBandwidthClear; +virNetDevBandwidthCopy; +virNetDevBandwidthEqual; +virNetDevBandwidthFormat; +virNetDevBandwidthFree; +virNetDevBandwidthParse; +virNetDevBandwidthSet; virSocketAddrBroadcast; virSocketAddrBroadcastByPrefix; virSocketAddrCheckNetmask; diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 5701467..2c1154f 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1275,8 +1275,8 @@ static int lxcSetupInterfaces(virConnectPtr conn, if (vethInterfaceUpOrDown(parentVeth, 1)< 0) goto error_exit;
- if (virBandwidthEnable(virDomainNetGetActualBandwidth(def->nets[i]), - def->nets[i]->ifname)< 0) { + if (virNetDevBandwidthSet(def->nets[i]->ifname, + virDomainNetGetActualBandwidth(def->nets[i]))< 0) { lxcError(VIR_ERR_INTERNAL_ERROR, _("cannot set bandwidth limits on %s"), def->nets[i]->ifname); diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index bd8f0b3..d213642 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -1778,7 +1778,7 @@ networkStartNetworkVirtual(struct network_driver *driver, if (v6present&& networkStartRadvd(network)< 0) goto err4;
- if (virBandwidthEnable(network->def->bandwidth, network->def->bridge)< 0) { + if (virNetDevBandwidthSet(network->def->bridge, network->def->bandwidth)< 0) { networkReportError(VIR_ERR_INTERNAL_ERROR, _("cannot set bandwidth limits on %s"), network->def->bridge); @@ -1790,10 +1790,7 @@ networkStartNetworkVirtual(struct network_driver *driver, return 0;
err5: - if (virBandwidthDisable(network->def->bridge, true)< 0) { - VIR_WARN("Failed to disable QoS on %s", - network->def->bridge); - } + ignore_value(virNetDevBandwidthClear(network->def->bridge));
err4: if (!save_err) @@ -1836,10 +1833,7 @@ networkStartNetworkVirtual(struct network_driver *driver, static int networkShutdownNetworkVirtual(struct network_driver *driver, virNetworkObjPtr network) { - if (virBandwidthDisable(network->def->bridge, true)< 0) { - VIR_WARN("Failed to disable QoS on %s", - network->def->name); - } + ignore_value(virNetDevBandwidthClear(network->def->bridge));
if (network->radvdPid> 0) { char *radvdpidbase; @@ -2733,10 +2727,9 @@ networkAllocateActualDevice(virDomainNetDefPtr iface) goto cleanup; }
- if (virBandwidthCopy(&iface->data.network.actual->bandwidth, - portgroup->bandwidth)< 0) { + if (virNetDevBandwidthCopy(&iface->data.network.actual->bandwidth, + portgroup->bandwidth)< 0) goto cleanup; - } }
if ((netdef->forwardType == VIR_NETWORK_FORWARD_NONE) || diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index fba9ace..11ebb69 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -298,8 +298,8 @@ qemuNetworkIfaceConnect(virDomainDefPtr def, }
if (tapfd>= 0&& - virBandwidthEnable(virDomainNetGetActualBandwidth(net), - net->ifname)< 0) { + virNetDevBandwidthSet(net->ifname, + virDomainNetGetActualBandwidth(net))< 0) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("cannot set bandwidth limits on %s"), net->ifname); diff --git a/src/util/macvtap.c b/src/util/macvtap.c index 54dc670..cb13d2b 100644 --- a/src/util/macvtap.c +++ b/src/util/macvtap.c @@ -271,7 +271,7 @@ openMacvtapTap(const char *tgifname, char **res_ifname, enum virVMOperationType vmOp, char *stateDir, - virBandwidthPtr bandwidth) + virNetDevBandwidthPtr bandwidth) { const char *type = "macvtap"; int c, rc; @@ -364,7 +364,7 @@ create_name: } else goto disassociate_exit;
- if (virBandwidthEnable(bandwidth, cr_ifname)< 0) { + if (virNetDevBandwidthSet(cr_ifname, bandwidth)< 0) { macvtapError(VIR_ERR_INTERNAL_ERROR, _("cannot set bandwidth limits on %s"), cr_ifname); diff --git a/src/util/macvtap.h b/src/util/macvtap.h index 2b2d835..330e5e2 100644 --- a/src/util/macvtap.h +++ b/src/util/macvtap.h @@ -63,7 +63,7 @@ int openMacvtapTap(const char *ifname, char **res_ifname, enum virVMOperationType vmop, char *stateDir, - virBandwidthPtr bandwidth); + virNetDevBandwidthPtr bandwidth);
void delMacvtap(const char *ifname, const unsigned char *macaddress, diff --git a/src/util/network.c b/src/util/network.c index 087df22..1ecbce3 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -17,6 +17,7 @@ #include "util.h" #include "virterror_internal.h" #include "command.h" +#include "ignore-value.h"
#define VIR_FROM_THIS VIR_FROM_NONE #define virSocketError(code, ...) \ @@ -918,7 +919,7 @@ virVirtualPortProfileFormat(virBufferPtr buf, }
static int -virBandwidthParseChildDefNode(xmlNodePtr node, virRatePtr rate) +virNetDevBandwidthParseRate(xmlNodePtr node, virNetDevBandwidthRatePtr rate) { int ret = -1; char *average = NULL; @@ -973,17 +974,17 @@ cleanup: }
/** - * virBandwidthDefParseNode: + * virNetDevBandwidthParse: * @node: XML node * * Parse bandwidth XML and return pointer to structure * * Returns !NULL on success, NULL on error. */ -virBandwidthPtr -virBandwidthDefParseNode(xmlNodePtr node) +virNetDevBandwidthPtr +virNetDevBandwidthParse(xmlNodePtr node) { - virBandwidthPtr def = NULL; + virNetDevBandwidthPtr def = NULL; xmlNodePtr cur = node->children; xmlNodePtr in = NULL, out = NULL;
@@ -1028,7 +1029,7 @@ virBandwidthDefParseNode(xmlNodePtr node) goto error; }
- if (virBandwidthParseChildDefNode(in, def->in)< 0) { + if (virNetDevBandwidthParseRate(in, def->in)< 0) { /* helper reported error for us */ goto error; } @@ -1040,7 +1041,7 @@ virBandwidthDefParseNode(xmlNodePtr node) goto error; }
- if (virBandwidthParseChildDefNode(out, def->out)< 0) { + if (virNetDevBandwidthParseRate(out, def->out)< 0) { /* helper reported error for us */ goto error; } @@ -1049,12 +1050,12 @@ virBandwidthDefParseNode(xmlNodePtr node) return def;
error: - virBandwidthDefFree(def); + virNetDevBandwidthFree(def); return NULL; }
void -virBandwidthDefFree(virBandwidthPtr def) +virNetDevBandwidthFree(virNetDevBandwidthPtr def) { if (!def) return; @@ -1065,9 +1066,9 @@ virBandwidthDefFree(virBandwidthPtr def) }
static int -virBandwidthChildDefFormat(virBufferPtr buf, - virRatePtr def, - const char *elem_name) +virNetDevBandwidthRateFormat(virNetDevBandwidthRatePtr def, + virBufferPtr buf, + const char *elem_name) { if (!buf || !elem_name) return -1; @@ -1090,9 +1091,9 @@ virBandwidthChildDefFormat(virBufferPtr buf, }
/** - * virBandwidthDefFormat: - * @buf: Buffer to print to + * virNetDevBandwidthDefFormat: * @def: Data source + * @buf: Buffer to print to * * Formats bandwidth and prepend each line with @indent. * @buf may use auto-indentation. @@ -1100,8 +1101,7 @@ virBandwidthChildDefFormat(virBufferPtr buf, * Returns 0 on success, else -1. */ int -virBandwidthDefFormat(virBufferPtr buf, - virBandwidthPtr def) +virNetDevBandwidthFormat(virNetDevBandwidthPtr def, virBufferPtr buf) { int ret = -1;
@@ -1114,8 +1114,8 @@ virBandwidthDefFormat(virBufferPtr buf, }
virBufferAddLit(buf, "<bandwidth>\n"); - if (virBandwidthChildDefFormat(buf, def->in, "inbound")< 0 || - virBandwidthChildDefFormat(buf, def->out, "outbound")< 0) + if (virNetDevBandwidthRateFormat(def->in, buf, "inbound")< 0 || + virNetDevBandwidthRateFormat(def->out, buf, "outbound")< 0) goto cleanup; virBufferAddLit(buf, "</bandwidth>\n");
@@ -1126,9 +1126,9 @@ cleanup: }
/** - * virBandwidthEnable: - * @bandwidth: rates to set - * @iface: on which interface + * virNetDevBandwidthSet: + * @ifname: on which interface + * @bandwidth: rates to set (may be NULL) * * This function enables QoS on specified interface * and set given traffic limits for both, incoming @@ -1138,8 +1138,8 @@ cleanup: * Return 0 on success, -1 otherwise. */ int -virBandwidthEnable(virBandwidthPtr bandwidth, - const char *iface) +virNetDevBandwidthSet(const char *ifname, + virNetDevBandwidthPtr bandwidth) { int ret = -1; virCommandPtr cmd = NULL; @@ -1147,17 +1147,13 @@ virBandwidthEnable(virBandwidthPtr bandwidth, char *peak = NULL; char *burst = NULL;
- if (!iface) - return -1; - if (!bandwidth) { /* nothing to be enabled */ ret = 0; goto cleanup; }
- if (virBandwidthDisable(iface, true)< 0) - goto cleanup; + ignore_value(virNetDevBandwidthClear(ifname));
if (bandwidth->in) { if (virAsprintf(&average, "%llukbps", bandwidth->in->average)< 0) @@ -1170,14 +1166,14 @@ virBandwidthEnable(virBandwidthPtr bandwidth, goto cleanup;
cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "qdisc", "add", "dev", iface, "root", + virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, "root", "handle", "1:", "htb", "default", "1", NULL); if (virCommandRun(cmd, NULL)< 0) goto cleanup;
virCommandFree(cmd); cmd = virCommandNew(TC); - virCommandAddArgList(cmd,"class", "add", "dev", iface, "parent", + virCommandAddArgList(cmd,"class", "add", "dev", ifname, "parent", "1:", "classid", "1:1", "htb", NULL); virCommandAddArgList(cmd, "rate", average, NULL);
@@ -1191,7 +1187,7 @@ virBandwidthEnable(virBandwidthPtr bandwidth,
virCommandFree(cmd); cmd = virCommandNew(TC); - virCommandAddArgList(cmd,"filter", "add", "dev", iface, "parent", + virCommandAddArgList(cmd,"filter", "add", "dev", ifname, "parent", "1:0", "protocol", "ip", "handle", "1", "fw", "flowid", "1", NULL);
@@ -1212,7 +1208,7 @@ virBandwidthEnable(virBandwidthPtr bandwidth,
virCommandFree(cmd); cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "qdisc", "add", "dev", iface, + virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, "ingress", NULL);
if (virCommandRun(cmd, NULL)< 0) @@ -1220,7 +1216,7 @@ virBandwidthEnable(virBandwidthPtr bandwidth,
virCommandFree(cmd); cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "filter", "add", "dev", iface, "parent", + virCommandAddArgList(cmd, "filter", "add", "dev", ifname, "parent", "ffff:", "protocol", "ip", "u32", "match", "ip", "src", "0.0.0.0/0", "police", "rate", average, "burst", burst, "mtu", burst, "drop", "flowid", @@ -1241,9 +1237,8 @@ cleanup: }
/** - * virBandwidthDisable: - * @iface: on which interface - * @may_fail: should be unsuccessful disable considered fatal? + * virNetDevBandwidthClear: + * @ifname: on which interface * * This function tries to disable QoS on specified interface * by deleting root and ingress qdisc. However, this may fail @@ -1252,59 +1247,43 @@ cleanup: * Return 0 on success, -1 otherwise. */ int -virBandwidthDisable(const char *iface, - bool may_fail) +virNetDevBandwidthClear(const char *ifname) { - int ret = -1; - int status; + int ret = 0; virCommandPtr cmd = NULL;
- if (!iface) - return -1; - cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "qdisc", "del", "dev", iface, "root", NULL); + virCommandAddArgList(cmd, "qdisc", "del", "dev", ifname, "root", NULL);
- if ((virCommandRun(cmd,&status)< 0) || - (!may_fail&& status)) - goto cleanup; + if (virCommandRun(cmd, NULL)< 0) + ret = -1;
virCommandFree(cmd);
cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "qdisc", "del", "dev", iface, "ingress", NULL); - - if ((virCommandRun(cmd,&status)< 0) || - (!may_fail&& status)) - goto cleanup; - - ret = 0; + virCommandAddArgList(cmd, "qdisc", "del", "dev", ifname, "ingress", NULL);
-cleanup: + if (virCommandRun(cmd, NULL)< 0) + ret = -1; virCommandFree(cmd); + return ret; }
/* - * virBandwidthCopy: + * virNetDevBandwidthCopy: * @dest: destination - * @src: source + * @src: source (may be NULL) * * Returns -1 on OOM error (which gets reported), * 0 otherwise. */ int -virBandwidthCopy(virBandwidthPtr *dest, - const virBandwidthPtr src) +virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest, + const virNetDevBandwidthPtr src) { int ret = -1;
- if (!dest) { - virSocketError(VIR_ERR_INVALID_ARG, "%s", - _("invalid argument supplied")); - return -1; - } - *dest = NULL; if (!src) { /* nothing to be copied */ @@ -1337,15 +1316,15 @@ virBandwidthCopy(virBandwidthPtr *dest,
cleanup: if (ret< 0) { - virBandwidthDefFree(*dest); + virNetDevBandwidthFree(*dest); *dest = NULL; } return ret; }
bool -virBandwidthEqual(virBandwidthPtr a, - virBandwidthPtr b) +virNetDevBandwidthEqual(virNetDevBandwidthPtr a, + virNetDevBandwidthPtr b) { if (!a&& !b) return true; diff --git a/src/util/network.h b/src/util/network.h index a2c68e9..1f3a53f 100644 --- a/src/util/network.h +++ b/src/util/network.h @@ -48,19 +48,19 @@ typedef struct {
typedef virSocketAddr *virSocketAddrPtr;
-typedef struct { +typedef struct _virNetDevBandwidthRate virNetDevBandwidthRate; +typedef virNetDevBandwidthRate *virNetDevBandwidthRatePtr; +struct _virNetDevBandwidthRate { unsigned long long average; /* kbytes/s */ unsigned long long peak; /* kbytes/s */ unsigned long long burst; /* kbytes */ -} virRate; - -typedef virRate *virRatePtr; - -typedef struct { - virRatePtr in, out; -} virBandwidth; +};
-typedef virBandwidth *virBandwidthPtr; +typedef struct _virNetDevBandwidth virNetDevBandwidth; +typedef virNetDevBandwidth *virNetDevBandwidthPtr; +struct _virNetDevBandwidth { + virNetDevBandwidthRatePtr in, out; +};
int virSocketAddrParse(virSocketAddrPtr addr, const char *val, @@ -152,16 +152,21 @@ virVirtualPortProfileFormat(virBufferPtr buf, bool virVirtualPortProfileEqual(virVirtualPortProfileParamsPtr a, virVirtualPortProfileParamsPtr b);
-virBandwidthPtr virBandwidthDefParseNode(xmlNodePtr node); -void virBandwidthDefFree(virBandwidthPtr def); -int virBandwidthDefFormat(virBufferPtr buf, - virBandwidthPtr def); - -int virBandwidthEnable(virBandwidthPtr bandwidth, const char *iface); -int virBandwidthDisable(const char *iface, bool may_fail); -int virBandwidthCopy(virBandwidthPtr *dest, const virBandwidthPtr src); - -bool virBandwidthEqual(virBandwidthPtr a, virBandwidthPtr b); +virNetDevBandwidthPtr virNetDevBandwidthParse(xmlNodePtr node) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +void virNetDevBandwidthFree(virNetDevBandwidthPtr def); +int virNetDevBandwidthFormat(virNetDevBandwidthPtr def, + virBufferPtr buf) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +int virNetDevBandwidthSet(const char *ifname, virNetDevBandwidthPtr bandwidth) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBandwidthClear(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest, const virNetDevBandwidthPtr src) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +bool virNetDevBandwidthEqual(virNetDevBandwidthPtr a, virNetDevBandwidthPtr b);
#endif /* __VIR_NETWORK_H__ */ diff --git a/tools/virsh.c b/tools/virsh.c index 5544a41..d8261f7 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -11250,7 +11250,7 @@ static const vshCmdOptDef opts_attach_interface[] = { /* parse inbound and outbound which are in the format of * 'average,peak,burst', in which peak and burst are optional, * thus 'average,,burst' and 'average,peak' are also legal. */ -static int parseRateStr(const char *rateStr, virRatePtr rate) +static int parseRateStr(const char *rateStr, virNetDevBandwidthRatePtr rate) { const char *average = NULL; char *peak = NULL, *burst = NULL; @@ -11289,7 +11289,7 @@ cmdAttachInterface(vshControl *ctl, const vshCmd *cmd) const char *mac = NULL, *target = NULL, *script = NULL, *type = NULL, *source = NULL, *model = NULL, *inboundStr = NULL, *outboundStr = NULL; - virRate inbound, outbound; + virNetDevBandwidthRate inbound, outbound; int typ; int ret; bool functionReturn = false;
ACK

From: "Daniel P. Berrange" <berrange@redhat.com> Rename the virVirtualPortProfileParams struct to be virNetDevVPortProfile, and rename the APIs to match this prefix. * src/util/network.c, src/util/network.h: Rename port profile APIs * src/conf/domain_conf.c, src/conf/domain_conf.h, src/conf/network_conf.c, src/conf/network_conf.h, src/network/bridge_driver.c, src/qemu/qemu_hotplug.c, src/util/macvtap.c, src/util/macvtap.h: Update for renamed APIs/structs --- src/conf/domain_conf.c | 16 +++++++------- src/conf/domain_conf.h | 8 +++--- src/conf/network_conf.c | 12 +++++----- src/conf/network_conf.h | 4 +- src/libvirt_private.syms | 6 ++-- src/network/bridge_driver.c | 6 ++-- src/qemu/qemu_hotplug.c | 4 +- src/util/macvtap.c | 36 ++++++++++++++++---------------- src/util/macvtap.h | 8 +++--- src/util/network.c | 48 +++++++++++++++++++++--------------------- src/util/network.h | 33 +++++++++++++++-------------- 11 files changed, 91 insertions(+), 90 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ab7853d..c1f8950 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3112,8 +3112,8 @@ virDomainActualNetDefParseXML(xmlNodePtr node, virtPortNode = virXPathNode("./virtualport", ctxt); if (virtPortNode && - virVirtualPortProfileParseXML(virtPortNode, - &actual->data.direct.virtPortProfile) < 0) { + virNetDevVPortProfileParse(virtPortNode, + &actual->data.direct.virtPortProfile) < 0) { goto error; } } @@ -3169,7 +3169,7 @@ virDomainNetDefParseXML(virCapsPtr caps, char *mode = NULL; char *linkstate = NULL; virNWFilterHashTablePtr filterparams = NULL; - virVirtualPortProfileParamsPtr virtPort = NULL; + virNetDevVPortProfilePtr virtPort = NULL; virDomainActualNetDefPtr actual = NULL; xmlNodePtr oldnode = ctxt->node; int ret; @@ -3221,7 +3221,7 @@ virDomainNetDefParseXML(virCapsPtr caps, ((def->type == VIR_DOMAIN_NET_TYPE_DIRECT) || (def->type == VIR_DOMAIN_NET_TYPE_NETWORK)) && xmlStrEqual(cur->name, BAD_CAST "virtualport")) { - if (virVirtualPortProfileParseXML(cur, &virtPort) < 0) + if (virNetDevVPortProfileParse(cur, &virtPort) < 0) goto error; } else if ((network == NULL) && ((def->type == VIR_DOMAIN_NET_TYPE_SERVER) || @@ -9721,7 +9721,7 @@ virDomainActualNetDefFormat(virBufferPtr buf, } virBufferAsprintf(buf, " mode='%s'/>\n", mode); virBufferAdjustIndent(buf, 8); - virVirtualPortProfileFormat(buf, def->data.direct.virtPortProfile); + virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf); virBufferAdjustIndent(buf, -8); break; default: @@ -9768,7 +9768,7 @@ virDomainNetDefFormat(virBufferPtr buf, def->data.network.portgroup); virBufferAddLit(buf, "/>\n"); virBufferAdjustIndent(buf, 6); - virVirtualPortProfileFormat(buf, def->data.network.virtPortProfile); + virNetDevVPortProfileFormat(def->data.network.virtPortProfile, buf); virBufferAdjustIndent(buf, -6); if ((flags & VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET) && (virDomainActualNetDefFormat(buf, def->data.network.actual) < 0)) @@ -9818,7 +9818,7 @@ virDomainNetDefFormat(virBufferPtr buf, virMacvtapModeTypeToString(def->data.direct.mode)); virBufferAddLit(buf, "/>\n"); virBufferAdjustIndent(buf, 6); - virVirtualPortProfileFormat(buf, def->data.direct.virtPortProfile); + virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf); virBufferAdjustIndent(buf, -6); break; @@ -13078,7 +13078,7 @@ virDomainNetGetActualDirectMode(virDomainNetDefPtr iface) return iface->data.network.actual->data.direct.mode; } -virVirtualPortProfileParamsPtr +virNetDevVPortProfilePtr virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface) { if (iface->type == VIR_DOMAIN_NET_TYPE_DIRECT) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a3cb834..255d8fd 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -508,7 +508,7 @@ struct _virDomainActualNetDef { struct { char *linkdev; int mode; /* enum virMacvtapMode from util/macvtap.h */ - virVirtualPortProfileParamsPtr virtPortProfile; + virNetDevVPortProfilePtr virtPortProfile; } direct; } data; virNetDevBandwidthPtr bandwidth; @@ -542,7 +542,7 @@ struct _virDomainNetDef { struct { char *name; char *portgroup; - virVirtualPortProfileParamsPtr virtPortProfile; + virNetDevVPortProfilePtr virtPortProfile; /* actual has info about the currently used physical * device (if the network is of type * bridge/private/vepa/passthrough). This is saved in the @@ -564,7 +564,7 @@ struct _virDomainNetDef { struct { char *linkdev; int mode; /* enum virMacvtapMode from util/macvtap.h */ - virVirtualPortProfileParamsPtr virtPortProfile; + virNetDevVPortProfilePtr virtPortProfile; } direct; } data; struct { @@ -1795,7 +1795,7 @@ int virDomainNetGetActualType(virDomainNetDefPtr iface); char *virDomainNetGetActualBridgeName(virDomainNetDefPtr iface); char *virDomainNetGetActualDirectDev(virDomainNetDefPtr iface); int virDomainNetGetActualDirectMode(virDomainNetDefPtr iface); -virVirtualPortProfileParamsPtr +virNetDevVPortProfilePtr virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface); virNetDevBandwidthPtr virDomainNetGetActualBandwidth(virDomainNetDefPtr iface); diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index a70b5a2..023eb9f 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -790,8 +790,8 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def, virtPortNode = virXPathNode("./virtualport", ctxt); if (virtPortNode && - (virVirtualPortProfileParseXML(virtPortNode, - &def->virtPortProfile) < 0)) { + (virNetDevVPortProfileParse(virtPortNode, + &def->virtPortProfile) < 0)) { goto error; } @@ -894,8 +894,8 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) virtPortNode = virXPathNode("./virtualport", ctxt); if (virtPortNode && - (virVirtualPortProfileParseXML(virtPortNode, - &def->virtPortProfile) < 0)) { + (virNetDevVPortProfileParse(virtPortNode, + &def->virtPortProfile) < 0)) { goto error; } @@ -1268,7 +1268,7 @@ virPortGroupDefFormat(virBufferPtr buf, } virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 4); - virVirtualPortProfileFormat(buf, def->virtPortProfile); + virNetDevVPortProfileFormat(def->virtPortProfile, buf); virNetDevBandwidthFormat(def->bandwidth, buf); virBufferAdjustIndent(buf, -4); virBufferAddLit(buf, " </portgroup>\n"); @@ -1354,7 +1354,7 @@ char *virNetworkDefFormat(const virNetworkDefPtr def) } virBufferAdjustIndent(&buf, 2); - virVirtualPortProfileFormat(&buf, def->virtPortProfile); + virNetDevVPortProfileFormat(def->virtPortProfile, &buf); virBufferAdjustIndent(&buf, -2); for (ii = 0; ii < def->nPortGroups; ii++) diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 2cfbe46..57ad637 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -122,7 +122,7 @@ typedef virPortGroupDef *virPortGroupDefPtr; struct _virPortGroupDef { char *name; bool isDefault; - virVirtualPortProfileParamsPtr virtPortProfile; + virNetDevVPortProfilePtr virtPortProfile; virNetDevBandwidthPtr bandwidth; }; @@ -151,7 +151,7 @@ struct _virNetworkDef { virNetworkIpDefPtr ips; /* ptr to array of IP addresses on this network */ virNetworkDNSDefPtr dns; /* ptr to dns related configuration */ - virVirtualPortProfileParamsPtr virtPortProfile; + virNetDevVPortProfilePtr virtPortProfile; size_t nPortGroups; virPortGroupDefPtr portGroups; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 81de6b4..4bc9217 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -786,9 +786,9 @@ virSocketAddrParseIPv4; virSocketAddrParseIPv6; virSocketAddrPrefixToNetmask; virSocketAddrSetPort; -virVirtualPortProfileEqual; -virVirtualPortProfileFormat; -virVirtualPortProfileParseXML; +virNetDevVPortProfileEqual; +virNetDevVPortProfileFormat; +virNetDevVPortProfileParse; # network_conf.h diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index d213642..b297f47 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -2765,7 +2765,7 @@ networkAllocateActualDevice(virDomainNetDefPtr iface) (netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) || (netdef->forwardType == VIR_NETWORK_FORWARD_VEPA) || (netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH)) { - virVirtualPortProfileParamsPtr virtport = NULL; + virNetDevVPortProfilePtr virtport = NULL; /* <forward type='bridge|private|vepa|passthrough'> are all * VIR_DOMAIN_NET_TYPE_DIRECT. @@ -2837,7 +2837,7 @@ networkAllocateActualDevice(virDomainNetDefPtr iface) ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) && iface->data.network.actual->data.direct.virtPortProfile && (iface->data.network.actual->data.direct.virtPortProfile->virtPortType - == VIR_VIRTUALPORT_8021QBH))) { + == VIR_NETDEV_VPORT_PROFILE_8021QBH))) { /* pick first dev with 0 usageCount */ for (ii = 0; ii < netdef->nForwardIfs; ii++) { @@ -2964,7 +2964,7 @@ networkNotifyActualDevice(virDomainNetDefPtr iface) ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) && iface->data.network.actual->data.direct.virtPortProfile && (iface->data.network.actual->data.direct.virtPortProfile->virtPortType - == VIR_VIRTUALPORT_8021QBH)))) { + == VIR_NETDEV_VPORT_PROFILE_8021QBH)))) { networkReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' claims dev='%s' is already in use by a different domain"), netdef->name, actualDev); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index fb95ab1..ab26e57 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1238,7 +1238,7 @@ int qemuDomainChangeNet(struct qemud_driver *driver, case VIR_DOMAIN_NET_TYPE_NETWORK: if (STRNEQ_NULLABLE(olddev->data.network.name, dev->data.network.name) || STRNEQ_NULLABLE(olddev->data.network.portgroup, dev->data.network.portgroup) || - !virVirtualPortProfileEqual(olddev->data.network.virtPortProfile, dev->data.network.virtPortProfile)) { + !virNetDevVPortProfileEqual(olddev->data.network.virtPortProfile, dev->data.network.virtPortProfile)) { qemuReportError(VIR_ERR_NO_SUPPORT, _("cannot modify network device configuration")); return -1; @@ -1257,7 +1257,7 @@ int qemuDomainChangeNet(struct qemud_driver *driver, case VIR_DOMAIN_NET_TYPE_DIRECT: if (STRNEQ_NULLABLE(olddev->data.direct.linkdev, dev->data.direct.linkdev) || olddev->data.direct.mode != dev->data.direct.mode || - !virVirtualPortProfileEqual(olddev->data.direct.virtPortProfile, dev->data.direct.virtPortProfile)) { + !virNetDevVPortProfileEqual(olddev->data.direct.virtPortProfile, dev->data.direct.virtPortProfile)) { qemuReportError(VIR_ERR_NO_SUPPORT, _("cannot modify direct network device configuration")); return -1; diff --git a/src/util/macvtap.c b/src/util/macvtap.c index cb13d2b..71243b8 100644 --- a/src/util/macvtap.c +++ b/src/util/macvtap.c @@ -89,7 +89,7 @@ VIR_ENUM_IMPL(virMacvtapMode, VIR_MACVTAP_MODE_LAST, # define LLDPAD_PID_FILE "/var/run/lldpad.pid" -enum virVirtualPortOp { +enum virNetDevVPortOp { ASSOCIATE = 0x1, DISASSOCIATE = 0x2, PREASSOCIATE = 0x3, @@ -267,7 +267,7 @@ openMacvtapTap(const char *tgifname, enum virMacvtapMode mode, int vnet_hdr, const unsigned char *vmuuid, - virVirtualPortProfileParamsPtr virtPortProfile, + virNetDevVPortProfilePtr virtPortProfile, char **res_ifname, enum virVMOperationType vmOp, char *stateDir, @@ -404,7 +404,7 @@ delMacvtap(const char *ifname, const unsigned char *macaddr, const char *linkdev, int mode, - virVirtualPortProfileParamsPtr virtPortProfile, + virNetDevVPortProfilePtr virtPortProfile, char *stateDir) { if (mode == VIR_MACVTAP_MODE_PASSTHRU) { @@ -866,8 +866,8 @@ getPhysdevAndVlan(const char *ifname, int *root_ifindex, char *root_ifname, static int doPortProfileOp8021Qbg(const char *ifname, const unsigned char *macaddr, - const virVirtualPortProfileParamsPtr virtPort, - enum virVirtualPortOp virtPortOp) + const virNetDevVPortProfilePtr virtPort, + enum virNetDevVPortOp virtPortOp) { int rc = 0; @@ -983,9 +983,9 @@ err_exit: static int doPortProfileOp8021Qbh(const char *ifname, const unsigned char *macaddr, - const virVirtualPortProfileParamsPtr virtPort, + const virNetDevVPortProfilePtr virtPort, const unsigned char *vm_uuid, - enum virVirtualPortOp virtPortOp) + enum virNetDevVPortOp virtPortOp) { int rc = 0; @@ -1097,7 +1097,7 @@ int vpAssociatePortProfileId(const char *macvtap_ifname, const unsigned char *macvtap_macaddr, const char *linkdev, - const virVirtualPortProfileParamsPtr virtPort, + const virNetDevVPortProfilePtr virtPort, const unsigned char *vmuuid, enum virVMOperationType vmOp) { @@ -1112,11 +1112,11 @@ vpAssociatePortProfileId(const char *macvtap_ifname, return 0; switch (virtPort->virtPortType) { - case VIR_VIRTUALPORT_NONE: - case VIR_VIRTUALPORT_TYPE_LAST: + case VIR_NETDEV_VPORT_PROFILE_NONE: + case VIR_NETDEV_VPORT_PROFILE_LAST: break; - case VIR_VIRTUALPORT_8021QBG: + case VIR_NETDEV_VPORT_PROFILE_8021QBG: rc = doPortProfileOp8021Qbg(macvtap_ifname, macvtap_macaddr, virtPort, (vmOp == VIR_VM_OP_MIGRATE_IN_START) @@ -1124,7 +1124,7 @@ vpAssociatePortProfileId(const char *macvtap_ifname, : ASSOCIATE); break; - case VIR_VIRTUALPORT_8021QBH: + case VIR_NETDEV_VPORT_PROFILE_8021QBH: rc = doPortProfileOp8021Qbh(linkdev, macvtap_macaddr, virtPort, vmuuid, (vmOp == VIR_VM_OP_MIGRATE_IN_START) @@ -1154,7 +1154,7 @@ int vpDisassociatePortProfileId(const char *macvtap_ifname, const unsigned char *macvtap_macaddr, const char *linkdev, - const virVirtualPortProfileParamsPtr virtPort, + const virNetDevVPortProfilePtr virtPort, enum virVMOperationType vmOp) { int rc = 0; @@ -1168,16 +1168,16 @@ vpDisassociatePortProfileId(const char *macvtap_ifname, return 0; switch (virtPort->virtPortType) { - case VIR_VIRTUALPORT_NONE: - case VIR_VIRTUALPORT_TYPE_LAST: + case VIR_NETDEV_VPORT_PROFILE_NONE: + case VIR_NETDEV_VPORT_PROFILE_LAST: break; - case VIR_VIRTUALPORT_8021QBG: + case VIR_NETDEV_VPORT_PROFILE_8021QBG: rc = doPortProfileOp8021Qbg(macvtap_ifname, macvtap_macaddr, virtPort, DISASSOCIATE); break; - case VIR_VIRTUALPORT_8021QBH: + case VIR_NETDEV_VPORT_PROFILE_8021QBH: /* avoid disassociating twice */ if (vmOp == VIR_VM_OP_MIGRATE_IN_FINISH) break; @@ -1190,7 +1190,7 @@ vpDisassociatePortProfileId(const char *macvtap_ifname, return rc; } -#endif /* WITH_MACVTAP || WITH_VIRTUALPORT */ +#endif /* WITH_MACVTAP || WITH_NETDEV_VPORT_PROFILE */ VIR_ENUM_IMPL(virVMOperation, VIR_VM_OP_LAST, "create", diff --git a/src/util/macvtap.h b/src/util/macvtap.h index 330e5e2..d685ab9 100644 --- a/src/util/macvtap.h +++ b/src/util/macvtap.h @@ -59,7 +59,7 @@ int openMacvtapTap(const char *ifname, enum virMacvtapMode mode, int vnet_hdr, const unsigned char *vmuuid, - virVirtualPortProfileParamsPtr virtPortProfile, + virNetDevVPortProfilePtr virtPortProfile, char **res_ifname, enum virVMOperationType vmop, char *stateDir, @@ -69,20 +69,20 @@ void delMacvtap(const char *ifname, const unsigned char *macaddress, const char *linkdev, int mode, - virVirtualPortProfileParamsPtr virtPortProfile, + virNetDevVPortProfilePtr virtPortProfile, char *stateDir); int vpAssociatePortProfileId(const char *macvtap_ifname, const unsigned char *macvtap_macaddr, const char *linkdev, - const virVirtualPortProfileParamsPtr virtPort, + const virNetDevVPortProfilePtr virtPort, const unsigned char *vmuuid, enum virVMOperationType vmOp); int vpDisassociatePortProfileId(const char *macvtap_ifname, const unsigned char *macvtap_macaddr, const char *linkdev, - const virVirtualPortProfileParamsPtr virtPort, + const virNetDevVPortProfilePtr virtPort, enum virVMOperationType vmOp); # endif /* WITH_MACVTAP */ diff --git a/src/util/network.c b/src/util/network.c index 1ecbce3..f7f5d6c 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -679,14 +679,14 @@ error: /* virtualPortProfile utilities */ -VIR_ENUM_IMPL(virVirtualPort, VIR_VIRTUALPORT_TYPE_LAST, +VIR_ENUM_IMPL(virNetDevVPort, VIR_NETDEV_VPORT_PROFILE_LAST, "none", "802.1Qbg", "802.1Qbh") int -virVirtualPortProfileParseXML(xmlNodePtr node, - virVirtualPortProfileParamsPtr *def) +virNetDevVPortProfileParse(xmlNodePtr node, + virNetDevVPortProfilePtr *def) { int ret = -1; char *virtPortType; @@ -695,7 +695,7 @@ virVirtualPortProfileParseXML(xmlNodePtr node, char *virtPortTypeIDVersion = NULL; char *virtPortInstanceID = NULL; char *virtPortProfileID = NULL; - virVirtualPortProfileParamsPtr virtPort = NULL; + virNetDevVPortProfilePtr virtPort = NULL; xmlNodePtr cur = node->children; if (VIR_ALLOC(virtPort) < 0) { @@ -725,11 +725,11 @@ virVirtualPortProfileParseXML(xmlNodePtr node, cur = cur->next; } - virtPort->virtPortType = VIR_VIRTUALPORT_NONE; + virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_NONE; - switch (virVirtualPortTypeFromString(virtPortType)) { + switch (virNetDevVPortTypeFromString(virtPortType)) { - case VIR_VIRTUALPORT_8021QBG: + case VIR_NETDEV_VPORT_PROFILE_8021QBG: if (virtPortManagerID != NULL && virtPortTypeID != NULL && virtPortTypeIDVersion != NULL) { unsigned int val; @@ -791,7 +791,7 @@ virVirtualPortProfileParseXML(xmlNodePtr node, } } - virtPort->virtPortType = VIR_VIRTUALPORT_8021QBG; + virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBG; } else { virSocketError(VIR_ERR_XML_ERROR, "%s", @@ -800,11 +800,11 @@ virVirtualPortProfileParseXML(xmlNodePtr node, } break; - case VIR_VIRTUALPORT_8021QBH: + case VIR_NETDEV_VPORT_PROFILE_8021QBH: if (virtPortProfileID != NULL) { if (virStrcpyStatic(virtPort->u.virtPort8021Qbh.profileID, virtPortProfileID) != NULL) { - virtPort->virtPortType = VIR_VIRTUALPORT_8021QBH; + virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBH; } else { virSocketError(VIR_ERR_XML_ERROR, "%s", _("profileid parameter too long")); @@ -819,8 +819,8 @@ virVirtualPortProfileParseXML(xmlNodePtr node, default: - case VIR_VIRTUALPORT_NONE: - case VIR_VIRTUALPORT_TYPE_LAST: + case VIR_NETDEV_VPORT_PROFILE_NONE: + case VIR_NETDEV_VPORT_PROFILE_LAST: virSocketError(VIR_ERR_XML_ERROR, "%s", _("unknown virtualport type")); goto error; @@ -843,7 +843,7 @@ error: } bool -virVirtualPortProfileEqual(virVirtualPortProfileParamsPtr a, virVirtualPortProfileParamsPtr b) +virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, virNetDevVPortProfilePtr b) { /* NULL resistant */ if (!a && !b) @@ -856,10 +856,10 @@ virVirtualPortProfileEqual(virVirtualPortProfileParamsPtr a, virVirtualPortProfi return false; switch (a->virtPortType) { - case VIR_VIRTUALPORT_NONE: + case VIR_NETDEV_VPORT_PROFILE_NONE: break; - case VIR_VIRTUALPORT_8021QBG: + case VIR_NETDEV_VPORT_PROFILE_8021QBG: if (a->u.virtPort8021Qbg.managerID != b->u.virtPort8021Qbg.managerID || a->u.virtPort8021Qbg.typeID != b->u.virtPort8021Qbg.typeID || a->u.virtPort8021Qbg.typeIDVersion != b->u.virtPort8021Qbg.typeIDVersion || @@ -867,7 +867,7 @@ virVirtualPortProfileEqual(virVirtualPortProfileParamsPtr a, virVirtualPortProfi return false; break; - case VIR_VIRTUALPORT_8021QBH: + case VIR_NETDEV_VPORT_PROFILE_8021QBH: if (STRNEQ(a->u.virtPort8021Qbh.profileID, b->u.virtPort8021Qbh.profileID)) return false; break; @@ -880,23 +880,23 @@ virVirtualPortProfileEqual(virVirtualPortProfileParamsPtr a, virVirtualPortProfi } void -virVirtualPortProfileFormat(virBufferPtr buf, - virVirtualPortProfileParamsPtr virtPort) +virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, + virBufferPtr buf) { char uuidstr[VIR_UUID_STRING_BUFLEN]; - if (!virtPort || virtPort->virtPortType == VIR_VIRTUALPORT_NONE) + if (!virtPort || virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE) return; virBufferAsprintf(buf, "<virtualport type='%s'>\n", - virVirtualPortTypeToString(virtPort->virtPortType)); + virNetDevVPortTypeToString(virtPort->virtPortType)); switch (virtPort->virtPortType) { - case VIR_VIRTUALPORT_NONE: - case VIR_VIRTUALPORT_TYPE_LAST: + case VIR_NETDEV_VPORT_PROFILE_NONE: + case VIR_NETDEV_VPORT_PROFILE_LAST: break; - case VIR_VIRTUALPORT_8021QBG: + case VIR_NETDEV_VPORT_PROFILE_8021QBG: virUUIDFormat(virtPort->u.virtPort8021Qbg.instanceID, uuidstr); virBufferAsprintf(buf, @@ -908,7 +908,7 @@ virVirtualPortProfileFormat(virBufferPtr buf, uuidstr); break; - case VIR_VIRTUALPORT_8021QBH: + case VIR_NETDEV_VPORT_PROFILE_8021QBH: virBufferAsprintf(buf, " <parameters profileid='%s'/>\n", virtPort->u.virtPort8021Qbh.profileID); diff --git a/src/util/network.h b/src/util/network.h index 1f3a53f..c3ab623 100644 --- a/src/util/network.h +++ b/src/util/network.h @@ -114,21 +114,21 @@ int virSocketAddrPrefixToNetmask(unsigned int prefix, # define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX 40 # endif -enum virVirtualPortType { - VIR_VIRTUALPORT_NONE, - VIR_VIRTUALPORT_8021QBG, - VIR_VIRTUALPORT_8021QBH, +enum virNetDevVPortProfile { + VIR_NETDEV_VPORT_PROFILE_NONE, + VIR_NETDEV_VPORT_PROFILE_8021QBG, + VIR_NETDEV_VPORT_PROFILE_8021QBH, - VIR_VIRTUALPORT_TYPE_LAST, + VIR_NETDEV_VPORT_PROFILE_LAST, }; -VIR_ENUM_DECL(virVirtualPort) +VIR_ENUM_DECL(virNetDevVPort) /* profile data for macvtap (VEPA) */ -typedef struct _virVirtualPortProfileParams virVirtualPortProfileParams; -typedef virVirtualPortProfileParams *virVirtualPortProfileParamsPtr; -struct _virVirtualPortProfileParams { - enum virVirtualPortType virtPortType; +typedef struct _virNetDevVPortProfile virNetDevVPortProfile; +typedef virNetDevVPortProfile *virNetDevVPortProfilePtr; +struct _virNetDevVPortProfile { + enum virNetDevVPortProfile virtPortType; union { struct { uint8_t managerID; @@ -143,14 +143,15 @@ struct _virVirtualPortProfileParams { }; int -virVirtualPortProfileParseXML(xmlNodePtr node, - virVirtualPortProfileParamsPtr *virtPort); +virNetDevVPortProfileParse(xmlNodePtr node, + virNetDevVPortProfilePtr *def); + void -virVirtualPortProfileFormat(virBufferPtr buf, - virVirtualPortProfileParamsPtr virtPort); +virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, + virBufferPtr buf); -bool virVirtualPortProfileEqual(virVirtualPortProfileParamsPtr a, - virVirtualPortProfileParamsPtr b); +bool virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, + virNetDevVPortProfilePtr b); virNetDevBandwidthPtr virNetDevBandwidthParse(xmlNodePtr node) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -- 1.7.6.4

On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
Rename the virVirtualPortProfileParams struct to be virNetDevVPortProfile, and rename the APIs to match this prefix.
* src/util/network.c, src/util/network.h: Rename port profile APIs * src/conf/domain_conf.c, src/conf/domain_conf.h, src/conf/network_conf.c, src/conf/network_conf.h, src/network/bridge_driver.c, src/qemu/qemu_hotplug.c, src/util/macvtap.c, src/util/macvtap.h: Update for renamed APIs/structs --- src/conf/domain_conf.c | 16 +++++++------- src/conf/domain_conf.h | 8 +++--- src/conf/network_conf.c | 12 +++++----- src/conf/network_conf.h | 4 +- src/libvirt_private.syms | 6 ++-- src/network/bridge_driver.c | 6 ++-- src/qemu/qemu_hotplug.c | 4 +- src/util/macvtap.c | 36 ++++++++++++++++---------------- src/util/macvtap.h | 8 +++--- src/util/network.c | 48 +++++++++++++++++++++--------------------- src/util/network.h | 33 +++++++++++++++-------------- 11 files changed, 91 insertions(+), 90 deletions(-)
diff --git a/src/util/macvtap.c b/src/util/macvtap.c index cb13d2b..71243b8 100644 --- a/src/util/macvtap.c +++ b/src/util/macvtap.c @@ -89,7 +89,7 @@ VIR_ENUM_IMPL(virMacvtapMode, VIR_MACVTAP_MODE_LAST, # define LLDPAD_PID_FILE "/var/run/lldpad.pid"
-enum virVirtualPortOp { +enum virNetDevVPortOp { ASSOCIATE = 0x1, DISASSOCIATE = 0x2, PREASSOCIATE = 0x3,
Do you think having such generic names for these enums might lead to a namespace conflict somewhere down the road? Maybe the enum value names could be changed as a part of this patch...
-#endif /* WITH_MACVTAP || WITH_VIRTUALPORT */ +#endif /* WITH_MACVTAP || WITH_NETDEV_VPORT_PROFILE */
WITH_VIRTUALPORT has been changed to WITH_NETDEV_VPORT_PROFILE in this comment, but not in the #ifdef, and the line was completely removed in PATCH 19/33. Since the latter name doesn't appear anywhere in the final result of the series, I think this must be a vestige of something you later decided against, or maybe a search-replace run amok. ACK aside from that.

On Wed, Nov 09, 2011 at 02:12:02AM -0500, Laine Stump wrote:
On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
Rename the virVirtualPortProfileParams struct to be virNetDevVPortProfile, and rename the APIs to match this prefix.
* src/util/network.c, src/util/network.h: Rename port profile APIs * src/conf/domain_conf.c, src/conf/domain_conf.h, src/conf/network_conf.c, src/conf/network_conf.h, src/network/bridge_driver.c, src/qemu/qemu_hotplug.c, src/util/macvtap.c, src/util/macvtap.h: Update for renamed APIs/structs --- src/conf/domain_conf.c | 16 +++++++------- src/conf/domain_conf.h | 8 +++--- src/conf/network_conf.c | 12 +++++----- src/conf/network_conf.h | 4 +- src/libvirt_private.syms | 6 ++-- src/network/bridge_driver.c | 6 ++-- src/qemu/qemu_hotplug.c | 4 +- src/util/macvtap.c | 36 ++++++++++++++++---------------- src/util/macvtap.h | 8 +++--- src/util/network.c | 48 +++++++++++++++++++++--------------------- src/util/network.h | 33 +++++++++++++++-------------- 11 files changed, 91 insertions(+), 90 deletions(-)
diff --git a/src/util/macvtap.c b/src/util/macvtap.c index cb13d2b..71243b8 100644 --- a/src/util/macvtap.c +++ b/src/util/macvtap.c @@ -89,7 +89,7 @@ VIR_ENUM_IMPL(virMacvtapMode, VIR_MACVTAP_MODE_LAST, # define LLDPAD_PID_FILE "/var/run/lldpad.pid"
-enum virVirtualPortOp { +enum virNetDevVPortOp { ASSOCIATE = 0x1, DISASSOCIATE = 0x2, PREASSOCIATE = 0x3,
Do you think having such generic names for these enums might lead to a namespace conflict somewhere down the road? Maybe the enum value names could be changed as a part of this patch...
The enum itself later gets renamed again to virNetDevVPortProfileLinkOp I'm moving the rename to this patch, and also renaming the constants to match by having a prefix VIR_NETDEV_VPORT_PROFILE_LINK_OP. Yes it is a little verbose, but these are only used in a handful of places.
-#endif /* WITH_MACVTAP || WITH_VIRTUALPORT */ +#endif /* WITH_MACVTAP || WITH_NETDEV_VPORT_PROFILE */
WITH_VIRTUALPORT has been changed to WITH_NETDEV_VPORT_PROFILE in this comment, but not in the #ifdef, and the line was completely removed in PATCH 19/33. Since the latter name doesn't appear anywhere in the final result of the series, I think this must be a vestige of something you later decided against, or maybe a search-replace run amok.
Yes, bogus search & replace I have reverted.
ACK aside from that.
Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: "Daniel P. Berrange" <berrange@redhat.com> The virtual port profile parsing/formatting APIs do not correctly handle unknown profile type strings/numbers. They behave as a no-op, instead of raising an error * src/util/network.c, src/util/network.h: Fix error handling of port profile APIs * src/conf/domain_conf.c, src/conf/network_conf.c: Update for API changes --- src/conf/domain_conf.c | 16 +++++++----- src/conf/network_conf.c | 20 +++++++------- src/util/network.c | 61 ++++++++++++++++++++++++----------------------- src/util/network.h | 8 +++--- 4 files changed, 54 insertions(+), 51 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c1f8950..b1e47a3 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3112,10 +3112,9 @@ virDomainActualNetDefParseXML(xmlNodePtr node, virtPortNode = virXPathNode("./virtualport", ctxt); if (virtPortNode && - virNetDevVPortProfileParse(virtPortNode, - &actual->data.direct.virtPortProfile) < 0) { + (!(actual->data.direct.virtPortProfile = + virNetDevVPortProfileParse(virtPortNode)))) goto error; - } } bandwidth_node = virXPathNode("./bandwidth", ctxt); @@ -3221,7 +3220,7 @@ virDomainNetDefParseXML(virCapsPtr caps, ((def->type == VIR_DOMAIN_NET_TYPE_DIRECT) || (def->type == VIR_DOMAIN_NET_TYPE_NETWORK)) && xmlStrEqual(cur->name, BAD_CAST "virtualport")) { - if (virNetDevVPortProfileParse(cur, &virtPort) < 0) + if (!(virtPort = virNetDevVPortProfileParse(cur))) goto error; } else if ((network == NULL) && ((def->type == VIR_DOMAIN_NET_TYPE_SERVER) || @@ -9721,7 +9720,8 @@ virDomainActualNetDefFormat(virBufferPtr buf, } virBufferAsprintf(buf, " mode='%s'/>\n", mode); virBufferAdjustIndent(buf, 8); - virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf); + if (virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf) < 0) + goto error; virBufferAdjustIndent(buf, -8); break; default: @@ -9768,7 +9768,8 @@ virDomainNetDefFormat(virBufferPtr buf, def->data.network.portgroup); virBufferAddLit(buf, "/>\n"); virBufferAdjustIndent(buf, 6); - virNetDevVPortProfileFormat(def->data.network.virtPortProfile, buf); + if (virNetDevVPortProfileFormat(def->data.network.virtPortProfile, buf) < 0) + return -1; virBufferAdjustIndent(buf, -6); if ((flags & VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET) && (virDomainActualNetDefFormat(buf, def->data.network.actual) < 0)) @@ -9818,7 +9819,8 @@ virDomainNetDefFormat(virBufferPtr buf, virMacvtapModeTypeToString(def->data.direct.mode)); virBufferAddLit(buf, "/>\n"); virBufferAdjustIndent(buf, 6); - virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf); + if (virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf) < 0) + return -1; virBufferAdjustIndent(buf, -6); break; diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 023eb9f..5e38bee 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -790,10 +790,8 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def, virtPortNode = virXPathNode("./virtualport", ctxt); if (virtPortNode && - (virNetDevVPortProfileParse(virtPortNode, - &def->virtPortProfile) < 0)) { + (!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode)))) goto error; - } bandwidth_node = virXPathNode("./bandwidth", ctxt); if (bandwidth_node && @@ -894,10 +892,8 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) virtPortNode = virXPathNode("./virtualport", ctxt); if (virtPortNode && - (virNetDevVPortProfileParse(virtPortNode, - &def->virtPortProfile) < 0)) { + (!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode)))) goto error; - } nPortGroups = virXPathNodeSet("./portgroup", ctxt, &portGroupNodes); if (nPortGroups < 0) @@ -1258,7 +1254,7 @@ error: return result; } -static void +static int virPortGroupDefFormat(virBufferPtr buf, const virPortGroupDefPtr def) { @@ -1268,10 +1264,12 @@ virPortGroupDefFormat(virBufferPtr buf, } virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 4); - virNetDevVPortProfileFormat(def->virtPortProfile, buf); + if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0) + return -1; virNetDevBandwidthFormat(def->bandwidth, buf); virBufferAdjustIndent(buf, -4); virBufferAddLit(buf, " </portgroup>\n"); + return 0; } char *virNetworkDefFormat(const virNetworkDefPtr def) @@ -1354,11 +1352,13 @@ char *virNetworkDefFormat(const virNetworkDefPtr def) } virBufferAdjustIndent(&buf, 2); - virNetDevVPortProfileFormat(def->virtPortProfile, &buf); + if (virNetDevVPortProfileFormat(def->virtPortProfile, &buf) < 0) + goto error; virBufferAdjustIndent(&buf, -2); for (ii = 0; ii < def->nPortGroups; ii++) - virPortGroupDefFormat(&buf, &def->portGroups[ii]); + if (virPortGroupDefFormat(&buf, &def->portGroups[ii]) < 0) + goto error; virBufferAddLit(&buf, "</network>\n"); diff --git a/src/util/network.c b/src/util/network.c index f7f5d6c..c467121 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -684,11 +684,10 @@ VIR_ENUM_IMPL(virNetDevVPort, VIR_NETDEV_VPORT_PROFILE_LAST, "802.1Qbg", "802.1Qbh") -int -virNetDevVPortProfileParse(xmlNodePtr node, - virNetDevVPortProfilePtr *def) + +virNetDevVPortProfilePtr +virNetDevVPortProfileParse(xmlNodePtr node) { - int ret = -1; char *virtPortType; char *virtPortManagerID = NULL; char *virtPortTypeID = NULL; @@ -700,13 +699,19 @@ virNetDevVPortProfileParse(xmlNodePtr node, if (VIR_ALLOC(virtPort) < 0) { virReportOOMError(); - return -1; + return NULL; } virtPortType = virXMLPropString(node, "type"); if (!virtPortType) { virSocketError(VIR_ERR_XML_ERROR, "%s", - _("missing virtualportprofile type")); + _("missing virtualportprofile type")); + goto error; + } + + if ((virtPortType = virNetDevVPortTypeFromString(virtPortType)) <= 0) { + virSocketError(VIR_ERR_XML_ERROR, + _("unknown virtualportprofile type %s"), virtPortType); goto error; } @@ -725,10 +730,7 @@ virNetDevVPortProfileParse(xmlNodePtr node, cur = cur->next; } - virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_NONE; - - switch (virNetDevVPortTypeFromString(virtPortType)) { - + switch (virtPort->virtPortType) { case VIR_NETDEV_VPORT_PROFILE_8021QBG: if (virtPortManagerID != NULL && virtPortTypeID != NULL && virtPortTypeIDVersion != NULL) { @@ -798,7 +800,7 @@ virNetDevVPortProfileParse(xmlNodePtr node, _("a parameter is missing for 802.1Qbg description")); goto error; } - break; + break; case VIR_NETDEV_VPORT_PROFILE_8021QBH: if (virtPortProfileID != NULL) { @@ -815,23 +817,15 @@ virNetDevVPortProfileParse(xmlNodePtr node, _("profileid parameter is missing for 802.1Qbh descripion")); goto error; } - break; - + break; default: - case VIR_NETDEV_VPORT_PROFILE_NONE: - case VIR_NETDEV_VPORT_PROFILE_LAST: - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("unknown virtualport type")); + virSocketError(VIR_ERR_XML_ERROR, + _("unexpected virtualport type %d"), virtPort->virtPortType); goto error; - break; } - ret = 0; - *def = virtPort; - virtPort = NULL; -error: - VIR_FREE(virtPort); +cleanup: VIR_FREE(virtPortManagerID); VIR_FREE(virtPortTypeID); VIR_FREE(virtPortTypeIDVersion); @@ -839,7 +833,11 @@ error: VIR_FREE(virtPortProfileID); VIR_FREE(virtPortType); - return ret; + return virtPort; + +error: + VIR_FREE(virtPort); + goto cleanup; } bool @@ -879,23 +877,20 @@ virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, virNetDevVPortProfilePtr return true; } -void + +int virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, virBufferPtr buf) { char uuidstr[VIR_UUID_STRING_BUFLEN]; if (!virtPort || virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE) - return; + return 0; virBufferAsprintf(buf, "<virtualport type='%s'>\n", virNetDevVPortTypeToString(virtPort->virtPortType)); switch (virtPort->virtPortType) { - case VIR_NETDEV_VPORT_PROFILE_NONE: - case VIR_NETDEV_VPORT_PROFILE_LAST: - break; - case VIR_NETDEV_VPORT_PROFILE_8021QBG: virUUIDFormat(virtPort->u.virtPort8021Qbg.instanceID, uuidstr); @@ -913,9 +908,15 @@ virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, " <parameters profileid='%s'/>\n", virtPort->u.virtPort8021Qbh.profileID); break; + + default: + virSocketError(VIR_ERR_XML_ERROR, + _("unexpected virtualport type %d"), virtPort->virtPortType); + return -1; } virBufferAddLit(buf, "</virtualport>\n"); + return 0; } static int diff --git a/src/util/network.h b/src/util/network.h index c3ab623..98dfacc 100644 --- a/src/util/network.h +++ b/src/util/network.h @@ -142,11 +142,11 @@ struct _virNetDevVPortProfile { } u; }; -int -virNetDevVPortProfileParse(xmlNodePtr node, - virNetDevVPortProfilePtr *def); -void +virNetDevVPortProfilePtr +virNetDevVPortProfileParse(xmlNodePtr node); + +int virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, virBufferPtr buf); -- 1.7.6.4

After applying this patch, make fails with: CC libvirt_util_la-network.lo cc1: warnings being treated as errors util/network.c: In function 'virNetDevVPortProfileParse': util/network.c:712:23: error: assignment makes pointer from integer without a cast util/network.c:712:69: error: ordered comparison of pointer with integer zero [-Wextra] On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
The virtual port profile parsing/formatting APIs do not correctly handle unknown profile type strings/numbers. They behave as a no-op, instead of raising an error
Actually I've noticed a *lot* of the *Format functions ignore the possibility of bad values in the vir*Def objects (e.g. invalid enum values), and have debated with myself about whether to ignore or report invalid data.
* src/util/network.c, src/util/network.h: Fix error handling of port profile APIs * src/conf/domain_conf.c, src/conf/network_conf.c: Update for API changes --- src/conf/domain_conf.c | 16 +++++++----- src/conf/network_conf.c | 20 +++++++------- src/util/network.c | 61 ++++++++++++++++++++++++----------------------- src/util/network.h | 8 +++--- 4 files changed, 54 insertions(+), 51 deletions(-)
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 023eb9f..5e38bee 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c
@@ -700,13 +699,19 @@ virNetDevVPortProfileParse(xmlNodePtr node,
if (VIR_ALLOC(virtPort)< 0) { virReportOOMError(); - return -1; + return NULL; }
virtPortType = virXMLPropString(node, "type"); if (!virtPortType) { virSocketError(VIR_ERR_XML_ERROR, "%s", - _("missing virtualportprofile type")); + _("missing virtualportprofile type")); + goto error; + }
The following should be "virtPort->virPortType = ....":
+ + if ((virtPortType = virNetDevVPortTypeFromString(virtPortType))<= 0) { + virSocketError(VIR_ERR_XML_ERROR, + _("unknown virtualportprofile type %s"), virtPortType); goto error; }
@@ -879,23 +877,20 @@ virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, virNetDevVPortProfilePtr return true; }
-void + +int virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, virBufferPtr buf) { char uuidstr[VIR_UUID_STRING_BUFLEN];
if (!virtPort || virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE) - return; + return 0;
virBufferAsprintf(buf, "<virtualport type='%s'>\n", virNetDevVPortTypeToString(virtPort->virtPortType));
switch (virtPort->virtPortType) { - case VIR_NETDEV_VPORT_PROFILE_NONE: - case VIR_NETDEV_VPORT_PROFILE_LAST: - break; - case VIR_NETDEV_VPORT_PROFILE_8021QBG: virUUIDFormat(virtPort->u.virtPort8021Qbg.instanceID, uuidstr); @@ -913,9 +908,15 @@ virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, "<parameters profileid='%s'/>\n", virtPort->u.virtPort8021Qbh.profileID); break; + + default: + virSocketError(VIR_ERR_XML_ERROR, + _("unexpected virtualport type %d"), virtPort->virtPortType); + return -1; }
A bit of digression: In the example here, you're doing something with the enum value aside from just converting it to a string, so there's a ready place to put in the check and return failure if it's out of bounds/unknown, but there are many many places where an XXXTypeToString() macro is used directly as an argument in a printf with no check for validity. On one hand, this is a bit sloppy if we consider that the [whatever]Def objects may contain unverified data (downright dangerous if you think about platforms that don't protect against NULL dereferences in printf!); on the other hand, if we changed every occurrence of that to get the string value into a temp and check for non-NULL before using it in a printf, it would add significant clutter to the code (domain_conf.c seems to be the biggest offender here). Even in this case, we're calling virBufferAsprintf with the unqualified return from virNetDevVPortTypeToString before we eventually vet it in the following switch statement. So do we consider objects sent to the Format functions to contain qualified data or not? If not, there's quite a large patch waiting in the wings :-) Anyway, ACK with the compile problem fixed.

On Wed, Nov 09, 2011 at 02:58:32AM -0500, Laine Stump wrote:
After applying this patch, make fails with:
CC libvirt_util_la-network.lo cc1: warnings being treated as errors util/network.c: In function 'virNetDevVPortProfileParse': util/network.c:712:23: error: assignment makes pointer from integer without a cast util/network.c:712:69: error: ordered comparison of pointer with integer zero [-Wextra]
On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
The virtual port profile parsing/formatting APIs do not correctly handle unknown profile type strings/numbers. They behave as a no-op, instead of raising an error
Actually I've noticed a *lot* of the *Format functions ignore the possibility of bad values in the vir*Def objects (e.g. invalid enum values), and have debated with myself about whether to ignore or report invalid data.
If we work from the assumption that the vir*Def objects can only be populated as a result of parsing an XML document, then we can assume the enum values in the vir*Def are all valid & within range. If we allow for the possibility that code can populate the vir*Def objects programmatically, then if it exclusively uses the enum constants we will again be safe. Only if we somehow populate vir*Def objects directly using int values, instead of constants or the formal string<->int conversion APIs, do we need to consider invalid values. This particular code *was* assuming the worst and explicitly trying to handle bogus values, but doing so in a really lame manner. IMHO it is not neccessary to handle invalid enum values in the formatting code, but if you do decide to handle them, then you *must* report the errors correctly and not just pretend they don't exist after you detected them. The latter is what this patch is fixing.
@@ -700,13 +699,19 @@ virNetDevVPortProfileParse(xmlNodePtr node,
if (VIR_ALLOC(virtPort)< 0) { virReportOOMError(); - return -1; + return NULL; }
virtPortType = virXMLPropString(node, "type"); if (!virtPortType) { virSocketError(VIR_ERR_XML_ERROR, "%s", - _("missing virtualportprofile type")); + _("missing virtualportprofile type")); + goto error; + }
The following should be "virtPort->virPortType = ....":
Opps, yes. Fixed in a later patch, will pull the fix back here.
Anyway, ACK with the compile problem fixed.
Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: "Daniel P. Berrange" <berrange@redhat.com> The src/util/network.c file is a dumping ground for many different APIs. Split it up into 5 pieces, along functional lines - src/util/virnetdevbandwidth.c: virNetDevBandwidth type & helper APIs - src/util/virnetdevvportprofile.c: virNetDevVPortProfile type & helper APIs - src/util/virsocketaddr.c: virSocketAddr and APIs - src/conf/netdev_bandwidth_conf.c: XML parsing / formatting for virNetDevBandwidth - src/conf/netdev_vport_profile_conf.c: XML parsing / formatting for virNetDevVPortProfile * src/util/network.c, src/util/network.h: Split into 5 pieces * src/conf/netdev_bandwidth_conf.c, src/conf/netdev_bandwidth_conf.h, src/conf/netdev_vport_profile_conf.c, src/conf/netdev_vport_profile_conf.h, src/util/virnetdevbandwidth.c, src/util/virnetdevbandwidth.h, src/util/virnetdevvportprofile.c, src/util/virnetdevvportprofile.h, src/util/virsocketaddr.c, src/util/virsocketaddr.h: New pieces * daemon/libvirtd.h, daemon/remote.c, src/conf/domain_conf.c, src/conf/domain_conf.h, src/conf/network_conf.c, src/conf/network_conf.h, src/conf/nwfilter_conf.h, src/esx/esx_util.h, src/network/bridge_driver.c, src/qemu/qemu_conf.c, src/rpc/virnetsocket.c, src/rpc/virnetsocket.h, src/util/dnsmasq.h, src/util/interface.h, src/util/iptables.h, src/util/macvtap.c, src/util/macvtap.h, src/util/virnetdev.h, src/util/virnetdevtap.c, tools/virsh.c: Update include files --- daemon/libvirtd.h | 1 - daemon/remote.c | 1 - po/POTFILES.in | 4 +- src/Makefile.am | 12 +- src/conf/domain_conf.c | 3 +- src/conf/domain_conf.h | 4 +- src/conf/netdev_bandwidth_conf.c | 230 ++++++ src/conf/netdev_bandwidth_conf.h | 37 + src/conf/netdev_vport_profile_conf.c | 236 ++++++ src/conf/netdev_vport_profile_conf.h | 39 + src/conf/network_conf.c | 3 +- src/conf/network_conf.h | 4 +- src/conf/nwfilter_conf.h | 2 +- src/esx/esx_util.h | 2 +- src/network/bridge_driver.c | 1 - src/qemu/qemu_conf.c | 1 - src/rpc/virnetsocket.c | 1 + src/rpc/virnetsocket.h | 2 +- src/util/dnsmasq.h | 2 +- src/util/interface.h | 2 +- src/util/iptables.h | 2 +- src/util/macvtap.c | 1 - src/util/macvtap.h | 8 +- src/util/network.c | 1349 ---------------------------------- src/util/network.h | 173 ----- src/util/virnetdev.h | 2 +- src/util/virnetdevbandwidth.c | 265 +++++++ src/util/virnetdevbandwidth.h | 53 ++ src/util/virnetdevtap.c | 1 + src/util/virnetdevvportprofile.c | 62 ++ src/util/virnetdevvportprofile.h | 64 ++ src/util/virsocketaddr.c | 687 +++++++++++++++++ src/util/virsocketaddr.h | 103 +++ tools/virsh.c | 2 +- 34 files changed, 1813 insertions(+), 1546 deletions(-) create mode 100644 src/conf/netdev_bandwidth_conf.c create mode 100644 src/conf/netdev_bandwidth_conf.h create mode 100644 src/conf/netdev_vport_profile_conf.c create mode 100644 src/conf/netdev_vport_profile_conf.h delete mode 100644 src/util/network.c delete mode 100644 src/util/network.h create mode 100644 src/util/virnetdevbandwidth.c create mode 100644 src/util/virnetdevbandwidth.h create mode 100644 src/util/virnetdevvportprofile.c create mode 100644 src/util/virnetdevvportprofile.h create mode 100644 src/util/virsocketaddr.c create mode 100644 src/util/virsocketaddr.h diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h index ecb7374..ce787a4 100644 --- a/daemon/libvirtd.h +++ b/daemon/libvirtd.h @@ -33,7 +33,6 @@ # include "qemu_protocol.h" # include "logging.h" # include "threads.h" -# include "network.h" # if HAVE_SASL # include "virnetsaslcontext.h" # endif diff --git a/daemon/remote.c b/daemon/remote.c index bd0c3e3..b028352 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -38,7 +38,6 @@ #include "util.h" #include "stream.h" #include "uuid.h" -#include "network.h" #include "libvirt/libvirt-qemu.h" #include "command.h" #include "intprops.h" diff --git a/po/POTFILES.in b/po/POTFILES.in index a3685e8..1665d2d 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -8,6 +8,8 @@ src/conf/cpu_conf.c src/conf/domain_conf.c src/conf/domain_event.c src/conf/interface_conf.c +src/conf/netdev_bandwidth_conf.c +src/conf/netdev_vport_profile_conf.c src/conf/network_conf.c src/conf/node_device_conf.c src/conf/nwfilter_conf.c @@ -116,7 +118,6 @@ src/util/iptables.c src/util/json.c src/util/macvtap.c src/util/netlink.c -src/util/network.c src/util/pci.c src/util/processinfo.c src/util/sexpr.c @@ -130,6 +131,7 @@ src/util/virnetdev.c src/util/virnetdevbridge.c src/util/virnetdevtap.c src/util/virpidfile.c +src/util/virsocketaddr.c src/util/virterror.c src/util/xml.c src/vbox/vbox_MSCOMGlue.c diff --git a/src/Makefile.am b/src/Makefile.am index f742f2a..2faf659 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -71,7 +71,6 @@ UTIL_SOURCES = \ util/pci.c util/pci.h \ util/processinfo.c util/processinfo.h \ util/hostusb.c util/hostusb.h \ - util/network.c util/network.h \ util/interface.c util/interface.h \ util/qparams.c util/qparams.h \ util/sexpr.c util/sexpr.h \ @@ -92,8 +91,11 @@ UTIL_SOURCES = \ util/virkeycode.c util/virkeycode.h \ util/virkeymaps.h \ util/virnetdev.h util/virnetdev.c \ + util/virnetdevbandwidth.h util/virnetdevbandwidth.c \ util/virnetdevbridge.h util/virnetdevbridge.c \ - util/virnetdevtap.h util/virnetdevtap.c + util/virnetdevtap.h util/virnetdevtap.c \ + util/virnetdevvportprofile.h util/virnetdevvportprofile.c \ + util/virsocketaddr.h util/virsocketaddr.c EXTRA_DIST += $(srcdir)/util/virkeymaps.h $(srcdir)/util/keymaps.csv \ $(srcdir)/util/virkeycode-mapgen.py @@ -124,6 +126,10 @@ LOCK_DRIVER_SANLOCK_SOURCES = \ locking/lock_driver_sanlock.c +NETDEV_CONF_SOURCES = \ + conf/netdev_bandwidth_conf.h conf/netdev_bandwidth_conf.c \ + conf/netdev_vport_profile_conf.h conf/netdev_vport_profile_conf.c + # XML configuration format handling sources # Domain driver generic impl APIs DOMAIN_CONF_SOURCES = \ @@ -171,6 +177,7 @@ CPU_CONF_SOURCES = \ conf/cpu_conf.c conf/cpu_conf.h CONF_SOURCES = \ + $(NETDEV_CONF_SOURCES) \ $(DOMAIN_CONF_SOURCES) \ $(DOMAIN_EVENT_SOURCES) \ $(NETWORK_CONF_SOURCES) \ @@ -1477,6 +1484,7 @@ libvirt_lxc_SOURCES = \ $(UTIL_SOURCES) \ $(NODE_INFO_SOURCES) \ $(ENCRYPTION_CONF_SOURCES) \ + $(NETDEV_CONF_SOURCES) \ $(DOMAIN_CONF_SOURCES) \ $(SECRET_CONF_SOURCES) \ $(CPU_CONF_SOURCES) \ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b1e47a3..b3c3339 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -42,7 +42,6 @@ #include "buf.h" #include "c-ctype.h" #include "logging.h" -#include "network.h" #include "nwfilter_conf.h" #include "ignore-value.h" #include "storage_file.h" @@ -50,6 +49,8 @@ #include "bitmap.h" #include "count-one-bits.h" #include "secret_conf.h" +#include "netdev_vport_profile_conf.h" +#include "netdev_bandwidth_conf.h" #define VIR_FROM_THIS VIR_FROM_DOMAIN diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 255d8fd..c360674 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -35,11 +35,13 @@ # include "util.h" # include "threads.h" # include "hash.h" -# include "network.h" +# include "virsocketaddr.h" # include "nwfilter_params.h" # include "nwfilter_conf.h" # include "macvtap.h" # include "sysinfo.h" +# include "virnetdevvportprofile.h" +# include "virnetdevbandwidth.h" /* Different types of hypervisor */ /* NB: Keep in sync with virDomainVirtTypeToString impl */ diff --git a/src/conf/netdev_bandwidth_conf.c b/src/conf/netdev_bandwidth_conf.c new file mode 100644 index 0000000..24cd13d --- /dev/null +++ b/src/conf/netdev_bandwidth_conf.c @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Michal Privoznik <mprivozn@redhat.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#include <config.h> + +#include "netdev_bandwidth_conf.h" +#include "virterror_internal.h" +#include "util.h" +#include "memory.h" + +#define VIR_FROM_THIS VIR_FROM_NONE +#define virNetDevError(code, ...) \ + virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \ + __FUNCTION__, __LINE__, __VA_ARGS__) + + +static int +virNetDevBandwidthParseRate(xmlNodePtr node, virNetDevBandwidthRatePtr rate) +{ + int ret = -1; + char *average = NULL; + char *peak = NULL; + char *burst = NULL; + + if (!node || !rate) { + virNetDevError(VIR_ERR_INVALID_ARG, "%s", + _("invalid argument supplied")); + return -1; + } + + average = virXMLPropString(node, "average"); + peak = virXMLPropString(node, "peak"); + burst = virXMLPropString(node, "burst"); + + if (average) { + if (virStrToLong_ull(average, NULL, 10, &rate->average) < 0) { + virNetDevError(VIR_ERR_CONFIG_UNSUPPORTED, + _("could not convert %s"), + average); + goto cleanup; + } + } else { + virNetDevError(VIR_ERR_XML_DETAIL, "%s", + _("Missing mandatory average attribute")); + goto cleanup; + } + + if (peak && virStrToLong_ull(peak, NULL, 10, &rate->peak) < 0) { + virNetDevError(VIR_ERR_CONFIG_UNSUPPORTED, + _("could not convert %s"), + peak); + goto cleanup; + } + + if (burst && virStrToLong_ull(burst, NULL, 10, &rate->burst) < 0) { + virNetDevError(VIR_ERR_CONFIG_UNSUPPORTED, + _("could not convert %s"), + burst); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(average); + VIR_FREE(peak); + VIR_FREE(burst); + + return ret; +} + +/** + * virNetDevBandwidthParse: + * @node: XML node + * + * Parse bandwidth XML and return pointer to structure + * + * Returns !NULL on success, NULL on error. + */ +virNetDevBandwidthPtr +virNetDevBandwidthParse(xmlNodePtr node) +{ + virNetDevBandwidthPtr def = NULL; + xmlNodePtr cur = node->children; + xmlNodePtr in = NULL, out = NULL; + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(); + return NULL; + } + + if (!node || !xmlStrEqual(node->name, BAD_CAST "bandwidth")) { + virNetDevError(VIR_ERR_INVALID_ARG, "%s", + _("invalid argument supplied")); + goto error; + } + + while (cur) { + if (cur->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(cur->name, BAD_CAST "inbound")) { + if (in) { + virNetDevError(VIR_ERR_XML_DETAIL, "%s", + _("Only one child <inbound> " + "element allowed")); + goto error; + } + in = cur; + } else if (xmlStrEqual(cur->name, BAD_CAST "outbound")) { + if (out) { + virNetDevError(VIR_ERR_XML_DETAIL, "%s", + _("Only one child <outbound> " + "element allowed")); + goto error; + } + out = cur; + } + /* Silently ignore unknown elements */ + } + cur = cur->next; + } + + if (in) { + if (VIR_ALLOC(def->in) < 0) { + virReportOOMError(); + goto error; + } + + if (virNetDevBandwidthParseRate(in, def->in) < 0) { + /* helper reported error for us */ + goto error; + } + } + + if (out) { + if (VIR_ALLOC(def->out) < 0) { + virReportOOMError(); + goto error; + } + + if (virNetDevBandwidthParseRate(out, def->out) < 0) { + /* helper reported error for us */ + goto error; + } + } + + return def; + +error: + virNetDevBandwidthFree(def); + return NULL; +} + +static int +virNetDevBandwidthRateFormat(virNetDevBandwidthRatePtr def, + virBufferPtr buf, + const char *elem_name) +{ + if (!buf || !elem_name) + return -1; + if (!def) + return 0; + + if (def->average) { + virBufferAsprintf(buf, " <%s average='%llu'", elem_name, + def->average); + + if (def->peak) + virBufferAsprintf(buf, " peak='%llu'", def->peak); + + if (def->burst) + virBufferAsprintf(buf, " burst='%llu'", def->burst); + virBufferAddLit(buf, "/>\n"); + } + + return 0; +} + +/** + * virNetDevBandwidthDefFormat: + * @def: Data source + * @buf: Buffer to print to + * + * Formats bandwidth and prepend each line with @indent. + * @buf may use auto-indentation. + * + * Returns 0 on success, else -1. + */ +int +virNetDevBandwidthFormat(virNetDevBandwidthPtr def, virBufferPtr buf) +{ + int ret = -1; + + if (!buf) + goto cleanup; + + if (!def) { + ret = 0; + goto cleanup; + } + + virBufferAddLit(buf, "<bandwidth>\n"); + if (virNetDevBandwidthRateFormat(def->in, buf, "inbound") < 0 || + virNetDevBandwidthRateFormat(def->out, buf, "outbound") < 0) + goto cleanup; + virBufferAddLit(buf, "</bandwidth>\n"); + + ret = 0; + +cleanup: + return ret; +} diff --git a/src/conf/netdev_bandwidth_conf.h b/src/conf/netdev_bandwidth_conf.h new file mode 100644 index 0000000..4bb7def --- /dev/null +++ b/src/conf/netdev_bandwidth_conf.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Michal Privoznik <mprivozn@redhat.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#ifndef __VIR_NETDEV_BANDWIDTH_CONF_H__ +# define __VIR_NETDEV_BANDWIDTH_CONF_H__ + +# include "internal.h" +# include "virnetdevbandwidth.h" +# include "buf.h" +# include "xml.h" + +virNetDevBandwidthPtr virNetDevBandwidthParse(xmlNodePtr node) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBandwidthFormat(virNetDevBandwidthPtr def, + virBufferPtr buf) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +#endif /* __VIR_NETDEV_BANDWIDTH_CONF_H__ */ diff --git a/src/conf/netdev_vport_profile_conf.c b/src/conf/netdev_vport_profile_conf.c new file mode 100644 index 0000000..63c6668 --- /dev/null +++ b/src/conf/netdev_vport_profile_conf.c @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Laine Stump <laine@laine.org> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#include <config.h> + +#include "netdev_vport_profile_conf.h" +#include "virterror_internal.h" +#include "memory.h" + +#define VIR_FROM_THIS VIR_FROM_NONE +#define virNetDevError(code, ...) \ + virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \ + __FUNCTION__, __LINE__, __VA_ARGS__) + + +VIR_ENUM_IMPL(virNetDevVPort, VIR_NETDEV_VPORT_PROFILE_LAST, + "none", + "802.1Qbg", + "802.1Qbh") + + +virNetDevVPortProfilePtr +virNetDevVPortProfileParse(xmlNodePtr node) +{ + char *virtPortType; + char *virtPortManagerID = NULL; + char *virtPortTypeID = NULL; + char *virtPortTypeIDVersion = NULL; + char *virtPortInstanceID = NULL; + char *virtPortProfileID = NULL; + virNetDevVPortProfilePtr virtPort = NULL; + xmlNodePtr cur = node->children; + + if (VIR_ALLOC(virtPort) < 0) { + virReportOOMError(); + return NULL; + } + + virtPortType = virXMLPropString(node, "type"); + if (!virtPortType) { + virNetDevError(VIR_ERR_XML_ERROR, "%s", + _("missing virtualportprofile type")); + goto error; + } + + if ((virtPort->virtPortType = virNetDevVPortTypeFromString(virtPortType)) <= 0) { + virNetDevError(VIR_ERR_XML_ERROR, + _("unknown virtualportprofile type %s"), virtPortType); + goto error; + } + + while (cur != NULL) { + if (xmlStrEqual(cur->name, BAD_CAST "parameters")) { + + virtPortManagerID = virXMLPropString(cur, "managerid"); + virtPortTypeID = virXMLPropString(cur, "typeid"); + virtPortTypeIDVersion = virXMLPropString(cur, "typeidversion"); + virtPortInstanceID = virXMLPropString(cur, "instanceid"); + virtPortProfileID = virXMLPropString(cur, "profileid"); + + break; + } + + cur = cur->next; + } + + switch (virtPort->virtPortType) { + case VIR_NETDEV_VPORT_PROFILE_8021QBG: + if (virtPortManagerID != NULL && virtPortTypeID != NULL && + virtPortTypeIDVersion != NULL) { + unsigned int val; + + if (virStrToLong_ui(virtPortManagerID, NULL, 0, &val)) { + virNetDevError(VIR_ERR_XML_ERROR, "%s", + _("cannot parse value of managerid parameter")); + goto error; + } + + if (val > 0xff) { + virNetDevError(VIR_ERR_XML_ERROR, "%s", + _("value of managerid out of range")); + goto error; + } + + virtPort->u.virtPort8021Qbg.managerID = (uint8_t)val; + + if (virStrToLong_ui(virtPortTypeID, NULL, 0, &val)) { + virNetDevError(VIR_ERR_XML_ERROR, "%s", + _("cannot parse value of typeid parameter")); + goto error; + } + + if (val > 0xffffff) { + virNetDevError(VIR_ERR_XML_ERROR, "%s", + _("value for typeid out of range")); + goto error; + } + + virtPort->u.virtPort8021Qbg.typeID = (uint32_t)val; + + if (virStrToLong_ui(virtPortTypeIDVersion, NULL, 0, &val)) { + virNetDevError(VIR_ERR_XML_ERROR, "%s", + _("cannot parse value of typeidversion parameter")); + goto error; + } + + if (val > 0xff) { + virNetDevError(VIR_ERR_XML_ERROR, "%s", + _("value of typeidversion out of range")); + goto error; + } + + virtPort->u.virtPort8021Qbg.typeIDVersion = (uint8_t)val; + + if (virtPortInstanceID != NULL) { + if (virUUIDParse(virtPortInstanceID, + virtPort->u.virtPort8021Qbg.instanceID)) { + virNetDevError(VIR_ERR_XML_ERROR, "%s", + _("cannot parse instanceid parameter as a uuid")); + goto error; + } + } else { + if (virUUIDGenerate(virtPort->u.virtPort8021Qbg.instanceID)) { + virNetDevError(VIR_ERR_XML_ERROR, "%s", + _("cannot generate a random uuid for instanceid")); + goto error; + } + } + + virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBG; + + } else { + virNetDevError(VIR_ERR_XML_ERROR, "%s", + _("a parameter is missing for 802.1Qbg description")); + goto error; + } + break; + + case VIR_NETDEV_VPORT_PROFILE_8021QBH: + if (virtPortProfileID != NULL) { + if (virStrcpyStatic(virtPort->u.virtPort8021Qbh.profileID, + virtPortProfileID) != NULL) { + virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBH; + } else { + virNetDevError(VIR_ERR_XML_ERROR, "%s", + _("profileid parameter too long")); + goto error; + } + } else { + virNetDevError(VIR_ERR_XML_ERROR, "%s", + _("profileid parameter is missing for 802.1Qbh descripion")); + goto error; + } + break; + + default: + virNetDevError(VIR_ERR_XML_ERROR, + _("unexpected virtualport type %d"), virtPort->virtPortType); + goto error; + } + +cleanup: + VIR_FREE(virtPortManagerID); + VIR_FREE(virtPortTypeID); + VIR_FREE(virtPortTypeIDVersion); + VIR_FREE(virtPortInstanceID); + VIR_FREE(virtPortProfileID); + VIR_FREE(virtPortType); + + return virtPort; + +error: + VIR_FREE(virtPort); + goto cleanup; +} + + +int +virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, + virBufferPtr buf) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + + if (!virtPort || virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE) + return 0; + + virBufferAsprintf(buf, "<virtualport type='%s'>\n", + virNetDevVPortTypeToString(virtPort->virtPortType)); + + switch (virtPort->virtPortType) { + case VIR_NETDEV_VPORT_PROFILE_8021QBG: + virUUIDFormat(virtPort->u.virtPort8021Qbg.instanceID, + uuidstr); + virBufferAsprintf(buf, + " <parameters managerid='%d' typeid='%d' " + "typeidversion='%d' instanceid='%s'/>\n", + virtPort->u.virtPort8021Qbg.managerID, + virtPort->u.virtPort8021Qbg.typeID, + virtPort->u.virtPort8021Qbg.typeIDVersion, + uuidstr); + break; + + case VIR_NETDEV_VPORT_PROFILE_8021QBH: + virBufferAsprintf(buf, + " <parameters profileid='%s'/>\n", + virtPort->u.virtPort8021Qbh.profileID); + break; + + default: + virNetDevError(VIR_ERR_XML_ERROR, + _("unexpected virtualport type %d"), virtPort->virtPortType); + return -1; + } + + virBufferAddLit(buf, "</virtualport>\n"); + return 0; +} diff --git a/src/conf/netdev_vport_profile_conf.h b/src/conf/netdev_vport_profile_conf.h new file mode 100644 index 0000000..3ab6975 --- /dev/null +++ b/src/conf/netdev_vport_profile_conf.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Laine Stump <laine@laine.org> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#ifndef __VIR_NETDEV_VPORT_PROFILE_CONF_H__ +# define __VIR_NETDEV_VPORT_PROFILE_CONF_H__ + +# include "internal.h" +# include "virnetdevvportprofile.h" +# include "buf.h" +# include "xml.h" + +virNetDevVPortProfilePtr +virNetDevVPortProfileParse(xmlNodePtr node); + +int +virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, + virBufferPtr buf); + + +#endif /* __VIR_NETDEV_VPORT_PROFILE_CONF_H__ */ diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 5e38bee..10afcde 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -34,7 +34,8 @@ #include "virterror_internal.h" #include "datatypes.h" #include "network_conf.h" -#include "network.h" +#include "netdev_vport_profile_conf.h" +#include "netdev_bandwidth_conf.h" #include "memory.h" #include "xml.h" #include "uuid.h" diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 57ad637..1be20f8 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -30,7 +30,9 @@ # include "internal.h" # include "threads.h" -# include "network.h" +# include "virsocketaddr.h" +# include "virnetdevbandwidth.h" +# include "virnetdevvportprofile.h" # include "util.h" enum virNetworkForwardType { diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index c96851a..f48c7cd 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -35,7 +35,7 @@ # include "hash.h" # include "xml.h" # include "buf.h" -# include "network.h" +# include "virsocketaddr.h" /* XXX * The config parser/structs should not be using platform specific diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h index 8d172e1..2bee510 100644 --- a/src/esx/esx_util.h +++ b/src/esx/esx_util.h @@ -23,7 +23,7 @@ # define __ESX_UTIL_H__ # include <libxml/uri.h> - +# include <netdb.h> # include "internal.h" typedef struct _esxUtil_ParsedUri esxUtil_ParsedUri; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index b297f47..e68712f 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -59,7 +59,6 @@ #include "interface.h" #include "logging.h" #include "dnsmasq.h" -#include "util/network.h" #include "configmake.h" #include "ignore-value.h" #include "virnetdev.h" diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index d1bf075..4c20d17 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -50,7 +50,6 @@ #include "xml.h" #include "nodeinfo.h" #include "logging.h" -#include "network.h" #include "macvtap.h" #include "cpu/cpu.h" #include "domain_nwfilter.h" diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index 3c9f327..8ef4887 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -29,6 +29,7 @@ #include <sys/wait.h> #include <signal.h> #include <fcntl.h> +#include <netdb.h> #ifdef HAVE_NETINET_TCP_H # include <netinet/tcp.h> diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h index 13cbb14..b795ab9 100644 --- a/src/rpc/virnetsocket.h +++ b/src/rpc/virnetsocket.h @@ -24,7 +24,7 @@ #ifndef __VIR_NET_SOCKET_H__ # define __VIR_NET_SOCKET_H__ -# include "network.h" +# include "virsocketaddr.h" # include "command.h" # include "virnettlscontext.h" # ifdef HAVE_SASL diff --git a/src/util/dnsmasq.h b/src/util/dnsmasq.h index d16a54f..2bec726 100644 --- a/src/util/dnsmasq.h +++ b/src/util/dnsmasq.h @@ -22,7 +22,7 @@ #ifndef __DNSMASQ_H__ # define __DNSMASQ_H__ -# include "network.h" +# include "virsocketaddr.h" typedef struct { diff --git a/src/util/interface.h b/src/util/interface.h index 7be1444..3603c68 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -25,7 +25,7 @@ struct nlattr; # endif # include "datatypes.h" -# include "network.h" +# include "virsocketaddr.h" # define NET_SYSFS "/sys/class/net/" diff --git a/src/util/iptables.h b/src/util/iptables.h index 572d612..429f29c 100644 --- a/src/util/iptables.h +++ b/src/util/iptables.h @@ -22,7 +22,7 @@ #ifndef __QEMUD_IPTABLES_H__ # define __QEMUD_IPTABLES_H__ -# include "network.h" +# include "virsocketaddr.h" typedef struct _iptablesContext iptablesContext; diff --git a/src/util/macvtap.c b/src/util/macvtap.c index 71243b8..c4629ed 100644 --- a/src/util/macvtap.c +++ b/src/util/macvtap.c @@ -50,7 +50,6 @@ #include "util.h" #include "macvtap.h" -#include "network.h" VIR_ENUM_IMPL(virMacvtapMode, VIR_MACVTAP_MODE_LAST, "vepa", diff --git a/src/util/macvtap.h b/src/util/macvtap.h index d685ab9..a6b00fe 100644 --- a/src/util/macvtap.h +++ b/src/util/macvtap.h @@ -23,7 +23,10 @@ #ifndef __UTIL_MACVTAP_H__ # define __UTIL_MACVTAP_H__ -# include <config.h> +# include "internal.h" +# include "virsocketaddr.h" +# include "virnetdevbandwidth.h" +# include "virnetdevvportprofile.h" /* the mode type for macvtap devices */ enum virMacvtapMode { @@ -50,9 +53,6 @@ enum virVMOperationType { # if WITH_MACVTAP -# include "internal.h" -# include "network.h" - int openMacvtapTap(const char *ifname, const unsigned char *macaddress, const char *linkdev, diff --git a/src/util/network.c b/src/util/network.c deleted file mode 100644 index c467121..0000000 --- a/src/util/network.c +++ /dev/null @@ -1,1349 +0,0 @@ -/* - * network.c: network helper APIs for libvirt - * - * Copyright (C) 2009-2011 Red Hat, Inc. - * - * See COPYING.LIB for the License of this software - * - * Daniel Veillard <veillard@redhat.com> - */ - -#include <config.h> -#include <arpa/inet.h> - -#include "memory.h" -#include "uuid.h" -#include "network.h" -#include "util.h" -#include "virterror_internal.h" -#include "command.h" -#include "ignore-value.h" - -#define VIR_FROM_THIS VIR_FROM_NONE -#define virSocketError(code, ...) \ - virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \ - __FUNCTION__, __LINE__, __VA_ARGS__) - -/* - * Helpers to extract the IP arrays from the virSocketAddrPtr - * That part is the less portable of the module - */ -typedef unsigned char virSocketAddrIPv4[4]; -typedef virSocketAddrIPv4 *virSocketAddrIPv4Ptr; -typedef unsigned short virSocketAddrIPv6[8]; -typedef virSocketAddrIPv6 *virSocketAddrIPv6Ptr; - -static int virSocketAddrGetIPv4Addr(virSocketAddrPtr addr, virSocketAddrIPv4Ptr tab) { - unsigned long val; - int i; - - if ((addr == NULL) || (tab == NULL) || (addr->data.stor.ss_family != AF_INET)) - return(-1); - - val = ntohl(addr->data.inet4.sin_addr.s_addr); - - for (i = 0;i < 4;i++) { - (*tab)[3 - i] = val & 0xFF; - val >>= 8; - } - - return(0); -} - -static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr tab) { - int i; - - if ((addr == NULL) || (tab == NULL) || (addr->data.stor.ss_family != AF_INET6)) - return(-1); - - for (i = 0;i < 8;i++) { - (*tab)[i] = ((addr->data.inet6.sin6_addr.s6_addr[2 * i] << 8) | - addr->data.inet6.sin6_addr.s6_addr[2 * i + 1]); - } - - return(0); -} - -/** - * virSocketAddrParse: - * @val: a numeric network address IPv4 or IPv6 - * @addr: where to store the return value, optional. - * @family: address family to pass down to getaddrinfo - * - * Mostly a wrapper for getaddrinfo() extracting the address storage - * from the numeric string like 1.2.3.4 or 2001:db8:85a3:0:0:8a2e:370:7334 - * - * Returns the length of the network address or -1 in case of error. - */ -int virSocketAddrParse(virSocketAddrPtr addr, const char *val, int family) { - int len; - struct addrinfo hints; - struct addrinfo *res = NULL; - int err; - - if (val == NULL) { - virSocketError(VIR_ERR_INVALID_ARG, "%s", _("Missing address")); - return -1; - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = family; - hints.ai_flags = AI_NUMERICHOST; - if ((err = getaddrinfo(val, NULL, &hints, &res)) != 0) { - virSocketError(VIR_ERR_SYSTEM_ERROR, - _("Cannot parse socket address '%s': %s"), - val, gai_strerror(err)); - return -1; - } - - if (res == NULL) { - virSocketError(VIR_ERR_SYSTEM_ERROR, - _("No socket addresses found for '%s'"), - val); - return -1; - } - - len = res->ai_addrlen; - if (addr != NULL) { - memcpy(&addr->data.stor, res->ai_addr, len); - addr->len = res->ai_addrlen; - } - - freeaddrinfo(res); - return(len); -} - -/* - * virSocketAddrParseIPv4: - * @val: an IPv4 numeric address - * @addr: the location to store the result - * - * Extract the address storage from an IPv4 numeric address - * - * Returns the length of the network address or -1 in case of error. - */ -int -virSocketAddrParseIPv4(virSocketAddrPtr addr, const char *val) { - return virSocketAddrParse(addr, val, AF_INET); -} - -/* - * virSocketAddrParseIPv6: - * @val: an IPv6 numeric address - * @addr: the location to store the result - * - * Extract the address storage from an IPv6 numeric address - * - * Returns the length of the network address or -1 in case of error. - */ -int -virSocketAddrParseIPv6(virSocketAddrPtr addr, const char *val) { - return virSocketAddrParse(addr, val, AF_INET6); -} - -/* - * virSocketAddrFormat: - * @addr: an initialized virSocketAddrPtr - * - * Returns a string representation of the given address - * Returns NULL on any error - * Caller must free the returned string - */ -char * -virSocketAddrFormat(virSocketAddrPtr addr) { - return virSocketAddrFormatFull(addr, false, NULL); -} - - -/* - * virSocketAddrFormatFull: - * @addr: an initialized virSocketAddrPtr - * @withService: if true, then service info is appended - * @separator: separator between hostname & service. - * - * Returns a string representation of the given address - * Returns NULL on any error - * Caller must free the returned string - */ -char * -virSocketAddrFormatFull(virSocketAddrPtr addr, - bool withService, - const char *separator) -{ - char host[NI_MAXHOST], port[NI_MAXSERV]; - char *addrstr; - int err; - - if (addr == NULL) { - virSocketError(VIR_ERR_INVALID_ARG, "%s", _("Missing address")); - return NULL; - } - - /* Short-circuit since getnameinfo doesn't work - * nicely for UNIX sockets */ - if (addr->data.sa.sa_family == AF_UNIX) { - if (withService) { - if (virAsprintf(&addrstr, "127.0.0.1%s0", - separator ? separator : ":") < 0) - goto no_memory; - } else { - if (!(addrstr = strdup("127.0.0.1"))) - goto no_memory; - } - return addrstr; - } - - if ((err = getnameinfo(&addr->data.sa, - addr->len, - host, sizeof(host), - port, sizeof(port), - NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { - virSocketError(VIR_ERR_SYSTEM_ERROR, - _("Cannot convert socket address to string: %s"), - gai_strerror(err)); - return NULL; - } - - if (withService) { - if (virAsprintf(&addrstr, "%s%s%s", host, separator, port) == -1) - goto no_memory; - } else { - if (!(addrstr = strdup(host))) - goto no_memory; - } - - return addrstr; - -no_memory: - virReportOOMError(); - return NULL; -} - - -/* - * virSocketAddrSetPort: - * @addr: an initialized virSocketAddrPtr - * @port: the port number to set - * - * Set the transport layer port of the given virtSocketAddr - * - * Returns 0 on success, -1 on failure - */ -int -virSocketAddrSetPort(virSocketAddrPtr addr, int port) { - if (addr == NULL) - return -1; - - port = htons(port); - - if(addr->data.stor.ss_family == AF_INET) { - addr->data.inet4.sin_port = port; - } - - else if(addr->data.stor.ss_family == AF_INET6) { - addr->data.inet6.sin6_port = port; - } - - else { - return -1; - } - - return 0; -} - -/* - * virSocketGetPort: - * @addr: an initialized virSocketAddrPtr - * - * Returns the transport layer port of the given virtSocketAddr - * Returns -1 if @addr is invalid - */ -int -virSocketAddrGetPort(virSocketAddrPtr addr) { - if (addr == NULL) - return -1; - - if(addr->data.stor.ss_family == AF_INET) { - return ntohs(addr->data.inet4.sin_port); - } - - else if(addr->data.stor.ss_family == AF_INET6) { - return ntohs(addr->data.inet6.sin6_port); - } - - return -1; -} - -/** - * virSocketAddrIsNetmask: - * @netmask: the netmask address - * - * Check that @netmask is a proper network mask - * - * Returns 0 in case of success and -1 in case of error - */ -int virSocketAddrIsNetmask(virSocketAddrPtr netmask) { - int n = virSocketAddrGetNumNetmaskBits(netmask); - if (n < 0) - return -1; - return 0; -} - -/** - * virSocketAddrMask: - * @addr: address that needs to be masked - * @netmask: the netmask address - * @network: where to store the result, can be same as @addr - * - * Mask off the host bits of @addr according to @netmask, turning it - * into a network address. - * - * Returns 0 in case of success, or -1 on error. - */ -int -virSocketAddrMask(const virSocketAddrPtr addr, - const virSocketAddrPtr netmask, - virSocketAddrPtr network) -{ - if (addr->data.stor.ss_family != netmask->data.stor.ss_family) { - network->data.stor.ss_family = AF_UNSPEC; - return -1; - } - - if (addr->data.stor.ss_family == AF_INET) { - network->data.inet4.sin_addr.s_addr - = (addr->data.inet4.sin_addr.s_addr - & netmask->data.inet4.sin_addr.s_addr); - network->data.inet4.sin_port = 0; - network->data.stor.ss_family = AF_INET; - network->len = addr->len; - return 0; - } - if (addr->data.stor.ss_family == AF_INET6) { - int ii; - for (ii = 0; ii < 16; ii++) { - network->data.inet6.sin6_addr.s6_addr[ii] - = (addr->data.inet6.sin6_addr.s6_addr[ii] - & netmask->data.inet6.sin6_addr.s6_addr[ii]); - } - network->data.inet6.sin6_port = 0; - network->data.stor.ss_family = AF_INET6; - network->len = addr->len; - return 0; - } - network->data.stor.ss_family = AF_UNSPEC; - return -1; -} - -/** - * virSocketAddrMaskByPrefix: - * @addr: address that needs to be masked - * @prefix: prefix (# of 1 bits) of netmask to apply - * @network: where to store the result, can be same as @addr - * - * Mask off the host bits of @addr according to @prefix, turning it - * into a network address. - * - * Returns 0 in case of success, or -1 on error. - */ -int -virSocketAddrMaskByPrefix(const virSocketAddrPtr addr, - unsigned int prefix, - virSocketAddrPtr network) -{ - virSocketAddr netmask; - - if (virSocketAddrPrefixToNetmask(prefix, &netmask, - addr->data.stor.ss_family) < 0) { - network->data.stor.ss_family = AF_UNSPEC; - return -1; - } - - return virSocketAddrMask(addr, &netmask, network); -} - -/** - * virSocketAddrBroadcast: - * @addr: address that needs to be turned into broadcast address (IPv4 only) - * @netmask: the netmask address - * @broadcast: virSocketAddr to recieve the broadcast address - * - * Mask ON the host bits of @addr according to @netmask, turning it - * into a broadcast address. - * - * Returns 0 in case of success, or -1 on error. - */ -int -virSocketAddrBroadcast(const virSocketAddrPtr addr, - const virSocketAddrPtr netmask, - virSocketAddrPtr broadcast) -{ - if ((addr->data.stor.ss_family != AF_INET) || - (netmask->data.stor.ss_family != AF_INET)) { - broadcast->data.stor.ss_family = AF_UNSPEC; - return -1; - } - - broadcast->data.stor.ss_family = AF_INET; - broadcast->len = addr->len; - broadcast->data.inet4.sin_addr.s_addr - = (addr->data.inet4.sin_addr.s_addr - | ~netmask->data.inet4.sin_addr.s_addr); - return 0; -} - -/** - * virSocketAddrBroadcastByPrefix: - * @addr: address that needs to be turned into broadcast address (IPv4 only) - * @prefix: prefix (# of 1 bits) of netmask to apply - * @broadcast: virSocketAddr to recieve the broadcast address - * - * Mask off the host bits of @addr according to @prefix, turning it - * into a network address. - * - * Returns 0 in case of success, or -1 on error. - */ -int -virSocketAddrBroadcastByPrefix(const virSocketAddrPtr addr, - unsigned int prefix, - virSocketAddrPtr broadcast) -{ - virSocketAddr netmask; - - if (virSocketAddrPrefixToNetmask(prefix, &netmask, - addr->data.stor.ss_family) < 0) - return -1; - - return virSocketAddrBroadcast(addr, &netmask, broadcast); -} - -/** - * virSocketCheckNetmask: - * @addr1: a first network address - * @addr2: a second network address - * @netmask: the netmask address - * - * Check that @addr1 and @addr2 pertain to the same @netmask address - * range and returns the size of the range - * - * Returns 1 in case of success and 0 in case of failure and - * -1 in case of error - */ -int virSocketAddrCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2, - virSocketAddrPtr netmask) { - int i; - - if ((addr1 == NULL) || (addr2 == NULL) || (netmask == NULL)) - return(-1); - if ((addr1->data.stor.ss_family != addr2->data.stor.ss_family) || - (addr1->data.stor.ss_family != netmask->data.stor.ss_family)) - return(-1); - - if (virSocketAddrIsNetmask(netmask) != 0) - return(-1); - - if (addr1->data.stor.ss_family == AF_INET) { - virSocketAddrIPv4 t1, t2, tm; - - if ((virSocketAddrGetIPv4Addr(addr1, &t1) < 0) || - (virSocketAddrGetIPv4Addr(addr2, &t2) < 0) || - (virSocketAddrGetIPv4Addr(netmask, &tm) < 0)) - return(-1); - - for (i = 0;i < 4;i++) { - if ((t1[i] & tm[i]) != (t2[i] & tm[i])) - return(0); - } - - } else if (addr1->data.stor.ss_family == AF_INET6) { - virSocketAddrIPv6 t1, t2, tm; - - if ((virSocketAddrGetIPv6Addr(addr1, &t1) < 0) || - (virSocketAddrGetIPv6Addr(addr2, &t2) < 0) || - (virSocketAddrGetIPv6Addr(netmask, &tm) < 0)) - return(-1); - - for (i = 0;i < 8;i++) { - if ((t1[i] & tm[i]) != (t2[i] & tm[i])) - return(0); - } - - } else { - return(-1); - } - return(1); -} - -/** - * virSocketGetRange: - * @start: start of an IP range - * @end: end of an IP range - * - * Check the order of the 2 addresses and compute the range, this - * will return 1 for identical addresses. Errors can come from incompatible - * addresses type, excessive range (>= 2^^16) where the two addresses are - * unrelated or inverted start and end. - * - * Returns the size of the range or -1 in case of failure - */ -int virSocketAddrGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { - int ret = 0, i; - - if ((start == NULL) || (end == NULL)) - return(-1); - if (start->data.stor.ss_family != end->data.stor.ss_family) - return(-1); - - if (start->data.stor.ss_family == AF_INET) { - virSocketAddrIPv4 t1, t2; - - if ((virSocketAddrGetIPv4Addr(start, &t1) < 0) || - (virSocketAddrGetIPv4Addr(end, &t2) < 0)) - return(-1); - - for (i = 0;i < 2;i++) { - if (t1[i] != t2[i]) - return(-1); - } - ret = (t2[2] - t1[2]) * 256 + (t2[3] - t1[3]); - if (ret < 0) - return(-1); - ret++; - } else if (start->data.stor.ss_family == AF_INET6) { - virSocketAddrIPv6 t1, t2; - - if ((virSocketAddrGetIPv6Addr(start, &t1) < 0) || - (virSocketAddrGetIPv6Addr(end, &t2) < 0)) - return(-1); - - for (i = 0;i < 7;i++) { - if (t1[i] != t2[i]) - return(-1); - } - ret = t2[7] - t1[7]; - if (ret < 0) - return(-1); - ret++; - } else { - return(-1); - } - return(ret); -} - - -/** - * virSocketAddrGetNumNetmaskBits - * @netmask: the presumed netmask - * - * Get the number of netmask bits in a netmask. - * - * Returns the number of bits in the netmask or -1 if an error occurred - * or the netmask is invalid. - */ -int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask) -{ - int i, j; - int c = 0; - - if (netmask->data.stor.ss_family == AF_INET) { - virSocketAddrIPv4 tm; - uint8_t bit; - - if (virSocketAddrGetIPv4Addr(netmask, &tm) < 0) - return -1; - - for (i = 0; i < 4; i++) - if (tm[i] == 0xff) - c += 8; - else - break; - - if (c == 8 * 4) - return c; - - j = i << 3; - while (j < (8 * 4)) { - bit = 1 << (7 - (j & 7)); - if ((tm[j >> 3] & bit)) { - c++; - } else - break; - j++; - } - - while (j < (8 * 4)) { - bit = 1 << (7 - (j & 7)); - if ((tm[j >> 3] & bit)) - return -1; - j++; - } - - return c; - } else if (netmask->data.stor.ss_family == AF_INET6) { - virSocketAddrIPv6 tm; - uint16_t bit; - - if (virSocketAddrGetIPv6Addr(netmask, &tm) < 0) - return -1; - - for (i = 0; i < 8; i++) - if (tm[i] == 0xffff) - c += 16; - else - break; - - if (c == 16 * 8) - return c; - - j = i << 4; - while (j < (16 * 8)) { - bit = 1 << (15 - (j & 0xf)); - if ((tm[j >> 4] & bit)) { - c++; - } else - break; - j++; - } - - while (j < (16 * 8)) { - bit = 1 << (15 - (j & 0xf)); - if ((tm[j >> 4]) & bit) - return -1; - j++; - } - - return c; - } - return -1; -} - -/** - * virSocketPrefixToNetmask: - * @prefix: number of 1 bits to put in the netmask - * @netmask: address to fill in with the desired netmask - * @family: family of the address (AF_INET or AF_INET6 only) - * - * given @prefix and @family, fill in @netmask with a netmask - * (eg 255.255.255.0). - * - * Returns 0 on success or -1 on error. - */ - -int -virSocketAddrPrefixToNetmask(unsigned int prefix, - virSocketAddrPtr netmask, - int family) -{ - int result = -1; - - netmask->data.stor.ss_family = AF_UNSPEC; /* assume failure */ - - if (family == AF_INET) { - int ip; - - if (prefix > 32) - goto error; - - ip = prefix ? ~((1 << (32 - prefix)) - 1) : 0; - netmask->data.inet4.sin_addr.s_addr = htonl(ip); - netmask->data.stor.ss_family = AF_INET; - result = 0; - - } else if (family == AF_INET6) { - int ii = 0; - - if (prefix > 128) - goto error; - - while (prefix >= 8) { - /* do as much as possible an entire byte at a time */ - netmask->data.inet6.sin6_addr.s6_addr[ii++] = 0xff; - prefix -= 8; - } - if (prefix > 0) { - /* final partial byte */ - netmask->data.inet6.sin6_addr.s6_addr[ii++] - = ~((1 << (8 - prefix)) -1); - } - while (ii < 16) { - /* zerofill remainder in case it wasn't initialized */ - netmask->data.inet6.sin6_addr.s6_addr[ii++] = 0; - } - netmask->data.stor.ss_family = AF_INET6; - result = 0; - } - -error: - return result; -} - -/* virtualPortProfile utilities */ - -VIR_ENUM_IMPL(virNetDevVPort, VIR_NETDEV_VPORT_PROFILE_LAST, - "none", - "802.1Qbg", - "802.1Qbh") - - -virNetDevVPortProfilePtr -virNetDevVPortProfileParse(xmlNodePtr node) -{ - char *virtPortType; - char *virtPortManagerID = NULL; - char *virtPortTypeID = NULL; - char *virtPortTypeIDVersion = NULL; - char *virtPortInstanceID = NULL; - char *virtPortProfileID = NULL; - virNetDevVPortProfilePtr virtPort = NULL; - xmlNodePtr cur = node->children; - - if (VIR_ALLOC(virtPort) < 0) { - virReportOOMError(); - return NULL; - } - - virtPortType = virXMLPropString(node, "type"); - if (!virtPortType) { - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("missing virtualportprofile type")); - goto error; - } - - if ((virtPortType = virNetDevVPortTypeFromString(virtPortType)) <= 0) { - virSocketError(VIR_ERR_XML_ERROR, - _("unknown virtualportprofile type %s"), virtPortType); - goto error; - } - - while (cur != NULL) { - if (xmlStrEqual(cur->name, BAD_CAST "parameters")) { - - virtPortManagerID = virXMLPropString(cur, "managerid"); - virtPortTypeID = virXMLPropString(cur, "typeid"); - virtPortTypeIDVersion = virXMLPropString(cur, "typeidversion"); - virtPortInstanceID = virXMLPropString(cur, "instanceid"); - virtPortProfileID = virXMLPropString(cur, "profileid"); - - break; - } - - cur = cur->next; - } - - switch (virtPort->virtPortType) { - case VIR_NETDEV_VPORT_PROFILE_8021QBG: - if (virtPortManagerID != NULL && virtPortTypeID != NULL && - virtPortTypeIDVersion != NULL) { - unsigned int val; - - if (virStrToLong_ui(virtPortManagerID, NULL, 0, &val)) { - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("cannot parse value of managerid parameter")); - goto error; - } - - if (val > 0xff) { - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("value of managerid out of range")); - goto error; - } - - virtPort->u.virtPort8021Qbg.managerID = (uint8_t)val; - - if (virStrToLong_ui(virtPortTypeID, NULL, 0, &val)) { - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("cannot parse value of typeid parameter")); - goto error; - } - - if (val > 0xffffff) { - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("value for typeid out of range")); - goto error; - } - - virtPort->u.virtPort8021Qbg.typeID = (uint32_t)val; - - if (virStrToLong_ui(virtPortTypeIDVersion, NULL, 0, &val)) { - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("cannot parse value of typeidversion parameter")); - goto error; - } - - if (val > 0xff) { - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("value of typeidversion out of range")); - goto error; - } - - virtPort->u.virtPort8021Qbg.typeIDVersion = (uint8_t)val; - - if (virtPortInstanceID != NULL) { - if (virUUIDParse(virtPortInstanceID, - virtPort->u.virtPort8021Qbg.instanceID)) { - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("cannot parse instanceid parameter as a uuid")); - goto error; - } - } else { - if (virUUIDGenerate(virtPort->u.virtPort8021Qbg.instanceID)) { - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("cannot generate a random uuid for instanceid")); - goto error; - } - } - - virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBG; - - } else { - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("a parameter is missing for 802.1Qbg description")); - goto error; - } - break; - - case VIR_NETDEV_VPORT_PROFILE_8021QBH: - if (virtPortProfileID != NULL) { - if (virStrcpyStatic(virtPort->u.virtPort8021Qbh.profileID, - virtPortProfileID) != NULL) { - virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBH; - } else { - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("profileid parameter too long")); - goto error; - } - } else { - virSocketError(VIR_ERR_XML_ERROR, "%s", - _("profileid parameter is missing for 802.1Qbh descripion")); - goto error; - } - break; - - default: - virSocketError(VIR_ERR_XML_ERROR, - _("unexpected virtualport type %d"), virtPort->virtPortType); - goto error; - } - -cleanup: - VIR_FREE(virtPortManagerID); - VIR_FREE(virtPortTypeID); - VIR_FREE(virtPortTypeIDVersion); - VIR_FREE(virtPortInstanceID); - VIR_FREE(virtPortProfileID); - VIR_FREE(virtPortType); - - return virtPort; - -error: - VIR_FREE(virtPort); - goto cleanup; -} - -bool -virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, virNetDevVPortProfilePtr b) -{ - /* NULL resistant */ - if (!a && !b) - return true; - - if (!a || !b) - return false; - - if (a->virtPortType != b->virtPortType) - return false; - - switch (a->virtPortType) { - case VIR_NETDEV_VPORT_PROFILE_NONE: - break; - - case VIR_NETDEV_VPORT_PROFILE_8021QBG: - if (a->u.virtPort8021Qbg.managerID != b->u.virtPort8021Qbg.managerID || - a->u.virtPort8021Qbg.typeID != b->u.virtPort8021Qbg.typeID || - a->u.virtPort8021Qbg.typeIDVersion != b->u.virtPort8021Qbg.typeIDVersion || - memcmp(a->u.virtPort8021Qbg.instanceID, b->u.virtPort8021Qbg.instanceID, VIR_UUID_BUFLEN) != 0) - return false; - break; - - case VIR_NETDEV_VPORT_PROFILE_8021QBH: - if (STRNEQ(a->u.virtPort8021Qbh.profileID, b->u.virtPort8021Qbh.profileID)) - return false; - break; - - default: - break; - } - - return true; -} - - -int -virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, - virBufferPtr buf) -{ - char uuidstr[VIR_UUID_STRING_BUFLEN]; - - if (!virtPort || virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE) - return 0; - - virBufferAsprintf(buf, "<virtualport type='%s'>\n", - virNetDevVPortTypeToString(virtPort->virtPortType)); - - switch (virtPort->virtPortType) { - case VIR_NETDEV_VPORT_PROFILE_8021QBG: - virUUIDFormat(virtPort->u.virtPort8021Qbg.instanceID, - uuidstr); - virBufferAsprintf(buf, - " <parameters managerid='%d' typeid='%d' " - "typeidversion='%d' instanceid='%s'/>\n", - virtPort->u.virtPort8021Qbg.managerID, - virtPort->u.virtPort8021Qbg.typeID, - virtPort->u.virtPort8021Qbg.typeIDVersion, - uuidstr); - break; - - case VIR_NETDEV_VPORT_PROFILE_8021QBH: - virBufferAsprintf(buf, - " <parameters profileid='%s'/>\n", - virtPort->u.virtPort8021Qbh.profileID); - break; - - default: - virSocketError(VIR_ERR_XML_ERROR, - _("unexpected virtualport type %d"), virtPort->virtPortType); - return -1; - } - - virBufferAddLit(buf, "</virtualport>\n"); - return 0; -} - -static int -virNetDevBandwidthParseRate(xmlNodePtr node, virNetDevBandwidthRatePtr rate) -{ - int ret = -1; - char *average = NULL; - char *peak = NULL; - char *burst = NULL; - - if (!node || !rate) { - virSocketError(VIR_ERR_INVALID_ARG, "%s", - _("invalid argument supplied")); - return -1; - } - - average = virXMLPropString(node, "average"); - peak = virXMLPropString(node, "peak"); - burst = virXMLPropString(node, "burst"); - - if (average) { - if (virStrToLong_ull(average, NULL, 10, &rate->average) < 0) { - virSocketError(VIR_ERR_CONFIG_UNSUPPORTED, - _("could not convert %s"), - average); - goto cleanup; - } - } else { - virSocketError(VIR_ERR_XML_DETAIL, "%s", - _("Missing mandatory average attribute")); - goto cleanup; - } - - if (peak && virStrToLong_ull(peak, NULL, 10, &rate->peak) < 0) { - virSocketError(VIR_ERR_CONFIG_UNSUPPORTED, - _("could not convert %s"), - peak); - goto cleanup; - } - - if (burst && virStrToLong_ull(burst, NULL, 10, &rate->burst) < 0) { - virSocketError(VIR_ERR_CONFIG_UNSUPPORTED, - _("could not convert %s"), - burst); - goto cleanup; - } - - ret = 0; - -cleanup: - VIR_FREE(average); - VIR_FREE(peak); - VIR_FREE(burst); - - return ret; -} - -/** - * virNetDevBandwidthParse: - * @node: XML node - * - * Parse bandwidth XML and return pointer to structure - * - * Returns !NULL on success, NULL on error. - */ -virNetDevBandwidthPtr -virNetDevBandwidthParse(xmlNodePtr node) -{ - virNetDevBandwidthPtr def = NULL; - xmlNodePtr cur = node->children; - xmlNodePtr in = NULL, out = NULL; - - if (VIR_ALLOC(def) < 0) { - virReportOOMError(); - return NULL; - } - - if (!node || !xmlStrEqual(node->name, BAD_CAST "bandwidth")) { - virSocketError(VIR_ERR_INVALID_ARG, "%s", - _("invalid argument supplied")); - goto error; - } - - while (cur) { - if (cur->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(cur->name, BAD_CAST "inbound")) { - if (in) { - virSocketError(VIR_ERR_XML_DETAIL, "%s", - _("Only one child <inbound> " - "element allowed")); - goto error; - } - in = cur; - } else if (xmlStrEqual(cur->name, BAD_CAST "outbound")) { - if (out) { - virSocketError(VIR_ERR_XML_DETAIL, "%s", - _("Only one child <outbound> " - "element allowed")); - goto error; - } - out = cur; - } - /* Silently ignore unknown elements */ - } - cur = cur->next; - } - - if (in) { - if (VIR_ALLOC(def->in) < 0) { - virReportOOMError(); - goto error; - } - - if (virNetDevBandwidthParseRate(in, def->in) < 0) { - /* helper reported error for us */ - goto error; - } - } - - if (out) { - if (VIR_ALLOC(def->out) < 0) { - virReportOOMError(); - goto error; - } - - if (virNetDevBandwidthParseRate(out, def->out) < 0) { - /* helper reported error for us */ - goto error; - } - } - - return def; - -error: - virNetDevBandwidthFree(def); - return NULL; -} - -void -virNetDevBandwidthFree(virNetDevBandwidthPtr def) -{ - if (!def) - return; - - VIR_FREE(def->in); - VIR_FREE(def->out); - VIR_FREE(def); -} - -static int -virNetDevBandwidthRateFormat(virNetDevBandwidthRatePtr def, - virBufferPtr buf, - const char *elem_name) -{ - if (!buf || !elem_name) - return -1; - if (!def) - return 0; - - if (def->average) { - virBufferAsprintf(buf, " <%s average='%llu'", elem_name, - def->average); - - if (def->peak) - virBufferAsprintf(buf, " peak='%llu'", def->peak); - - if (def->burst) - virBufferAsprintf(buf, " burst='%llu'", def->burst); - virBufferAddLit(buf, "/>\n"); - } - - return 0; -} - -/** - * virNetDevBandwidthDefFormat: - * @def: Data source - * @buf: Buffer to print to - * - * Formats bandwidth and prepend each line with @indent. - * @buf may use auto-indentation. - * - * Returns 0 on success, else -1. - */ -int -virNetDevBandwidthFormat(virNetDevBandwidthPtr def, virBufferPtr buf) -{ - int ret = -1; - - if (!buf) - goto cleanup; - - if (!def) { - ret = 0; - goto cleanup; - } - - virBufferAddLit(buf, "<bandwidth>\n"); - if (virNetDevBandwidthRateFormat(def->in, buf, "inbound") < 0 || - virNetDevBandwidthRateFormat(def->out, buf, "outbound") < 0) - goto cleanup; - virBufferAddLit(buf, "</bandwidth>\n"); - - ret = 0; - -cleanup: - return ret; -} - -/** - * virNetDevBandwidthSet: - * @ifname: on which interface - * @bandwidth: rates to set (may be NULL) - * - * This function enables QoS on specified interface - * and set given traffic limits for both, incoming - * and outgoing traffic. Any previous setting get - * overwritten. - * - * Return 0 on success, -1 otherwise. - */ -int -virNetDevBandwidthSet(const char *ifname, - virNetDevBandwidthPtr bandwidth) -{ - int ret = -1; - virCommandPtr cmd = NULL; - char *average = NULL; - char *peak = NULL; - char *burst = NULL; - - if (!bandwidth) { - /* nothing to be enabled */ - ret = 0; - goto cleanup; - } - - ignore_value(virNetDevBandwidthClear(ifname)); - - if (bandwidth->in) { - if (virAsprintf(&average, "%llukbps", bandwidth->in->average) < 0) - goto cleanup; - if (bandwidth->in->peak && - (virAsprintf(&peak, "%llukbps", bandwidth->in->peak) < 0)) - goto cleanup; - if (bandwidth->in->burst && - (virAsprintf(&burst, "%llukb", bandwidth->in->burst) < 0)) - goto cleanup; - - cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, "root", - "handle", "1:", "htb", "default", "1", NULL); - if (virCommandRun(cmd, NULL) < 0) - goto cleanup; - - virCommandFree(cmd); - cmd = virCommandNew(TC); - virCommandAddArgList(cmd,"class", "add", "dev", ifname, "parent", - "1:", "classid", "1:1", "htb", NULL); - virCommandAddArgList(cmd, "rate", average, NULL); - - if (peak) - virCommandAddArgList(cmd, "ceil", peak, NULL); - if (burst) - virCommandAddArgList(cmd, "burst", burst, NULL); - - if (virCommandRun(cmd, NULL) < 0) - goto cleanup; - - virCommandFree(cmd); - cmd = virCommandNew(TC); - virCommandAddArgList(cmd,"filter", "add", "dev", ifname, "parent", - "1:0", "protocol", "ip", "handle", "1", "fw", - "flowid", "1", NULL); - - if (virCommandRun(cmd, NULL) < 0) - goto cleanup; - - VIR_FREE(average); - VIR_FREE(peak); - VIR_FREE(burst); - } - - if (bandwidth->out) { - if (virAsprintf(&average, "%llukbps", bandwidth->out->average) < 0) - goto cleanup; - if (virAsprintf(&burst, "%llukb", bandwidth->out->burst ? - bandwidth->out->burst : bandwidth->out->average) < 0) - goto cleanup; - - virCommandFree(cmd); - cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, - "ingress", NULL); - - if (virCommandRun(cmd, NULL) < 0) - goto cleanup; - - virCommandFree(cmd); - cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "filter", "add", "dev", ifname, "parent", - "ffff:", "protocol", "ip", "u32", "match", "ip", - "src", "0.0.0.0/0", "police", "rate", average, - "burst", burst, "mtu", burst, "drop", "flowid", - ":1", NULL); - - if (virCommandRun(cmd, NULL) < 0) - goto cleanup; - } - - ret = 0; - -cleanup: - virCommandFree(cmd); - VIR_FREE(average); - VIR_FREE(peak); - VIR_FREE(burst); - return ret; -} - -/** - * virNetDevBandwidthClear: - * @ifname: on which interface - * - * This function tries to disable QoS on specified interface - * by deleting root and ingress qdisc. However, this may fail - * if we try to remove the default one. - * - * Return 0 on success, -1 otherwise. - */ -int -virNetDevBandwidthClear(const char *ifname) -{ - int ret = 0; - virCommandPtr cmd = NULL; - - cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "qdisc", "del", "dev", ifname, "root", NULL); - - if (virCommandRun(cmd, NULL) < 0) - ret = -1; - - virCommandFree(cmd); - - cmd = virCommandNew(TC); - virCommandAddArgList(cmd, "qdisc", "del", "dev", ifname, "ingress", NULL); - - if (virCommandRun(cmd, NULL) < 0) - ret = -1; - virCommandFree(cmd); - - return ret; -} - -/* - * virNetDevBandwidthCopy: - * @dest: destination - * @src: source (may be NULL) - * - * Returns -1 on OOM error (which gets reported), - * 0 otherwise. - */ -int -virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest, - const virNetDevBandwidthPtr src) -{ - int ret = -1; - - *dest = NULL; - if (!src) { - /* nothing to be copied */ - return 0; - } - - if (VIR_ALLOC(*dest) < 0) { - virReportOOMError(); - goto cleanup; - } - - if (src->in) { - if (VIR_ALLOC((*dest)->in) < 0) { - virReportOOMError(); - goto cleanup; - } - memcpy((*dest)->in, src->in, sizeof(*src->in)); - } - - if (src->out) { - if (VIR_ALLOC((*dest)->out) < 0) { - virReportOOMError(); - VIR_FREE((*dest)->in); - goto cleanup; - } - memcpy((*dest)->out, src->out, sizeof(*src->out)); - } - - ret = 0; - -cleanup: - if (ret < 0) { - virNetDevBandwidthFree(*dest); - *dest = NULL; - } - return ret; -} - -bool -virNetDevBandwidthEqual(virNetDevBandwidthPtr a, - virNetDevBandwidthPtr b) -{ - if (!a && !b) - return true; - - if (!a || !b) - return false; - - /* in */ - if (a->in->average != b->in->average || - a->in->peak != b->in->peak || - a->in->burst != b->in->burst) - return false; - - /*out*/ - if (a->out->average != b->out->average || - a->out->peak != b->out->peak || - a->out->burst != b->out->burst) - return false; - - return true; -} diff --git a/src/util/network.h b/src/util/network.h deleted file mode 100644 index 98dfacc..0000000 --- a/src/util/network.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * network.h: network helper APIs for libvirt - * - * Copyright (C) 2009-2011 Red Hat, Inc. - * - * See COPYING.LIB for the License of this software - * - * Daniel Veillard <veillard@redhat.com> - */ - -#ifndef __VIR_NETWORK_H__ -# define __VIR_NETWORK_H__ - -# include "internal.h" -# include "buf.h" -# include "util.h" - -# include <sys/types.h> -# include <sys/socket.h> -# ifdef HAVE_SYS_UN_H -# include <sys/un.h> -# endif -# include <netdb.h> -# include <netinet/in.h> -# include <xml.h> - -typedef struct { - union { - struct sockaddr sa; - struct sockaddr_storage stor; - struct sockaddr_in inet4; - struct sockaddr_in6 inet6; -# ifdef HAVE_SYS_UN_H - struct sockaddr_un un; -# endif - } data; - socklen_t len; -} virSocketAddr; - -# define VIR_SOCKET_ADDR_VALID(s) \ - ((s)->data.sa.sa_family != AF_UNSPEC) - -# define VIR_SOCKET_ADDR_IS_FAMILY(s, f) \ - ((s)->data.sa.sa_family == f) - -# define VIR_SOCKET_ADDR_FAMILY(s) \ - ((s)->data.sa.sa_family) - -typedef virSocketAddr *virSocketAddrPtr; - -typedef struct _virNetDevBandwidthRate virNetDevBandwidthRate; -typedef virNetDevBandwidthRate *virNetDevBandwidthRatePtr; -struct _virNetDevBandwidthRate { - unsigned long long average; /* kbytes/s */ - unsigned long long peak; /* kbytes/s */ - unsigned long long burst; /* kbytes */ -}; - -typedef struct _virNetDevBandwidth virNetDevBandwidth; -typedef virNetDevBandwidth *virNetDevBandwidthPtr; -struct _virNetDevBandwidth { - virNetDevBandwidthRatePtr in, out; -}; - -int virSocketAddrParse(virSocketAddrPtr addr, - const char *val, - int family); - -int virSocketAddrParseIPv4(virSocketAddrPtr addr, - const char *val); - -int virSocketAddrParseIPv6(virSocketAddrPtr addr, - const char *val); - -char * virSocketAddrFormat(virSocketAddrPtr addr); -char * virSocketAddrFormatFull(virSocketAddrPtr addr, - bool withService, - const char *separator); - -int virSocketAddrSetPort(virSocketAddrPtr addr, int port); - -int virSocketAddrGetPort(virSocketAddrPtr addr); - -int virSocketAddrGetRange(virSocketAddrPtr start, - virSocketAddrPtr end); - -int virSocketAddrIsNetmask(virSocketAddrPtr netmask); - -int virSocketAddrCheckNetmask(virSocketAddrPtr addr1, - virSocketAddrPtr addr2, - virSocketAddrPtr netmask); -int virSocketAddrMask(const virSocketAddrPtr addr, - const virSocketAddrPtr netmask, - virSocketAddrPtr network); -int virSocketAddrMaskByPrefix(const virSocketAddrPtr addr, - unsigned int prefix, - virSocketAddrPtr network); -int virSocketAddrBroadcast(const virSocketAddrPtr addr, - const virSocketAddrPtr netmask, - virSocketAddrPtr broadcast); -int virSocketAddrBroadcastByPrefix(const virSocketAddrPtr addr, - unsigned int prefix, - virSocketAddrPtr broadcast); - -int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask); -int virSocketAddrPrefixToNetmask(unsigned int prefix, - virSocketAddrPtr netmask, - int family); - -/* virtualPortProfile utilities */ -# ifdef IFLA_VF_PORT_PROFILE_MAX -# define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX IFLA_VF_PORT_PROFILE_MAX -# else -# define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX 40 -# endif - -enum virNetDevVPortProfile { - VIR_NETDEV_VPORT_PROFILE_NONE, - VIR_NETDEV_VPORT_PROFILE_8021QBG, - VIR_NETDEV_VPORT_PROFILE_8021QBH, - - VIR_NETDEV_VPORT_PROFILE_LAST, -}; - -VIR_ENUM_DECL(virNetDevVPort) - -/* profile data for macvtap (VEPA) */ -typedef struct _virNetDevVPortProfile virNetDevVPortProfile; -typedef virNetDevVPortProfile *virNetDevVPortProfilePtr; -struct _virNetDevVPortProfile { - enum virNetDevVPortProfile virtPortType; - union { - struct { - uint8_t managerID; - uint32_t typeID; /* 24 bit valid */ - uint8_t typeIDVersion; - unsigned char instanceID[VIR_UUID_BUFLEN]; - } virtPort8021Qbg; - struct { - char profileID[LIBVIRT_IFLA_VF_PORT_PROFILE_MAX]; - } virtPort8021Qbh; - } u; -}; - - -virNetDevVPortProfilePtr -virNetDevVPortProfileParse(xmlNodePtr node); - -int -virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, - virBufferPtr buf); - -bool virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, - virNetDevVPortProfilePtr b); - -virNetDevBandwidthPtr virNetDevBandwidthParse(xmlNodePtr node) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -void virNetDevBandwidthFree(virNetDevBandwidthPtr def); -int virNetDevBandwidthFormat(virNetDevBandwidthPtr def, - virBufferPtr buf) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); - -int virNetDevBandwidthSet(const char *ifname, virNetDevBandwidthPtr bandwidth) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevBandwidthClear(const char *ifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest, const virNetDevBandwidthPtr src) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -bool virNetDevBandwidthEqual(virNetDevBandwidthPtr a, virNetDevBandwidthPtr b); - - -#endif /* __VIR_NETWORK_H__ */ diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index cae98b7..5324b66 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -23,7 +23,7 @@ #ifndef __VIR_NETDEV_H__ # define __VIR_NETDEV_H__ -# include "network.h" +# include "virsocketaddr.h" int virNetDevExists(const char *brname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c new file mode 100644 index 0000000..10db1ff --- /dev/null +++ b/src/util/virnetdevbandwidth.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Michal Privoznik <mprivozn@redhat.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#include <config.h> + +#include "virnetdevbandwidth.h" +#include "command.h" +#include "memory.h" +#include "virterror_internal.h" +#include "ignore-value.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +void +virNetDevBandwidthFree(virNetDevBandwidthPtr def) +{ + if (!def) + return; + + VIR_FREE(def->in); + VIR_FREE(def->out); + VIR_FREE(def); +} + + +/** + * virNetDevBandwidthSet: + * @ifname: on which interface + * @bandwidth: rates to set (may be NULL) + * + * This function enables QoS on specified interface + * and set given traffic limits for both, incoming + * and outgoing traffic. Any previous setting get + * overwritten. + * + * Return 0 on success, -1 otherwise. + */ +int +virNetDevBandwidthSet(const char *ifname, + virNetDevBandwidthPtr bandwidth) +{ + int ret = -1; + virCommandPtr cmd = NULL; + char *average = NULL; + char *peak = NULL; + char *burst = NULL; + + if (!bandwidth) { + /* nothing to be enabled */ + ret = 0; + goto cleanup; + } + + ignore_value(virNetDevBandwidthClear(ifname)); + + if (bandwidth->in) { + if (virAsprintf(&average, "%llukbps", bandwidth->in->average) < 0) + goto cleanup; + if (bandwidth->in->peak && + (virAsprintf(&peak, "%llukbps", bandwidth->in->peak) < 0)) + goto cleanup; + if (bandwidth->in->burst && + (virAsprintf(&burst, "%llukb", bandwidth->in->burst) < 0)) + goto cleanup; + + cmd = virCommandNew(TC); + virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, "root", + "handle", "1:", "htb", "default", "1", NULL); + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + virCommandFree(cmd); + cmd = virCommandNew(TC); + virCommandAddArgList(cmd,"class", "add", "dev", ifname, "parent", + "1:", "classid", "1:1", "htb", NULL); + virCommandAddArgList(cmd, "rate", average, NULL); + + if (peak) + virCommandAddArgList(cmd, "ceil", peak, NULL); + if (burst) + virCommandAddArgList(cmd, "burst", burst, NULL); + + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + virCommandFree(cmd); + cmd = virCommandNew(TC); + virCommandAddArgList(cmd,"filter", "add", "dev", ifname, "parent", + "1:0", "protocol", "ip", "handle", "1", "fw", + "flowid", "1", NULL); + + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + VIR_FREE(average); + VIR_FREE(peak); + VIR_FREE(burst); + } + + if (bandwidth->out) { + if (virAsprintf(&average, "%llukbps", bandwidth->out->average) < 0) + goto cleanup; + if (virAsprintf(&burst, "%llukb", bandwidth->out->burst ? + bandwidth->out->burst : bandwidth->out->average) < 0) + goto cleanup; + + virCommandFree(cmd); + cmd = virCommandNew(TC); + virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, + "ingress", NULL); + + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + virCommandFree(cmd); + cmd = virCommandNew(TC); + virCommandAddArgList(cmd, "filter", "add", "dev", ifname, "parent", + "ffff:", "protocol", "ip", "u32", "match", "ip", + "src", "0.0.0.0/0", "police", "rate", average, + "burst", burst, "mtu", burst, "drop", "flowid", + ":1", NULL); + + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + } + + ret = 0; + +cleanup: + virCommandFree(cmd); + VIR_FREE(average); + VIR_FREE(peak); + VIR_FREE(burst); + return ret; +} + +/** + * virNetDevBandwidthClear: + * @ifname: on which interface + * + * This function tries to disable QoS on specified interface + * by deleting root and ingress qdisc. However, this may fail + * if we try to remove the default one. + * + * Return 0 on success, -1 otherwise. + */ +int +virNetDevBandwidthClear(const char *ifname) +{ + int ret = 0; + virCommandPtr cmd = NULL; + + cmd = virCommandNew(TC); + virCommandAddArgList(cmd, "qdisc", "del", "dev", ifname, "root", NULL); + + if (virCommandRun(cmd, NULL) < 0) + ret = -1; + + virCommandFree(cmd); + + cmd = virCommandNew(TC); + virCommandAddArgList(cmd, "qdisc", "del", "dev", ifname, "ingress", NULL); + + if (virCommandRun(cmd, NULL) < 0) + ret = -1; + virCommandFree(cmd); + + return ret; +} + +/* + * virNetDevBandwidthCopy: + * @dest: destination + * @src: source (may be NULL) + * + * Returns -1 on OOM error (which gets reported), + * 0 otherwise. + */ +int +virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest, + const virNetDevBandwidthPtr src) +{ + int ret = -1; + + *dest = NULL; + if (!src) { + /* nothing to be copied */ + return 0; + } + + if (VIR_ALLOC(*dest) < 0) { + virReportOOMError(); + goto cleanup; + } + + if (src->in) { + if (VIR_ALLOC((*dest)->in) < 0) { + virReportOOMError(); + goto cleanup; + } + memcpy((*dest)->in, src->in, sizeof(*src->in)); + } + + if (src->out) { + if (VIR_ALLOC((*dest)->out) < 0) { + virReportOOMError(); + VIR_FREE((*dest)->in); + goto cleanup; + } + memcpy((*dest)->out, src->out, sizeof(*src->out)); + } + + ret = 0; + +cleanup: + if (ret < 0) { + virNetDevBandwidthFree(*dest); + *dest = NULL; + } + return ret; +} + +bool +virNetDevBandwidthEqual(virNetDevBandwidthPtr a, + virNetDevBandwidthPtr b) +{ + if (!a && !b) + return true; + + if (!a || !b) + return false; + + /* in */ + if (a->in->average != b->in->average || + a->in->peak != b->in->peak || + a->in->burst != b->in->burst) + return false; + + /*out*/ + if (a->out->average != b->out->average || + a->out->peak != b->out->peak || + a->out->burst != b->out->burst) + return false; + + return true; +} diff --git a/src/util/virnetdevbandwidth.h b/src/util/virnetdevbandwidth.h new file mode 100644 index 0000000..58decff --- /dev/null +++ b/src/util/virnetdevbandwidth.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Michal Privoznik <mprivozn@redhat.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#ifndef __VIR_NETDEV_BANDWIDTH_H__ +# define __VIR_NETDEV_BANDWIDTH_H__ + +# include "internal.h" + +typedef struct _virNetDevBandwidthRate virNetDevBandwidthRate; +typedef virNetDevBandwidthRate *virNetDevBandwidthRatePtr; +struct _virNetDevBandwidthRate { + unsigned long long average; /* kbytes/s */ + unsigned long long peak; /* kbytes/s */ + unsigned long long burst; /* kbytes */ +}; + +typedef struct _virNetDevBandwidth virNetDevBandwidth; +typedef virNetDevBandwidth *virNetDevBandwidthPtr; +struct _virNetDevBandwidth { + virNetDevBandwidthRatePtr in, out; +}; + +void virNetDevBandwidthFree(virNetDevBandwidthPtr def); + +int virNetDevBandwidthSet(const char *ifname, virNetDevBandwidthPtr bandwidth) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBandwidthClear(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest, const virNetDevBandwidthPtr src) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +bool virNetDevBandwidthEqual(virNetDevBandwidthPtr a, virNetDevBandwidthPtr b); + +#endif /* __VIR_NETDEV_BANDWIDTH_H__ */ diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c index 5c60925..2ed53c6 100644 --- a/src/util/virnetdevtap.c +++ b/src/util/virnetdevtap.c @@ -30,6 +30,7 @@ #include "virterror_internal.h" #include "memory.h" #include "logging.h" +#include "util.h" #include <sys/ioctl.h> #ifdef HAVE_NET_IF_H diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c new file mode 100644 index 0000000..29abce6 --- /dev/null +++ b/src/util/virnetdevvportprofile.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Laine Stump <laine@laine.org> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#include <config.h> + +#include "virnetdevvportprofile.h" + +bool +virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, virNetDevVPortProfilePtr b) +{ + /* NULL resistant */ + if (!a && !b) + return true; + + if (!a || !b) + return false; + + if (a->virtPortType != b->virtPortType) + return false; + + switch (a->virtPortType) { + case VIR_NETDEV_VPORT_PROFILE_NONE: + break; + + case VIR_NETDEV_VPORT_PROFILE_8021QBG: + if (a->u.virtPort8021Qbg.managerID != b->u.virtPort8021Qbg.managerID || + a->u.virtPort8021Qbg.typeID != b->u.virtPort8021Qbg.typeID || + a->u.virtPort8021Qbg.typeIDVersion != b->u.virtPort8021Qbg.typeIDVersion || + memcmp(a->u.virtPort8021Qbg.instanceID, b->u.virtPort8021Qbg.instanceID, VIR_UUID_BUFLEN) != 0) + return false; + break; + + case VIR_NETDEV_VPORT_PROFILE_8021QBH: + if (STRNEQ(a->u.virtPort8021Qbh.profileID, b->u.virtPort8021Qbh.profileID)) + return false; + break; + + default: + break; + } + + return true; +} diff --git a/src/util/virnetdevvportprofile.h b/src/util/virnetdevvportprofile.h new file mode 100644 index 0000000..3e6887e --- /dev/null +++ b/src/util/virnetdevvportprofile.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Laine Stump <laine@laine.org> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#ifndef __VIR_NETDEV_VPORT_PROFILE_H__ +# define __VIR_NETDEV_VPORT_PROFILE_H__ + +# include "internal.h" +# include "uuid.h" +# include "util.h" + +# define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX 40 + +enum virNetDevVPortProfile { + VIR_NETDEV_VPORT_PROFILE_NONE, + VIR_NETDEV_VPORT_PROFILE_8021QBG, + VIR_NETDEV_VPORT_PROFILE_8021QBH, + + VIR_NETDEV_VPORT_PROFILE_LAST, +}; + +VIR_ENUM_DECL(virNetDevVPort) + +/* profile data for macvtap (VEPA) */ +typedef struct _virNetDevVPortProfile virNetDevVPortProfile; +typedef virNetDevVPortProfile *virNetDevVPortProfilePtr; +struct _virNetDevVPortProfile { + enum virNetDevVPortProfile virtPortType; + union { + struct { + uint8_t managerID; + uint32_t typeID; /* 24 bit valid */ + uint8_t typeIDVersion; + unsigned char instanceID[VIR_UUID_BUFLEN]; + } virtPort8021Qbg; + struct { + char profileID[LIBVIRT_IFLA_VF_PORT_PROFILE_MAX]; + } virtPort8021Qbh; + } u; +}; + + +bool virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, + virNetDevVPortProfilePtr b); + +#endif /* __VIR_NETDEV_VPORT_PROFILE_H__ */ diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c new file mode 100644 index 0000000..c2c2060 --- /dev/null +++ b/src/util/virsocketaddr.c @@ -0,0 +1,687 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Daniel Veillard <veillard@redhat.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#include <config.h> + +#include "virsocketaddr.h" +#include "virterror_internal.h" +#include "util.h" + +#include <netdb.h> + +#define VIR_FROM_THIS VIR_FROM_NONE +#define virSocketError(code, ...) \ + virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \ + __FUNCTION__, __LINE__, __VA_ARGS__) + +/* + * Helpers to extract the IP arrays from the virSocketAddrPtr + * That part is the less portable of the module + */ +typedef unsigned char virSocketAddrIPv4[4]; +typedef virSocketAddrIPv4 *virSocketAddrIPv4Ptr; +typedef unsigned short virSocketAddrIPv6[8]; +typedef virSocketAddrIPv6 *virSocketAddrIPv6Ptr; + +static int virSocketAddrGetIPv4Addr(virSocketAddrPtr addr, virSocketAddrIPv4Ptr tab) { + unsigned long val; + int i; + + if ((addr == NULL) || (tab == NULL) || (addr->data.stor.ss_family != AF_INET)) + return(-1); + + val = ntohl(addr->data.inet4.sin_addr.s_addr); + + for (i = 0;i < 4;i++) { + (*tab)[3 - i] = val & 0xFF; + val >>= 8; + } + + return(0); +} + +static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr tab) { + int i; + + if ((addr == NULL) || (tab == NULL) || (addr->data.stor.ss_family != AF_INET6)) + return(-1); + + for (i = 0;i < 8;i++) { + (*tab)[i] = ((addr->data.inet6.sin6_addr.s6_addr[2 * i] << 8) | + addr->data.inet6.sin6_addr.s6_addr[2 * i + 1]); + } + + return(0); +} + +/** + * virSocketAddrParse: + * @val: a numeric network address IPv4 or IPv6 + * @addr: where to store the return value, optional. + * @family: address family to pass down to getaddrinfo + * + * Mostly a wrapper for getaddrinfo() extracting the address storage + * from the numeric string like 1.2.3.4 or 2001:db8:85a3:0:0:8a2e:370:7334 + * + * Returns the length of the network address or -1 in case of error. + */ +int virSocketAddrParse(virSocketAddrPtr addr, const char *val, int family) { + int len; + struct addrinfo hints; + struct addrinfo *res = NULL; + int err; + + if (val == NULL) { + virSocketError(VIR_ERR_INVALID_ARG, "%s", _("Missing address")); + return -1; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_flags = AI_NUMERICHOST; + if ((err = getaddrinfo(val, NULL, &hints, &res)) != 0) { + virSocketError(VIR_ERR_SYSTEM_ERROR, + _("Cannot parse socket address '%s': %s"), + val, gai_strerror(err)); + return -1; + } + + if (res == NULL) { + virSocketError(VIR_ERR_SYSTEM_ERROR, + _("No socket addresses found for '%s'"), + val); + return -1; + } + + len = res->ai_addrlen; + if (addr != NULL) { + memcpy(&addr->data.stor, res->ai_addr, len); + addr->len = res->ai_addrlen; + } + + freeaddrinfo(res); + return(len); +} + +/* + * virSocketAddrParseIPv4: + * @val: an IPv4 numeric address + * @addr: the location to store the result + * + * Extract the address storage from an IPv4 numeric address + * + * Returns the length of the network address or -1 in case of error. + */ +int +virSocketAddrParseIPv4(virSocketAddrPtr addr, const char *val) { + return virSocketAddrParse(addr, val, AF_INET); +} + +/* + * virSocketAddrParseIPv6: + * @val: an IPv6 numeric address + * @addr: the location to store the result + * + * Extract the address storage from an IPv6 numeric address + * + * Returns the length of the network address or -1 in case of error. + */ +int +virSocketAddrParseIPv6(virSocketAddrPtr addr, const char *val) { + return virSocketAddrParse(addr, val, AF_INET6); +} + +/* + * virSocketAddrFormat: + * @addr: an initialized virSocketAddrPtr + * + * Returns a string representation of the given address + * Returns NULL on any error + * Caller must free the returned string + */ +char * +virSocketAddrFormat(virSocketAddrPtr addr) { + return virSocketAddrFormatFull(addr, false, NULL); +} + + +/* + * virSocketAddrFormatFull: + * @addr: an initialized virSocketAddrPtr + * @withService: if true, then service info is appended + * @separator: separator between hostname & service. + * + * Returns a string representation of the given address + * Returns NULL on any error + * Caller must free the returned string + */ +char * +virSocketAddrFormatFull(virSocketAddrPtr addr, + bool withService, + const char *separator) +{ + char host[NI_MAXHOST], port[NI_MAXSERV]; + char *addrstr; + int err; + + if (addr == NULL) { + virSocketError(VIR_ERR_INVALID_ARG, "%s", _("Missing address")); + return NULL; + } + + /* Short-circuit since getnameinfo doesn't work + * nicely for UNIX sockets */ + if (addr->data.sa.sa_family == AF_UNIX) { + if (withService) { + if (virAsprintf(&addrstr, "127.0.0.1%s0", + separator ? separator : ":") < 0) + goto no_memory; + } else { + if (!(addrstr = strdup("127.0.0.1"))) + goto no_memory; + } + return addrstr; + } + + if ((err = getnameinfo(&addr->data.sa, + addr->len, + host, sizeof(host), + port, sizeof(port), + NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { + virSocketError(VIR_ERR_SYSTEM_ERROR, + _("Cannot convert socket address to string: %s"), + gai_strerror(err)); + return NULL; + } + + if (withService) { + if (virAsprintf(&addrstr, "%s%s%s", host, separator, port) == -1) + goto no_memory; + } else { + if (!(addrstr = strdup(host))) + goto no_memory; + } + + return addrstr; + +no_memory: + virReportOOMError(); + return NULL; +} + + +/* + * virSocketAddrSetPort: + * @addr: an initialized virSocketAddrPtr + * @port: the port number to set + * + * Set the transport layer port of the given virtSocketAddr + * + * Returns 0 on success, -1 on failure + */ +int +virSocketAddrSetPort(virSocketAddrPtr addr, int port) { + if (addr == NULL) + return -1; + + port = htons(port); + + if(addr->data.stor.ss_family == AF_INET) { + addr->data.inet4.sin_port = port; + } + + else if(addr->data.stor.ss_family == AF_INET6) { + addr->data.inet6.sin6_port = port; + } + + else { + return -1; + } + + return 0; +} + +/* + * virSocketGetPort: + * @addr: an initialized virSocketAddrPtr + * + * Returns the transport layer port of the given virtSocketAddr + * Returns -1 if @addr is invalid + */ +int +virSocketAddrGetPort(virSocketAddrPtr addr) { + if (addr == NULL) + return -1; + + if(addr->data.stor.ss_family == AF_INET) { + return ntohs(addr->data.inet4.sin_port); + } + + else if(addr->data.stor.ss_family == AF_INET6) { + return ntohs(addr->data.inet6.sin6_port); + } + + return -1; +} + +/** + * virSocketAddrIsNetmask: + * @netmask: the netmask address + * + * Check that @netmask is a proper network mask + * + * Returns 0 in case of success and -1 in case of error + */ +int virSocketAddrIsNetmask(virSocketAddrPtr netmask) { + int n = virSocketAddrGetNumNetmaskBits(netmask); + if (n < 0) + return -1; + return 0; +} + +/** + * virSocketAddrMask: + * @addr: address that needs to be masked + * @netmask: the netmask address + * @network: where to store the result, can be same as @addr + * + * Mask off the host bits of @addr according to @netmask, turning it + * into a network address. + * + * Returns 0 in case of success, or -1 on error. + */ +int +virSocketAddrMask(const virSocketAddrPtr addr, + const virSocketAddrPtr netmask, + virSocketAddrPtr network) +{ + if (addr->data.stor.ss_family != netmask->data.stor.ss_family) { + network->data.stor.ss_family = AF_UNSPEC; + return -1; + } + + if (addr->data.stor.ss_family == AF_INET) { + network->data.inet4.sin_addr.s_addr + = (addr->data.inet4.sin_addr.s_addr + & netmask->data.inet4.sin_addr.s_addr); + network->data.inet4.sin_port = 0; + network->data.stor.ss_family = AF_INET; + network->len = addr->len; + return 0; + } + if (addr->data.stor.ss_family == AF_INET6) { + int ii; + for (ii = 0; ii < 16; ii++) { + network->data.inet6.sin6_addr.s6_addr[ii] + = (addr->data.inet6.sin6_addr.s6_addr[ii] + & netmask->data.inet6.sin6_addr.s6_addr[ii]); + } + network->data.inet6.sin6_port = 0; + network->data.stor.ss_family = AF_INET6; + network->len = addr->len; + return 0; + } + network->data.stor.ss_family = AF_UNSPEC; + return -1; +} + +/** + * virSocketAddrMaskByPrefix: + * @addr: address that needs to be masked + * @prefix: prefix (# of 1 bits) of netmask to apply + * @network: where to store the result, can be same as @addr + * + * Mask off the host bits of @addr according to @prefix, turning it + * into a network address. + * + * Returns 0 in case of success, or -1 on error. + */ +int +virSocketAddrMaskByPrefix(const virSocketAddrPtr addr, + unsigned int prefix, + virSocketAddrPtr network) +{ + virSocketAddr netmask; + + if (virSocketAddrPrefixToNetmask(prefix, &netmask, + addr->data.stor.ss_family) < 0) { + network->data.stor.ss_family = AF_UNSPEC; + return -1; + } + + return virSocketAddrMask(addr, &netmask, network); +} + +/** + * virSocketAddrBroadcast: + * @addr: address that needs to be turned into broadcast address (IPv4 only) + * @netmask: the netmask address + * @broadcast: virSocketAddr to recieve the broadcast address + * + * Mask ON the host bits of @addr according to @netmask, turning it + * into a broadcast address. + * + * Returns 0 in case of success, or -1 on error. + */ +int +virSocketAddrBroadcast(const virSocketAddrPtr addr, + const virSocketAddrPtr netmask, + virSocketAddrPtr broadcast) +{ + if ((addr->data.stor.ss_family != AF_INET) || + (netmask->data.stor.ss_family != AF_INET)) { + broadcast->data.stor.ss_family = AF_UNSPEC; + return -1; + } + + broadcast->data.stor.ss_family = AF_INET; + broadcast->len = addr->len; + broadcast->data.inet4.sin_addr.s_addr + = (addr->data.inet4.sin_addr.s_addr + | ~netmask->data.inet4.sin_addr.s_addr); + return 0; +} + +/** + * virSocketAddrBroadcastByPrefix: + * @addr: address that needs to be turned into broadcast address (IPv4 only) + * @prefix: prefix (# of 1 bits) of netmask to apply + * @broadcast: virSocketAddr to recieve the broadcast address + * + * Mask off the host bits of @addr according to @prefix, turning it + * into a network address. + * + * Returns 0 in case of success, or -1 on error. + */ +int +virSocketAddrBroadcastByPrefix(const virSocketAddrPtr addr, + unsigned int prefix, + virSocketAddrPtr broadcast) +{ + virSocketAddr netmask; + + if (virSocketAddrPrefixToNetmask(prefix, &netmask, + addr->data.stor.ss_family) < 0) + return -1; + + return virSocketAddrBroadcast(addr, &netmask, broadcast); +} + +/** + * virSocketCheckNetmask: + * @addr1: a first network address + * @addr2: a second network address + * @netmask: the netmask address + * + * Check that @addr1 and @addr2 pertain to the same @netmask address + * range and returns the size of the range + * + * Returns 1 in case of success and 0 in case of failure and + * -1 in case of error + */ +int virSocketAddrCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2, + virSocketAddrPtr netmask) { + int i; + + if ((addr1 == NULL) || (addr2 == NULL) || (netmask == NULL)) + return(-1); + if ((addr1->data.stor.ss_family != addr2->data.stor.ss_family) || + (addr1->data.stor.ss_family != netmask->data.stor.ss_family)) + return(-1); + + if (virSocketAddrIsNetmask(netmask) != 0) + return(-1); + + if (addr1->data.stor.ss_family == AF_INET) { + virSocketAddrIPv4 t1, t2, tm; + + if ((virSocketAddrGetIPv4Addr(addr1, &t1) < 0) || + (virSocketAddrGetIPv4Addr(addr2, &t2) < 0) || + (virSocketAddrGetIPv4Addr(netmask, &tm) < 0)) + return(-1); + + for (i = 0;i < 4;i++) { + if ((t1[i] & tm[i]) != (t2[i] & tm[i])) + return(0); + } + + } else if (addr1->data.stor.ss_family == AF_INET6) { + virSocketAddrIPv6 t1, t2, tm; + + if ((virSocketAddrGetIPv6Addr(addr1, &t1) < 0) || + (virSocketAddrGetIPv6Addr(addr2, &t2) < 0) || + (virSocketAddrGetIPv6Addr(netmask, &tm) < 0)) + return(-1); + + for (i = 0;i < 8;i++) { + if ((t1[i] & tm[i]) != (t2[i] & tm[i])) + return(0); + } + + } else { + return(-1); + } + return(1); +} + +/** + * virSocketGetRange: + * @start: start of an IP range + * @end: end of an IP range + * + * Check the order of the 2 addresses and compute the range, this + * will return 1 for identical addresses. Errors can come from incompatible + * addresses type, excessive range (>= 2^^16) where the two addresses are + * unrelated or inverted start and end. + * + * Returns the size of the range or -1 in case of failure + */ +int virSocketAddrGetRange(virSocketAddrPtr start, virSocketAddrPtr end) { + int ret = 0, i; + + if ((start == NULL) || (end == NULL)) + return(-1); + if (start->data.stor.ss_family != end->data.stor.ss_family) + return(-1); + + if (start->data.stor.ss_family == AF_INET) { + virSocketAddrIPv4 t1, t2; + + if ((virSocketAddrGetIPv4Addr(start, &t1) < 0) || + (virSocketAddrGetIPv4Addr(end, &t2) < 0)) + return(-1); + + for (i = 0;i < 2;i++) { + if (t1[i] != t2[i]) + return(-1); + } + ret = (t2[2] - t1[2]) * 256 + (t2[3] - t1[3]); + if (ret < 0) + return(-1); + ret++; + } else if (start->data.stor.ss_family == AF_INET6) { + virSocketAddrIPv6 t1, t2; + + if ((virSocketAddrGetIPv6Addr(start, &t1) < 0) || + (virSocketAddrGetIPv6Addr(end, &t2) < 0)) + return(-1); + + for (i = 0;i < 7;i++) { + if (t1[i] != t2[i]) + return(-1); + } + ret = t2[7] - t1[7]; + if (ret < 0) + return(-1); + ret++; + } else { + return(-1); + } + return(ret); +} + + +/** + * virSocketAddrGetNumNetmaskBits + * @netmask: the presumed netmask + * + * Get the number of netmask bits in a netmask. + * + * Returns the number of bits in the netmask or -1 if an error occurred + * or the netmask is invalid. + */ +int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask) +{ + int i, j; + int c = 0; + + if (netmask->data.stor.ss_family == AF_INET) { + virSocketAddrIPv4 tm; + uint8_t bit; + + if (virSocketAddrGetIPv4Addr(netmask, &tm) < 0) + return -1; + + for (i = 0; i < 4; i++) + if (tm[i] == 0xff) + c += 8; + else + break; + + if (c == 8 * 4) + return c; + + j = i << 3; + while (j < (8 * 4)) { + bit = 1 << (7 - (j & 7)); + if ((tm[j >> 3] & bit)) { + c++; + } else + break; + j++; + } + + while (j < (8 * 4)) { + bit = 1 << (7 - (j & 7)); + if ((tm[j >> 3] & bit)) + return -1; + j++; + } + + return c; + } else if (netmask->data.stor.ss_family == AF_INET6) { + virSocketAddrIPv6 tm; + uint16_t bit; + + if (virSocketAddrGetIPv6Addr(netmask, &tm) < 0) + return -1; + + for (i = 0; i < 8; i++) + if (tm[i] == 0xffff) + c += 16; + else + break; + + if (c == 16 * 8) + return c; + + j = i << 4; + while (j < (16 * 8)) { + bit = 1 << (15 - (j & 0xf)); + if ((tm[j >> 4] & bit)) { + c++; + } else + break; + j++; + } + + while (j < (16 * 8)) { + bit = 1 << (15 - (j & 0xf)); + if ((tm[j >> 4]) & bit) + return -1; + j++; + } + + return c; + } + return -1; +} + +/** + * virSocketPrefixToNetmask: + * @prefix: number of 1 bits to put in the netmask + * @netmask: address to fill in with the desired netmask + * @family: family of the address (AF_INET or AF_INET6 only) + * + * given @prefix and @family, fill in @netmask with a netmask + * (eg 255.255.255.0). + * + * Returns 0 on success or -1 on error. + */ + +int +virSocketAddrPrefixToNetmask(unsigned int prefix, + virSocketAddrPtr netmask, + int family) +{ + int result = -1; + + netmask->data.stor.ss_family = AF_UNSPEC; /* assume failure */ + + if (family == AF_INET) { + int ip; + + if (prefix > 32) + goto error; + + ip = prefix ? ~((1 << (32 - prefix)) - 1) : 0; + netmask->data.inet4.sin_addr.s_addr = htonl(ip); + netmask->data.stor.ss_family = AF_INET; + result = 0; + + } else if (family == AF_INET6) { + int ii = 0; + + if (prefix > 128) + goto error; + + while (prefix >= 8) { + /* do as much as possible an entire byte at a time */ + netmask->data.inet6.sin6_addr.s6_addr[ii++] = 0xff; + prefix -= 8; + } + if (prefix > 0) { + /* final partial byte */ + netmask->data.inet6.sin6_addr.s6_addr[ii++] + = ~((1 << (8 - prefix)) -1); + } + while (ii < 16) { + /* zerofill remainder in case it wasn't initialized */ + netmask->data.inet6.sin6_addr.s6_addr[ii++] = 0; + } + netmask->data.stor.ss_family = AF_INET6; + result = 0; + } + +error: + return result; +} diff --git a/src/util/virsocketaddr.h b/src/util/virsocketaddr.h new file mode 100644 index 0000000..24a5548 --- /dev/null +++ b/src/util/virsocketaddr.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Daniel Veillard <veillard@redhat.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#ifndef __VIR_SOCKETADDR_H__ +# define __VIR_SOCKETADDR_H__ + +# include "internal.h" + +# include <netinet/in.h> +# include <sys/socket.h> +# ifdef HAVE_SYS_UN_H +# include <sys/un.h> +# endif + +typedef struct { + union { + struct sockaddr sa; + struct sockaddr_storage stor; + struct sockaddr_in inet4; + struct sockaddr_in6 inet6; +# ifdef HAVE_SYS_UN_H + struct sockaddr_un un; +# endif + } data; + socklen_t len; +} virSocketAddr; + +# define VIR_SOCKET_ADDR_VALID(s) \ + ((s)->data.sa.sa_family != AF_UNSPEC) + +# define VIR_SOCKET_ADDR_IS_FAMILY(s, f) \ + ((s)->data.sa.sa_family == f) + +# define VIR_SOCKET_ADDR_FAMILY(s) \ + ((s)->data.sa.sa_family) + +typedef virSocketAddr *virSocketAddrPtr; + +int virSocketAddrParse(virSocketAddrPtr addr, + const char *val, + int family); + +int virSocketAddrParseIPv4(virSocketAddrPtr addr, + const char *val); + +int virSocketAddrParseIPv6(virSocketAddrPtr addr, + const char *val); + +char * virSocketAddrFormat(virSocketAddrPtr addr); +char * virSocketAddrFormatFull(virSocketAddrPtr addr, + bool withService, + const char *separator); + +int virSocketAddrSetPort(virSocketAddrPtr addr, int port); + +int virSocketAddrGetPort(virSocketAddrPtr addr); + +int virSocketAddrGetRange(virSocketAddrPtr start, + virSocketAddrPtr end); + +int virSocketAddrIsNetmask(virSocketAddrPtr netmask); + +int virSocketAddrCheckNetmask(virSocketAddrPtr addr1, + virSocketAddrPtr addr2, + virSocketAddrPtr netmask); +int virSocketAddrMask(const virSocketAddrPtr addr, + const virSocketAddrPtr netmask, + virSocketAddrPtr network); +int virSocketAddrMaskByPrefix(const virSocketAddrPtr addr, + unsigned int prefix, + virSocketAddrPtr network); +int virSocketAddrBroadcast(const virSocketAddrPtr addr, + const virSocketAddrPtr netmask, + virSocketAddrPtr broadcast); +int virSocketAddrBroadcastByPrefix(const virSocketAddrPtr addr, + unsigned int prefix, + virSocketAddrPtr broadcast); + +int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask); +int virSocketAddrPrefixToNetmask(unsigned int prefix, + virSocketAddrPtr netmask, + int family); + +#endif /* __VIR_SOCKETADDR_H__ */ diff --git a/tools/virsh.c b/tools/virsh.c index d8261f7..a479465 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -59,7 +59,7 @@ #include "threads.h" #include "command.h" #include "virkeycode.h" -#include "network.h" +#include "virnetdevbandwidth.h" static char *progname; -- 1.7.6.4

(Of course fixing the two problems I noted in earlier patches 1) caused a conflict when applying this patch and 2) caused a new build failure with make check ) ACK on this, aside from some files wrongly attributed to me :-) On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
The src/util/network.c file is a dumping ground for many different APIs. Split it up into 5 pieces, along functional lines
- src/util/virnetdevbandwidth.c: virNetDevBandwidth type& helper APIs - src/util/virnetdevvportprofile.c: virNetDevVPortProfile type& helper APIs - src/util/virsocketaddr.c: virSocketAddr and APIs - src/conf/netdev_bandwidth_conf.c: XML parsing / formatting for virNetDevBandwidth - src/conf/netdev_vport_profile_conf.c: XML parsing / formatting for virNetDevVPortProfile
* src/util/network.c, src/util/network.h: Split into 5 pieces * src/conf/netdev_bandwidth_conf.c, src/conf/netdev_bandwidth_conf.h, src/conf/netdev_vport_profile_conf.c, src/conf/netdev_vport_profile_conf.h, src/util/virnetdevbandwidth.c, src/util/virnetdevbandwidth.h, src/util/virnetdevvportprofile.c, src/util/virnetdevvportprofile.h, src/util/virsocketaddr.c, src/util/virsocketaddr.h: New pieces * daemon/libvirtd.h, daemon/remote.c, src/conf/domain_conf.c, src/conf/domain_conf.h, src/conf/network_conf.c, src/conf/network_conf.h, src/conf/nwfilter_conf.h, src/esx/esx_util.h, src/network/bridge_driver.c, src/qemu/qemu_conf.c, src/rpc/virnetsocket.c, src/rpc/virnetsocket.h, src/util/dnsmasq.h, src/util/interface.h, src/util/iptables.h, src/util/macvtap.c, src/util/macvtap.h, src/util/virnetdev.h, src/util/virnetdevtap.c, tools/virsh.c: Update include files --- daemon/libvirtd.h | 1 - daemon/remote.c | 1 - po/POTFILES.in | 4 +- src/Makefile.am | 12 +- src/conf/domain_conf.c | 3 +- src/conf/domain_conf.h | 4 +- src/conf/netdev_bandwidth_conf.c | 230 ++++++ src/conf/netdev_bandwidth_conf.h | 37 + src/conf/netdev_vport_profile_conf.c | 236 ++++++ src/conf/netdev_vport_profile_conf.h | 39 + src/conf/network_conf.c | 3 +- src/conf/network_conf.h | 4 +- src/conf/nwfilter_conf.h | 2 +- src/esx/esx_util.h | 2 +- src/network/bridge_driver.c | 1 - src/qemu/qemu_conf.c | 1 - src/rpc/virnetsocket.c | 1 + src/rpc/virnetsocket.h | 2 +- src/util/dnsmasq.h | 2 +- src/util/interface.h | 2 +- src/util/iptables.h | 2 +- src/util/macvtap.c | 1 - src/util/macvtap.h | 8 +- src/util/network.c | 1349 ---------------------------------- src/util/network.h | 173 ----- src/util/virnetdev.h | 2 +- src/util/virnetdevbandwidth.c | 265 +++++++ src/util/virnetdevbandwidth.h | 53 ++ src/util/virnetdevtap.c | 1 + src/util/virnetdevvportprofile.c | 62 ++ src/util/virnetdevvportprofile.h | 64 ++ src/util/virsocketaddr.c | 687 +++++++++++++++++ src/util/virsocketaddr.h | 103 +++ tools/virsh.c | 2 +- 34 files changed, 1813 insertions(+), 1546 deletions(-) create mode 100644 src/conf/netdev_bandwidth_conf.c create mode 100644 src/conf/netdev_bandwidth_conf.h create mode 100644 src/conf/netdev_vport_profile_conf.c create mode 100644 src/conf/netdev_vport_profile_conf.h delete mode 100644 src/util/network.c delete mode 100644 src/util/network.h create mode 100644 src/util/virnetdevbandwidth.c create mode 100644 src/util/virnetdevbandwidth.h create mode 100644 src/util/virnetdevvportprofile.c create mode 100644 src/util/virnetdevvportprofile.h create mode 100644 src/util/virsocketaddr.c create mode 100644 src/util/virsocketaddr.h
diff --git a/src/conf/netdev_vport_profile_conf.c b/src/conf/netdev_vport_profile_conf.c new file mode 100644 index 0000000..63c6668 --- /dev/null +++ b/src/conf/netdev_vport_profile_conf.c @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Laine Stump<laine@laine.org>
Actually, although my name is probably on the most recent git blame for much of this code, that's only because I moved it from domain_conf.c into network.c so that it could be used by multiple other files. The original author is Stefan Berger.
+ * Daniel P. Berrange<berrange@redhat.com> + */
diff --git a/src/conf/netdev_vport_profile_conf.h b/src/conf/netdev_vport_profile_conf.h new file mode 100644 index 0000000..3ab6975 --- /dev/null +++ b/src/conf/netdev_vport_profile_conf.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Laine Stump<laine@laine.org>
Same comment - Stefan was the original author.
+ * Daniel P. Berrange<berrange@redhat.com> + */
diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c new file mode 100644 index 0000000..29abce6 --- /dev/null +++ b/src/util/virnetdevvportprofile.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Laine Stump<laine@laine.org>
Stefan was the original author.
+ * Daniel P. Berrange<berrange@redhat.com> + */ diff --git a/src/util/virnetdevvportprofile.h b/src/util/virnetdevvportprofile.h new file mode 100644 index 0000000..3e6887e --- /dev/null +++ b/src/util/virnetdevvportprofile.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Laine Stump<laine@laine.org>
Again, Stefan.
+ * Daniel P. Berrange<berrange@redhat.com> + */ +
diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c new file mode 100644 index 0000000..c2c2060 --- /dev/null +++ b/src/util/virsocketaddr.c @@ -0,0 +1,687 @@ +/* + * Copyright (C) 2009-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Daniel Veillard<veillard@redhat.com> + * Daniel P. Berrange<berrange@redhat.com>
Actually if my name were to be added to any of these files, I'd say this one - DV was the original author, and about 1/3 of the lines here are attributed to him, about 1/3 to me, the rest between you, Matt Booth, and Stefan mostly.
+ */

On Wed, Nov 09, 2011 at 04:07:28AM -0500, Laine Stump wrote:
(Of course fixing the two problems I noted in earlier patches 1) caused a conflict when applying this patch and 2) caused a new build failure with make check )
ACK on this, aside from some files wrongly attributed to me :-)
Ok, i've changed all the attributions as you suggest Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

From: "Daniel P. Berrange" <berrange@redhat.com> The src/lxc/veth.c file contains APIs for managing veth devices, but some of the APIs duplicate stuff from src/util/virnetdev.h. Delete thed duplicate APIs and rename the remaining ones to follow virNetDevVethXXXX * src/lxc/veth.c, src/lxc/veth.h: Rename APIs & delete duplicates * src/lxc/lxc_container.c, src/lxc/lxc_controller.c, src/lxc/lxc_driver.c: Update for API renaming --- po/POTFILES.in | 1 - src/lxc/lxc_container.c | 7 ++- src/lxc/lxc_controller.c | 4 +- src/lxc/lxc_driver.c | 19 +++----- src/lxc/veth.c | 109 ++++++++------------------------------------- src/lxc/veth.h | 20 +++----- 6 files changed, 42 insertions(+), 118 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 1665d2d..810cf68 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -42,7 +42,6 @@ src/lxc/lxc_container.c src/lxc/lxc_conf.c src/lxc/lxc_controller.c src/lxc/lxc_driver.c -src/lxc/veth.c src/libxl/libxl_driver.c src/libxl/libxl_conf.c src/network/bridge_driver.c diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index c4e5f28..1617117 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -60,6 +60,7 @@ #include "uuid.h" #include "virfile.h" #include "command.h" +#include "virnetdev.h" #define VIR_FROM_THIS VIR_FROM_LXC @@ -269,12 +270,12 @@ static int lxcContainerRenameAndEnableInterfaces(unsigned int nveths, } VIR_DEBUG("Renaming %s to %s", veths[i], newname); - rc = setInterfaceName(veths[i], newname); + rc = virNetDevSetName(veths[i], newname); if (rc < 0) goto error_out; VIR_DEBUG("Enabling %s", newname); - rc = vethInterfaceUpOrDown(newname, 1); + rc = virNetDevSetOnline(newname, true); if (rc < 0) goto error_out; @@ -283,7 +284,7 @@ static int lxcContainerRenameAndEnableInterfaces(unsigned int nveths, /* enable lo device only if there were other net devices */ if (veths) - rc = vethInterfaceUpOrDown("lo", 1); + rc = virNetDevSetOnline("lo", true); error_out: VIR_FREE(newname); diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 649ac87..d18055a 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -932,7 +932,7 @@ static int lxcControllerMoveInterfaces(unsigned int nveths, { unsigned int i; for (i = 0 ; i < nveths ; i++) - if (moveInterfaceToNetNs(veths[i], container) < 0) + if (virNetDevSetNamespace(veths[i], container) < 0) return -1; return 0; @@ -953,7 +953,7 @@ static int lxcControllerCleanupInterfaces(unsigned int nveths, { unsigned int i; for (i = 0 ; i < nveths ; i++) - vethDelete(veths[i]); + ignore_value(virNetDevVethDelete(veths[i])); return 0; } diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 2c1154f..77ac605 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -55,6 +55,7 @@ #include "domain_audit.h" #include "domain_nwfilter.h" #include "network/bridge_driver.h" +#include "virnetdev.h" #define VIR_FROM_THIS VIR_FROM_LXC @@ -1152,8 +1153,8 @@ static void lxcVmCleanup(lxc_driver_t *driver, priv->monitorWatch = -1; for (i = 0 ; i < vm->def->nnets ; i++) { - vethInterfaceUpOrDown(vm->def->nets[i]->ifname, 0); - vethDelete(vm->def->nets[i]->ifname); + ignore_value(virNetDevSetOnline(vm->def->nets[i]->ifname, false)); + ignore_value(virNetDevVethDelete(vm->def->nets[i]->ifname)); networkReleaseActualDevice(vm->def->nets[i]); } @@ -1246,7 +1247,7 @@ static int lxcSetupInterfaces(virConnectPtr conn, VIR_DEBUG("calling vethCreate()"); parentVeth = def->nets[i]->ifname; - if (vethCreate(&parentVeth, &containerVeth) < 0) + if (virNetDevVethCreate(&parentVeth, &containerVeth) < 0) goto error_exit; VIR_DEBUG("parentVeth: %s, containerVeth: %s", parentVeth, containerVeth); @@ -1262,17 +1263,13 @@ static int lxcSetupInterfaces(virConnectPtr conn, (*veths)[(*nveths)] = containerVeth; (*nveths)++; - { - char macaddr[VIR_MAC_STRING_BUFLEN]; - virFormatMacAddr(def->nets[i]->mac, macaddr); - if (setMacAddr(containerVeth, macaddr) < 0) - goto error_exit; - } + if (virNetDevSetMAC(containerVeth, def->nets[i]->mac) < 0) + goto error_exit; if (virNetDevBridgeAddPort(bridge, parentVeth) < 0) goto error_exit; - if (vethInterfaceUpOrDown(parentVeth, 1) < 0) + if (virNetDevSetOnline(parentVeth, true) < 0) goto error_exit; if (virNetDevBandwidthSet(def->nets[i]->ifname, @@ -1829,7 +1826,7 @@ cleanup: } for (i = 0 ; i < nveths ; i++) { if (rc != 0) - vethDelete(veths[i]); + ignore_value(virNetDevVethDelete(veths[i])); VIR_FREE(veths[i]); } if (rc != 0) { diff --git a/src/lxc/veth.c b/src/lxc/veth.c index e4db65c..b31ce33 100644 --- a/src/lxc/veth.c +++ b/src/lxc/veth.c @@ -28,15 +28,15 @@ #include "virterror_internal.h" #include "virfile.h" -#define VIR_FROM_THIS VIR_FROM_LXC +#define VIR_FROM_THIS VIR_FROM_NONE -#define vethError(code, ...) \ - virReportErrorHelper(VIR_FROM_LXC, code, __FILE__, \ +#define virNetDevvError(code, ...) \ + virReportErrorHelper(VIR_FROM_NONE, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__) /* Functions */ /** - * getFreeVethName: + * virNetDevVethGetFreeName: * @veth: pointer to store returned name for veth device * @startDev: device number to start at (x in vethx) * @@ -45,7 +45,7 @@ * * Returns non-negative device number on success or -1 in case of error */ -static int getFreeVethName(char **veth, int startDev) +static int virNetDevVethGetFreeName(char **veth, int startDev) { int devNum = startDev-1; char *path = NULL; @@ -71,7 +71,7 @@ static int getFreeVethName(char **veth, int startDev) } /** - * vethCreate: + * virNetDevVethCreate: * @veth1: pointer to name for parent end of veth pair * @veth2: pointer to return name for container end of veth pair * @@ -95,7 +95,7 @@ static int getFreeVethName(char **veth, int startDev) * * Returns 0 on success or -1 in case of error */ -int vethCreate(char** veth1, char** veth2) +int virNetDevVethCreate(char** veth1, char** veth2) { int rc = -1; const char *argv[] = { @@ -108,7 +108,7 @@ int vethCreate(char** veth1, char** veth2) VIR_DEBUG("Host: %s guest: %s", NULLSTR(*veth1), NULLSTR(*veth2)); if (*veth1 == NULL) { - if ((vethDev = getFreeVethName(veth1, vethDev)) < 0) + if ((vethDev = virNetDevVethGetFreeName(veth1, vethDev)) < 0) goto cleanup; VIR_DEBUG("Assigned host: %s", *veth1); veth1_alloc = true; @@ -117,7 +117,7 @@ int vethCreate(char** veth1, char** veth2) argv[3] = *veth1; while (*veth2 == NULL) { - if ((vethDev = getFreeVethName(veth2, vethDev)) < 0) { + if ((vethDev = virNetDevVethGetFreeName(veth2, vethDev)) < 0) { if (veth1_alloc) VIR_FREE(*veth1); goto cleanup; @@ -151,7 +151,7 @@ cleanup: } /** - * vethDelete: + * virNetDevVethDelete: * @veth: name for one end of veth pair * * This will delete both veth devices in a pair. Only one end needs to @@ -161,7 +161,7 @@ cleanup: * * Returns 0 on success or -1 in case of error */ -int vethDelete(const char *veth) +int virNetDevVethDelete(const char *veth) { int rc; const char *argv[] = {"ip", "link", "del", veth, NULL}; @@ -185,59 +185,10 @@ int vethDelete(const char *veth) return rc; } -/** - * vethInterfaceUpOrDown: - * @veth: name of veth device - * @upOrDown: 0 => down, 1 => up - * - * Enables a veth device using SIOCSIFFLAGS - * - * Returns 0 on success, -1 on failure, with errno set - */ -int vethInterfaceUpOrDown(const char* veth, int upOrDown) -{ - struct ifreq ifr; - int fd, ret; - - if ((fd = socket(PF_PACKET, SOCK_DGRAM, 0)) == -1) - return(-1); - - memset(&ifr, 0, sizeof(struct ifreq)); - - if (virStrcpyStatic(ifr.ifr_name, veth) == NULL) { - errno = EINVAL; - return -1; - } - - if ((ret = ioctl(fd, SIOCGIFFLAGS, &ifr)) == 0) { - if (upOrDown) - ifr.ifr_flags |= IFF_UP; - else - ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING); - - ret = ioctl(fd, SIOCSIFFLAGS, &ifr); - } - - VIR_FORCE_CLOSE(fd); - if (ret == -1) - if (upOrDown == 0) - /* - * Prevent overwriting an error log which may be set - * where an actual failure occurs. - */ - VIR_DEBUG("Failed to disable '%s'", veth); - else - vethError(VIR_ERR_INTERNAL_ERROR, - _("Failed to enable '%s'"), veth); - else - ret = 0; - - return(ret); -} /** - * moveInterfaceToNetNs: - * @iface: name of device + * virNetDevSetNamespace: + * @ifname: name of device * @pidInNs: PID of process in target net namespace * * Moves the given device into the target net namespace specified by the given @@ -246,12 +197,12 @@ int vethInterfaceUpOrDown(const char* veth, int upOrDown) * * Returns 0 on success or -1 in case of error */ -int moveInterfaceToNetNs(const char* iface, int pidInNs) +int virNetDevSetNamespace(const char* ifname, int pidInNs) { int rc; char *pid = NULL; const char *argv[] = { - "ip", "link", "set", iface, "netns", NULL, NULL + "ip", "link", "set", ifname, "netns", NULL, NULL }; if (virAsprintf(&pid, "%d", pidInNs) == -1) { @@ -267,42 +218,22 @@ int moveInterfaceToNetNs(const char* iface, int pidInNs) } /** - * setMacAddr - * @iface: name of device - * @macaddr: MAC address to be assigned - * - * Changes the MAC address of the given device with the - * given address using this command: - * ip link set @iface address @macaddr - * - * Returns 0 on success or -1 in case of error - */ -int setMacAddr(const char* iface, const char* macaddr) -{ - const char *argv[] = { - "ip", "link", "set", iface, "address", macaddr, NULL - }; - - return virRun(argv, NULL); -} - -/** - * setInterfaceName - * @iface: name of device - * @new: new name of @iface + * virNetDevSetName: + * @ifname: name of device + * @new: new name of @ifname * * Changes the name of the given device. * * Returns 0 on success, -1 on failure with errno set. */ -int setInterfaceName(const char* iface, const char* new) +int virNetDevSetName(const char* ifname, const char* new) { struct ifreq ifr; int fd = socket(PF_PACKET, SOCK_DGRAM, 0); memset(&ifr, 0, sizeof(struct ifreq)); - if (virStrcpyStatic(ifr.ifr_name, iface) == NULL) { + if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { errno = EINVAL; return -1; } diff --git a/src/lxc/veth.h b/src/lxc/veth.h index f50a939..4a66098 100644 --- a/src/lxc/veth.h +++ b/src/lxc/veth.h @@ -17,17 +17,13 @@ # include "internal.h" /* Function declarations */ -int vethCreate(char** veth1, char** veth2) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); -int vethDelete(const char* veth) - ATTRIBUTE_NONNULL(1); -int vethInterfaceUpOrDown(const char* veth, int upOrDown) - ATTRIBUTE_NONNULL(1); -int moveInterfaceToNetNs(const char *iface, int pidInNs) - ATTRIBUTE_NONNULL(1); -int setMacAddr(const char* iface, const char* macaddr) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); -int setInterfaceName(const char* iface, const char* new) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +int virNetDevVethCreate(char **veth1, char **veth2) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevVethDelete(const char *veth) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetNamespace(const char *ifname, int pidInNs) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetName(const char *ifname, const char *newifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; #endif /* VETH_H */ -- 1.7.6.4

On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
The src/lxc/veth.c file contains APIs for managing veth devices, but some of the APIs duplicate stuff from src/util/virnetdev.h. Delete thed duplicate APIs and rename the remaining ones to follow virNetDevVethXXXX
* src/lxc/veth.c, src/lxc/veth.h: Rename APIs& delete duplicates * src/lxc/lxc_container.c, src/lxc/lxc_controller.c, src/lxc/lxc_driver.c: Update for API renaming --- po/POTFILES.in | 1 - src/lxc/lxc_container.c | 7 ++- src/lxc/lxc_controller.c | 4 +- src/lxc/lxc_driver.c | 19 +++----- src/lxc/veth.c | 109 ++++++++------------------------------------- src/lxc/veth.h | 20 +++----- 6 files changed, 42 insertions(+), 118 deletions(-)
ACK.

From: "Daniel P. Berrange" <berrange@redhat.com> Move the virNetDevSetName and virNetDevSetNamespace APIs out of LXC's veth.c and into virnetdev.c. Move the remaining content of the file to src/util/virnetdevveth.c * src/lxc/veth.c: Rename to src/util/virnetdevveth.c * src/lxc/veth.h: Rename to src/util/virnetdevveth.h * src/util/virnetdev.c, src/util/virnetdev.h: Add virNetDevSetName and virNetDevSetNamespace * src/lxc/lxc_container.c, src/lxc/lxc_controller.c, src/lxc/lxc_driver.c: Update include paths --- src/Makefile.am | 7 +- src/lxc/lxc_container.c | 2 +- src/lxc/lxc_controller.c | 3 +- src/lxc/lxc_driver.c | 2 +- src/lxc/veth.h | 29 --------- src/util/virnetdev.c | 81 +++++++++++++++++++++++++ src/util/virnetdev.h | 4 + src/{lxc/veth.c => util/virnetdevveth.c} | 95 +++++------------------------ src/util/virnetdevveth.h | 35 +++++++++++ 9 files changed, 144 insertions(+), 114 deletions(-) delete mode 100644 src/lxc/veth.h rename src/{lxc/veth.c => util/virnetdevveth.c} (74%) create mode 100644 src/util/virnetdevveth.h diff --git a/src/Makefile.am b/src/Makefile.am index 2faf659..6ffa8c6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -94,6 +94,7 @@ UTIL_SOURCES = \ util/virnetdevbandwidth.h util/virnetdevbandwidth.c \ util/virnetdevbridge.h util/virnetdevbridge.c \ util/virnetdevtap.h util/virnetdevtap.c \ + util/virnetdevveth.h util/virnetdevveth.c \ util/virnetdevvportprofile.h util/virnetdevvportprofile.c \ util/virsocketaddr.h util/virsocketaddr.c @@ -318,14 +319,12 @@ endif LXC_DRIVER_SOURCES = \ lxc/lxc_conf.c lxc/lxc_conf.h \ lxc/lxc_container.c lxc/lxc_container.h \ - lxc/lxc_driver.c lxc/lxc_driver.h \ - lxc/veth.c lxc/veth.h + lxc/lxc_driver.c lxc/lxc_driver.h LXC_CONTROLLER_SOURCES = \ lxc/lxc_conf.c lxc/lxc_conf.h \ lxc/lxc_container.c lxc/lxc_container.h \ - lxc/lxc_controller.c \ - lxc/veth.c lxc/veth.h + lxc/lxc_controller.c SECURITY_DRIVER_APPARMOR_HELPER_SOURCES = \ security/virt-aa-helper.c diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index 1617117..7163ad8 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -56,7 +56,7 @@ #include "lxc_container.h" #include "util.h" #include "memory.h" -#include "veth.h" +#include "virnetdevveth.h" #include "uuid.h" #include "virfile.h" #include "command.h" diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index d18055a..d863f38 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -54,7 +54,8 @@ #include "lxc_conf.h" #include "lxc_container.h" -#include "veth.h" +#include "virnetdev.h" +#include "virnetdevveth.h" #include "memory.h" #include "util.h" #include "virfile.h" diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 77ac605..ccb0bbf 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -44,7 +44,7 @@ #include "memory.h" #include "util.h" #include "virnetdevbridge.h" -#include "veth.h" +#include "virnetdevveth.h" #include "nodeinfo.h" #include "uuid.h" #include "stats_linux.h" diff --git a/src/lxc/veth.h b/src/lxc/veth.h deleted file mode 100644 index 4a66098..0000000 --- a/src/lxc/veth.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * veth.h: Interface to tools for managing veth pairs - * - * Copyright (C) 2010 Red Hat, Inc. - * Copyright IBM Corp. 2008 - * - * See COPYING.LIB for the License of this software - * - * Authors: - * David L. Leskovec <dlesko at linux.vnet.ibm.com> - */ - -#ifndef VETH_H -# define VETH_H - -# include <config.h> -# include "internal.h" - -/* Function declarations */ -int virNetDevVethCreate(char **veth1, char **veth2) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; -int virNetDevVethDelete(const char *veth) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevSetNamespace(const char *ifname, int pidInNs) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevSetName(const char *ifname, const char *newifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -#endif /* VETH_H */ diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index c9fb6a1..5311ae7 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -332,6 +332,87 @@ int virNetDevSetMTUFromDevice(const char *ifname, } +/** + * virNetDevSetNamespace: + * @ifname: name of device + * @pidInNs: PID of process in target net namespace + * + * Moves the given device into the target net namespace specified by the given + * pid using this command: + * ip link set @iface netns @pidInNs + * + * Returns 0 on success or -1 in case of error + */ +int virNetDevSetNamespace(const char *ifname, int pidInNs) +{ + int rc; + char *pid = NULL; + const char *argv[] = { + "ip", "link", "set", ifname, "netns", NULL, NULL + }; + + if (virAsprintf(&pid, "%d", pidInNs) == -1) { + virReportOOMError(); + return -1; + } + + argv[5] = pid; + rc = virRun(argv, NULL); + + VIR_FREE(pid); + return rc; +} + +#ifdef SIOCSIFNAME +/** + * virNetDevSetName: + * @ifname: name of device + * @newifname: new name of @ifname + * + * Changes the name of the given device. + * + * Returns 0 on success, -1 on error + */ +int virNetDevSetName(const char* ifname, const char *newifname) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + if (virStrcpyStatic(ifr.ifr_newname, newifname) == NULL) { + virReportSystemError(ERANGE, + _("Network interface name '%s' is too long"), + newifname); + goto cleanup; + } + + if (ioctl(fd, SIOCSIFNAME, &ifr)) { + virReportSystemError(errno, + _("Unable to rename '%s' to '%s'"), + ifname, newifname); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} +#else +int virNetDevSetName(const char* ifname, const char *newifname) +{ + virReportSystemError(ENOSYS, + _("Cannot rename interface '%s' to '%s' on this platform"), + ifname, newifname); + return -1; +} +#endif + + #ifdef SIOCSIFFLAGS /** * virNetDevSetOnline: diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index 5324b66..de98553 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -59,5 +59,9 @@ int virNetDevSetMTUFromDevice(const char *ifname, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevGetMTU(const char *ifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetNamespace(const char *ifname, int pidInNs) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevSetName(const char *ifname, const char *newifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; #endif /* __VIR_NETDEV_H__ */ diff --git a/src/lxc/veth.c b/src/util/virnetdevveth.c similarity index 74% rename from src/lxc/veth.c rename to src/util/virnetdevveth.c index b31ce33..c77e558 100644 --- a/src/lxc/veth.c +++ b/src/util/virnetdevveth.c @@ -1,32 +1,35 @@ /* - * veth.c: Tools for managing veth pairs - * * Copyright (C) 2010-2011 Red Hat, Inc. * Copyright IBM Corp. 2008 * - * See COPYING.LIB for the License of this software + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Authors: - * David L. Leskovec <dlesko at linux.vnet.ibm.com> + * David L. Leskovec <dlesko at linux.vnet.ibm.com> + * Daniel P. Berrange <berrange@redhat.com> */ #include <config.h> -#include <linux/sockios.h> -#include <net/if.h> -#include <string.h> -#include <stdio.h> -#include <sys/ioctl.h> -#include <sys/types.h> #include <sys/wait.h> -#include "veth.h" -#include "internal.h" -#include "logging.h" +#include "virnetdevveth.h" #include "memory.h" +#include "logging.h" #include "command.h" #include "virterror_internal.h" -#include "virfile.h" #define VIR_FROM_THIS VIR_FROM_NONE @@ -184,67 +187,3 @@ int virNetDevVethDelete(const char *veth) return rc; } - - -/** - * virNetDevSetNamespace: - * @ifname: name of device - * @pidInNs: PID of process in target net namespace - * - * Moves the given device into the target net namespace specified by the given - * pid using this command: - * ip link set @iface netns @pidInNs - * - * Returns 0 on success or -1 in case of error - */ -int virNetDevSetNamespace(const char* ifname, int pidInNs) -{ - int rc; - char *pid = NULL; - const char *argv[] = { - "ip", "link", "set", ifname, "netns", NULL, NULL - }; - - if (virAsprintf(&pid, "%d", pidInNs) == -1) { - virReportOOMError(); - return -1; - } - - argv[5] = pid; - rc = virRun(argv, NULL); - - VIR_FREE(pid); - return rc; -} - -/** - * virNetDevSetName: - * @ifname: name of device - * @new: new name of @ifname - * - * Changes the name of the given device. - * - * Returns 0 on success, -1 on failure with errno set. - */ -int virNetDevSetName(const char* ifname, const char* new) -{ - struct ifreq ifr; - int fd = socket(PF_PACKET, SOCK_DGRAM, 0); - - memset(&ifr, 0, sizeof(struct ifreq)); - - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { - errno = EINVAL; - return -1; - } - - if (virStrcpyStatic(ifr.ifr_newname, new) == NULL) { - errno = EINVAL; - return -1; - } - - if (ioctl(fd, SIOCSIFNAME, &ifr)) - return -1; - - return 0; -} diff --git a/src/util/virnetdevveth.h b/src/util/virnetdevveth.h new file mode 100644 index 0000000..0d450f1 --- /dev/null +++ b/src/util/virnetdevveth.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2010-2011 Red Hat, Inc. + * Copyright IBM Corp. 2008 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * David L. Leskovec <dlesko at linux.vnet.ibm.com> + * Daniel P. Berrange <berrange@redhat.com> + */ + +#ifndef __VIR_NETDEV_VETH_H__ +# define __VIR_NETDEV_VETH_H__ + +# include "internal.h" + +/* Function declarations */ +int virNetDevVethCreate(char **veth1, char **veth2) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevVethDelete(const char *veth) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +#endif /* __VIR_NETDEV_VETH_H__ */ -- 1.7.6.4

On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
Move the virNetDevSetName and virNetDevSetNamespace APIs out of LXC's veth.c and into virnetdev.c.
Move the remaining content of the file to src/util/virnetdevveth.c
* src/lxc/veth.c: Rename to src/util/virnetdevveth.c * src/lxc/veth.h: Rename to src/util/virnetdevveth.h * src/util/virnetdev.c, src/util/virnetdev.h: Add virNetDevSetName and virNetDevSetNamespace * src/lxc/lxc_container.c, src/lxc/lxc_controller.c, src/lxc/lxc_driver.c: Update include paths --- src/Makefile.am | 7 +- src/lxc/lxc_container.c | 2 +- src/lxc/lxc_controller.c | 3 +- src/lxc/lxc_driver.c | 2 +- src/lxc/veth.h | 29 --------- src/util/virnetdev.c | 81 +++++++++++++++++++++++++ src/util/virnetdev.h | 4 + src/{lxc/veth.c => util/virnetdevveth.c} | 95 +++++------------------------ src/util/virnetdevveth.h | 35 +++++++++++ 9 files changed, 144 insertions(+), 114 deletions(-) delete mode 100644 src/lxc/veth.h rename src/{lxc/veth.c => util/virnetdevveth.c} (74%) create mode 100644 src/util/virnetdevveth.h
ACK.

From: "Daniel P. Berrange" <berrange@redhat.com> The ifaceUp, ifaceDown, ifaceCtrl & ifaceIsUp APIs can be replaced with calls to virNetDevSetOnline and virNetDevIsOnline * src/util/interface.c, src/util/interface.h: Delete ifaceUp, ifaceDown, ifaceCtrl & ifaceIsUp * src/nwfilter/nwfilter_gentech_driver.c, src/util/macvtap.c: Update to use virNetDevSetOnline and virNetDevIsOnline --- src/libvirt_private.syms | 3 - src/nwfilter/nwfilter_gentech_driver.c | 4 +- src/util/interface.c | 150 -------------------------------- src/util/interface.h | 12 --- src/util/macvtap.c | 18 ++-- 5 files changed, 10 insertions(+), 177 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4bc9217..a88b806 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -576,8 +576,6 @@ virHookPresent; # interface.h ifaceCheck; -ifaceCtrl; -ifaceGetFlags; ifaceGetIndex; ifaceGetMacAddress; ifaceGetIPAddress; @@ -585,7 +583,6 @@ ifaceGetNthParent; ifaceGetPhysicalFunction; ifaceGetVirtualFunctionIndex; ifaceGetVlanID; -ifaceIsUp; ifaceIsVirtualFunction; ifaceLinkDel; ifaceMacvtapLinkAdd; diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 7891983..899bd32 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -34,7 +34,7 @@ #include "nwfilter_gentech_driver.h" #include "nwfilter_ebiptables_driver.h" #include "nwfilter_learnipaddr.h" - +#include "virnetdev.h" #define VIR_FROM_THIS VIR_FROM_NWFILTER @@ -963,7 +963,7 @@ virNWFilterInstantiateFilterLate(virConnectPtr conn, if (rc) { /* something went wrong... 'DOWN' the interface */ if ((ifaceCheck(false, ifname, NULL, ifindex) < 0) || - (ifaceDown(ifname) < 0)) { + (virNetDevSetOnline(ifname, false) < 0)) { /* assuming interface disappeared... */ _virNWFilterTeardownFilter(ifname); } diff --git a/src/util/interface.c b/src/util/interface.c index 12bf7bc..913beb5 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -54,156 +54,6 @@ virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__) -#if __linux__ -static int -getFlags(int fd, const char *ifname, struct ifreq *ifr) { - - memset(ifr, 0, sizeof(*ifr)); - - if (virStrncpy(ifr->ifr_name, - ifname, strlen(ifname), sizeof(ifr->ifr_name)) == NULL) - return -ENODEV; - - if (ioctl(fd, SIOCGIFFLAGS, ifr) < 0) - return -errno; - - return 0; -} - - -/** - * ifaceGetFlags - * - * @ifname : name of the interface - * @flags : pointer to short holding the flags on success - * - * Get the flags of the interface. Returns 0 on success, -errno on failure. - */ -int -ifaceGetFlags(const char *ifname, short *flags) { - struct ifreq ifr; - int rc; - int fd = socket(PF_PACKET, SOCK_DGRAM, 0); - - if (fd < 0) - return -errno; - - rc = getFlags(fd, ifname, &ifr); - - *flags = ifr.ifr_flags; - - VIR_FORCE_CLOSE(fd); - - return rc; -} - - -int -ifaceIsUp(const char *ifname, bool *up) { - short flags = 0; - int rc = ifaceGetFlags(ifname, &flags); - - if (rc < 0) - return rc; - - *up = ((flags & IFF_UP) == IFF_UP); - - return 0; -} -#else - -/* Note: Showstopper on cygwin is only missing PF_PACKET */ - -int - -ifaceGetFlags(const char *ifname ATTRIBUTE_UNUSED, - short *flags ATTRIBUTE_UNUSED) { - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("ifaceGetFlags is not supported on non-linux platforms")); - return -ENOSYS; -} - -int -ifaceIsUp(const char *ifname ATTRIBUTE_UNUSED, - bool *up ATTRIBUTE_UNUSED) { - - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("ifaceIsUp is not supported on non-linux platforms")); - return -ENOSYS; -} - -#endif /* __linux__ */ - -/* - * chgIfaceFlags: Change flags on an interface - * - * @ifname : name of the interface - * @flagclear : the flags to clear - * @flagset : the flags to set - * - * The new flags of the interface will be calculated as - * flagmask = (~0 ^ flagclear) - * newflags = (curflags & flagmask) | flagset; - * - * Returns 0 on success, -errno on failure. - */ -#ifdef __linux__ -static int chgIfaceFlags(const char *ifname, short flagclear, short flagset) { - struct ifreq ifr; - int rc = 0; - short flags; - short flagmask = (~0 ^ flagclear); - int fd = socket(PF_PACKET, SOCK_DGRAM, 0); - - if (fd < 0) - return -errno; - - rc = getFlags(fd, ifname, &ifr); - if (rc < 0) - goto cleanup; - - flags = (ifr.ifr_flags & flagmask) | flagset; - - if (ifr.ifr_flags != flags) { - ifr.ifr_flags = flags; - - if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) - rc = -errno; - } - -cleanup: - VIR_FORCE_CLOSE(fd); - return rc; -} - - -/* - * ifaceCtrl - * @name: name of the interface - * @up: true (1) for up, false (0) for down - * - * Function to control if an interface is activated (up, 1) or not (down, 0) - * - * Returns 0 on success, -errno on failure. - */ -int -ifaceCtrl(const char *name, bool up) -{ - return chgIfaceFlags(name, - (up) ? 0 : IFF_UP, - (up) ? IFF_UP : 0); -} - -#else - -int -ifaceCtrl(const char *name ATTRIBUTE_UNUSED, bool up ATTRIBUTE_UNUSED) -{ - return -ENOSYS; -} - -#endif /* __linux__ */ - /** * ifaceCheck * diff --git a/src/util/interface.h b/src/util/interface.h index 3603c68..5068adb 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -29,18 +29,6 @@ struct nlattr; # define NET_SYSFS "/sys/class/net/" -int ifaceGetFlags(const char *name, short *flags); -int ifaceIsUp(const char *name, bool *up); - -int ifaceCtrl(const char *name, bool up); - -static inline int ifaceUp(const char *name) { - return ifaceCtrl(name, true); -} - -static inline int ifaceDown(const char *name) { - return ifaceCtrl(name, false); -} int ifaceCheck(bool reportError, const char *ifname, const unsigned char *macaddr, int ifindex); diff --git a/src/util/macvtap.c b/src/util/macvtap.c index c4629ed..bd3c33c 100644 --- a/src/util/macvtap.c +++ b/src/util/macvtap.c @@ -50,6 +50,7 @@ #include "util.h" #include "macvtap.h" +#include "virnetdev.h" VIR_ENUM_IMPL(virMacvtapMode, VIR_MACVTAP_MODE_LAST, "vepa", @@ -342,13 +343,7 @@ create_name: goto link_del_exit; } - rc = ifaceUp(cr_ifname); - if (rc < 0) { - virReportSystemError(errno, - _("cannot 'up' interface %s -- another " - "macvtap device may be 'up' and have the same " - "MAC address"), - cr_ifname); + if (virNetDevSetOnline(cr_ifname, true) < 0) { rc = -1; goto disassociate_exit; } @@ -1129,8 +1124,11 @@ vpAssociatePortProfileId(const char *macvtap_ifname, (vmOp == VIR_VM_OP_MIGRATE_IN_START) ? PREASSOCIATE_RR : ASSOCIATE); - if (vmOp != VIR_VM_OP_MIGRATE_IN_START && !rc) - ifaceUp(linkdev); + if (vmOp != VIR_VM_OP_MIGRATE_IN_START && !rc) { + /* XXX bogus error handling */ + ignore_value(virNetDevSetOnline(linkdev, true)); + } + break; } @@ -1180,7 +1178,7 @@ vpDisassociatePortProfileId(const char *macvtap_ifname, /* avoid disassociating twice */ if (vmOp == VIR_VM_OP_MIGRATE_IN_FINISH) break; - ifaceDown(linkdev); + ignore_value(virNetDevSetOnline(linkdev, false)); rc = doPortProfileOp8021Qbh(linkdev, macvtap_macaddr, virtPort, NULL, DISASSOCIATE); break; -- 1.7.6.4

On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange"<berrange@redhat.com>
The ifaceUp, ifaceDown, ifaceCtrl& ifaceIsUp APIs can be replaced with calls to virNetDevSetOnline and virNetDevIsOnline
* src/util/interface.c, src/util/interface.h: Delete ifaceUp, ifaceDown, ifaceCtrl& ifaceIsUp * src/nwfilter/nwfilter_gentech_driver.c, src/util/macvtap.c: Update to use virNetDevSetOnline and virNetDevIsOnline --- src/libvirt_private.syms | 3 - src/nwfilter/nwfilter_gentech_driver.c | 4 +- src/util/interface.c | 150 -------------------------------- src/util/interface.h | 12 --- src/util/macvtap.c | 18 ++-- 5 files changed, 10 insertions(+), 177 deletions(-)
ACK.

From: "Daniel P. Berrange" <berrange@redhat.com> The ifaceSetMac and ifaceGetMac APIs duplicate the functionality of the virNetDevSetMAC and virNetDevGetMAC APIs, but returning errno's instead of raising errors. * src/util/interface.c, src/util/interface.h: Remove ifaceSetMac and ifaceGetMac APIs, adjusting callers for new error behaviour --- src/libvirt_private.syms | 2 - src/util/interface.c | 190 +++++++--------------------------------------- src/util/interface.h | 4 - 3 files changed, 27 insertions(+), 169 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a88b806..52d2076 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -577,7 +577,6 @@ virHookPresent; # interface.h ifaceCheck; ifaceGetIndex; -ifaceGetMacAddress; ifaceGetIPAddress; ifaceGetNthParent; ifaceGetPhysicalFunction; @@ -589,7 +588,6 @@ ifaceMacvtapLinkAdd; ifaceMacvtapLinkDump; ifaceReplaceMacAddress; ifaceRestoreMacAddress; -ifaceSetMacAddress; # interface_conf.h diff --git a/src/util/interface.c b/src/util/interface.c index 913beb5..63e6bf7 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -47,6 +47,7 @@ #include "netlink.h" #include "pci.h" #include "logging.h" +#include "virnetdev.h" #define VIR_FROM_THIS VIR_FROM_NET @@ -251,118 +252,6 @@ ifaceGetVlanID(const char *vlanifname ATTRIBUTE_UNUSED, } #endif /* __linux__ */ -/** - * ifaceGetMacAddress: - * @ifname: interface name to set MTU for - * @macaddr: MAC address (VIR_MAC_BUFLEN in size) - * - * This function gets the @macaddr for a given interface @ifname. - * - * Returns 0 on success, -errno on failure. - */ -#ifdef __linux__ -int -ifaceGetMacAddress(const char *ifname, - unsigned char *macaddr) -{ - struct ifreq ifr; - int fd; - int rc = 0; - - if (!ifname) - return -EINVAL; - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) - return -errno; - - memset(&ifr, 0, sizeof(struct ifreq)); - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { - rc = -EINVAL; - goto cleanup; - } - - if (ioctl(fd, SIOCGIFHWADDR, (char *)&ifr) != 0) { - rc = -errno; - goto cleanup; - } - - memcpy(macaddr, ifr.ifr_ifru.ifru_hwaddr.sa_data, VIR_MAC_BUFLEN); - -cleanup: - VIR_FORCE_CLOSE(fd); - return rc; -} - -#else - -int -ifaceGetMacAddress(const char *ifname ATTRIBUTE_UNUSED, - unsigned char *macaddr ATTRIBUTE_UNUSED) -{ - return -ENOSYS; -} - -#endif /* __linux__ */ - -/** - * ifaceSetMacAddress: - * @ifname: interface name to set MTU for - * @macaddr: MAC address (VIR_MAC_BUFLEN in size) - * - * This function sets the @macaddr for a given interface @ifname. This - * gets rid of the kernel's automatically assigned random MAC. - * - * Returns 0 on success, -errno on failure. - */ -#ifdef __linux__ -int -ifaceSetMacAddress(const char *ifname, - const unsigned char *macaddr) -{ - struct ifreq ifr; - int fd; - int rc = 0; - - if (!ifname) - return -EINVAL; - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) - return -errno; - - memset(&ifr, 0, sizeof(struct ifreq)); - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { - rc = -EINVAL; - goto cleanup; - } - - /* To fill ifr.ifr_hdaddr.sa_family field */ - if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0) { - rc = -errno; - goto cleanup; - } - - memcpy(ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN); - - rc = ioctl(fd, SIOCSIFHWADDR, &ifr) == 0 ? 0 : -errno; - -cleanup: - VIR_FORCE_CLOSE(fd); - return rc; -} - -#else - -int -ifaceSetMacAddress(const char *ifname ATTRIBUTE_UNUSED, - const unsigned char *macaddr ATTRIBUTE_UNUSED) -{ - return -ENOSYS; -} - -#endif /* __linux__ */ - /** * ifaceGetIPAddress: @@ -945,7 +834,7 @@ ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, * @linkdev: name of interface * @stateDir: directory to store old MAC address * - * Returns 0 on success, -errno on failure. + * Returns 0 on success, -1 on failure * */ int @@ -954,46 +843,30 @@ ifaceReplaceMacAddress(const unsigned char *macaddress, const char *stateDir) { unsigned char oldmac[6]; - int rc; + char *path = NULL; + char macstr[VIR_MAC_STRING_BUFLEN]; - rc = ifaceGetMacAddress(linkdev, oldmac); - - if (rc < 0) { - virReportSystemError(rc, - _("Getting MAC address from '%s' " - "to '%02x:%02x:%02x:%02x:%02x:%02x' failed."), - linkdev, - oldmac[0], oldmac[1], oldmac[2], - oldmac[3], oldmac[4], oldmac[5]); - } else { - char *path = NULL; - char macstr[VIR_MAC_STRING_BUFLEN]; - - if (virAsprintf(&path, "%s/%s", - stateDir, - linkdev) < 0) { - virReportOOMError(); - return -errno; - } - virFormatMacAddr(oldmac, macstr); - if (virFileWriteStr(path, macstr, O_CREAT|O_TRUNC|O_WRONLY) < 0) { - virReportSystemError(errno, _("Unable to preserve mac for %s"), - linkdev); - return -errno; - } - } + if (virNetDevGetMAC(linkdev, oldmac) < 0) + return -1; - rc = ifaceSetMacAddress(linkdev, macaddress); - if (rc < 0) { - virReportSystemError(rc, - _("Setting MAC address on '%s' to " - "'%02x:%02x:%02x:%02x:%02x:%02x' failed."), - linkdev, - macaddress[0], macaddress[1], macaddress[2], - macaddress[3], macaddress[4], macaddress[5]); + + if (virAsprintf(&path, "%s/%s", + stateDir, + linkdev) < 0) { + virReportOOMError(); + return -1; + } + virFormatMacAddr(oldmac, macstr); + if (virFileWriteStr(path, macstr, O_CREAT|O_TRUNC|O_WRONLY) < 0) { + virReportSystemError(errno, _("Unable to preserve mac for %s"), + linkdev); + return -1; } - return rc; + if (virNetDevSetMAC(linkdev, macaddress) < 0) + return -1; + + return 0; } /** @@ -1018,31 +891,22 @@ ifaceRestoreMacAddress(const char *linkdev, stateDir, linkdev) < 0) { virReportOOMError(); - return -errno; + return -1; } - if (virFileReadAll(path, VIR_MAC_STRING_BUFLEN, &macstr) < 0) { - return -errno; - } + if (virFileReadAll(path, VIR_MAC_STRING_BUFLEN, &macstr) < 0) + return -1; if (virParseMacAddr(macstr, &oldmac[0]) != 0) { ifaceError(VIR_ERR_INTERNAL_ERROR, _("Cannot parse MAC address from '%s'"), oldmacname); VIR_FREE(macstr); - return -EINVAL; + return -1; } /*reset mac and remove file-ignore results*/ - rc = ifaceSetMacAddress(linkdev, oldmac); - if (rc < 0) { - virReportSystemError(rc, - _("Setting MAC address on '%s' to " - "'%02x:%02x:%02x:%02x:%02x:%02x' failed."), - linkdev, - oldmac[0], oldmac[1], oldmac[2], - oldmac[3], oldmac[4], oldmac[5]); - } + rc = virNetDevSetMAC(linkdev, oldmac); ignore_value(unlink(path)); VIR_FREE(macstr); diff --git a/src/util/interface.h b/src/util/interface.h index 5068adb..4adc601 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -37,10 +37,6 @@ int ifaceGetIndex(bool reportError, const char *ifname, int *ifindex); int ifaceGetVlanID(const char *vlanifname, int *vlanid); -int ifaceSetMacAddress(const char *ifname, const unsigned char *macaddr); - -int ifaceGetMacAddress(const char *ifname, unsigned char *macaddr); - int ifaceGetIPAddress(const char *ifname, virSocketAddrPtr addr); int ifaceMacvtapLinkAdd(const char *type, -- 1.7.6.4

On 11/03/2011 01:30 PM, Daniel P. Berrange wrote:
The ifaceSetMac and ifaceGetMac APIs duplicate the functionality of the virNetDevSetMAC and virNetDevGetMAC APIs, but returning errno's instead of raising errors.
* src/util/interface.c, src/util/interface.h: Remove ifaceSetMac and ifaceGetMac APIs, adjusting callers for new error behaviour --- src/libvirt_private.syms | 2 - src/util/interface.c | 190 +++++++--------------------------------------- src/util/interface.h | 4 - 3 files changed, 27 insertions(+), 169 deletions(-)
Everything seems in order, and make && make check && make syntax-check passes. ACK.

From: "Daniel P. Berrange" <berrange@redhat.com> In preparation for code re-organization, rename the Macvtap management APIs to have the following patterns virNetDevMacVLanXXXXX - macvlan/macvtap interface management virNetDevVPortProfileXXXX - virtual port profile management * src/util/macvtap.c, src/util/macvtap.h: Rename APIs * src/conf/domain_conf.c, src/network/bridge_driver.c, src/qemu/qemu_command.c, src/qemu/qemu_command.h, src/qemu/qemu_driver.c, src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c, src/qemu/qemu_process.c, src/qemu/qemu_process.h: Update for renamed APIs --- src/conf/domain_conf.c | 10 +- src/libvirt_private.syms | 4 +- src/network/bridge_driver.c | 8 +- src/qemu/qemu_command.c | 30 ++-- src/qemu/qemu_command.h | 4 +- src/qemu/qemu_driver.c | 12 +- src/qemu/qemu_hotplug.c | 12 +- src/qemu/qemu_migration.c | 24 ++-- src/qemu/qemu_process.c | 12 +- src/qemu/qemu_process.h | 2 +- src/util/macvtap.c | 386 ++++++++++++++++++++++--------------------- src/util/macvtap.h | 100 ++++++----- tests/qemuxml2argvtest.c | 2 +- tests/qemuxmlnstest.c | 2 +- 14 files changed, 312 insertions(+), 296 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b3c3339..f6d2892 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3102,7 +3102,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node, mode = virXPathString("string(./source[1]/@mode)", ctxt); if (mode) { int m; - if ((m = virMacvtapModeTypeFromString(mode)) < 0) { + if ((m = virNetDevMacVLanModeTypeFromString(mode)) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _("Unkown mode '%s' in interface <actual> element"), mode); @@ -3416,14 +3416,14 @@ virDomainNetDefParseXML(virCapsPtr caps, if (mode != NULL) { int m; - if ((m = virMacvtapModeTypeFromString(mode)) < 0) { + if ((m = virNetDevMacVLanModeTypeFromString(mode)) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unkown mode has been specified")); goto error; } def->data.direct.mode = m; } else - def->data.direct.mode = VIR_MACVTAP_MODE_VEPA; + def->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_VEPA; def->data.direct.virtPortProfile = virtPort; virtPort = NULL; @@ -9712,7 +9712,7 @@ virDomainActualNetDefFormat(virBufferPtr buf, virBufferEscapeString(buf, " dev='%s'", def->data.direct.linkdev); - mode = virMacvtapModeTypeToString(def->data.direct.mode); + mode = virNetDevMacVLanModeTypeToString(def->data.direct.mode); if (!mode) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected source mode %d"), @@ -9817,7 +9817,7 @@ virDomainNetDefFormat(virBufferPtr buf, virBufferEscapeString(buf, " <source dev='%s'", def->data.direct.linkdev); virBufferAsprintf(buf, " mode='%s'", - virMacvtapModeTypeToString(def->data.direct.mode)); + virNetDevMacVLanModeTypeToString(def->data.direct.mode)); virBufferAddLit(buf, "/>\n"); virBufferAdjustIndent(buf, 6); if (virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf) < 0) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 52d2076..85f4064 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -739,8 +739,8 @@ virLogUnlock; # macvtap.h -virVMOperationTypeFromString; -virVMOperationTypeToString; +virNetDevVPortProfileOpTypeFromString; +virNetDevVPortProfileOpTypeToString; # memory.h diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index e68712f..bad5337 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -2780,16 +2780,16 @@ networkAllocateActualDevice(virDomainNetDefPtr iface) iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_DIRECT; switch (netdef->forwardType) { case VIR_NETWORK_FORWARD_BRIDGE: - iface->data.network.actual->data.direct.mode = VIR_MACVTAP_MODE_BRIDGE; + iface->data.network.actual->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_BRIDGE; break; case VIR_NETWORK_FORWARD_PRIVATE: - iface->data.network.actual->data.direct.mode = VIR_MACVTAP_MODE_PRIVATE; + iface->data.network.actual->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_PRIVATE; break; case VIR_NETWORK_FORWARD_VEPA: - iface->data.network.actual->data.direct.mode = VIR_MACVTAP_MODE_VEPA; + iface->data.network.actual->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_VEPA; break; case VIR_NETWORK_FORWARD_PASSTHROUGH: - iface->data.network.actual->data.direct.mode = VIR_MACVTAP_MODE_PASSTHRU; + iface->data.network.actual->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_PASSTHRU; break; } diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 11ebb69..6d19f95 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -139,7 +139,7 @@ qemuPhysIfaceConnect(virDomainDefPtr def, struct qemud_driver *driver, virDomainNetDefPtr net, virBitmapPtr qemuCaps, - enum virVMOperationType vmop) + enum virNetDevVPortProfileOp vmop) { int rc; #if WITH_MACVTAP @@ -151,14 +151,14 @@ qemuPhysIfaceConnect(virDomainDefPtr def, net->model && STREQ(net->model, "virtio")) vnet_hdr = 1; - rc = openMacvtapTap(net->ifname, net->mac, - virDomainNetGetActualDirectDev(net), - virDomainNetGetActualDirectMode(net), - vnet_hdr, def->uuid, - virDomainNetGetActualDirectVirtPortProfile(net), - &res_ifname, - vmop, driver->stateDir, - virDomainNetGetActualBandwidth(net)); + rc = virNetDevMacVLanCreate(net->ifname, net->mac, + virDomainNetGetActualDirectDev(net), + virDomainNetGetActualDirectMode(net), + vnet_hdr, def->uuid, + virDomainNetGetActualDirectVirtPortProfile(net), + &res_ifname, + vmop, driver->stateDir, + virDomainNetGetActualBandwidth(net)); if (rc >= 0) { virDomainAuditNetDevice(def, net, res_ifname, true); VIR_FREE(net->ifname); @@ -178,11 +178,11 @@ qemuPhysIfaceConnect(virDomainDefPtr def, err = virDomainConfNWFilterInstantiate(conn, net); if (err) { VIR_FORCE_CLOSE(rc); - delMacvtap(net->ifname, net->mac, - virDomainNetGetActualDirectDev(net), - virDomainNetGetActualDirectMode(net), - virDomainNetGetActualDirectVirtPortProfile(net), - driver->stateDir); + ignore_value(virNetDevMacVLanDelete(net->ifname, net->mac, + virDomainNetGetActualDirectDev(net), + virDomainNetGetActualDirectMode(net), + virDomainNetGetActualDirectVirtPortProfile(net), + driver->stateDir)); VIR_FREE(net->ifname); } } @@ -3258,7 +3258,7 @@ qemuBuildCommandLine(virConnectPtr conn, const char *migrateFrom, int migrateFd, virDomainSnapshotObjPtr snapshot, - enum virVMOperationType vmop) + enum virNetDevVPortProfileOp vmop) { int i; struct utsname ut; diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 76e67b2..e10e278 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -50,7 +50,7 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn, const char *migrateFrom, int migrateFd, virDomainSnapshotObjPtr current_snapshot, - enum virVMOperationType vmop) + enum virNetDevVPortProfileOp vmop) ATTRIBUTE_NONNULL(1); /* With vlan == -1, use netdev syntax, else old hostnet */ @@ -136,7 +136,7 @@ int qemuPhysIfaceConnect(virDomainDefPtr def, struct qemud_driver *driver, virDomainNetDefPtr net, virBitmapPtr qemuCaps, - enum virVMOperationType vmop); + enum virNetDevVPortProfileOp vmop); int qemuOpenVhostNet(virDomainDefPtr def, virDomainNetDefPtr net, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 628dac1..465640f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1324,7 +1324,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml, if (qemuProcessStart(conn, driver, vm, NULL, (flags & VIR_DOMAIN_START_PAUSED) != 0, (flags & VIR_DOMAIN_START_AUTODESTROY) != 0, - -1, NULL, NULL, VIR_VM_OP_CREATE) < 0) { + -1, NULL, NULL, VIR_NETDEV_VPORT_PROFILE_OP_CREATE) < 0) { virDomainAuditStart(vm, "booted", false); if (qemuDomainObjEndJob(driver, vm) > 0) qemuDomainRemoveInactive(driver, vm); @@ -4098,7 +4098,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, /* Set the migration source and start it up. */ ret = qemuProcessStart(conn, driver, vm, "stdio", true, - false, *fd, path, NULL, VIR_VM_OP_RESTORE); + false, *fd, path, NULL, VIR_NETDEV_VPORT_PROFILE_OP_RESTORE); if (intermediatefd != -1) { if (ret < 0) { @@ -4618,7 +4618,7 @@ static char *qemuDomainXMLToNative(virConnectPtr conn, if (!(cmd = qemuBuildCommandLine(conn, driver, def, &monConfig, monitor_json, qemuCaps, - NULL, -1, NULL, VIR_VM_OP_NO_OP))) + NULL, -1, NULL, VIR_NETDEV_VPORT_PROFILE_OP_NO_OP))) goto cleanup; ret = virCommandToString(cmd); @@ -4700,7 +4700,7 @@ qemuDomainObjStart(virConnectPtr conn, } ret = qemuProcessStart(conn, driver, vm, NULL, start_paused, - autodestroy, -1, NULL, NULL, VIR_VM_OP_CREATE); + autodestroy, -1, NULL, NULL, VIR_NETDEV_VPORT_PROFILE_OP_CREATE); virDomainAuditStart(vm, "booted", ret >= 0); if (ret >= 0) { virDomainEventPtr event = @@ -10036,7 +10036,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, rc = qemuProcessStart(snapshot->domain->conn, driver, vm, NULL, true, false, -1, NULL, snap, - VIR_VM_OP_CREATE); + VIR_NETDEV_VPORT_PROFILE_OP_CREATE); virDomainAuditStart(vm, "from-snapshot", rc >= 0); detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT; event = virDomainEventNewFromObj(vm, @@ -10126,7 +10126,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, qemuDomainEventQueue(driver, event); rc = qemuProcessStart(snapshot->domain->conn, driver, vm, NULL, paused, false, -1, NULL, NULL, - VIR_VM_OP_CREATE); + VIR_NETDEV_VPORT_PROFILE_OP_CREATE); virDomainAuditStart(vm, "from-snapshot", rc >= 0); if (rc < 0) { if (!vm->persistent) { diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index ab26e57..a9d9a32 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -678,7 +678,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) { if ((tapfd = qemuPhysIfaceConnect(vm->def, conn, driver, net, priv->qemuCaps, - VIR_VM_OP_CREATE)) < 0) + VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0) goto cleanup; iface_connected = true; if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0) @@ -1911,11 +1911,11 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver, #if WITH_MACVTAP if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_DIRECT) { - delMacvtap(detach->ifname, detach->mac, - virDomainNetGetActualDirectDev(detach), - virDomainNetGetActualDirectMode(detach), - virDomainNetGetActualDirectVirtPortProfile(detach), - driver->stateDir); + ignore_value(virNetDevMacVLanDelete(detach->ifname, detach->mac, + virDomainNetGetActualDirectDev(detach), + virDomainNetGetActualDirectMode(detach), + virDomainNetGetActualDirectVirtPortProfile(detach), + driver->stateDir)); VIR_FREE(detach->ifname); } #endif diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 838a31f..fbff29b 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1147,7 +1147,7 @@ qemuMigrationPrepareAny(struct qemud_driver *driver, */ if (qemuProcessStart(dconn, driver, vm, migrateFrom, true, true, dataFD[0], NULL, NULL, - VIR_VM_OP_MIGRATE_IN_START) < 0) { + VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START) < 0) { virDomainAuditStart(vm, "migrated", false); /* Note that we don't set an error here because qemuProcessStart * should have already done that. @@ -2522,12 +2522,12 @@ qemuMigrationVPAssociatePortProfiles(virDomainDefPtr def) { for (i = 0; i < def->nnets; i++) { net = def->nets[i]; if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) { - if (vpAssociatePortProfileId(net->ifname, - net->mac, - virDomainNetGetActualDirectDev(net), - virDomainNetGetActualDirectVirtPortProfile(net), - def->uuid, - VIR_VM_OP_MIGRATE_IN_FINISH) < 0) + if (virNetDevVPortProfileAssociate(net->ifname, + virDomainNetGetActualDirectVirtPortProfile(net), + net->mac, + virDomainNetGetActualDirectDev(net), + def->uuid, + VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH) < 0) goto err_exit; } last_good_net = i; @@ -2539,11 +2539,11 @@ err_exit: for (i = 0; i < last_good_net; i++) { net = def->nets[i]; if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) { - vpDisassociatePortProfileId(net->ifname, - net->mac, - virDomainNetGetActualDirectDev(net), - virDomainNetGetActualDirectVirtPortProfile(net), - VIR_VM_OP_MIGRATE_IN_FINISH); + ignore_value(virNetDevVPortProfileDisassociate(net->ifname, + virDomainNetGetActualDirectVirtPortProfile(net), + net->mac, + virDomainNetGetActualDirectDev(net), + VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH)); } } } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 2882ef8..4dc9357 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2816,7 +2816,7 @@ int qemuProcessStart(virConnectPtr conn, int stdin_fd, const char *stdin_path, virDomainSnapshotObjPtr snapshot, - enum virVMOperationType vmop) + enum virNetDevVPortProfileOp vmop) { int ret; off_t pos = -1; @@ -3412,11 +3412,11 @@ void qemuProcessStop(struct qemud_driver *driver, virDomainNetDefPtr net = def->nets[i]; #if WITH_MACVTAP if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) { - delMacvtap(net->ifname, net->mac, - virDomainNetGetActualDirectDev(net), - virDomainNetGetActualDirectMode(net), - virDomainNetGetActualDirectVirtPortProfile(net), - driver->stateDir); + ignore_value(virNetDevMacVLanDelete(net->ifname, net->mac, + virDomainNetGetActualDirectDev(net), + virDomainNetGetActualDirectMode(net), + virDomainNetGetActualDirectVirtPortProfile(net), + driver->stateDir)); VIR_FREE(net->ifname); } #endif diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index ef422c4..062d79e 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -53,7 +53,7 @@ int qemuProcessStart(virConnectPtr conn, int stdin_fd, const char *stdin_path, virDomainSnapshotObjPtr snapshot, - enum virVMOperationType vmop); + enum virNetDevVPortProfileOp vmop); void qemuProcessStop(struct qemud_driver *driver, virDomainObjPtr vm, diff --git a/src/util/macvtap.c b/src/util/macvtap.c index bd3c33c..79bdcaa 100644 --- a/src/util/macvtap.c +++ b/src/util/macvtap.c @@ -52,7 +52,7 @@ #include "macvtap.h" #include "virnetdev.h" -VIR_ENUM_IMPL(virMacvtapMode, VIR_MACVTAP_MODE_LAST, +VIR_ENUM_IMPL(virNetDevMacVLanMode, VIR_NETDEV_MACVLAN_MODE_LAST, "vepa", "private", "bridge", @@ -101,15 +101,17 @@ enum virNetDevVPortOp { # if WITH_MACVTAP -/* Open the macvtap's tap device. +/** + * virNetDevMacVLanTapOpen: + * Open the macvtap's tap device. * @ifname: Name of the macvtap interface * @retries : Number of retries in case udev for example may need to be * waited for to create the tap chardev * Returns negative value in case of error, the file descriptor otherwise. */ static -int openTap(const char *ifname, - int retries) +int virNetDevMacVLanTapOpen(const char *ifname, + int retries) { FILE *file; char path[64]; @@ -173,7 +175,7 @@ int openTap(const char *ifname, /** - * configMacvtapTap: + * virNetDevMacVLanTapSetup: * @tapfd: file descriptor of the macvtap tap * @vnet_hdr: 1 to enable IFF_VNET_HDR, 0 to disable it * @@ -187,7 +189,7 @@ int openTap(const char *ifname, * macvtap device should not be used. */ static int -configMacvtapTap(int tapfd, int vnet_hdr) +virNetDevMacVLanTapSetup(int tapfd, int vnet_hdr) { unsigned int features; struct ifreq ifreq; @@ -233,15 +235,15 @@ configMacvtapTap(int tapfd, int vnet_hdr) } -static const uint32_t modeMap[VIR_MACVTAP_MODE_LAST] = { - [VIR_MACVTAP_MODE_VEPA] = MACVLAN_MODE_VEPA, - [VIR_MACVTAP_MODE_PRIVATE] = MACVLAN_MODE_PRIVATE, - [VIR_MACVTAP_MODE_BRIDGE] = MACVLAN_MODE_BRIDGE, - [VIR_MACVTAP_MODE_PASSTHRU] = MACVLAN_MODE_PASSTHRU, +static const uint32_t modeMap[VIR_NETDEV_MACVLAN_MODE_LAST] = { + [VIR_NETDEV_MACVLAN_MODE_VEPA] = MACVLAN_MODE_VEPA, + [VIR_NETDEV_MACVLAN_MODE_PRIVATE] = MACVLAN_MODE_PRIVATE, + [VIR_NETDEV_MACVLAN_MODE_BRIDGE] = MACVLAN_MODE_BRIDGE, + [VIR_NETDEV_MACVLAN_MODE_PASSTHRU] = MACVLAN_MODE_PASSTHRU, }; /** - * openMacvtapTap: + * virNetDevMacVLanCreate: * Create an instance of a macvtap device and open its tap character * device. * @tgifname: Interface name that the macvtap is supposed to have. May @@ -260,18 +262,17 @@ static const uint32_t modeMap[VIR_MACVTAP_MODE_LAST] = { * negative value otherwise with error reported. * */ -int -openMacvtapTap(const char *tgifname, - const unsigned char *macaddress, - const char *linkdev, - enum virMacvtapMode mode, - int vnet_hdr, - const unsigned char *vmuuid, - virNetDevVPortProfilePtr virtPortProfile, - char **res_ifname, - enum virVMOperationType vmOp, - char *stateDir, - virNetDevBandwidthPtr bandwidth) +int virNetDevMacVLanCreate(const char *tgifname, + const unsigned char *macaddress, + const char *linkdev, + enum virNetDevMacVLanMode mode, + int vnet_hdr, + const unsigned char *vmuuid, + virNetDevVPortProfilePtr virtPortProfile, + char **res_ifname, + enum virNetDevVPortProfileOp vmOp, + char *stateDir, + virNetDevBandwidthPtr bandwidth) { const char *type = "macvtap"; int c, rc; @@ -285,7 +286,7 @@ openMacvtapTap(const char *tgifname, *res_ifname = NULL; - VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virVMOperationTypeToString(vmOp)); + VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virNetDevVPortProfileOpTypeToString(vmOp)); /** Note: When using PASSTHROUGH mode with MACVTAP devices the link * device's MAC address must be set to the VMs MAC address. In @@ -294,7 +295,7 @@ openMacvtapTap(const char *tgifname, * This is especially important when using SRIOV capable cards that * emulate their switch in firmware. */ - if (mode == VIR_MACVTAP_MODE_PASSTHRU) { + if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { if (ifaceReplaceMacAddress(macaddress, linkdev, stateDir) < 0) { return -1; } @@ -334,11 +335,11 @@ create_name: cr_ifname = ifname; } - if (vpAssociatePortProfileId(cr_ifname, - macaddress, - linkdev, - virtPortProfile, - vmuuid, vmOp) < 0) { + if (virNetDevVPortProfileAssociate(cr_ifname, + virtPortProfile, + macaddress, + linkdev, + vmuuid, vmOp) < 0) { rc = -1; goto link_del_exit; } @@ -348,9 +349,9 @@ create_name: goto disassociate_exit; } - rc = openTap(cr_ifname, 10); + rc = virNetDevMacVLanTapOpen(cr_ifname, 10); if (rc >= 0) { - if (configMacvtapTap(rc, vnet_hdr) < 0) { + if (virNetDevMacVLanTapSetup(rc, vnet_hdr) < 0) { VIR_FORCE_CLOSE(rc); /* sets rc to -1 */ goto disassociate_exit; } @@ -370,11 +371,11 @@ create_name: return rc; disassociate_exit: - vpDisassociatePortProfileId(cr_ifname, - macaddress, - linkdev, - virtPortProfile, - vmOp); + ignore_value(virNetDevVPortProfileDisassociate(cr_ifname, + virtPortProfile, + macaddress, + linkdev, + vmOp)); link_del_exit: ifaceLinkDel(cr_ifname); @@ -393,25 +394,29 @@ link_del_exit: * it with the switch if port profile parameters * were provided. */ -void -delMacvtap(const char *ifname, - const unsigned char *macaddr, - const char *linkdev, - int mode, - virNetDevVPortProfilePtr virtPortProfile, - char *stateDir) +int virNetDevMacVLanDelete(const char *ifname, + const unsigned char *macaddr, + const char *linkdev, + int mode, + virNetDevVPortProfilePtr virtPortProfile, + char *stateDir) { - if (mode == VIR_MACVTAP_MODE_PASSTHRU) { + int ret = 0; + if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { ifaceRestoreMacAddress(linkdev, stateDir); } if (ifname) { - vpDisassociatePortProfileId(ifname, macaddr, - linkdev, - virtPortProfile, - VIR_VM_OP_DESTROY); - ifaceLinkDel(ifname); + if (virNetDevVPortProfileDisassociate(ifname, + virtPortProfile, + macaddr, + linkdev, + VIR_NETDEV_VPORT_PROFILE_OP_DESTROY) < 0) + ret = -1; + if (ifaceLinkDel(ifname) < 0) + ret = -1; } + return ret; } # endif /* WITH_MACVTAP */ @@ -425,7 +430,7 @@ static struct nla_policy ifla_port_policy[IFLA_PORT_MAX + 1] = static uint32_t -getLldpadPid(void) { +virNetDevVPortProfileGetLldpadPid(void) { int fd; uint32_t pid = 0; @@ -458,7 +463,7 @@ getLldpadPid(void) { /** - * getPortProfileStatus + * virNetDevVPortProfileGetStatus: * * tb: top level netlink response attributes + values * vf: The virtual function used in the request @@ -470,11 +475,11 @@ getLldpadPid(void) { * case of success, < 0 otherwise with error having been reported */ static int -getPortProfileStatus(struct nlattr **tb, int32_t vf, - const unsigned char *instanceId, - bool nltarget_kernel, - bool is8021Qbg, - uint16_t *status) +virNetDevVPortProfileGetStatus(struct nlattr **tb, int32_t vf, + const unsigned char *instanceId, + bool nltarget_kernel, + bool is8021Qbg, + uint16_t *status) { int rc = -1; const char *msg = NULL; @@ -557,16 +562,16 @@ err_exit: static int -doPortProfileOpSetLink(bool nltarget_kernel, - const char *ifname, int ifindex, - const unsigned char *macaddr, - int vlanid, - const char *profileId, - struct ifla_port_vsi *portVsi, - const unsigned char *instanceId, - const unsigned char *hostUUID, - int32_t vf, - uint8_t op) +virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex, + bool nltarget_kernel, + const unsigned char *macaddr, + int vlanid, + const char *profileId, + struct ifla_port_vsi *portVsi, + const unsigned char *instanceId, + const unsigned char *hostUUID, + int32_t vf, + uint8_t op) { int rc = -1; struct nlmsghdr *resp; @@ -685,7 +690,7 @@ doPortProfileOpSetLink(bool nltarget_kernel, } if (!nltarget_kernel) { - pid = getLldpadPid(); + pid = virNetDevVPortProfileGetLldpadPid(); if (pid == 0) goto err_exit; } @@ -747,16 +752,16 @@ buffer_too_small: /* Returns 0 on success, -1 on general failure, and -2 on timeout */ static int -doPortProfileOpCommon(bool nltarget_kernel, - const char *ifname, int ifindex, - const unsigned char *macaddr, - int vlanid, - const char *profileId, - struct ifla_port_vsi *portVsi, - const unsigned char *instanceId, - const unsigned char *hostUUID, - int32_t vf, - uint8_t op) +virNetDevVPortProfileOpCommon(const char *ifname, int ifindex, + bool nltarget_kernel, + const unsigned char *macaddr, + int vlanid, + const char *profileId, + struct ifla_port_vsi *portVsi, + const unsigned char *instanceId, + const unsigned char *hostUUID, + int32_t vf, + uint8_t op) { int rc; unsigned char *recvbuf = NULL; @@ -765,16 +770,16 @@ doPortProfileOpCommon(bool nltarget_kernel, uint16_t status = 0; bool is8021Qbg = (profileId == NULL); - rc = doPortProfileOpSetLink(nltarget_kernel, - ifname, ifindex, - macaddr, - vlanid, - profileId, - portVsi, - instanceId, - hostUUID, - vf, - op); + rc = virNetDevVPortProfileOpSetLink(ifname, ifindex, + nltarget_kernel, + macaddr, + vlanid, + profileId, + portVsi, + instanceId, + hostUUID, + vf, + op); if (rc < 0) { macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", _("sending of PortProfileRequest failed.")); @@ -783,12 +788,12 @@ doPortProfileOpCommon(bool nltarget_kernel, while (--repeats >= 0) { rc = ifaceMacvtapLinkDump(nltarget_kernel, NULL, ifindex, tb, - &recvbuf, getLldpadPid); + &recvbuf, virNetDevVPortProfileGetLldpadPid); if (rc < 0) goto err_exit; - rc = getPortProfileStatus(tb, vf, instanceId, nltarget_kernel, - is8021Qbg, &status); + rc = virNetDevVPortProfileGetStatus(tb, vf, instanceId, nltarget_kernel, + is8021Qbg, &status); if (rc < 0) goto err_exit; if (status == PORT_PROFILE_RESPONSE_SUCCESS || @@ -828,8 +833,8 @@ err_exit: # ifdef IFLA_VF_PORT_MAX static int -getPhysdevAndVlan(const char *ifname, int *root_ifindex, char *root_ifname, - int *vlanid) +virNetDevVPortProfileGetPhysdevAndVlan(const char *ifname, int *root_ifindex, char *root_ifname, + int *vlanid) { int ret; unsigned int nth; @@ -858,10 +863,10 @@ getPhysdevAndVlan(const char *ifname, int *root_ifindex, char *root_ifname, /* Returns 0 on success, -1 on general failure, and -2 on timeout */ static int -doPortProfileOp8021Qbg(const char *ifname, - const unsigned char *macaddr, - const virNetDevVPortProfilePtr virtPort, - enum virNetDevVPortOp virtPortOp) +virNetDevVPortProfileOp8021Qbg(const char *ifname, + const unsigned char *macaddr, + const virNetDevVPortProfilePtr virtPort, + enum virNetDevVPortOp virtPortOp) { int rc = 0; @@ -888,8 +893,8 @@ doPortProfileOp8021Qbg(const char *ifname, char physdev_ifname[IFNAMSIZ] = { 0, }; int vf = PORT_SELF_VF; - if (getPhysdevAndVlan(ifname, &physdev_ifindex, physdev_ifname, - &vlanid) < 0) { + if (virNetDevVPortProfileGetPhysdevAndVlan(ifname, &physdev_ifindex, physdev_ifname, + &vlanid) < 0) { rc = -1; goto err_exit; } @@ -918,16 +923,16 @@ doPortProfileOp8021Qbg(const char *ifname, goto err_exit; } - rc = doPortProfileOpCommon(nltarget_kernel, - physdev_ifname, physdev_ifindex, - macaddr, - vlanid, - NULL, - &portVsi, - virtPort->u.virtPort8021Qbg.instanceID, - NULL, - vf, - op); + rc = virNetDevVPortProfileOpCommon(physdev_ifname, physdev_ifindex, + nltarget_kernel, + macaddr, + vlanid, + NULL, + &portVsi, + virtPort->u.virtPort8021Qbg.instanceID, + NULL, + vf, + op); err_exit: @@ -939,9 +944,9 @@ err_exit: # ifdef IFLA_VF_PORT_MAX static int -getPhysfnDev(const char *linkdev, - int32_t *vf, - char **physfndev) +virNetDevVPortProfileGetPhysfnDev(const char *linkdev, + int32_t *vf, + char **physfndev) { int rc = -1; @@ -975,11 +980,11 @@ err_exit: /* Returns 0 on success, -1 on general failure, and -2 on timeout */ static int -doPortProfileOp8021Qbh(const char *ifname, - const unsigned char *macaddr, - const virNetDevVPortProfilePtr virtPort, - const unsigned char *vm_uuid, - enum virNetDevVPortOp virtPortOp) +virNetDevVPortProfileOp8021Qbh(const char *ifname, + const unsigned char *macaddr, + const virNetDevVPortProfilePtr virtPort, + const unsigned char *vm_uuid, + enum virNetDevVPortOp virtPortOp) { int rc = 0; @@ -1003,7 +1008,7 @@ doPortProfileOp8021Qbh(const char *ifname, int ifindex; int vlanid = -1; - rc = getPhysfnDev(ifname, &vf, &physfndev); + rc = virNetDevVPortProfileGetPhysfnDev(ifname, &vf, &physfndev); if (rc < 0) goto err_exit; @@ -1020,40 +1025,43 @@ doPortProfileOp8021Qbh(const char *ifname, goto err_exit; } - rc = doPortProfileOpCommon(nltarget_kernel, NULL, ifindex, - macaddr, - vlanid, - virtPort->u.virtPort8021Qbh.profileID, - NULL, - vm_uuid, - hostuuid, - vf, - (virtPortOp == PREASSOCIATE_RR) ? - PORT_REQUEST_PREASSOCIATE_RR - : PORT_REQUEST_ASSOCIATE); + rc = virNetDevVPortProfileOpCommon(NULL, ifindex, + nltarget_kernel, + macaddr, + vlanid, + virtPort->u.virtPort8021Qbh.profileID, + NULL, + vm_uuid, + hostuuid, + vf, + (virtPortOp == PREASSOCIATE_RR) ? + PORT_REQUEST_PREASSOCIATE_RR + : PORT_REQUEST_ASSOCIATE); if (rc == -2) /* Association timed out, disassociate */ - doPortProfileOpCommon(nltarget_kernel, NULL, ifindex, - NULL, - vlanid, - NULL, - NULL, - NULL, - NULL, - vf, - PORT_REQUEST_DISASSOCIATE); + virNetDevVPortProfileOpCommon(NULL, ifindex, + nltarget_kernel, + NULL, + vlanid, + NULL, + NULL, + NULL, + NULL, + vf, + PORT_REQUEST_DISASSOCIATE); break; case DISASSOCIATE: - rc = doPortProfileOpCommon(nltarget_kernel, NULL, ifindex, - NULL, - vlanid, - NULL, - NULL, - NULL, - NULL, - vf, - PORT_REQUEST_DISASSOCIATE); + rc = virNetDevVPortProfileOpCommon(NULL, ifindex, + nltarget_kernel, + NULL, + vlanid, + NULL, + NULL, + NULL, + NULL, + vf, + PORT_REQUEST_DISASSOCIATE); break; default: @@ -1071,7 +1079,7 @@ err_exit: } /** - * vpAssociatePortProfile + * virNetDevVPortProfileAssociate: * * @macvtap_ifname: The name of the macvtap device * @virtPort: pointer to the object holding port profile parameters @@ -1088,21 +1096,21 @@ err_exit: * having been reported. */ int -vpAssociatePortProfileId(const char *macvtap_ifname, - const unsigned char *macvtap_macaddr, - const char *linkdev, - const virNetDevVPortProfilePtr virtPort, - const unsigned char *vmuuid, - enum virVMOperationType vmOp) +virNetDevVPortProfileAssociate(const char *macvtap_ifname, + const virNetDevVPortProfilePtr virtPort, + const unsigned char *macvtap_macaddr, + const char *linkdev, + const unsigned char *vmuuid, + enum virNetDevVPortProfileOp vmOp) { int rc = 0; VIR_DEBUG("Associating port profile '%p' on link device '%s'", virtPort, macvtap_ifname); - VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virVMOperationTypeToString(vmOp)); + VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virNetDevVPortProfileOpTypeToString(vmOp)); - if (!virtPort || vmOp == VIR_VM_OP_NO_OP) + if (!virtPort || vmOp == VIR_NETDEV_VPORT_PROFILE_OP_NO_OP) return 0; switch (virtPort->virtPortType) { @@ -1111,20 +1119,20 @@ vpAssociatePortProfileId(const char *macvtap_ifname, break; case VIR_NETDEV_VPORT_PROFILE_8021QBG: - rc = doPortProfileOp8021Qbg(macvtap_ifname, macvtap_macaddr, - virtPort, - (vmOp == VIR_VM_OP_MIGRATE_IN_START) - ? PREASSOCIATE - : ASSOCIATE); + rc = virNetDevVPortProfileOp8021Qbg(macvtap_ifname, macvtap_macaddr, + virtPort, + (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START) + ? PREASSOCIATE + : ASSOCIATE); break; case VIR_NETDEV_VPORT_PROFILE_8021QBH: - rc = doPortProfileOp8021Qbh(linkdev, macvtap_macaddr, - virtPort, vmuuid, - (vmOp == VIR_VM_OP_MIGRATE_IN_START) - ? PREASSOCIATE_RR - : ASSOCIATE); - if (vmOp != VIR_VM_OP_MIGRATE_IN_START && !rc) { + rc = virNetDevVPortProfileOp8021Qbh(linkdev, macvtap_macaddr, + virtPort, vmuuid, + (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START) + ? PREASSOCIATE_RR + : ASSOCIATE); + if (vmOp != VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START && !rc) { /* XXX bogus error handling */ ignore_value(virNetDevSetOnline(linkdev, true)); } @@ -1137,7 +1145,7 @@ vpAssociatePortProfileId(const char *macvtap_ifname, /** - * vpDisassociatePortProfile + * virNetDevVPortProfileDisassociate: * * @macvtap_ifname: The name of the macvtap device * @macvtap_macaddr : The MAC address of the macvtap @@ -1148,18 +1156,18 @@ vpAssociatePortProfileId(const char *macvtap_ifname, * having been reported. */ int -vpDisassociatePortProfileId(const char *macvtap_ifname, - const unsigned char *macvtap_macaddr, - const char *linkdev, - const virNetDevVPortProfilePtr virtPort, - enum virVMOperationType vmOp) +virNetDevVPortProfileDisassociate(const char *macvtap_ifname, + const virNetDevVPortProfilePtr virtPort, + const unsigned char *macvtap_macaddr, + const char *linkdev, + enum virNetDevVPortProfileOp vmOp) { int rc = 0; VIR_DEBUG("Disassociating port profile id '%p' on link device '%s' ", virtPort, macvtap_ifname); - VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virVMOperationTypeToString(vmOp)); + VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virNetDevVPortProfileOpTypeToString(vmOp)); if (!virtPort) return 0; @@ -1170,17 +1178,17 @@ vpDisassociatePortProfileId(const char *macvtap_ifname, break; case VIR_NETDEV_VPORT_PROFILE_8021QBG: - rc = doPortProfileOp8021Qbg(macvtap_ifname, macvtap_macaddr, - virtPort, DISASSOCIATE); + rc = virNetDevVPortProfileOp8021Qbg(macvtap_ifname, macvtap_macaddr, + virtPort, DISASSOCIATE); break; case VIR_NETDEV_VPORT_PROFILE_8021QBH: /* avoid disassociating twice */ - if (vmOp == VIR_VM_OP_MIGRATE_IN_FINISH) + if (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH) break; ignore_value(virNetDevSetOnline(linkdev, false)); - rc = doPortProfileOp8021Qbh(linkdev, macvtap_macaddr, - virtPort, NULL, DISASSOCIATE); + rc = virNetDevVPortProfileOp8021Qbh(linkdev, macvtap_macaddr, + virtPort, NULL, DISASSOCIATE); break; } @@ -1189,12 +1197,12 @@ vpDisassociatePortProfileId(const char *macvtap_ifname, #endif /* WITH_MACVTAP || WITH_NETDEV_VPORT_PROFILE */ -VIR_ENUM_IMPL(virVMOperation, VIR_VM_OP_LAST, - "create", - "save", - "restore", - "destroy", - "migrate out", - "migrate in start", - "migrate in finish", - "no-op") +VIR_ENUM_IMPL(virNetDevVPortProfileOp, VIR_NETDEV_VPORT_PROFILE_OP_LAST, + "create", + "save", + "restore", + "destroy", + "migrate out", + "migrate in start", + "migrate in finish", + "no-op") diff --git a/src/util/macvtap.h b/src/util/macvtap.h index a6b00fe..5c5d84a 100644 --- a/src/util/macvtap.h +++ b/src/util/macvtap.h @@ -29,65 +29,73 @@ # include "virnetdevvportprofile.h" /* the mode type for macvtap devices */ -enum virMacvtapMode { - VIR_MACVTAP_MODE_VEPA, - VIR_MACVTAP_MODE_PRIVATE, - VIR_MACVTAP_MODE_BRIDGE, - VIR_MACVTAP_MODE_PASSTHRU, +enum virNetDevMacVLanMode { + VIR_NETDEV_MACVLAN_MODE_VEPA, + VIR_NETDEV_MACVLAN_MODE_PRIVATE, + VIR_NETDEV_MACVLAN_MODE_BRIDGE, + VIR_NETDEV_MACVLAN_MODE_PASSTHRU, - VIR_MACVTAP_MODE_LAST, + VIR_NETDEV_MACVLAN_MODE_LAST, }; -enum virVMOperationType { - VIR_VM_OP_CREATE, - VIR_VM_OP_SAVE, - VIR_VM_OP_RESTORE, - VIR_VM_OP_DESTROY, - VIR_VM_OP_MIGRATE_OUT, - VIR_VM_OP_MIGRATE_IN_START, - VIR_VM_OP_MIGRATE_IN_FINISH, - VIR_VM_OP_NO_OP, +enum virNetDevVPortProfileOp { + VIR_NETDEV_VPORT_PROFILE_OP_CREATE, + VIR_NETDEV_VPORT_PROFILE_OP_SAVE, + VIR_NETDEV_VPORT_PROFILE_OP_RESTORE, + VIR_NETDEV_VPORT_PROFILE_OP_DESTROY, + VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_OUT, + VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START, + VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH, + VIR_NETDEV_VPORT_PROFILE_OP_NO_OP, - VIR_VM_OP_LAST + VIR_NETDEV_VPORT_PROFILE_OP_LAST }; # if WITH_MACVTAP -int openMacvtapTap(const char *ifname, - const unsigned char *macaddress, - const char *linkdev, - enum virMacvtapMode mode, - int vnet_hdr, - const unsigned char *vmuuid, - virNetDevVPortProfilePtr virtPortProfile, - char **res_ifname, - enum virVMOperationType vmop, - char *stateDir, - virNetDevBandwidthPtr bandwidth); +int virNetDevMacVLanCreate(const char *ifname, + const unsigned char *macaddress, + const char *linkdev, + enum virNetDevMacVLanMode mode, + int vnet_hdr, + const unsigned char *vmuuid, + virNetDevVPortProfilePtr virtPortProfile, + char **res_ifname, + enum virNetDevVPortProfileOp vmop, + char *stateDir, + virNetDevBandwidthPtr bandwidth) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(6) + ATTRIBUTE_NONNULL(8) ATTRIBUTE_NONNULL(10) ATTRIBUTE_RETURN_CHECK; -void delMacvtap(const char *ifname, - const unsigned char *macaddress, - const char *linkdev, - int mode, - virNetDevVPortProfilePtr virtPortProfile, - char *stateDir); +int virNetDevMacVLanDelete(const char *ifname, + const unsigned char *macaddress, + const char *linkdev, + int mode, + virNetDevVPortProfilePtr virtPortProfile, + char *stateDir) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_NONNULL(6) ATTRIBUTE_RETURN_CHECK; -int vpAssociatePortProfileId(const char *macvtap_ifname, - const unsigned char *macvtap_macaddr, - const char *linkdev, - const virNetDevVPortProfilePtr virtPort, - const unsigned char *vmuuid, - enum virVMOperationType vmOp); +int virNetDevVPortProfileAssociate(const char *ifname, + const virNetDevVPortProfilePtr virtPort, + const unsigned char *macaddr, + const char *linkdev, + const unsigned char *vmuuid, + enum virNetDevVPortProfileOp vmOp) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) + ATTRIBUTE_NONNULL(5) ATTRIBUTE_RETURN_CHECK; -int vpDisassociatePortProfileId(const char *macvtap_ifname, - const unsigned char *macvtap_macaddr, - const char *linkdev, - const virNetDevVPortProfilePtr virtPort, - enum virVMOperationType vmOp); +int virNetDevVPortProfileDisassociate(const char *ifname, + const virNetDevVPortProfilePtr virtPort, + const unsigned char *macaddr, + const char *linkdev, + enum virNetDevVPortProfileOp vmOp) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) + ATTRIBUTE_RETURN_CHECK; # endif /* WITH_MACVTAP */ -VIR_ENUM_DECL(virVMOperation) -VIR_ENUM_DECL(virMacvtapMode) +VIR_ENUM_DECL(virNetDevVPortProfileOp) +VIR_ENUM_DECL(virNetDevMacVLanMode) #endif /* __UTIL_MACVTAP_H__ */ diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index d9a6e8d..5d3b74c 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -124,7 +124,7 @@ static int testCompareXMLToArgvFiles(const char *xml, if (!(cmd = qemuBuildCommandLine(conn, &driver, vmdef, &monitor_chr, json, extraFlags, migrateFrom, migrateFd, NULL, - VIR_VM_OP_NO_OP))) + VIR_NETDEV_VPORT_PROFILE_OP_NO_OP))) goto fail; if (!!virGetLastError() != expectError) { diff --git a/tests/qemuxmlnstest.c b/tests/qemuxmlnstest.c index b13b409..ee3ad1b 100644 --- a/tests/qemuxmlnstest.c +++ b/tests/qemuxmlnstest.c @@ -124,7 +124,7 @@ static int testCompareXMLToArgvFiles(const char *xml, if (!(cmd = qemuBuildCommandLine(conn, &driver, vmdef, &monitor_chr, json, extraFlags, migrateFrom, migrateFd, NULL, - VIR_VM_OP_NO_OP))) + VIR_NETDEV_VPORT_PROFILE_OP_NO_OP))) goto fail; if (!!virGetLastError() != expectError) { -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Rename the macvtap.c file to virnetdevmacvlan.c to reflect its functionality. Move the port profile association code out into virnetdevvportprofile.c. Make the APIs available unconditionally to callers * src/util/macvtap.h: rename to src/util/virnetdevmacvlan.h, * src/util/macvtap.c: rename to src/util/virnetdevmacvlan.c * src/util/virnetdevvportprofile.c, src/util/virnetdevvportprofile.h: Pull in vport association code * src/Makefile.am, src/conf/domain_conf.h, src/qemu/qemu_conf.c, src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update include paths & remove conditional compilation --- po/POTFILES.in | 3 +- src/Makefile.am | 2 +- src/conf/domain_conf.h | 2 +- src/qemu/qemu_command.c | 12 - src/qemu/qemu_conf.c | 1 - src/qemu/qemu_conf.h | 1 - src/qemu/qemu_driver.c | 1 - src/qemu/qemu_hotplug.c | 2 - src/qemu/qemu_migration.c | 5 - src/qemu/qemu_process.c | 2 - src/util/macvtap.c | 1208 ---------------------------- src/util/virnetdevmacvlan.c | 423 ++++++++++ src/util/{macvtap.h => virnetdevmacvlan.h} | 38 +- src/util/virnetdevvportprofile.c | 820 +++++++++++++++++++ src/util/virnetdevvportprofile.h | 33 +- 15 files changed, 1280 insertions(+), 1273 deletions(-) delete mode 100644 src/util/macvtap.c create mode 100644 src/util/virnetdevmacvlan.c rename src/util/{macvtap.h => virnetdevmacvlan.h} (63%) diff --git a/po/POTFILES.in b/po/POTFILES.in index 810cf68..6797298 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -115,7 +115,6 @@ src/util/iohelper.c src/util/interface.c src/util/iptables.c src/util/json.c -src/util/macvtap.c src/util/netlink.c src/util/pci.c src/util/processinfo.c @@ -128,7 +127,9 @@ src/util/viraudit.c src/util/virfile.c src/util/virnetdev.c src/util/virnetdevbridge.c +src/util/virnetdevmacvlan.c src/util/virnetdevtap.c +src/util/virnetdevvportprofile.c src/util/virpidfile.c src/util/virsocketaddr.c src/util/virterror.c diff --git a/src/Makefile.am b/src/Makefile.am index 6ffa8c6..6703bc1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -65,7 +65,6 @@ UTIL_SOURCES = \ util/dnsmasq.c util/dnsmasq.h \ util/json.c util/json.h \ util/logging.c util/logging.h \ - util/macvtap.c util/macvtap.h \ util/memory.c util/memory.h \ util/netlink.c util/netlink.h \ util/pci.c util/pci.h \ @@ -93,6 +92,7 @@ UTIL_SOURCES = \ util/virnetdev.h util/virnetdev.c \ util/virnetdevbandwidth.h util/virnetdevbandwidth.c \ util/virnetdevbridge.h util/virnetdevbridge.c \ + util/virnetdevmacvlan.c util/virnetdevmacvlan.h \ util/virnetdevtap.h util/virnetdevtap.c \ util/virnetdevveth.h util/virnetdevveth.c \ util/virnetdevvportprofile.h util/virnetdevvportprofile.c \ diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index c360674..9528199 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -38,7 +38,7 @@ # include "virsocketaddr.h" # include "nwfilter_params.h" # include "nwfilter_conf.h" -# include "macvtap.h" +# include "virnetdevmacvlan.h" # include "sysinfo.h" # include "virnetdevvportprofile.h" # include "virnetdevbandwidth.h" diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6d19f95..687d284 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -142,7 +142,6 @@ qemuPhysIfaceConnect(virDomainDefPtr def, enum virNetDevVPortProfileOp vmop) { int rc; -#if WITH_MACVTAP char *res_ifname = NULL; int vnet_hdr = 0; int err; @@ -187,17 +186,6 @@ qemuPhysIfaceConnect(virDomainDefPtr def, } } } -#else - (void)def; - (void)conn; - (void)net; - (void)qemuCaps; - (void)driver; - (void)vmop; - qemuReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("No support for macvtap device")); - rc = -1; -#endif return rc; } diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 4c20d17..f6c04ae 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -50,7 +50,6 @@ #include "xml.h" #include "nodeinfo.h" #include "logging.h" -#include "macvtap.h" #include "cpu/cpu.h" #include "domain_nwfilter.h" #include "virfile.h" diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index bbe7e74..e13cd08 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -39,7 +39,6 @@ # include "cpu_conf.h" # include "driver.h" # include "bitmap.h" -# include "macvtap.h" # include "command.h" # include "threadpool.h" # include "locking/lock_manager.h" diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 465640f..0c885f1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -77,7 +77,6 @@ #include "libvirt_internal.h" #include "xml.h" #include "cpu/cpu.h" -#include "macvtap.h" #include "sysinfo.h" #include "domain_nwfilter.h" #include "hooks.h" diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index a9d9a32..f9365fe 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1909,7 +1909,6 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver, virDomainConfNWFilterTeardown(detach); -#if WITH_MACVTAP if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_DIRECT) { ignore_value(virNetDevMacVLanDelete(detach->ifname, detach->mac, virDomainNetGetActualDirectDev(detach), @@ -1918,7 +1917,6 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver, driver->stateDir)); VIR_FREE(detach->ifname); } -#endif if ((driver->macFilter) && (detach->ifname != NULL)) { if ((errno = networkDisallowMacOnPort(driver, diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index fbff29b..8925660 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2512,7 +2512,6 @@ qemuMigrationPerform(struct qemud_driver *driver, } } -#if WITH_MACVTAP static void qemuMigrationVPAssociatePortProfiles(virDomainDefPtr def) { int i; @@ -2547,10 +2546,6 @@ err_exit: } } } -#else /* !WITH_MACVTAP */ -static void -qemuMigrationVPAssociatePortProfiles(virDomainDefPtr def ATTRIBUTE_UNUSED) { } -#endif /* WITH_MACVTAP */ virDomainPtr diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 4dc9357..f4096f8 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3410,7 +3410,6 @@ void qemuProcessStop(struct qemud_driver *driver, def = vm->def; for (i = 0; i < def->nnets; i++) { virDomainNetDefPtr net = def->nets[i]; -#if WITH_MACVTAP if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) { ignore_value(virNetDevMacVLanDelete(net->ifname, net->mac, virDomainNetGetActualDirectDev(net), @@ -3419,7 +3418,6 @@ void qemuProcessStop(struct qemud_driver *driver, driver->stateDir)); VIR_FREE(net->ifname); } -#endif /* release the physical device (or any other resources used by * this interface in the network driver */ diff --git a/src/util/macvtap.c b/src/util/macvtap.c deleted file mode 100644 index 79bdcaa..0000000 --- a/src/util/macvtap.c +++ /dev/null @@ -1,1208 +0,0 @@ -/* - * Copyright (C) 2010-2011 Red Hat, Inc. - * Copyright (C) 2010 IBM Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Authors: - * Stefan Berger <stefanb@us.ibm.com> - * - * Notes: - * netlink: http://lovezutto.googlepages.com/netlink.pdf - * iproute2 package - * - */ - -#include <config.h> - -#include <stdint.h> - -#if WITH_MACVTAP || WITH_VIRTUALPORT - -# include <stdio.h> -# include <errno.h> -# include <fcntl.h> -# include <c-ctype.h> -# include <sys/socket.h> -# include <sys/ioctl.h> - -# include <linux/if.h> -# include <linux/if_tun.h> - -/* Older kernels lacked this enum value. */ -# if !HAVE_DECL_MACVLAN_MODE_PASSTHRU -# define MACVLAN_MODE_PASSTHRU 8 -# endif - -#endif /* WITH_MACVTAP || WITH_VIRTUALPORT */ - -#include "util.h" -#include "macvtap.h" -#include "virnetdev.h" - -VIR_ENUM_IMPL(virNetDevMacVLanMode, VIR_NETDEV_MACVLAN_MODE_LAST, - "vepa", - "private", - "bridge", - "passthrough") - -#if WITH_MACVTAP || WITH_VIRTUALPORT - -# include "memory.h" -# include "logging.h" -# include "interface.h" -# include "virterror_internal.h" -# include "uuid.h" -# include "virfile.h" -# include "netlink.h" - -# define VIR_FROM_THIS VIR_FROM_NET - -# define macvtapError(code, ...) \ - virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \ - __FUNCTION__, __LINE__, __VA_ARGS__) - -# define MACVTAP_NAME_PREFIX "macvtap" -# define MACVTAP_NAME_PATTERN "macvtap%d" - -# define MICROSEC_PER_SEC (1000 * 1000) - -# define NLMSGBUF_SIZE 256 -# define RATTBUF_SIZE 64 - -# define STATUS_POLL_TIMEOUT_USEC (10 * MICROSEC_PER_SEC) -# define STATUS_POLL_INTERVL_USEC (MICROSEC_PER_SEC / 8) - - -# define LLDPAD_PID_FILE "/var/run/lldpad.pid" - - -enum virNetDevVPortOp { - ASSOCIATE = 0x1, - DISASSOCIATE = 0x2, - PREASSOCIATE = 0x3, - PREASSOCIATE_RR = 0x4, -}; - - - - -# if WITH_MACVTAP - -/** - * virNetDevMacVLanTapOpen: - * Open the macvtap's tap device. - * @ifname: Name of the macvtap interface - * @retries : Number of retries in case udev for example may need to be - * waited for to create the tap chardev - * Returns negative value in case of error, the file descriptor otherwise. - */ -static -int virNetDevMacVLanTapOpen(const char *ifname, - int retries) -{ - FILE *file; - char path[64]; - int ifindex; - char tapname[50]; - int tapfd; - - if (snprintf(path, sizeof(path), - "/sys/class/net/%s/ifindex", ifname) >= sizeof(path)) { - virReportSystemError(errno, - "%s", - _("buffer for ifindex path is too small")); - return -1; - } - - file = fopen(path, "r"); - - if (!file) { - virReportSystemError(errno, - _("cannot open macvtap file %s to determine " - "interface index"), path); - return -1; - } - - if (fscanf(file, "%d", &ifindex) != 1) { - virReportSystemError(errno, - "%s",_("cannot determine macvtap's tap device " - "interface index")); - VIR_FORCE_FCLOSE(file); - return -1; - } - - VIR_FORCE_FCLOSE(file); - - if (snprintf(tapname, sizeof(tapname), - "/dev/tap%d", ifindex) >= sizeof(tapname)) { - virReportSystemError(errno, - "%s", - _("internal buffer for tap device is too small")); - return -1; - } - - while (1) { - /* may need to wait for udev to be done */ - tapfd = open(tapname, O_RDWR); - if (tapfd < 0 && retries > 0) { - retries--; - usleep(20000); - continue; - } - break; - } - - if (tapfd < 0) - virReportSystemError(errno, - _("cannot open macvtap tap device %s"), - tapname); - - return tapfd; -} - - -/** - * virNetDevMacVLanTapSetup: - * @tapfd: file descriptor of the macvtap tap - * @vnet_hdr: 1 to enable IFF_VNET_HDR, 0 to disable it - * - * Returns 0 on success, -1 in case of fatal error, error code otherwise. - * - * Turn the IFF_VNET_HDR flag, if requested and available, make sure - * it's off in the other cases. - * A fatal error is defined as the VNET_HDR flag being set but it cannot - * be turned off for some reason. This is reported with -1. Other fatal - * error is not being able to read the interface flags. In that case the - * macvtap device should not be used. - */ -static int -virNetDevMacVLanTapSetup(int tapfd, int vnet_hdr) -{ - unsigned int features; - struct ifreq ifreq; - short new_flags = 0; - int rc_on_fail = 0; - const char *errmsg = NULL; - - memset(&ifreq, 0, sizeof(ifreq)); - - if (ioctl(tapfd, TUNGETIFF, &ifreq) < 0) { - virReportSystemError(errno, "%s", - _("cannot get interface flags on macvtap tap")); - return -1; - } - - new_flags = ifreq.ifr_flags; - - if ((ifreq.ifr_flags & IFF_VNET_HDR) && !vnet_hdr) { - new_flags = ifreq.ifr_flags & ~IFF_VNET_HDR; - rc_on_fail = -1; - errmsg = _("cannot clean IFF_VNET_HDR flag on macvtap tap"); - } else if ((ifreq.ifr_flags & IFF_VNET_HDR) == 0 && vnet_hdr) { - if (ioctl(tapfd, TUNGETFEATURES, &features) < 0) { - virReportSystemError(errno, "%s", - _("cannot get feature flags on macvtap tap")); - return -1; - } - if ((features & IFF_VNET_HDR)) { - new_flags = ifreq.ifr_flags | IFF_VNET_HDR; - errmsg = _("cannot set IFF_VNET_HDR flag on macvtap tap"); - } - } - - if (new_flags != ifreq.ifr_flags) { - ifreq.ifr_flags = new_flags; - if (ioctl(tapfd, TUNSETIFF, &ifreq) < 0) { - virReportSystemError(errno, "%s", errmsg); - return rc_on_fail; - } - } - - return 0; -} - - -static const uint32_t modeMap[VIR_NETDEV_MACVLAN_MODE_LAST] = { - [VIR_NETDEV_MACVLAN_MODE_VEPA] = MACVLAN_MODE_VEPA, - [VIR_NETDEV_MACVLAN_MODE_PRIVATE] = MACVLAN_MODE_PRIVATE, - [VIR_NETDEV_MACVLAN_MODE_BRIDGE] = MACVLAN_MODE_BRIDGE, - [VIR_NETDEV_MACVLAN_MODE_PASSTHRU] = MACVLAN_MODE_PASSTHRU, -}; - -/** - * virNetDevMacVLanCreate: - * Create an instance of a macvtap device and open its tap character - * device. - * @tgifname: Interface name that the macvtap is supposed to have. May - * be NULL if this function is supposed to choose a name - * @macaddress: The MAC address for the macvtap device - * @linkdev: The interface name of the NIC to connect to the external bridge - * @mode: int describing the mode for 'bridge', 'vepa', 'private' or 'passthru'. - * @vnet_hdr: 1 to enable IFF_VNET_HDR, 0 to disable it - * @vmuuid: The UUID of the VM the macvtap belongs to - * @virtPortProfile: pointer to object holding the virtual port profile data - * @res_ifname: Pointer to a string pointer where the actual name of the - * interface will be stored into if everything succeeded. It is up - * to the caller to free the string. - * - * Returns file descriptor of the tap device in case of success, - * negative value otherwise with error reported. - * - */ -int virNetDevMacVLanCreate(const char *tgifname, - const unsigned char *macaddress, - const char *linkdev, - enum virNetDevMacVLanMode mode, - int vnet_hdr, - const unsigned char *vmuuid, - virNetDevVPortProfilePtr virtPortProfile, - char **res_ifname, - enum virNetDevVPortProfileOp vmOp, - char *stateDir, - virNetDevBandwidthPtr bandwidth) -{ - const char *type = "macvtap"; - int c, rc; - char ifname[IFNAMSIZ]; - int retries, do_retry = 0; - uint32_t macvtapMode; - const char *cr_ifname; - int ifindex; - - macvtapMode = modeMap[mode]; - - *res_ifname = NULL; - - VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virNetDevVPortProfileOpTypeToString(vmOp)); - - /** Note: When using PASSTHROUGH mode with MACVTAP devices the link - * device's MAC address must be set to the VMs MAC address. In - * order to not confuse the first switch or bridge in line this MAC - * address must be reset when the VM is shut down. - * This is especially important when using SRIOV capable cards that - * emulate their switch in firmware. - */ - if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { - if (ifaceReplaceMacAddress(macaddress, linkdev, stateDir) < 0) { - return -1; - } - } - - if (tgifname) { - if(ifaceGetIndex(false, tgifname, &ifindex) == 0) { - if (STRPREFIX(tgifname, - MACVTAP_NAME_PREFIX)) { - goto create_name; - } - virReportSystemError(errno, - _("Interface %s already exists"), tgifname); - return -1; - } - cr_ifname = tgifname; - rc = ifaceMacvtapLinkAdd(type, macaddress, 6, tgifname, linkdev, - macvtapMode, &do_retry); - if (rc < 0) - return -1; - } else { -create_name: - retries = 5; - for (c = 0; c < 8192; c++) { - snprintf(ifname, sizeof(ifname), MACVTAP_NAME_PATTERN, c); - if (ifaceGetIndex(false, ifname, &ifindex) == -ENODEV) { - rc = ifaceMacvtapLinkAdd(type, macaddress, 6, ifname, linkdev, - macvtapMode, &do_retry); - if (rc == 0) - break; - - if (do_retry && --retries) - continue; - return -1; - } - } - cr_ifname = ifname; - } - - if (virNetDevVPortProfileAssociate(cr_ifname, - virtPortProfile, - macaddress, - linkdev, - vmuuid, vmOp) < 0) { - rc = -1; - goto link_del_exit; - } - - if (virNetDevSetOnline(cr_ifname, true) < 0) { - rc = -1; - goto disassociate_exit; - } - - rc = virNetDevMacVLanTapOpen(cr_ifname, 10); - if (rc >= 0) { - if (virNetDevMacVLanTapSetup(rc, vnet_hdr) < 0) { - VIR_FORCE_CLOSE(rc); /* sets rc to -1 */ - goto disassociate_exit; - } - *res_ifname = strdup(cr_ifname); - } else - goto disassociate_exit; - - if (virNetDevBandwidthSet(cr_ifname, bandwidth) < 0) { - macvtapError(VIR_ERR_INTERNAL_ERROR, - _("cannot set bandwidth limits on %s"), - cr_ifname); - rc = -1; - goto disassociate_exit; - } - - - return rc; - -disassociate_exit: - ignore_value(virNetDevVPortProfileDisassociate(cr_ifname, - virtPortProfile, - macaddress, - linkdev, - vmOp)); - -link_del_exit: - ifaceLinkDel(cr_ifname); - - return rc; -} - - -/** - * delMacvtap: - * @ifname : The name of the macvtap interface - * @linkdev: The interface name of the NIC to connect to the external bridge - * @virtPortProfile: pointer to object holding the virtual port profile data - * - * Delete an interface given its name. Disassociate - * it with the switch if port profile parameters - * were provided. - */ -int virNetDevMacVLanDelete(const char *ifname, - const unsigned char *macaddr, - const char *linkdev, - int mode, - virNetDevVPortProfilePtr virtPortProfile, - char *stateDir) -{ - int ret = 0; - if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { - ifaceRestoreMacAddress(linkdev, stateDir); - } - - if (ifname) { - if (virNetDevVPortProfileDisassociate(ifname, - virtPortProfile, - macaddr, - linkdev, - VIR_NETDEV_VPORT_PROFILE_OP_DESTROY) < 0) - ret = -1; - if (ifaceLinkDel(ifname) < 0) - ret = -1; - } - return ret; -} - -# endif /* WITH_MACVTAP */ - -# ifdef IFLA_PORT_MAX - -static struct nla_policy ifla_port_policy[IFLA_PORT_MAX + 1] = -{ - [IFLA_PORT_RESPONSE] = { .type = NLA_U16 }, -}; - - -static uint32_t -virNetDevVPortProfileGetLldpadPid(void) { - int fd; - uint32_t pid = 0; - - fd = open(LLDPAD_PID_FILE, O_RDONLY); - if (fd >= 0) { - char buffer[10]; - - if (saferead(fd, buffer, sizeof(buffer)) <= sizeof(buffer)) { - unsigned int res; - char *endptr; - - if (virStrToLong_ui(buffer, &endptr, 10, &res) == 0 - && (*endptr == '\0' || c_isspace(*endptr)) - && res != 0) { - pid = res; - } else { - macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", - _("error parsing pid of lldpad")); - } - } - } else { - virReportSystemError(errno, - _("Error opening file %s"), LLDPAD_PID_FILE); - } - - VIR_FORCE_CLOSE(fd); - - return pid; -} - - -/** - * virNetDevVPortProfileGetStatus: - * - * tb: top level netlink response attributes + values - * vf: The virtual function used in the request - * instanceId: instanceId of the interface (vm uuid in case of 802.1Qbh) - * is8021Qbg: whether this function is call for 8021Qbg - * status: pointer to a uint16 where the status will be written into - * - * Get the status from the IFLA_PORT_RESPONSE field; Returns 0 in - * case of success, < 0 otherwise with error having been reported - */ -static int -virNetDevVPortProfileGetStatus(struct nlattr **tb, int32_t vf, - const unsigned char *instanceId, - bool nltarget_kernel, - bool is8021Qbg, - uint16_t *status) -{ - int rc = -1; - const char *msg = NULL; - struct nlattr *tb_port[IFLA_PORT_MAX + 1] = { NULL, }; - - if (vf == PORT_SELF_VF && nltarget_kernel) { - if (tb[IFLA_PORT_SELF]) { - if (nla_parse_nested(tb_port, IFLA_PORT_MAX, tb[IFLA_PORT_SELF], - ifla_port_policy)) { - msg = _("error parsing IFLA_PORT_SELF part"); - goto err_exit; - } - } else { - msg = _("IFLA_PORT_SELF is missing"); - goto err_exit; - } - } else { - if (tb[IFLA_VF_PORTS]) { - int rem; - bool found = false; - struct nlattr *tb_vf_ports = { NULL, }; - - nla_for_each_nested(tb_vf_ports, tb[IFLA_VF_PORTS], rem) { - - if (nla_type(tb_vf_ports) != IFLA_VF_PORT) { - msg = _("error while iterating over IFLA_VF_PORTS part"); - goto err_exit; - } - - if (nla_parse_nested(tb_port, IFLA_PORT_MAX, tb_vf_ports, - ifla_port_policy)) { - msg = _("error parsing IFLA_VF_PORT part"); - goto err_exit; - } - - if (instanceId && - tb_port[IFLA_PORT_INSTANCE_UUID] && - !memcmp(instanceId, - (unsigned char *) - RTA_DATA(tb_port[IFLA_PORT_INSTANCE_UUID]), - VIR_UUID_BUFLEN) && - tb_port[IFLA_PORT_VF] && - vf == *(uint32_t *)RTA_DATA(tb_port[IFLA_PORT_VF])) { - found = true; - break; - } - } - - if (!found) { - msg = _("Could not find netlink response with " - "expected parameters"); - goto err_exit; - } - } else { - msg = _("IFLA_VF_PORTS is missing"); - goto err_exit; - } - } - - if (tb_port[IFLA_PORT_RESPONSE]) { - *status = *(uint16_t *)RTA_DATA(tb_port[IFLA_PORT_RESPONSE]); - rc = 0; - } else { - if (is8021Qbg) { - /* no in-progress here; may be missing */ - *status = PORT_PROFILE_RESPONSE_INPROGRESS; - rc = 0; - } else { - msg = _("no IFLA_PORT_RESPONSE found in netlink message"); - goto err_exit; - } - } - -err_exit: - if (msg) - macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", msg); - - return rc; -} - - -static int -virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex, - bool nltarget_kernel, - const unsigned char *macaddr, - int vlanid, - const char *profileId, - struct ifla_port_vsi *portVsi, - const unsigned char *instanceId, - const unsigned char *hostUUID, - int32_t vf, - uint8_t op) -{ - int rc = -1; - struct nlmsghdr *resp; - struct nlmsgerr *err; - struct ifinfomsg ifinfo = { - .ifi_family = AF_UNSPEC, - .ifi_index = ifindex, - }; - unsigned char *recvbuf = NULL; - unsigned int recvbuflen = 0; - uint32_t pid = 0; - struct nl_msg *nl_msg; - struct nlattr *vfports = NULL, *vfport; - - nl_msg = nlmsg_alloc_simple(RTM_SETLINK, NLM_F_REQUEST); - if (!nl_msg) { - virReportOOMError(); - return rc; - } - - if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) - goto buffer_too_small; - - if (ifname && - nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) - goto buffer_too_small; - - if (macaddr || vlanid >= 0) { - struct nlattr *vfinfolist, *vfinfo; - - if (!(vfinfolist = nla_nest_start(nl_msg, IFLA_VFINFO_LIST))) - goto buffer_too_small; - - if (!(vfinfo = nla_nest_start(nl_msg, IFLA_VF_INFO))) - goto buffer_too_small; - - if (macaddr) { - struct ifla_vf_mac ifla_vf_mac = { - .vf = vf, - .mac = { 0, }, - }; - - memcpy(ifla_vf_mac.mac, macaddr, 6); - - if (nla_put(nl_msg, IFLA_VF_MAC, sizeof(ifla_vf_mac), - &ifla_vf_mac) < 0) - goto buffer_too_small; - } - - if (vlanid >= 0) { - struct ifla_vf_vlan ifla_vf_vlan = { - .vf = vf, - .vlan = vlanid, - .qos = 0, - }; - - if (nla_put(nl_msg, IFLA_VF_VLAN, sizeof(ifla_vf_vlan), - &ifla_vf_vlan) < 0) - goto buffer_too_small; - } - - nla_nest_end(nl_msg, vfinfo); - nla_nest_end(nl_msg, vfinfolist); - } - - if (vf == PORT_SELF_VF && nltarget_kernel) { - if (!(vfport = nla_nest_start(nl_msg, IFLA_PORT_SELF))) - goto buffer_too_small; - } else { - if (!(vfports = nla_nest_start(nl_msg, IFLA_VF_PORTS))) - goto buffer_too_small; - - /* begin nesting vfports */ - if (!(vfport = nla_nest_start(nl_msg, IFLA_VF_PORT))) - goto buffer_too_small; - } - - if (profileId) { - if (nla_put(nl_msg, IFLA_PORT_PROFILE, strlen(profileId) + 1, - profileId) < 0) - goto buffer_too_small; - } - - if (portVsi) { - if (nla_put(nl_msg, IFLA_PORT_VSI_TYPE, sizeof(*portVsi), - portVsi) < 0) - goto buffer_too_small; - } - - if (instanceId) { - if (nla_put(nl_msg, IFLA_PORT_INSTANCE_UUID, VIR_UUID_BUFLEN, - instanceId) < 0) - goto buffer_too_small; - } - - if (hostUUID) { - if (nla_put(nl_msg, IFLA_PORT_HOST_UUID, VIR_UUID_BUFLEN, - hostUUID) < 0) - goto buffer_too_small; - } - - if (vf != PORT_SELF_VF) { - if (nla_put(nl_msg, IFLA_PORT_VF, sizeof(vf), &vf) < 0) - goto buffer_too_small; - } - - if (nla_put(nl_msg, IFLA_PORT_REQUEST, sizeof(op), &op) < 0) - goto buffer_too_small; - - /* end nesting of vport */ - nla_nest_end(nl_msg, vfport); - - if (vfports) { - /* end nesting of vfports */ - nla_nest_end(nl_msg, vfports); - } - - if (!nltarget_kernel) { - pid = virNetDevVPortProfileGetLldpadPid(); - if (pid == 0) - goto err_exit; - } - - if (nlComm(nl_msg, &recvbuf, &recvbuflen, pid) < 0) - goto err_exit; - - if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL) - goto malformed_resp; - - resp = (struct nlmsghdr *)recvbuf; - - switch (resp->nlmsg_type) { - case NLMSG_ERROR: - err = (struct nlmsgerr *)NLMSG_DATA(resp); - if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) - goto malformed_resp; - - if (err->error) { - virReportSystemError(-err->error, - _("error during virtual port configuration of ifindex %d"), - ifindex); - goto err_exit; - } - break; - - case NLMSG_DONE: - break; - - default: - goto malformed_resp; - } - - rc = 0; - -err_exit: - nlmsg_free(nl_msg); - - VIR_FREE(recvbuf); - - return rc; - -malformed_resp: - nlmsg_free(nl_msg); - - macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", - _("malformed netlink response message")); - VIR_FREE(recvbuf); - return rc; - -buffer_too_small: - nlmsg_free(nl_msg); - - macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", - _("allocated netlink buffer is too small")); - return rc; -} - - -/* Returns 0 on success, -1 on general failure, and -2 on timeout */ -static int -virNetDevVPortProfileOpCommon(const char *ifname, int ifindex, - bool nltarget_kernel, - const unsigned char *macaddr, - int vlanid, - const char *profileId, - struct ifla_port_vsi *portVsi, - const unsigned char *instanceId, - const unsigned char *hostUUID, - int32_t vf, - uint8_t op) -{ - int rc; - unsigned char *recvbuf = NULL; - struct nlattr *tb[IFLA_MAX + 1] = { NULL , }; - int repeats = STATUS_POLL_TIMEOUT_USEC / STATUS_POLL_INTERVL_USEC; - uint16_t status = 0; - bool is8021Qbg = (profileId == NULL); - - rc = virNetDevVPortProfileOpSetLink(ifname, ifindex, - nltarget_kernel, - macaddr, - vlanid, - profileId, - portVsi, - instanceId, - hostUUID, - vf, - op); - if (rc < 0) { - macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", - _("sending of PortProfileRequest failed.")); - return rc; - } - - while (--repeats >= 0) { - rc = ifaceMacvtapLinkDump(nltarget_kernel, NULL, ifindex, tb, - &recvbuf, virNetDevVPortProfileGetLldpadPid); - if (rc < 0) - goto err_exit; - - rc = virNetDevVPortProfileGetStatus(tb, vf, instanceId, nltarget_kernel, - is8021Qbg, &status); - if (rc < 0) - goto err_exit; - if (status == PORT_PROFILE_RESPONSE_SUCCESS || - status == PORT_VDP_RESPONSE_SUCCESS) { - break; - } else if (status == PORT_PROFILE_RESPONSE_INPROGRESS) { - /* keep trying... */ - } else { - virReportSystemError(EINVAL, - _("error %d during port-profile setlink on " - "interface %s (%d)"), - status, ifname, ifindex); - rc = -1; - break; - } - - usleep(STATUS_POLL_INTERVL_USEC); - - VIR_FREE(recvbuf); - } - - if (status == PORT_PROFILE_RESPONSE_INPROGRESS) { - macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", - _("port-profile setlink timed out")); - rc = -2; - } - -err_exit: - VIR_FREE(recvbuf); - - return rc; -} - -# endif /* IFLA_PORT_MAX */ - - -# ifdef IFLA_VF_PORT_MAX - -static int -virNetDevVPortProfileGetPhysdevAndVlan(const char *ifname, int *root_ifindex, char *root_ifname, - int *vlanid) -{ - int ret; - unsigned int nth; - int ifindex = -1; - - *vlanid = -1; - while (1) { - if ((ret = ifaceGetNthParent(ifindex, ifname, 1, - root_ifindex, root_ifname, &nth)) < 0) - return ret; - if (nth == 0) - break; - if (*vlanid == -1) { - if (ifaceGetVlanID(root_ifname, vlanid) < 0) - *vlanid = -1; - } - - ifindex = *root_ifindex; - ifname = NULL; - } - - return 0; -} - -# endif - -/* Returns 0 on success, -1 on general failure, and -2 on timeout */ -static int -virNetDevVPortProfileOp8021Qbg(const char *ifname, - const unsigned char *macaddr, - const virNetDevVPortProfilePtr virtPort, - enum virNetDevVPortOp virtPortOp) -{ - int rc = 0; - -# ifndef IFLA_VF_PORT_MAX - - (void)ifname; - (void)macaddr; - (void)virtPort; - (void)virtPortOp; - macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Kernel VF Port support was missing at compile time.")); - rc = -1; - -# else /* IFLA_VF_PORT_MAX */ - - int op = PORT_REQUEST_ASSOCIATE; - struct ifla_port_vsi portVsi = { - .vsi_mgr_id = virtPort->u.virtPort8021Qbg.managerID, - .vsi_type_version = virtPort->u.virtPort8021Qbg.typeIDVersion, - }; - bool nltarget_kernel = false; - int vlanid; - int physdev_ifindex = 0; - char physdev_ifname[IFNAMSIZ] = { 0, }; - int vf = PORT_SELF_VF; - - if (virNetDevVPortProfileGetPhysdevAndVlan(ifname, &physdev_ifindex, physdev_ifname, - &vlanid) < 0) { - rc = -1; - goto err_exit; - } - - if (vlanid < 0) - vlanid = 0; - - portVsi.vsi_type_id[2] = virtPort->u.virtPort8021Qbg.typeID >> 16; - portVsi.vsi_type_id[1] = virtPort->u.virtPort8021Qbg.typeID >> 8; - portVsi.vsi_type_id[0] = virtPort->u.virtPort8021Qbg.typeID; - - switch (virtPortOp) { - case PREASSOCIATE: - op = PORT_REQUEST_PREASSOCIATE; - break; - case ASSOCIATE: - op = PORT_REQUEST_ASSOCIATE; - break; - case DISASSOCIATE: - op = PORT_REQUEST_DISASSOCIATE; - break; - default: - macvtapError(VIR_ERR_INTERNAL_ERROR, - _("operation type %d not supported"), virtPortOp); - rc = -1; - goto err_exit; - } - - rc = virNetDevVPortProfileOpCommon(physdev_ifname, physdev_ifindex, - nltarget_kernel, - macaddr, - vlanid, - NULL, - &portVsi, - virtPort->u.virtPort8021Qbg.instanceID, - NULL, - vf, - op); - -err_exit: - -# endif /* IFLA_VF_PORT_MAX */ - - return rc; -} - - -# ifdef IFLA_VF_PORT_MAX -static int -virNetDevVPortProfileGetPhysfnDev(const char *linkdev, - int32_t *vf, - char **physfndev) -{ - int rc = -1; - - if (ifaceIsVirtualFunction(linkdev) == 1) { - /* if linkdev is SR-IOV VF, then set vf = VF index */ - /* and set linkdev = PF device */ - - rc = ifaceGetPhysicalFunction(linkdev, physfndev); - if (!rc) - rc = ifaceGetVirtualFunctionIndex(*physfndev, linkdev, vf); - } else { - - /* Not SR-IOV VF: physfndev is linkdev and VF index - * refers to linkdev self - */ - - *vf = PORT_SELF_VF; - *physfndev = strdup(linkdev); - if (!*physfndev) { - virReportOOMError(); - goto err_exit; - } - rc = 0; - } - -err_exit: - - return rc; -} -# endif /* IFLA_VF_PORT_MAX */ - -/* Returns 0 on success, -1 on general failure, and -2 on timeout */ -static int -virNetDevVPortProfileOp8021Qbh(const char *ifname, - const unsigned char *macaddr, - const virNetDevVPortProfilePtr virtPort, - const unsigned char *vm_uuid, - enum virNetDevVPortOp virtPortOp) -{ - int rc = 0; - -# ifndef IFLA_VF_PORT_MAX - - (void)ifname; - (void)macaddr; - (void)virtPort; - (void)vm_uuid; - (void)virtPortOp; - macvtapError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Kernel VF Port support was missing at compile time.")); - rc = -1; - -# else /* IFLA_VF_PORT_MAX */ - - char *physfndev = NULL; - unsigned char hostuuid[VIR_UUID_BUFLEN]; - int32_t vf; - bool nltarget_kernel = true; - int ifindex; - int vlanid = -1; - - rc = virNetDevVPortProfileGetPhysfnDev(ifname, &vf, &physfndev); - if (rc < 0) - goto err_exit; - - rc = ifaceGetIndex(true, physfndev, &ifindex); - if (rc < 0) - goto err_exit; - - switch (virtPortOp) { - case PREASSOCIATE_RR: - case ASSOCIATE: - errno = virGetHostUUID(hostuuid); - if (errno) { - rc = -1; - goto err_exit; - } - - rc = virNetDevVPortProfileOpCommon(NULL, ifindex, - nltarget_kernel, - macaddr, - vlanid, - virtPort->u.virtPort8021Qbh.profileID, - NULL, - vm_uuid, - hostuuid, - vf, - (virtPortOp == PREASSOCIATE_RR) ? - PORT_REQUEST_PREASSOCIATE_RR - : PORT_REQUEST_ASSOCIATE); - if (rc == -2) - /* Association timed out, disassociate */ - virNetDevVPortProfileOpCommon(NULL, ifindex, - nltarget_kernel, - NULL, - vlanid, - NULL, - NULL, - NULL, - NULL, - vf, - PORT_REQUEST_DISASSOCIATE); - break; - - case DISASSOCIATE: - rc = virNetDevVPortProfileOpCommon(NULL, ifindex, - nltarget_kernel, - NULL, - vlanid, - NULL, - NULL, - NULL, - NULL, - vf, - PORT_REQUEST_DISASSOCIATE); - break; - - default: - macvtapError(VIR_ERR_INTERNAL_ERROR, - _("operation type %d not supported"), virtPortOp); - rc = -1; - } - -err_exit: - VIR_FREE(physfndev); - -# endif /* IFLA_VF_PORT_MAX */ - - return rc; -} - -/** - * virNetDevVPortProfileAssociate: - * - * @macvtap_ifname: The name of the macvtap device - * @virtPort: pointer to the object holding port profile parameters - * @vmuuid : the UUID of the virtual machine - * @vmOp : The VM operation (i.e., create, no-op) - * - * Associate a port on a swtich with a profile. This function - * may notify a kernel driver or an external daemon to run - * the setup protocol. If profile parameters were not supplied - * by the user, then this function returns without doing - * anything. - * - * Returns 0 in case of success, < 0 otherwise with error - * having been reported. - */ -int -virNetDevVPortProfileAssociate(const char *macvtap_ifname, - const virNetDevVPortProfilePtr virtPort, - const unsigned char *macvtap_macaddr, - const char *linkdev, - const unsigned char *vmuuid, - enum virNetDevVPortProfileOp vmOp) -{ - int rc = 0; - - VIR_DEBUG("Associating port profile '%p' on link device '%s'", - virtPort, macvtap_ifname); - - VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virNetDevVPortProfileOpTypeToString(vmOp)); - - if (!virtPort || vmOp == VIR_NETDEV_VPORT_PROFILE_OP_NO_OP) - return 0; - - switch (virtPort->virtPortType) { - case VIR_NETDEV_VPORT_PROFILE_NONE: - case VIR_NETDEV_VPORT_PROFILE_LAST: - break; - - case VIR_NETDEV_VPORT_PROFILE_8021QBG: - rc = virNetDevVPortProfileOp8021Qbg(macvtap_ifname, macvtap_macaddr, - virtPort, - (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START) - ? PREASSOCIATE - : ASSOCIATE); - break; - - case VIR_NETDEV_VPORT_PROFILE_8021QBH: - rc = virNetDevVPortProfileOp8021Qbh(linkdev, macvtap_macaddr, - virtPort, vmuuid, - (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START) - ? PREASSOCIATE_RR - : ASSOCIATE); - if (vmOp != VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START && !rc) { - /* XXX bogus error handling */ - ignore_value(virNetDevSetOnline(linkdev, true)); - } - - break; - } - - return rc; -} - - -/** - * virNetDevVPortProfileDisassociate: - * - * @macvtap_ifname: The name of the macvtap device - * @macvtap_macaddr : The MAC address of the macvtap - * @linkdev: The link device in case of macvtap - * @virtPort: point to object holding port profile parameters - * - * Returns 0 in case of success, != 0 otherwise with error - * having been reported. - */ -int -virNetDevVPortProfileDisassociate(const char *macvtap_ifname, - const virNetDevVPortProfilePtr virtPort, - const unsigned char *macvtap_macaddr, - const char *linkdev, - enum virNetDevVPortProfileOp vmOp) -{ - int rc = 0; - - VIR_DEBUG("Disassociating port profile id '%p' on link device '%s' ", - virtPort, macvtap_ifname); - - VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virNetDevVPortProfileOpTypeToString(vmOp)); - - if (!virtPort) - return 0; - - switch (virtPort->virtPortType) { - case VIR_NETDEV_VPORT_PROFILE_NONE: - case VIR_NETDEV_VPORT_PROFILE_LAST: - break; - - case VIR_NETDEV_VPORT_PROFILE_8021QBG: - rc = virNetDevVPortProfileOp8021Qbg(macvtap_ifname, macvtap_macaddr, - virtPort, DISASSOCIATE); - break; - - case VIR_NETDEV_VPORT_PROFILE_8021QBH: - /* avoid disassociating twice */ - if (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH) - break; - ignore_value(virNetDevSetOnline(linkdev, false)); - rc = virNetDevVPortProfileOp8021Qbh(linkdev, macvtap_macaddr, - virtPort, NULL, DISASSOCIATE); - break; - } - - return rc; -} - -#endif /* WITH_MACVTAP || WITH_NETDEV_VPORT_PROFILE */ - -VIR_ENUM_IMPL(virNetDevVPortProfileOp, VIR_NETDEV_VPORT_PROFILE_OP_LAST, - "create", - "save", - "restore", - "destroy", - "migrate out", - "migrate in start", - "migrate in finish", - "no-op") diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c new file mode 100644 index 0000000..ab111f0 --- /dev/null +++ b/src/util/virnetdevmacvlan.c @@ -0,0 +1,423 @@ +/* + * Copyright (C) 2010-2011 Red Hat, Inc. + * Copyright (C) 2010 IBM Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Stefan Berger <stefanb@us.ibm.com> + * + * Notes: + * netlink: http://lovezutto.googlepages.com/netlink.pdf + * iproute2 package + * + */ + +#include <config.h> + + +#include "virnetdevmacvlan.h" +#include "util.h" +#include "virterror_internal.h" + +#define VIR_FROM_THIS VIR_FROM_NET + +#define macvtapError(code, ...) \ + virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \ + __FUNCTION__, __LINE__, __VA_ARGS__) + + +VIR_ENUM_IMPL(virNetDevMacVLanMode, VIR_NETDEV_MACVLAN_MODE_LAST, + "vepa", + "private", + "bridge", + "passthrough") + +#if WITH_MACVTAP + +# include <stdint.h> +# include <stdio.h> +# include <errno.h> +# include <fcntl.h> +# include <sys/socket.h> +# include <sys/ioctl.h> + +# include <linux/if.h> +# include <linux/if_tun.h> + +/* Older kernels lacked this enum value. */ +# if !HAVE_DECL_MACVLAN_MODE_PASSTHRU +# define MACVLAN_MODE_PASSTHRU 8 +# endif + +# include "memory.h" +# include "logging.h" +# include "interface.h" +# include "uuid.h" +# include "virfile.h" +# include "netlink.h" +# include "virnetdev.h" + +# define MACVTAP_NAME_PREFIX "macvtap" +# define MACVTAP_NAME_PATTERN "macvtap%d" + +/** + * virNetDevMacVLanTapOpen: + * Open the macvtap's tap device. + * @ifname: Name of the macvtap interface + * @retries : Number of retries in case udev for example may need to be + * waited for to create the tap chardev + * Returns negative value in case of error, the file descriptor otherwise. + */ +static +int virNetDevMacVLanTapOpen(const char *ifname, + int retries) +{ + FILE *file; + char path[64]; + int ifindex; + char tapname[50]; + int tapfd; + + if (snprintf(path, sizeof(path), + "/sys/class/net/%s/ifindex", ifname) >= sizeof(path)) { + virReportSystemError(errno, + "%s", + _("buffer for ifindex path is too small")); + return -1; + } + + file = fopen(path, "r"); + + if (!file) { + virReportSystemError(errno, + _("cannot open macvtap file %s to determine " + "interface index"), path); + return -1; + } + + if (fscanf(file, "%d", &ifindex) != 1) { + virReportSystemError(errno, + "%s",_("cannot determine macvtap's tap device " + "interface index")); + VIR_FORCE_FCLOSE(file); + return -1; + } + + VIR_FORCE_FCLOSE(file); + + if (snprintf(tapname, sizeof(tapname), + "/dev/tap%d", ifindex) >= sizeof(tapname)) { + virReportSystemError(errno, + "%s", + _("internal buffer for tap device is too small")); + return -1; + } + + while (1) { + /* may need to wait for udev to be done */ + tapfd = open(tapname, O_RDWR); + if (tapfd < 0 && retries > 0) { + retries--; + usleep(20000); + continue; + } + break; + } + + if (tapfd < 0) + virReportSystemError(errno, + _("cannot open macvtap tap device %s"), + tapname); + + return tapfd; +} + + +/** + * virNetDevMacVLanTapSetup: + * @tapfd: file descriptor of the macvtap tap + * @vnet_hdr: 1 to enable IFF_VNET_HDR, 0 to disable it + * + * Returns 0 on success, -1 in case of fatal error, error code otherwise. + * + * Turn the IFF_VNET_HDR flag, if requested and available, make sure + * it's off in the other cases. + * A fatal error is defined as the VNET_HDR flag being set but it cannot + * be turned off for some reason. This is reported with -1. Other fatal + * error is not being able to read the interface flags. In that case the + * macvtap device should not be used. + */ +static int +virNetDevMacVLanTapSetup(int tapfd, int vnet_hdr) +{ + unsigned int features; + struct ifreq ifreq; + short new_flags = 0; + int rc_on_fail = 0; + const char *errmsg = NULL; + + memset(&ifreq, 0, sizeof(ifreq)); + + if (ioctl(tapfd, TUNGETIFF, &ifreq) < 0) { + virReportSystemError(errno, "%s", + _("cannot get interface flags on macvtap tap")); + return -1; + } + + new_flags = ifreq.ifr_flags; + + if ((ifreq.ifr_flags & IFF_VNET_HDR) && !vnet_hdr) { + new_flags = ifreq.ifr_flags & ~IFF_VNET_HDR; + rc_on_fail = -1; + errmsg = _("cannot clean IFF_VNET_HDR flag on macvtap tap"); + } else if ((ifreq.ifr_flags & IFF_VNET_HDR) == 0 && vnet_hdr) { + if (ioctl(tapfd, TUNGETFEATURES, &features) < 0) { + virReportSystemError(errno, "%s", + _("cannot get feature flags on macvtap tap")); + return -1; + } + if ((features & IFF_VNET_HDR)) { + new_flags = ifreq.ifr_flags | IFF_VNET_HDR; + errmsg = _("cannot set IFF_VNET_HDR flag on macvtap tap"); + } + } + + if (new_flags != ifreq.ifr_flags) { + ifreq.ifr_flags = new_flags; + if (ioctl(tapfd, TUNSETIFF, &ifreq) < 0) { + virReportSystemError(errno, "%s", errmsg); + return rc_on_fail; + } + } + + return 0; +} + + +static const uint32_t modeMap[VIR_NETDEV_MACVLAN_MODE_LAST] = { + [VIR_NETDEV_MACVLAN_MODE_VEPA] = MACVLAN_MODE_VEPA, + [VIR_NETDEV_MACVLAN_MODE_PRIVATE] = MACVLAN_MODE_PRIVATE, + [VIR_NETDEV_MACVLAN_MODE_BRIDGE] = MACVLAN_MODE_BRIDGE, + [VIR_NETDEV_MACVLAN_MODE_PASSTHRU] = MACVLAN_MODE_PASSTHRU, +}; + +/** + * virNetDevMacVLanCreate: + * Create an instance of a macvtap device and open its tap character + * device. + * @tgifname: Interface name that the macvtap is supposed to have. May + * be NULL if this function is supposed to choose a name + * @macaddress: The MAC address for the macvtap device + * @linkdev: The interface name of the NIC to connect to the external bridge + * @mode: int describing the mode for 'bridge', 'vepa', 'private' or 'passthru'. + * @vnet_hdr: 1 to enable IFF_VNET_HDR, 0 to disable it + * @vmuuid: The UUID of the VM the macvtap belongs to + * @virtPortProfile: pointer to object holding the virtual port profile data + * @res_ifname: Pointer to a string pointer where the actual name of the + * interface will be stored into if everything succeeded. It is up + * to the caller to free the string. + * + * Returns file descriptor of the tap device in case of success, + * negative value otherwise with error reported. + * + */ +int virNetDevMacVLanCreate(const char *tgifname, + const unsigned char *macaddress, + const char *linkdev, + enum virNetDevMacVLanMode mode, + int vnet_hdr, + const unsigned char *vmuuid, + virNetDevVPortProfilePtr virtPortProfile, + char **res_ifname, + enum virNetDevVPortProfileOp vmOp, + char *stateDir, + virNetDevBandwidthPtr bandwidth) +{ + const char *type = "macvtap"; + int c, rc; + char ifname[IFNAMSIZ]; + int retries, do_retry = 0; + uint32_t macvtapMode; + const char *cr_ifname; + int ifindex; + + macvtapMode = modeMap[mode]; + + *res_ifname = NULL; + + VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virNetDevVPortProfileOpTypeToString(vmOp)); + + /** Note: When using PASSTHROUGH mode with MACVTAP devices the link + * device's MAC address must be set to the VMs MAC address. In + * order to not confuse the first switch or bridge in line this MAC + * address must be reset when the VM is shut down. + * This is especially important when using SRIOV capable cards that + * emulate their switch in firmware. + */ + if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { + if (ifaceReplaceMacAddress(macaddress, linkdev, stateDir) < 0) { + return -1; + } + } + + if (tgifname) { + if(ifaceGetIndex(false, tgifname, &ifindex) == 0) { + if (STRPREFIX(tgifname, + MACVTAP_NAME_PREFIX)) { + goto create_name; + } + virReportSystemError(errno, + _("Interface %s already exists"), tgifname); + return -1; + } + cr_ifname = tgifname; + rc = ifaceMacvtapLinkAdd(type, macaddress, 6, tgifname, linkdev, + macvtapMode, &do_retry); + if (rc < 0) + return -1; + } else { +create_name: + retries = 5; + for (c = 0; c < 8192; c++) { + snprintf(ifname, sizeof(ifname), MACVTAP_NAME_PATTERN, c); + if (ifaceGetIndex(false, ifname, &ifindex) == -ENODEV) { + rc = ifaceMacvtapLinkAdd(type, macaddress, 6, ifname, linkdev, + macvtapMode, &do_retry); + if (rc == 0) + break; + + if (do_retry && --retries) + continue; + return -1; + } + } + cr_ifname = ifname; + } + + if (virNetDevVPortProfileAssociate(cr_ifname, + virtPortProfile, + macaddress, + linkdev, + vmuuid, vmOp) < 0) { + rc = -1; + goto link_del_exit; + } + + if (virNetDevSetOnline(cr_ifname, true) < 0) { + rc = -1; + goto disassociate_exit; + } + + rc = virNetDevMacVLanTapOpen(cr_ifname, 10); + if (rc >= 0) { + if (virNetDevMacVLanTapSetup(rc, vnet_hdr) < 0) { + VIR_FORCE_CLOSE(rc); /* sets rc to -1 */ + goto disassociate_exit; + } + *res_ifname = strdup(cr_ifname); + } else + goto disassociate_exit; + + if (virNetDevBandwidthSet(cr_ifname, bandwidth) < 0) { + macvtapError(VIR_ERR_INTERNAL_ERROR, + _("cannot set bandwidth limits on %s"), + cr_ifname); + rc = -1; + goto disassociate_exit; + } + + + return rc; + +disassociate_exit: + ignore_value(virNetDevVPortProfileDisassociate(cr_ifname, + virtPortProfile, + macaddress, + linkdev, + vmOp)); + +link_del_exit: + ifaceLinkDel(cr_ifname); + + return rc; +} + + +/** + * delMacvtap: + * @ifname : The name of the macvtap interface + * @linkdev: The interface name of the NIC to connect to the external bridge + * @virtPortProfile: pointer to object holding the virtual port profile data + * + * Delete an interface given its name. Disassociate + * it with the switch if port profile parameters + * were provided. + */ +int virNetDevMacVLanDelete(const char *ifname, + const unsigned char *macaddr, + const char *linkdev, + int mode, + virNetDevVPortProfilePtr virtPortProfile, + char *stateDir) +{ + int ret = 0; + if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { + ifaceRestoreMacAddress(linkdev, stateDir); + } + + if (ifname) { + if (virNetDevVPortProfileDisassociate(ifname, + virtPortProfile, + macaddr, + linkdev, + VIR_NETDEV_VPORT_PROFILE_OP_DESTROY) < 0) + ret = -1; + if (ifaceLinkDel(ifname) < 0) + ret = -1; + } + return ret; +} + +#else /* ! WITH_MACVTAP */ +int virNetDevMacVLanCreate(const char *ifname ATTRIBUTE_UNUSED, + const unsigned char *macaddress ATTRIBUTE_UNUSED, + const char *linkdev ATTRIBUTE_UNUSED, + enum virNetDevMacVLanMode mode ATTRIBUTE_UNUSED, + int vnet_hdr ATTRIBUTE_UNUSED, + const unsigned char *vmuuid ATTRIBUTE_UNUSED, + virNetDevVPortProfilePtr virtPortProfile ATTRIBUTE_UNUSED, + char **res_ifname ATTRIBUTE_UNUSED, + enum virNetDevVPortProfileOp vmop ATTRIBUTE_UNUSED, + char *stateDir ATTRIBUTE_UNUSED, + virNetDevBandwidthPtr bandwidth ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Cannot create macvlan devices on this platform")); + return -1; +} + +int virNetDevMacVLanDelete(const char *ifname ATTRIBUTE_UNUSED, + const unsigned char *macaddress ATTRIBUTE_UNUSED, + const char *linkdev ATTRIBUTE_UNUSED, + int mode ATTRIBUTE_UNUSED, + virNetDevVPortProfilePtr virtPortProfile ATTRIBUTE_UNUSED, + char *stateDir ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Cannot create macvlan devices on this platform")); + return -1; +} +#endif /* ! WITH_MACVTAP */ diff --git a/src/util/macvtap.h b/src/util/virnetdevmacvlan.h similarity index 63% rename from src/util/macvtap.h rename to src/util/virnetdevmacvlan.h index 5c5d84a..f3277f9 100644 --- a/src/util/macvtap.h +++ b/src/util/virnetdevmacvlan.h @@ -37,21 +37,7 @@ enum virNetDevMacVLanMode { VIR_NETDEV_MACVLAN_MODE_LAST, }; - -enum virNetDevVPortProfileOp { - VIR_NETDEV_VPORT_PROFILE_OP_CREATE, - VIR_NETDEV_VPORT_PROFILE_OP_SAVE, - VIR_NETDEV_VPORT_PROFILE_OP_RESTORE, - VIR_NETDEV_VPORT_PROFILE_OP_DESTROY, - VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_OUT, - VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START, - VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH, - VIR_NETDEV_VPORT_PROFILE_OP_NO_OP, - - VIR_NETDEV_VPORT_PROFILE_OP_LAST -}; - -# if WITH_MACVTAP +VIR_ENUM_DECL(virNetDevMacVLanMode) int virNetDevMacVLanCreate(const char *ifname, const unsigned char *macaddress, @@ -76,26 +62,4 @@ int virNetDevMacVLanDelete(const char *ifname, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(6) ATTRIBUTE_RETURN_CHECK; -int virNetDevVPortProfileAssociate(const char *ifname, - const virNetDevVPortProfilePtr virtPort, - const unsigned char *macaddr, - const char *linkdev, - const unsigned char *vmuuid, - enum virNetDevVPortProfileOp vmOp) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) - ATTRIBUTE_NONNULL(5) ATTRIBUTE_RETURN_CHECK; - -int virNetDevVPortProfileDisassociate(const char *ifname, - const virNetDevVPortProfilePtr virtPort, - const unsigned char *macaddr, - const char *linkdev, - enum virNetDevVPortProfileOp vmOp) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) - ATTRIBUTE_RETURN_CHECK; - -# endif /* WITH_MACVTAP */ - -VIR_ENUM_DECL(virNetDevVPortProfileOp) -VIR_ENUM_DECL(virNetDevMacVLanMode) - #endif /* __UTIL_MACVTAP_H__ */ diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c index 29abce6..1e826db 100644 --- a/src/util/virnetdevvportprofile.c +++ b/src/util/virnetdevvportprofile.c @@ -23,6 +23,65 @@ #include <config.h> #include "virnetdevvportprofile.h" +#include "virterror_internal.h" + +#define VIR_FROM_THIS VIR_FROM_NET + +#define virNetDevError(code, ...) \ + virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \ + __FUNCTION__, __LINE__, __VA_ARGS__) + + +VIR_ENUM_IMPL(virNetDevVPortProfileOp, VIR_NETDEV_VPORT_PROFILE_OP_LAST, + "create", + "save", + "restore", + "destroy", + "migrate out", + "migrate in start", + "migrate in finish", + "no-op") + +#if WITH_VIRTUALPORT + +# include <stdint.h> +# include <stdio.h> +# include <errno.h> +# include <fcntl.h> +# include <c-ctype.h> +# include <sys/socket.h> +# include <sys/ioctl.h> + +# include <linux/if.h> +# include <linux/if_tun.h> + +# include "netlink.h" +# include "virfile.h" +# include "memory.h" +# include "interface.h" +# include "logging.h" +# include "virnetdev.h" + +# define MICROSEC_PER_SEC (1000 * 1000) + +# define NLMSGBUF_SIZE 256 +# define RATTBUF_SIZE 64 + + +# define STATUS_POLL_TIMEOUT_USEC (10 * MICROSEC_PER_SEC) +# define STATUS_POLL_INTERVL_USEC (MICROSEC_PER_SEC / 8) + +# define LLDPAD_PID_FILE "/var/run/lldpad.pid" + + +enum virNetDevVPortProfileLinkOp { + ASSOCIATE = 0x1, + DISASSOCIATE = 0x2, + PREASSOCIATE = 0x3, + PREASSOCIATE_RR = 0x4, +}; + +#endif bool virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, virNetDevVPortProfilePtr b) @@ -60,3 +119,764 @@ virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, virNetDevVPortProfilePtr return true; } + + +#ifdef WITH_VIRTUALPORT + +static struct nla_policy ifla_port_policy[IFLA_PORT_MAX + 1] = +{ + [IFLA_PORT_RESPONSE] = { .type = NLA_U16 }, +}; + + +static uint32_t +virNetDevVPortProfileGetLldpadPid(void) { + int fd; + uint32_t pid = 0; + + fd = open(LLDPAD_PID_FILE, O_RDONLY); + if (fd >= 0) { + char buffer[10]; + + if (saferead(fd, buffer, sizeof(buffer)) <= sizeof(buffer)) { + unsigned int res; + char *endptr; + + if (virStrToLong_ui(buffer, &endptr, 10, &res) == 0 + && (*endptr == '\0' || c_isspace(*endptr)) + && res != 0) { + pid = res; + } else { + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("error parsing pid of lldpad")); + } + } + } else { + virReportSystemError(errno, + _("Error opening file %s"), LLDPAD_PID_FILE); + } + + VIR_FORCE_CLOSE(fd); + + return pid; +} + + +/** + * virNetDevVPortProfileGetStatus: + * + * tb: top level netlink response attributes + values + * vf: The virtual function used in the request + * instanceId: instanceId of the interface (vm uuid in case of 802.1Qbh) + * is8021Qbg: whether this function is call for 8021Qbg + * status: pointer to a uint16 where the status will be written into + * + * Get the status from the IFLA_PORT_RESPONSE field; Returns 0 in + * case of success, < 0 otherwise with error having been reported + */ +static int +virNetDevVPortProfileGetStatus(struct nlattr **tb, int32_t vf, + const unsigned char *instanceId, + bool nltarget_kernel, + bool is8021Qbg, + uint16_t *status) +{ + int rc = -1; + const char *msg = NULL; + struct nlattr *tb_port[IFLA_PORT_MAX + 1] = { NULL, }; + + if (vf == PORT_SELF_VF && nltarget_kernel) { + if (tb[IFLA_PORT_SELF]) { + if (nla_parse_nested(tb_port, IFLA_PORT_MAX, tb[IFLA_PORT_SELF], + ifla_port_policy)) { + msg = _("error parsing IFLA_PORT_SELF part"); + goto err_exit; + } + } else { + msg = _("IFLA_PORT_SELF is missing"); + goto err_exit; + } + } else { + if (tb[IFLA_VF_PORTS]) { + int rem; + bool found = false; + struct nlattr *tb_vf_ports = { NULL, }; + + nla_for_each_nested(tb_vf_ports, tb[IFLA_VF_PORTS], rem) { + + if (nla_type(tb_vf_ports) != IFLA_VF_PORT) { + msg = _("error while iterating over IFLA_VF_PORTS part"); + goto err_exit; + } + + if (nla_parse_nested(tb_port, IFLA_PORT_MAX, tb_vf_ports, + ifla_port_policy)) { + msg = _("error parsing IFLA_VF_PORT part"); + goto err_exit; + } + + if (instanceId && + tb_port[IFLA_PORT_INSTANCE_UUID] && + !memcmp(instanceId, + (unsigned char *) + RTA_DATA(tb_port[IFLA_PORT_INSTANCE_UUID]), + VIR_UUID_BUFLEN) && + tb_port[IFLA_PORT_VF] && + vf == *(uint32_t *)RTA_DATA(tb_port[IFLA_PORT_VF])) { + found = true; + break; + } + } + + if (!found) { + msg = _("Could not find netlink response with " + "expected parameters"); + goto err_exit; + } + } else { + msg = _("IFLA_VF_PORTS is missing"); + goto err_exit; + } + } + + if (tb_port[IFLA_PORT_RESPONSE]) { + *status = *(uint16_t *)RTA_DATA(tb_port[IFLA_PORT_RESPONSE]); + rc = 0; + } else { + if (is8021Qbg) { + /* no in-progress here; may be missing */ + *status = PORT_PROFILE_RESPONSE_INPROGRESS; + rc = 0; + } else { + msg = _("no IFLA_PORT_RESPONSE found in netlink message"); + goto err_exit; + } + } + +err_exit: + if (msg) + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", msg); + + return rc; +} + + +static int +virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex, + bool nltarget_kernel, + const unsigned char *macaddr, + int vlanid, + const char *profileId, + struct ifla_port_vsi *portVsi, + const unsigned char *instanceId, + const unsigned char *hostUUID, + int32_t vf, + uint8_t op) +{ + int rc = -1; + struct nlmsghdr *resp; + struct nlmsgerr *err; + struct ifinfomsg ifinfo = { + .ifi_family = AF_UNSPEC, + .ifi_index = ifindex, + }; + unsigned char *recvbuf = NULL; + unsigned int recvbuflen = 0; + uint32_t pid = 0; + struct nl_msg *nl_msg; + struct nlattr *vfports = NULL, *vfport; + + nl_msg = nlmsg_alloc_simple(RTM_SETLINK, NLM_F_REQUEST); + if (!nl_msg) { + virReportOOMError(); + return rc; + } + + if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) + goto buffer_too_small; + + if (ifname && + nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) + goto buffer_too_small; + + if (macaddr || vlanid >= 0) { + struct nlattr *vfinfolist, *vfinfo; + + if (!(vfinfolist = nla_nest_start(nl_msg, IFLA_VFINFO_LIST))) + goto buffer_too_small; + + if (!(vfinfo = nla_nest_start(nl_msg, IFLA_VF_INFO))) + goto buffer_too_small; + + if (macaddr) { + struct ifla_vf_mac ifla_vf_mac = { + .vf = vf, + .mac = { 0, }, + }; + + memcpy(ifla_vf_mac.mac, macaddr, 6); + + if (nla_put(nl_msg, IFLA_VF_MAC, sizeof(ifla_vf_mac), + &ifla_vf_mac) < 0) + goto buffer_too_small; + } + + if (vlanid >= 0) { + struct ifla_vf_vlan ifla_vf_vlan = { + .vf = vf, + .vlan = vlanid, + .qos = 0, + }; + + if (nla_put(nl_msg, IFLA_VF_VLAN, sizeof(ifla_vf_vlan), + &ifla_vf_vlan) < 0) + goto buffer_too_small; + } + + nla_nest_end(nl_msg, vfinfo); + nla_nest_end(nl_msg, vfinfolist); + } + + if (vf == PORT_SELF_VF && nltarget_kernel) { + if (!(vfport = nla_nest_start(nl_msg, IFLA_PORT_SELF))) + goto buffer_too_small; + } else { + if (!(vfports = nla_nest_start(nl_msg, IFLA_VF_PORTS))) + goto buffer_too_small; + + /* begin nesting vfports */ + if (!(vfport = nla_nest_start(nl_msg, IFLA_VF_PORT))) + goto buffer_too_small; + } + + if (profileId) { + if (nla_put(nl_msg, IFLA_PORT_PROFILE, strlen(profileId) + 1, + profileId) < 0) + goto buffer_too_small; + } + + if (portVsi) { + if (nla_put(nl_msg, IFLA_PORT_VSI_TYPE, sizeof(*portVsi), + portVsi) < 0) + goto buffer_too_small; + } + + if (instanceId) { + if (nla_put(nl_msg, IFLA_PORT_INSTANCE_UUID, VIR_UUID_BUFLEN, + instanceId) < 0) + goto buffer_too_small; + } + + if (hostUUID) { + if (nla_put(nl_msg, IFLA_PORT_HOST_UUID, VIR_UUID_BUFLEN, + hostUUID) < 0) + goto buffer_too_small; + } + + if (vf != PORT_SELF_VF) { + if (nla_put(nl_msg, IFLA_PORT_VF, sizeof(vf), &vf) < 0) + goto buffer_too_small; + } + + if (nla_put(nl_msg, IFLA_PORT_REQUEST, sizeof(op), &op) < 0) + goto buffer_too_small; + + /* end nesting of vport */ + nla_nest_end(nl_msg, vfport); + + if (vfports) { + /* end nesting of vfports */ + nla_nest_end(nl_msg, vfports); + } + + if (!nltarget_kernel) { + pid = virNetDevVPortProfileGetLldpadPid(); + if (pid == 0) + goto err_exit; + } + + if (nlComm(nl_msg, &recvbuf, &recvbuflen, pid) < 0) + goto err_exit; + + if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL) + goto malformed_resp; + + resp = (struct nlmsghdr *)recvbuf; + + switch (resp->nlmsg_type) { + case NLMSG_ERROR: + err = (struct nlmsgerr *)NLMSG_DATA(resp); + if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) + goto malformed_resp; + + if (err->error) { + virReportSystemError(-err->error, + _("error during virtual port configuration of ifindex %d"), + ifindex); + goto err_exit; + } + break; + + case NLMSG_DONE: + break; + + default: + goto malformed_resp; + } + + rc = 0; + +err_exit: + nlmsg_free(nl_msg); + + VIR_FREE(recvbuf); + + return rc; + +malformed_resp: + nlmsg_free(nl_msg); + + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("malformed netlink response message")); + VIR_FREE(recvbuf); + return rc; + +buffer_too_small: + nlmsg_free(nl_msg); + + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("allocated netlink buffer is too small")); + return rc; +} + + +/* Returns 0 on success, -1 on general failure, and -2 on timeout */ +static int +virNetDevVPortProfileOpCommon(const char *ifname, int ifindex, + bool nltarget_kernel, + const unsigned char *macaddr, + int vlanid, + const char *profileId, + struct ifla_port_vsi *portVsi, + const unsigned char *instanceId, + const unsigned char *hostUUID, + int32_t vf, + uint8_t op) +{ + int rc; + unsigned char *recvbuf = NULL; + struct nlattr *tb[IFLA_MAX + 1] = { NULL , }; + int repeats = STATUS_POLL_TIMEOUT_USEC / STATUS_POLL_INTERVL_USEC; + uint16_t status = 0; + bool is8021Qbg = (profileId == NULL); + + rc = virNetDevVPortProfileOpSetLink(ifname, ifindex, + nltarget_kernel, + macaddr, + vlanid, + profileId, + portVsi, + instanceId, + hostUUID, + vf, + op); + if (rc < 0) { + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("sending of PortProfileRequest failed.")); + return rc; + } + + while (--repeats >= 0) { + rc = ifaceMacvtapLinkDump(nltarget_kernel, NULL, ifindex, tb, + &recvbuf, virNetDevVPortProfileGetLldpadPid); + if (rc < 0) + goto err_exit; + + rc = virNetDevVPortProfileGetStatus(tb, vf, instanceId, nltarget_kernel, + is8021Qbg, &status); + if (rc < 0) + goto err_exit; + if (status == PORT_PROFILE_RESPONSE_SUCCESS || + status == PORT_VDP_RESPONSE_SUCCESS) { + break; + } else if (status == PORT_PROFILE_RESPONSE_INPROGRESS) { + /* keep trying... */ + } else { + virReportSystemError(EINVAL, + _("error %d during port-profile setlink on " + "interface %s (%d)"), + status, ifname, ifindex); + rc = -1; + break; + } + + usleep(STATUS_POLL_INTERVL_USEC); + + VIR_FREE(recvbuf); + } + + if (status == PORT_PROFILE_RESPONSE_INPROGRESS) { + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("port-profile setlink timed out")); + rc = -2; + } + +err_exit: + VIR_FREE(recvbuf); + + return rc; +} + + +static int +virNetDevVPortProfileGetPhysdevAndVlan(const char *ifname, int *root_ifindex, char *root_ifname, + int *vlanid) +{ + int ret; + unsigned int nth; + int ifindex = -1; + + *vlanid = -1; + while (1) { + if ((ret = ifaceGetNthParent(ifindex, ifname, 1, + root_ifindex, root_ifname, &nth)) < 0) + return ret; + if (nth == 0) + break; + if (*vlanid == -1) { + if (ifaceGetVlanID(root_ifname, vlanid) < 0) + *vlanid = -1; + } + + ifindex = *root_ifindex; + ifname = NULL; + } + + return 0; +} + +/* Returns 0 on success, -1 on general failure, and -2 on timeout */ +static int +virNetDevVPortProfileOp8021Qbg(const char *ifname, + const unsigned char *macaddr, + const virNetDevVPortProfilePtr virtPort, + enum virNetDevVPortProfileLinkOp virtPortOp) +{ + int rc = 0; + int op = PORT_REQUEST_ASSOCIATE; + struct ifla_port_vsi portVsi = { + .vsi_mgr_id = virtPort->u.virtPort8021Qbg.managerID, + .vsi_type_version = virtPort->u.virtPort8021Qbg.typeIDVersion, + }; + bool nltarget_kernel = false; + int vlanid; + int physdev_ifindex = 0; + char physdev_ifname[IFNAMSIZ] = { 0, }; + int vf = PORT_SELF_VF; + + if (virNetDevVPortProfileGetPhysdevAndVlan(ifname, &physdev_ifindex, physdev_ifname, + &vlanid) < 0) { + rc = -1; + goto err_exit; + } + + if (vlanid < 0) + vlanid = 0; + + portVsi.vsi_type_id[2] = virtPort->u.virtPort8021Qbg.typeID >> 16; + portVsi.vsi_type_id[1] = virtPort->u.virtPort8021Qbg.typeID >> 8; + portVsi.vsi_type_id[0] = virtPort->u.virtPort8021Qbg.typeID; + + switch (virtPortOp) { + case PREASSOCIATE: + op = PORT_REQUEST_PREASSOCIATE; + break; + case ASSOCIATE: + op = PORT_REQUEST_ASSOCIATE; + break; + case DISASSOCIATE: + op = PORT_REQUEST_DISASSOCIATE; + break; + default: + virNetDevError(VIR_ERR_INTERNAL_ERROR, + _("operation type %d not supported"), virtPortOp); + rc = -1; + goto err_exit; + } + + rc = virNetDevVPortProfileOpCommon(physdev_ifname, physdev_ifindex, + nltarget_kernel, + macaddr, + vlanid, + NULL, + &portVsi, + virtPort->u.virtPort8021Qbg.instanceID, + NULL, + vf, + op); + +err_exit: + + return rc; +} + + +static int +virNetDevVPortProfileGetPhysfnDev(const char *linkdev, + int32_t *vf, + char **physfndev) +{ + int rc = -1; + + if (ifaceIsVirtualFunction(linkdev) == 1) { + /* if linkdev is SR-IOV VF, then set vf = VF index */ + /* and set linkdev = PF device */ + + rc = ifaceGetPhysicalFunction(linkdev, physfndev); + if (!rc) + rc = ifaceGetVirtualFunctionIndex(*physfndev, linkdev, vf); + } else { + + /* Not SR-IOV VF: physfndev is linkdev and VF index + * refers to linkdev self + */ + + *vf = PORT_SELF_VF; + *physfndev = strdup(linkdev); + if (!*physfndev) { + virReportOOMError(); + goto err_exit; + } + rc = 0; + } + +err_exit: + + return rc; +} + + +/* Returns 0 on success, -1 on general failure, and -2 on timeout */ +static int +virNetDevVPortProfileOp8021Qbh(const char *ifname, + const unsigned char *macaddr, + const virNetDevVPortProfilePtr virtPort, + const unsigned char *vm_uuid, + enum virNetDevVPortProfileLinkOp virtPortOp) +{ + int rc = 0; + char *physfndev = NULL; + unsigned char hostuuid[VIR_UUID_BUFLEN]; + int32_t vf; + bool nltarget_kernel = true; + int ifindex; + int vlanid = -1; + + rc = virNetDevVPortProfileGetPhysfnDev(ifname, &vf, &physfndev); + if (rc < 0) + goto err_exit; + + rc = ifaceGetIndex(true, physfndev, &ifindex); + if (rc < 0) + goto err_exit; + + switch (virtPortOp) { + case PREASSOCIATE_RR: + case ASSOCIATE: + errno = virGetHostUUID(hostuuid); + if (errno) { + rc = -1; + goto err_exit; + } + + rc = virNetDevVPortProfileOpCommon(NULL, ifindex, + nltarget_kernel, + macaddr, + vlanid, + virtPort->u.virtPort8021Qbh.profileID, + NULL, + vm_uuid, + hostuuid, + vf, + (virtPortOp == PREASSOCIATE_RR) ? + PORT_REQUEST_PREASSOCIATE_RR + : PORT_REQUEST_ASSOCIATE); + if (rc == -2) + /* Association timed out, disassociate */ + virNetDevVPortProfileOpCommon(NULL, ifindex, + nltarget_kernel, + NULL, + vlanid, + NULL, + NULL, + NULL, + NULL, + vf, + PORT_REQUEST_DISASSOCIATE); + break; + + case DISASSOCIATE: + rc = virNetDevVPortProfileOpCommon(NULL, ifindex, + nltarget_kernel, + NULL, + vlanid, + NULL, + NULL, + NULL, + NULL, + vf, + PORT_REQUEST_DISASSOCIATE); + break; + + default: + virNetDevError(VIR_ERR_INTERNAL_ERROR, + _("operation type %d not supported"), virtPortOp); + rc = -1; + } + +err_exit: + VIR_FREE(physfndev); + return rc; +} + +/** + * virNetDevVPortProfileAssociate: + * + * @macvtap_ifname: The name of the macvtap device + * @virtPort: pointer to the object holding port profile parameters + * @vmuuid : the UUID of the virtual machine + * @vmOp : The VM operation (i.e., create, no-op) + * + * Associate a port on a swtich with a profile. This function + * may notify a kernel driver or an external daemon to run + * the setup protocol. If profile parameters were not supplied + * by the user, then this function returns without doing + * anything. + * + * Returns 0 in case of success, < 0 otherwise with error + * having been reported. + */ +int +virNetDevVPortProfileAssociate(const char *macvtap_ifname, + const virNetDevVPortProfilePtr virtPort, + const unsigned char *macvtap_macaddr, + const char *linkdev, + const unsigned char *vmuuid, + enum virNetDevVPortProfileOp vmOp) +{ + int rc = 0; + + VIR_DEBUG("Associating port profile '%p' on link device '%s'", + virtPort, macvtap_ifname); + + VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virNetDevVPortProfileOpTypeToString(vmOp)); + + if (!virtPort || vmOp == VIR_NETDEV_VPORT_PROFILE_OP_NO_OP) + return 0; + + switch (virtPort->virtPortType) { + case VIR_NETDEV_VPORT_PROFILE_NONE: + case VIR_NETDEV_VPORT_PROFILE_LAST: + break; + + case VIR_NETDEV_VPORT_PROFILE_8021QBG: + rc = virNetDevVPortProfileOp8021Qbg(macvtap_ifname, macvtap_macaddr, + virtPort, + (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START) + ? PREASSOCIATE + : ASSOCIATE); + break; + + case VIR_NETDEV_VPORT_PROFILE_8021QBH: + rc = virNetDevVPortProfileOp8021Qbh(linkdev, macvtap_macaddr, + virtPort, vmuuid, + (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START) + ? PREASSOCIATE_RR + : ASSOCIATE); + if (vmOp != VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START && !rc) { + /* XXX bogus error handling */ + ignore_value(virNetDevSetOnline(linkdev, true)); + } + + break; + } + + return rc; +} + + +/** + * virNetDevVPortProfileDisassociate: + * + * @macvtap_ifname: The name of the macvtap device + * @macvtap_macaddr : The MAC address of the macvtap + * @linkdev: The link device in case of macvtap + * @virtPort: point to object holding port profile parameters + * + * Returns 0 in case of success, != 0 otherwise with error + * having been reported. + */ +int +virNetDevVPortProfileDisassociate(const char *macvtap_ifname, + const virNetDevVPortProfilePtr virtPort, + const unsigned char *macvtap_macaddr, + const char *linkdev, + enum virNetDevVPortProfileOp vmOp) +{ + int rc = 0; + + VIR_DEBUG("Disassociating port profile id '%p' on link device '%s' ", + virtPort, macvtap_ifname); + + VIR_DEBUG("%s: VM OPERATION: %s", __FUNCTION__, virNetDevVPortProfileOpTypeToString(vmOp)); + + if (!virtPort) + return 0; + + switch (virtPort->virtPortType) { + case VIR_NETDEV_VPORT_PROFILE_NONE: + case VIR_NETDEV_VPORT_PROFILE_LAST: + break; + + case VIR_NETDEV_VPORT_PROFILE_8021QBG: + rc = virNetDevVPortProfileOp8021Qbg(macvtap_ifname, macvtap_macaddr, + virtPort, DISASSOCIATE); + break; + + case VIR_NETDEV_VPORT_PROFILE_8021QBH: + /* avoid disassociating twice */ + if (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH) + break; + ignore_value(virNetDevSetOnline(linkdev, false)); + rc = virNetDevVPortProfileOp8021Qbh(linkdev, macvtap_macaddr, + virtPort, NULL, DISASSOCIATE); + break; + } + + return rc; +} + +#else /* ! WITH_VIRTUALPORT */ +int virNetDevVPortProfileAssociate(const char *macvtap_ifname ATTRIBUTE_UNUSED, + const virNetDevVPortProfilePtr virtPort ATTRIBUTE_UNUSED, + const unsigned char *macvtap_macaddr ATTRIBUTE_UNUSED, + const char *linkdev ATTRIBUTE_UNUSED, + const unsigned char *vmuuid ATTRIBUTE_UNUSED, + enum virNetDevVPortProfileOp vmOp ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Virtual port profile association not supported on this platform")); + return -1; +} + +int virNetDevVPortProfileDisassociate(const char *macvtap_ifname ATTRIBUTE_UNUSED, + const virNetDevVPortProfilePtr virtPort ATTRIBUTE_UNUSED, + const unsigned char *macvtap_macaddr ATTRIBUTE_UNUSED, + const char *linkdev ATTRIBUTE_UNUSED, + enum virNetDevVPortProfileOp vmOp ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Virtual port profile association not supported on this platform")); + return -1; +} +#endif /* ! WITH_VIRTUALPORT */ diff --git a/src/util/virnetdevvportprofile.h b/src/util/virnetdevvportprofile.h index 3e6887e..19f6db5 100644 --- a/src/util/virnetdevvportprofile.h +++ b/src/util/virnetdevvportprofile.h @@ -36,9 +36,22 @@ enum virNetDevVPortProfile { VIR_NETDEV_VPORT_PROFILE_LAST, }; - VIR_ENUM_DECL(virNetDevVPort) +enum virNetDevVPortProfileOp { + VIR_NETDEV_VPORT_PROFILE_OP_CREATE, + VIR_NETDEV_VPORT_PROFILE_OP_SAVE, + VIR_NETDEV_VPORT_PROFILE_OP_RESTORE, + VIR_NETDEV_VPORT_PROFILE_OP_DESTROY, + VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_OUT, + VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START, + VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH, + VIR_NETDEV_VPORT_PROFILE_OP_NO_OP, + + VIR_NETDEV_VPORT_PROFILE_OP_LAST +}; +VIR_ENUM_DECL(virNetDevVPortProfileOp) + /* profile data for macvtap (VEPA) */ typedef struct _virNetDevVPortProfile virNetDevVPortProfile; typedef virNetDevVPortProfile *virNetDevVPortProfilePtr; @@ -61,4 +74,22 @@ struct _virNetDevVPortProfile { bool virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, virNetDevVPortProfilePtr b); +int virNetDevVPortProfileAssociate(const char *ifname, + const virNetDevVPortProfilePtr virtPort, + const unsigned char *macaddr, + const char *linkdev, + const unsigned char *vmuuid, + enum virNetDevVPortProfileOp vmOp) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) + ATTRIBUTE_NONNULL(5) ATTRIBUTE_RETURN_CHECK; + +int virNetDevVPortProfileDisassociate(const char *ifname, + const virNetDevVPortProfilePtr virtPort, + const unsigned char *macaddr, + const char *linkdev, + enum virNetDevVPortProfileOp vmOp) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) + ATTRIBUTE_RETURN_CHECK; + + #endif /* __VIR_NETDEV_VPORT_PROFILE_H__ */ -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Rename virNetDevMacVLanCreate to virNetDevMacVLanCreateWithVPortProfile and virNetDevMacVLanDelete to virNetDevMacVLanDeleteWithVPortProfile To make way for renaming the other macvlan creation APIs in interface.c * util/virnetdevmacvlan.c, util/virnetdevmacvlan.h, qemu/qemu_command.c, qemu/qemu_hotplug.c, qemu/qemu_process.c: Rename APIs --- src/qemu/qemu_command.c | 28 +++++++++-------- src/qemu/qemu_hotplug.c | 11 +++--- src/qemu/qemu_process.c | 11 +++--- src/util/virnetdevmacvlan.c | 72 +++++++++++++++++++++--------------------- src/util/virnetdevmacvlan.h | 34 ++++++++++---------- 5 files changed, 80 insertions(+), 76 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 687d284..6df1f83 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -150,14 +150,15 @@ qemuPhysIfaceConnect(virDomainDefPtr def, net->model && STREQ(net->model, "virtio")) vnet_hdr = 1; - rc = virNetDevMacVLanCreate(net->ifname, net->mac, - virDomainNetGetActualDirectDev(net), - virDomainNetGetActualDirectMode(net), - vnet_hdr, def->uuid, - virDomainNetGetActualDirectVirtPortProfile(net), - &res_ifname, - vmop, driver->stateDir, - virDomainNetGetActualBandwidth(net)); + rc = virNetDevMacVLanCreateWithVPortProfile( + net->ifname, net->mac, + virDomainNetGetActualDirectDev(net), + virDomainNetGetActualDirectMode(net), + vnet_hdr, def->uuid, + virDomainNetGetActualDirectVirtPortProfile(net), + &res_ifname, + vmop, driver->stateDir, + virDomainNetGetActualBandwidth(net)); if (rc >= 0) { virDomainAuditNetDevice(def, net, res_ifname, true); VIR_FREE(net->ifname); @@ -177,11 +178,12 @@ qemuPhysIfaceConnect(virDomainDefPtr def, err = virDomainConfNWFilterInstantiate(conn, net); if (err) { VIR_FORCE_CLOSE(rc); - ignore_value(virNetDevMacVLanDelete(net->ifname, net->mac, - virDomainNetGetActualDirectDev(net), - virDomainNetGetActualDirectMode(net), - virDomainNetGetActualDirectVirtPortProfile(net), - driver->stateDir)); + ignore_value(virNetDevMacVLanDeleteWithVPortProfile( + net->ifname, net->mac, + virDomainNetGetActualDirectDev(net), + virDomainNetGetActualDirectMode(net), + virDomainNetGetActualDirectVirtPortProfile(net), + driver->stateDir)); VIR_FREE(net->ifname); } } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index f9365fe..5c64482 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1910,11 +1910,12 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver, virDomainConfNWFilterTeardown(detach); if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_DIRECT) { - ignore_value(virNetDevMacVLanDelete(detach->ifname, detach->mac, - virDomainNetGetActualDirectDev(detach), - virDomainNetGetActualDirectMode(detach), - virDomainNetGetActualDirectVirtPortProfile(detach), - driver->stateDir)); + ignore_value(virNetDevMacVLanDeleteWithVPortProfile( + detach->ifname, detach->mac, + virDomainNetGetActualDirectDev(detach), + virDomainNetGetActualDirectMode(detach), + virDomainNetGetActualDirectVirtPortProfile(detach), + driver->stateDir)); VIR_FREE(detach->ifname); } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index f4096f8..04fcdef 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3411,11 +3411,12 @@ void qemuProcessStop(struct qemud_driver *driver, for (i = 0; i < def->nnets; i++) { virDomainNetDefPtr net = def->nets[i]; if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) { - ignore_value(virNetDevMacVLanDelete(net->ifname, net->mac, - virDomainNetGetActualDirectDev(net), - virDomainNetGetActualDirectMode(net), - virDomainNetGetActualDirectVirtPortProfile(net), - driver->stateDir)); + ignore_value(virNetDevMacVLanDeleteWithVPortProfile( + net->ifname, net->mac, + virDomainNetGetActualDirectDev(net), + virDomainNetGetActualDirectMode(net), + virDomainNetGetActualDirectVirtPortProfile(net), + driver->stateDir)); VIR_FREE(net->ifname); } /* release the physical device (or any other resources used by diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index ab111f0..a322ece 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -215,7 +215,7 @@ static const uint32_t modeMap[VIR_NETDEV_MACVLAN_MODE_LAST] = { }; /** - * virNetDevMacVLanCreate: + * virNetDevMacVLanCreateWithVPortProfile: * Create an instance of a macvtap device and open its tap character * device. * @tgifname: Interface name that the macvtap is supposed to have. May @@ -234,17 +234,17 @@ static const uint32_t modeMap[VIR_NETDEV_MACVLAN_MODE_LAST] = { * negative value otherwise with error reported. * */ -int virNetDevMacVLanCreate(const char *tgifname, - const unsigned char *macaddress, - const char *linkdev, - enum virNetDevMacVLanMode mode, - int vnet_hdr, - const unsigned char *vmuuid, - virNetDevVPortProfilePtr virtPortProfile, - char **res_ifname, - enum virNetDevVPortProfileOp vmOp, - char *stateDir, - virNetDevBandwidthPtr bandwidth) +int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname, + const unsigned char *macaddress, + const char *linkdev, + enum virNetDevMacVLanMode mode, + int vnet_hdr, + const unsigned char *vmuuid, + virNetDevVPortProfilePtr virtPortProfile, + char **res_ifname, + enum virNetDevVPortProfileOp vmOp, + char *stateDir, + virNetDevBandwidthPtr bandwidth) { const char *type = "macvtap"; int c, rc; @@ -357,7 +357,7 @@ link_del_exit: /** - * delMacvtap: + * virNetDevMacVLanDeleteWithVPortProfile: * @ifname : The name of the macvtap interface * @linkdev: The interface name of the NIC to connect to the external bridge * @virtPortProfile: pointer to object holding the virtual port profile data @@ -366,12 +366,12 @@ link_del_exit: * it with the switch if port profile parameters * were provided. */ -int virNetDevMacVLanDelete(const char *ifname, - const unsigned char *macaddr, - const char *linkdev, - int mode, - virNetDevVPortProfilePtr virtPortProfile, - char *stateDir) +int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname, + const unsigned char *macaddr, + const char *linkdev, + int mode, + virNetDevVPortProfilePtr virtPortProfile, + char *stateDir) { int ret = 0; if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { @@ -392,29 +392,29 @@ int virNetDevMacVLanDelete(const char *ifname, } #else /* ! WITH_MACVTAP */ -int virNetDevMacVLanCreate(const char *ifname ATTRIBUTE_UNUSED, - const unsigned char *macaddress ATTRIBUTE_UNUSED, - const char *linkdev ATTRIBUTE_UNUSED, - enum virNetDevMacVLanMode mode ATTRIBUTE_UNUSED, - int vnet_hdr ATTRIBUTE_UNUSED, - const unsigned char *vmuuid ATTRIBUTE_UNUSED, - virNetDevVPortProfilePtr virtPortProfile ATTRIBUTE_UNUSED, - char **res_ifname ATTRIBUTE_UNUSED, - enum virNetDevVPortProfileOp vmop ATTRIBUTE_UNUSED, - char *stateDir ATTRIBUTE_UNUSED, - virNetDevBandwidthPtr bandwidth ATTRIBUTE_UNUSED) +int virNetDevMacVLanCreateWithVPortProfile(const char *ifname ATTRIBUTE_UNUSED, + const unsigned char *macaddress ATTRIBUTE_UNUSED, + const char *linkdev ATTRIBUTE_UNUSED, + enum virNetDevMacVLanMode mode ATTRIBUTE_UNUSED, + int vnet_hdr ATTRIBUTE_UNUSED, + const unsigned char *vmuuid ATTRIBUTE_UNUSED, + virNetDevVPortProfilePtr virtPortProfile ATTRIBUTE_UNUSED, + char **res_ifname ATTRIBUTE_UNUSED, + enum virNetDevVPortProfileOp vmop ATTRIBUTE_UNUSED, + char *stateDir ATTRIBUTE_UNUSED, + virNetDevBandwidthPtr bandwidth ATTRIBUTE_UNUSED) { virReportSystemError(ENOSYS, "%s", _("Cannot create macvlan devices on this platform")); return -1; } -int virNetDevMacVLanDelete(const char *ifname ATTRIBUTE_UNUSED, - const unsigned char *macaddress ATTRIBUTE_UNUSED, - const char *linkdev ATTRIBUTE_UNUSED, - int mode ATTRIBUTE_UNUSED, - virNetDevVPortProfilePtr virtPortProfile ATTRIBUTE_UNUSED, - char *stateDir ATTRIBUTE_UNUSED) +int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname ATTRIBUTE_UNUSED, + const unsigned char *macaddress ATTRIBUTE_UNUSED, + const char *linkdev ATTRIBUTE_UNUSED, + int mode ATTRIBUTE_UNUSED, + virNetDevVPortProfilePtr virtPortProfile ATTRIBUTE_UNUSED, + char *stateDir ATTRIBUTE_UNUSED) { virReportSystemError(ENOSYS, "%s", _("Cannot create macvlan devices on this platform")); diff --git a/src/util/virnetdevmacvlan.h b/src/util/virnetdevmacvlan.h index f3277f9..9498f7b 100644 --- a/src/util/virnetdevmacvlan.h +++ b/src/util/virnetdevmacvlan.h @@ -39,26 +39,26 @@ enum virNetDevMacVLanMode { }; VIR_ENUM_DECL(virNetDevMacVLanMode) -int virNetDevMacVLanCreate(const char *ifname, - const unsigned char *macaddress, - const char *linkdev, - enum virNetDevMacVLanMode mode, - int vnet_hdr, - const unsigned char *vmuuid, - virNetDevVPortProfilePtr virtPortProfile, - char **res_ifname, - enum virNetDevVPortProfileOp vmop, - char *stateDir, - virNetDevBandwidthPtr bandwidth) +int virNetDevMacVLanCreateWithVPortProfile(const char *ifname, + const unsigned char *macaddress, + const char *linkdev, + enum virNetDevMacVLanMode mode, + int vnet_hdr, + const unsigned char *vmuuid, + virNetDevVPortProfilePtr virtPortProfile, + char **res_ifname, + enum virNetDevVPortProfileOp vmop, + char *stateDir, + virNetDevBandwidthPtr bandwidth) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(6) ATTRIBUTE_NONNULL(8) ATTRIBUTE_NONNULL(10) ATTRIBUTE_RETURN_CHECK; -int virNetDevMacVLanDelete(const char *ifname, - const unsigned char *macaddress, - const char *linkdev, - int mode, - virNetDevVPortProfilePtr virtPortProfile, - char *stateDir) +int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname, + const unsigned char *macaddress, + const char *linkdev, + int mode, + virNetDevVPortProfilePtr virtPortProfile, + char *stateDir) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(6) ATTRIBUTE_RETURN_CHECK; -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Rename ifaceMacvtapLinkAdd to virNetDevMacVLanCreate and ifaceLinkDel to virNetDevMacVLanDelete. Strictly speaking the latter isn't restricted to macvlan devices, but that's the only use libvirt has for it. * util/interface.c, util/interface.h, util/virnetdevmacvlan.c: Rename APIs --- src/libvirt_private.syms | 4 ++-- src/util/interface.c | 41 ++++++++++++++++++----------------------- src/util/interface.h | 19 +++++++++++-------- src/util/virnetdevmacvlan.c | 12 ++++++------ 4 files changed, 37 insertions(+), 39 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 85f4064..27a9fdf 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -583,8 +583,8 @@ ifaceGetPhysicalFunction; ifaceGetVirtualFunctionIndex; ifaceGetVlanID; ifaceIsVirtualFunction; -ifaceLinkDel; -ifaceMacvtapLinkAdd; +virNetDevMacVLanCreate; +virNetDevMacVLanDelete; ifaceMacvtapLinkDump; ifaceReplaceMacAddress; ifaceRestoreMacAddress; diff --git a/src/util/interface.c b/src/util/interface.c index 63e6bf7..a1c56f5 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -313,12 +313,11 @@ ifaceGetIPAddress(const char *ifname ATTRIBUTE_UNUSED, #endif /* __linux__ */ /** - * ifaceLinkAdd + * virNetDevMacVLanCreate: * + * @ifname: The name the interface is supposed to have; optional parameter * @type: The type of device, i.e., "macvtap" * @macaddress: The MAC address of the device - * @macaddrsize: The size of the MAC address, typically '6' - * @ifname: The name the interface is supposed to have; optional parameter * @srcdev: The name of the 'link' device * @macvlan_mode: The macvlan mode to use * @retry: Pointer to integer that will be '1' upon return if an interface @@ -331,12 +330,12 @@ ifaceGetIPAddress(const char *ifname ATTRIBUTE_UNUSED, */ #if defined(__linux__) && WITH_MACVTAP int -ifaceMacvtapLinkAdd(const char *type, - const unsigned char *macaddress, int macaddrsize, - const char *ifname, - const char *srcdev, - uint32_t macvlan_mode, - int *retry) +virNetDevMacVLanCreate(const char *ifname, + const char *type, + const unsigned char *macaddress, + const char *srcdev, + uint32_t macvlan_mode, + int *retry) { int rc = 0; struct nlmsghdr *resp; @@ -366,7 +365,7 @@ ifaceMacvtapLinkAdd(const char *type, if (nla_put_u32(nl_msg, IFLA_LINK, ifindex) < 0) goto buffer_too_small; - if (nla_put(nl_msg, IFLA_ADDRESS, macaddrsize, macaddress) < 0) + if (nla_put(nl_msg, IFLA_ADDRESS, VIR_MAC_BUFLEN, macaddress) < 0) goto buffer_too_small; if (ifname && @@ -458,14 +457,12 @@ buffer_too_small: #else -int -ifaceMacvtapLinkAdd(const char *type ATTRIBUTE_UNUSED, - const unsigned char *macaddress ATTRIBUTE_UNUSED, - int macaddrsize ATTRIBUTE_UNUSED, - const char *ifname ATTRIBUTE_UNUSED, - const char *srcdev ATTRIBUTE_UNUSED, - uint32_t macvlan_mode ATTRIBUTE_UNUSED, - int *retry ATTRIBUTE_UNUSED) +int virNetDevMacVLanCreate(const char *ifname ATTRIBUTE_UNUSED, + const char *type ATTRIBUTE_UNUSED, + const unsigned char *macaddress ATTRIBUTE_UNUSED, + const char *srcdev ATTRIBUTE_UNUSED, + uint32_t macvlan_mode ATTRIBUTE_UNUSED, + int *retry ATTRIBUTE_UNUSED) { ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", # if defined(__linux__) && !WITH_MACVTAP @@ -483,7 +480,7 @@ ifaceMacvtapLinkAdd(const char *type ATTRIBUTE_UNUSED, /** - * ifaceLinkDel + * virNetDevMacVLanDelete: * * @ifname: Name of the interface * @@ -492,8 +489,7 @@ ifaceMacvtapLinkAdd(const char *type ATTRIBUTE_UNUSED, * Returns 0 on success, -1 on fatal error. */ #if defined( __linux__) && WITH_MACVTAP -int -ifaceLinkDel(const char *ifname) +int virNetDevMacVLanDelete(const char *ifname) { int rc = 0; struct nlmsghdr *resp; @@ -572,8 +568,7 @@ buffer_too_small: #else -int -ifaceLinkDel(const char *ifname ATTRIBUTE_UNUSED) +int virNetDevMacVLanDelete(const char *ifname ATTRIBUTE_UNUSED) { ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", # if defined(__linux__) && !WITH_MACVTAP diff --git a/src/util/interface.h b/src/util/interface.h index 4adc601..a62f26a 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -39,14 +39,17 @@ int ifaceGetVlanID(const char *vlanifname, int *vlanid); int ifaceGetIPAddress(const char *ifname, virSocketAddrPtr addr); -int ifaceMacvtapLinkAdd(const char *type, - const unsigned char *macaddress, int macaddrsize, - const char *ifname, - const char *srcdev, - uint32_t macvlan_mode, - int *retry); - -int ifaceLinkDel(const char *ifname); +int virNetDevMacVLanCreate(const char *ifname, + const char *type, + const unsigned char *macaddress, + const char *srcdev, + uint32_t macvlan_mode, + int *retry) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) + ATTRIBUTE_RETURN_CHECK; + +int virNetDevMacVLanDelete(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, struct nlattr **tb, unsigned char **recvbuf, diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index a322ece..ab552af 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -284,8 +284,8 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname, return -1; } cr_ifname = tgifname; - rc = ifaceMacvtapLinkAdd(type, macaddress, 6, tgifname, linkdev, - macvtapMode, &do_retry); + rc = virNetDevMacVLanCreate(tgifname, type, macaddress, linkdev, + macvtapMode, &do_retry); if (rc < 0) return -1; } else { @@ -294,8 +294,8 @@ create_name: for (c = 0; c < 8192; c++) { snprintf(ifname, sizeof(ifname), MACVTAP_NAME_PATTERN, c); if (ifaceGetIndex(false, ifname, &ifindex) == -ENODEV) { - rc = ifaceMacvtapLinkAdd(type, macaddress, 6, ifname, linkdev, - macvtapMode, &do_retry); + rc = virNetDevMacVLanCreate(ifname, type, macaddress, linkdev, + macvtapMode, &do_retry); if (rc == 0) break; @@ -350,7 +350,7 @@ disassociate_exit: vmOp)); link_del_exit: - ifaceLinkDel(cr_ifname); + ignore_value(virNetDevMacVLanDelete(cr_ifname)); return rc; } @@ -385,7 +385,7 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname, linkdev, VIR_NETDEV_VPORT_PROFILE_OP_DESTROY) < 0) ret = -1; - if (ifaceLinkDel(ifname) < 0) + if (virNetDevMacVLanDelete(ifname) < 0) ret = -1; } return ret; -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Move the low level macvlan creation APIs into the virnetdevmacvlan.c file where they more naturally belong * util/interface.c, util/interface.h: Remove virNetDevMacVLanCreate and virNetDevMacVLanDelete * util/virnetdevmacvlan.c, util/virnetdevmacvlan.h: Add virNetDevMacVLanCreate and virNetDevMacVLanDelete --- src/util/interface.c | 270 ------------------------------------------- src/util/interface.h | 12 -- src/util/virnetdevmacvlan.c | 254 ++++++++++++++++++++++++++++++++++++++++- src/util/virnetdevmacvlan.h | 12 ++ 4 files changed, 263 insertions(+), 285 deletions(-) diff --git a/src/util/interface.c b/src/util/interface.c index a1c56f5..e757c6f 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -312,276 +312,6 @@ ifaceGetIPAddress(const char *ifname ATTRIBUTE_UNUSED, #endif /* __linux__ */ -/** - * virNetDevMacVLanCreate: - * - * @ifname: The name the interface is supposed to have; optional parameter - * @type: The type of device, i.e., "macvtap" - * @macaddress: The MAC address of the device - * @srcdev: The name of the 'link' device - * @macvlan_mode: The macvlan mode to use - * @retry: Pointer to integer that will be '1' upon return if an interface - * with the same name already exists and it is worth to try - * again with a different name - * - * Create a macvtap device with the given properties. - * - * Returns 0 on success, -1 on fatal error. - */ -#if defined(__linux__) && WITH_MACVTAP -int -virNetDevMacVLanCreate(const char *ifname, - const char *type, - const unsigned char *macaddress, - const char *srcdev, - uint32_t macvlan_mode, - int *retry) -{ - int rc = 0; - struct nlmsghdr *resp; - struct nlmsgerr *err; - struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC }; - int ifindex; - unsigned char *recvbuf = NULL; - unsigned int recvbuflen; - struct nl_msg *nl_msg; - struct nlattr *linkinfo, *info_data; - - if (ifaceGetIndex(true, srcdev, &ifindex) < 0) - return -1; - - *retry = 0; - - nl_msg = nlmsg_alloc_simple(RTM_NEWLINK, - NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); - if (!nl_msg) { - virReportOOMError(); - return -1; - } - - if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) - goto buffer_too_small; - - if (nla_put_u32(nl_msg, IFLA_LINK, ifindex) < 0) - goto buffer_too_small; - - if (nla_put(nl_msg, IFLA_ADDRESS, VIR_MAC_BUFLEN, macaddress) < 0) - goto buffer_too_small; - - if (ifname && - nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) - goto buffer_too_small; - - if (!(linkinfo = nla_nest_start(nl_msg, IFLA_LINKINFO))) - goto buffer_too_small; - - if (nla_put(nl_msg, IFLA_INFO_KIND, strlen(type), type) < 0) - goto buffer_too_small; - - if (macvlan_mode > 0) { - if (!(info_data = nla_nest_start(nl_msg, IFLA_INFO_DATA))) - goto buffer_too_small; - - if (nla_put(nl_msg, IFLA_MACVLAN_MODE, sizeof(macvlan_mode), - &macvlan_mode) < 0) - goto buffer_too_small; - - nla_nest_end(nl_msg, info_data); - } - - nla_nest_end(nl_msg, linkinfo); - - if (nlComm(nl_msg, &recvbuf, &recvbuflen, 0) < 0) { - rc = -1; - goto cleanup; - } - - if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL) - goto malformed_resp; - - resp = (struct nlmsghdr *)recvbuf; - - switch (resp->nlmsg_type) { - case NLMSG_ERROR: - err = (struct nlmsgerr *)NLMSG_DATA(resp); - if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) - goto malformed_resp; - - switch (err->error) { - - case 0: - break; - - case -EEXIST: - *retry = 1; - rc = -1; - break; - - default: - virReportSystemError(-err->error, - _("error creating %s type of interface"), - type); - rc = -1; - } - break; - - case NLMSG_DONE: - break; - - default: - goto malformed_resp; - } - -cleanup: - nlmsg_free(nl_msg); - - VIR_FREE(recvbuf); - - return rc; - -malformed_resp: - nlmsg_free(nl_msg); - - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("malformed netlink response message")); - VIR_FREE(recvbuf); - return -1; - -buffer_too_small: - nlmsg_free(nl_msg); - - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("allocated netlink buffer is too small")); - return -1; -} - -#else - -int virNetDevMacVLanCreate(const char *ifname ATTRIBUTE_UNUSED, - const char *type ATTRIBUTE_UNUSED, - const unsigned char *macaddress ATTRIBUTE_UNUSED, - const char *srcdev ATTRIBUTE_UNUSED, - uint32_t macvlan_mode ATTRIBUTE_UNUSED, - int *retry ATTRIBUTE_UNUSED) -{ - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", -# if defined(__linux__) && !WITH_MACVTAP - _("ifaceMacvtapLinkAdd is not supported since the include " - "files were too old")); -# else - _("ifaceMacvtapLinkAdd is not supported on non-linux " - "platforms")); -# endif - - return -1; -} - -#endif - - -/** - * virNetDevMacVLanDelete: - * - * @ifname: Name of the interface - * - * Tear down an interface with the given name. - * - * Returns 0 on success, -1 on fatal error. - */ -#if defined( __linux__) && WITH_MACVTAP -int virNetDevMacVLanDelete(const char *ifname) -{ - int rc = 0; - struct nlmsghdr *resp; - struct nlmsgerr *err; - struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC }; - unsigned char *recvbuf = NULL; - unsigned int recvbuflen; - struct nl_msg *nl_msg; - - nl_msg = nlmsg_alloc_simple(RTM_DELLINK, - NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); - if (!nl_msg) { - virReportOOMError(); - return -1; - } - - if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) - goto buffer_too_small; - - if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) - goto buffer_too_small; - - if (nlComm(nl_msg, &recvbuf, &recvbuflen, 0) < 0) { - rc = -1; - goto cleanup; - } - - if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL) - goto malformed_resp; - - resp = (struct nlmsghdr *)recvbuf; - - switch (resp->nlmsg_type) { - case NLMSG_ERROR: - err = (struct nlmsgerr *)NLMSG_DATA(resp); - if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) - goto malformed_resp; - - if (err->error) { - virReportSystemError(-err->error, - _("error destroying %s interface"), - ifname); - rc = -1; - } - break; - - case NLMSG_DONE: - break; - - default: - goto malformed_resp; - } - -cleanup: - nlmsg_free(nl_msg); - - VIR_FREE(recvbuf); - - return rc; - -malformed_resp: - nlmsg_free(nl_msg); - - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("malformed netlink response message")); - VIR_FREE(recvbuf); - return -1; - -buffer_too_small: - nlmsg_free(nl_msg); - - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("allocated netlink buffer is too small")); - return -1; -} - -#else - -int virNetDevMacVLanDelete(const char *ifname ATTRIBUTE_UNUSED) -{ - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", -# if defined(__linux__) && !WITH_MACVTAP - _("ifaceLinkDel is not supported since the include files " - "were too old")); -# else - _("ifaceLinkDel is not supported on non-linux platforms")); -# endif - return -1; -} - -#endif - #if defined(__linux__) && defined(IFLA_PORT_MAX) diff --git a/src/util/interface.h b/src/util/interface.h index a62f26a..1dd8f35 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -39,18 +39,6 @@ int ifaceGetVlanID(const char *vlanifname, int *vlanid); int ifaceGetIPAddress(const char *ifname, virSocketAddrPtr addr); -int virNetDevMacVLanCreate(const char *ifname, - const char *type, - const unsigned char *macaddress, - const char *srcdev, - uint32_t macvlan_mode, - int *retry) - ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) - ATTRIBUTE_RETURN_CHECK; - -int virNetDevMacVLanDelete(const char *ifname) - 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/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index ab552af..a4bad18 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -74,6 +74,235 @@ VIR_ENUM_IMPL(virNetDevMacVLanMode, VIR_NETDEV_MACVLAN_MODE_LAST, # define MACVTAP_NAME_PATTERN "macvtap%d" /** + * virNetDevMacVLanCreate: + * + * @ifname: The name the interface is supposed to have; optional parameter + * @type: The type of device, i.e., "macvtap" + * @macaddress: The MAC address of the device + * @srcdev: The name of the 'link' device + * @macvlan_mode: The macvlan mode to use + * @retry: Pointer to integer that will be '1' upon return if an interface + * with the same name already exists and it is worth to try + * again with a different name + * + * Create a macvtap device with the given properties. + * + * Returns 0 on success, -1 on fatal error. + */ +int +virNetDevMacVLanCreate(const char *ifname, + const char *type, + const unsigned char *macaddress, + const char *srcdev, + uint32_t macvlan_mode, + int *retry) +{ + int rc = 0; + struct nlmsghdr *resp; + struct nlmsgerr *err; + struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC }; + int ifindex; + unsigned char *recvbuf = NULL; + unsigned int recvbuflen; + struct nl_msg *nl_msg; + struct nlattr *linkinfo, *info_data; + + if (ifaceGetIndex(true, srcdev, &ifindex) < 0) + return -1; + + *retry = 0; + + nl_msg = nlmsg_alloc_simple(RTM_NEWLINK, + NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); + if (!nl_msg) { + virReportOOMError(); + return -1; + } + + if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) + goto buffer_too_small; + + if (nla_put_u32(nl_msg, IFLA_LINK, ifindex) < 0) + goto buffer_too_small; + + if (nla_put(nl_msg, IFLA_ADDRESS, VIR_MAC_BUFLEN, macaddress) < 0) + goto buffer_too_small; + + if (ifname && + nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) + goto buffer_too_small; + + if (!(linkinfo = nla_nest_start(nl_msg, IFLA_LINKINFO))) + goto buffer_too_small; + + if (nla_put(nl_msg, IFLA_INFO_KIND, strlen(type), type) < 0) + goto buffer_too_small; + + if (macvlan_mode > 0) { + if (!(info_data = nla_nest_start(nl_msg, IFLA_INFO_DATA))) + goto buffer_too_small; + + if (nla_put(nl_msg, IFLA_MACVLAN_MODE, sizeof(macvlan_mode), + &macvlan_mode) < 0) + goto buffer_too_small; + + nla_nest_end(nl_msg, info_data); + } + + nla_nest_end(nl_msg, linkinfo); + + if (nlComm(nl_msg, &recvbuf, &recvbuflen, 0) < 0) { + rc = -1; + goto cleanup; + } + + if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL) + goto malformed_resp; + + resp = (struct nlmsghdr *)recvbuf; + + switch (resp->nlmsg_type) { + case NLMSG_ERROR: + err = (struct nlmsgerr *)NLMSG_DATA(resp); + if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) + goto malformed_resp; + + switch (err->error) { + + case 0: + break; + + case -EEXIST: + *retry = 1; + rc = -1; + break; + + default: + virReportSystemError(-err->error, + _("error creating %s type of interface"), + type); + rc = -1; + } + break; + + case NLMSG_DONE: + break; + + default: + goto malformed_resp; + } + +cleanup: + nlmsg_free(nl_msg); + + VIR_FREE(recvbuf); + + return rc; + +malformed_resp: + nlmsg_free(nl_msg); + + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("malformed netlink response message")); + VIR_FREE(recvbuf); + return -1; + +buffer_too_small: + nlmsg_free(nl_msg); + + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("allocated netlink buffer is too small")); + return -1; +} + +/** + * virNetDevMacVLanDelete: + * + * @ifname: Name of the interface + * + * Tear down an interface with the given name. + * + * Returns 0 on success, -1 on fatal error. + */ +int virNetDevMacVLanDelete(const char *ifname) +{ + int rc = 0; + struct nlmsghdr *resp; + struct nlmsgerr *err; + struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC }; + unsigned char *recvbuf = NULL; + unsigned int recvbuflen; + struct nl_msg *nl_msg; + + nl_msg = nlmsg_alloc_simple(RTM_DELLINK, + NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); + if (!nl_msg) { + virReportOOMError(); + return -1; + } + + if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) + goto buffer_too_small; + + if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) + goto buffer_too_small; + + if (nlComm(nl_msg, &recvbuf, &recvbuflen, 0) < 0) { + rc = -1; + goto cleanup; + } + + if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL) + goto malformed_resp; + + resp = (struct nlmsghdr *)recvbuf; + + switch (resp->nlmsg_type) { + case NLMSG_ERROR: + err = (struct nlmsgerr *)NLMSG_DATA(resp); + if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) + goto malformed_resp; + + if (err->error) { + virReportSystemError(-err->error, + _("error destroying %s interface"), + ifname); + rc = -1; + } + break; + + case NLMSG_DONE: + break; + + default: + goto malformed_resp; + } + +cleanup: + nlmsg_free(nl_msg); + + VIR_FREE(recvbuf); + + return rc; + +malformed_resp: + nlmsg_free(nl_msg); + + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("malformed netlink response message")); + VIR_FREE(recvbuf); + return -1; + +buffer_too_small: + nlmsg_free(nl_msg); + + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("allocated netlink buffer is too small")); + return -1; +} + + +/** * virNetDevMacVLanTapOpen: * Open the macvtap's tap device. * @ifname: Name of the macvtap interface @@ -332,9 +561,9 @@ create_name: goto disassociate_exit; if (virNetDevBandwidthSet(cr_ifname, bandwidth) < 0) { - macvtapError(VIR_ERR_INTERNAL_ERROR, - _("cannot set bandwidth limits on %s"), - cr_ifname); + virNetDevError(VIR_ERR_INTERNAL_ERROR, + _("cannot set bandwidth limits on %s"), + cr_ifname); rc = -1; goto disassociate_exit; } @@ -392,6 +621,25 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname, } #else /* ! WITH_MACVTAP */ +int virNetDevMacVLanCreate(const char *ifname ATTRIBUTE_UNUSED, + const char *type ATTRIBUTE_UNUSED, + const unsigned char *macaddress ATTRIBUTE_UNUSED, + const char *srcdev ATTRIBUTE_UNUSED, + uint32_t macvlan_mode ATTRIBUTE_UNUSED, + int *retry ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Cannot create macvlan devices on this platform")); + return -1; +} + +int virNetDevMacVLanDelete(const char *ifname ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Cannot create macvlan devices on this platform")); + return -1; +} + int virNetDevMacVLanCreateWithVPortProfile(const char *ifname ATTRIBUTE_UNUSED, const unsigned char *macaddress ATTRIBUTE_UNUSED, const char *linkdev ATTRIBUTE_UNUSED, diff --git a/src/util/virnetdevmacvlan.h b/src/util/virnetdevmacvlan.h index 9498f7b..73918b8 100644 --- a/src/util/virnetdevmacvlan.h +++ b/src/util/virnetdevmacvlan.h @@ -39,6 +39,18 @@ enum virNetDevMacVLanMode { }; VIR_ENUM_DECL(virNetDevMacVLanMode) +int virNetDevMacVLanCreate(const char *ifname, + const char *type, + const unsigned char *macaddress, + const char *srcdev, + uint32_t macvlan_mode, + int *retry) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) + ATTRIBUTE_RETURN_CHECK; + +int virNetDevMacVLanDelete(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + int virNetDevMacVLanCreateWithVPortProfile(const char *ifname, const unsigned char *macaddress, const char *linkdev, -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Rename ifaceReplaceMacAddress to virNetDevReplaceMacAddress and ifaceRestoreMacAddress to virNetDevRestoreMacAddress. * util/interface.c, util/interface.h, util/virnetdevmacvlan.c: Rename APIs --- src/libvirt_private.syms | 4 ++-- src/util/interface.c | 14 +++++++------- src/util/interface.h | 15 +++++++++------ src/util/virnetdevmacvlan.c | 5 ++--- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 27a9fdf..9706efc 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -586,8 +586,8 @@ ifaceIsVirtualFunction; virNetDevMacVLanCreate; virNetDevMacVLanDelete; ifaceMacvtapLinkDump; -ifaceReplaceMacAddress; -ifaceRestoreMacAddress; +virNetDevReplaceMacAddress; +virNetDevRestoreMacAddress; # interface_conf.h diff --git a/src/util/interface.c b/src/util/interface.c index e757c6f..df2aa88 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -554,7 +554,7 @@ ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, #endif /** - * ifaceReplaceMacAddress: + * virNetDevReplaceMacAddress: * @macaddress: new MAC address for interface * @linkdev: name of interface * @stateDir: directory to store old MAC address @@ -563,9 +563,9 @@ ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, * */ int -ifaceReplaceMacAddress(const unsigned char *macaddress, - const char *linkdev, - const char *stateDir) +virNetDevReplaceMacAddress(const char *linkdev, + const unsigned char *macaddress, + const char *stateDir) { unsigned char oldmac[6]; char *path = NULL; @@ -595,7 +595,7 @@ ifaceReplaceMacAddress(const unsigned char *macaddress, } /** - * ifaceRestoreMacAddress: + * virNetDevRestoreMacAddress: * @linkdev: name of interface * @stateDir: directory containing old MAC address * @@ -603,8 +603,8 @@ ifaceReplaceMacAddress(const unsigned char *macaddress, * */ int -ifaceRestoreMacAddress(const char *linkdev, - const char *stateDir) +virNetDevRestoreMacAddress(const char *linkdev, + const char *stateDir) { int rc; char *oldmacname = NULL; diff --git a/src/util/interface.h b/src/util/interface.h index 1dd8f35..6a4631c 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -49,12 +49,15 @@ int ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent, ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6); -int ifaceReplaceMacAddress(const unsigned char *macaddress, - const char *linkdev, - const char *stateDir); - -int ifaceRestoreMacAddress(const char *linkdev, - const char *stateDir); +int virNetDevReplaceMacAddress(const char *linkdev, + const unsigned char *macaddress, + const char *stateDir) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_RETURN_CHECK; + +int virNetDevRestoreMacAddress(const char *linkdev, + const char *stateDir) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int ifaceIsVirtualFunction(const char *ifname); diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index a4bad18..6e09440 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -497,9 +497,8 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname, * emulate their switch in firmware. */ if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { - if (ifaceReplaceMacAddress(macaddress, linkdev, stateDir) < 0) { + if (virNetDevReplaceMacAddress(linkdev, macaddress, stateDir) < 0) return -1; - } } if (tgifname) { @@ -604,7 +603,7 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname, { int ret = 0; if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { - ifaceRestoreMacAddress(linkdev, stateDir); + ignore_value(virNetDevRestoreMacAddress(linkdev, stateDir)); } if (ifname) { -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Move virNetDevReplaceMacAddress and virNetDevRestoreMacAddress to the virnetdev.c file where they naturally belong * util/interface.c, util/interface.h: Remove virNetDevReplaceMacAddress and virNetDevRestoreMacAddress * util/virnetdev.c, util/virnetdev.h: Add virNetDevReplaceMacAddress and virNetDevRestoreMacAddress --- src/util/interface.c | 84 ---------------------------------------------- src/util/interface.h | 10 ----- src/util/virnetdev.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/util/virnetdev.h | 12 ++++++ 4 files changed, 103 insertions(+), 94 deletions(-) diff --git a/src/util/interface.c b/src/util/interface.c index df2aa88..ebe537e 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -553,90 +553,6 @@ ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, #endif -/** - * virNetDevReplaceMacAddress: - * @macaddress: new MAC address for interface - * @linkdev: name of interface - * @stateDir: directory to store old MAC address - * - * Returns 0 on success, -1 on failure - * - */ -int -virNetDevReplaceMacAddress(const char *linkdev, - const unsigned char *macaddress, - const char *stateDir) -{ - unsigned char oldmac[6]; - char *path = NULL; - char macstr[VIR_MAC_STRING_BUFLEN]; - - if (virNetDevGetMAC(linkdev, oldmac) < 0) - return -1; - - - if (virAsprintf(&path, "%s/%s", - stateDir, - linkdev) < 0) { - virReportOOMError(); - return -1; - } - virFormatMacAddr(oldmac, macstr); - if (virFileWriteStr(path, macstr, O_CREAT|O_TRUNC|O_WRONLY) < 0) { - virReportSystemError(errno, _("Unable to preserve mac for %s"), - linkdev); - return -1; - } - - if (virNetDevSetMAC(linkdev, macaddress) < 0) - return -1; - - return 0; -} - -/** - * virNetDevRestoreMacAddress: - * @linkdev: name of interface - * @stateDir: directory containing old MAC address - * - * Returns 0 on success, -errno on failure. - * - */ -int -virNetDevRestoreMacAddress(const char *linkdev, - const char *stateDir) -{ - int rc; - char *oldmacname = NULL; - char *macstr = NULL; - char *path = NULL; - unsigned char oldmac[6]; - - if (virAsprintf(&path, "%s/%s", - stateDir, - linkdev) < 0) { - virReportOOMError(); - return -1; - } - - if (virFileReadAll(path, VIR_MAC_STRING_BUFLEN, &macstr) < 0) - return -1; - - if (virParseMacAddr(macstr, &oldmac[0]) != 0) { - ifaceError(VIR_ERR_INTERNAL_ERROR, - _("Cannot parse MAC address from '%s'"), - oldmacname); - VIR_FREE(macstr); - return -1; - } - - /*reset mac and remove file-ignore results*/ - rc = virNetDevSetMAC(linkdev, oldmac); - ignore_value(unlink(path)); - VIR_FREE(macstr); - - return rc; -} #ifdef __linux__ static int diff --git a/src/util/interface.h b/src/util/interface.h index 6a4631c..e322a21 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -49,16 +49,6 @@ int ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent, ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6); -int virNetDevReplaceMacAddress(const char *linkdev, - const unsigned char *macaddress, - const char *stateDir) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) - ATTRIBUTE_RETURN_CHECK; - -int virNetDevRestoreMacAddress(const char *linkdev, - const char *stateDir) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - int ifaceIsVirtualFunction(const char *ifname); int ifaceGetVirtualFunctionIndex(const char *pfname, const char *vfname, diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 5311ae7..9674391 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -32,8 +32,12 @@ #ifdef HAVE_NET_IF_H # include <net/if.h> #endif +#include <fcntl.h> #define VIR_FROM_THIS VIR_FROM_NONE +#define virNetDevError(code, ...) \ + virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \ + __FUNCTION__, __LINE__, __VA_ARGS__) #ifdef HAVE_NET_IF_H static int virNetDevSetupControlFull(const char *ifname, @@ -223,6 +227,93 @@ int virNetDevGetMAC(const char *ifname, #endif + +/** + * virNetDevReplaceMacAddress: + * @macaddress: new MAC address for interface + * @linkdev: name of interface + * @stateDir: directory to store old MAC address + * + * Returns 0 on success, -1 on failure + * + */ +int +virNetDevReplaceMacAddress(const char *linkdev, + const unsigned char *macaddress, + const char *stateDir) +{ + unsigned char oldmac[6]; + char *path = NULL; + char macstr[VIR_MAC_STRING_BUFLEN]; + + if (virNetDevGetMAC(linkdev, oldmac) < 0) + return -1; + + + if (virAsprintf(&path, "%s/%s", + stateDir, + linkdev) < 0) { + virReportOOMError(); + return -1; + } + virFormatMacAddr(oldmac, macstr); + if (virFileWriteStr(path, macstr, O_CREAT|O_TRUNC|O_WRONLY) < 0) { + virReportSystemError(errno, _("Unable to preserve mac for %s"), + linkdev); + return -1; + } + + if (virNetDevSetMAC(linkdev, macaddress) < 0) + return -1; + + return 0; +} + +/** + * virNetDevRestoreMacAddress: + * @linkdev: name of interface + * @stateDir: directory containing old MAC address + * + * Returns 0 on success, -errno on failure. + * + */ +int +virNetDevRestoreMacAddress(const char *linkdev, + const char *stateDir) +{ + int rc; + char *oldmacname = NULL; + char *macstr = NULL; + char *path = NULL; + unsigned char oldmac[6]; + + if (virAsprintf(&path, "%s/%s", + stateDir, + linkdev) < 0) { + virReportOOMError(); + return -1; + } + + if (virFileReadAll(path, VIR_MAC_STRING_BUFLEN, &macstr) < 0) + return -1; + + if (virParseMacAddr(macstr, &oldmac[0]) != 0) { + virNetDevError(VIR_ERR_INTERNAL_ERROR, + _("Cannot parse MAC address from '%s'"), + oldmacname); + VIR_FREE(macstr); + return -1; + } + + /*reset mac and remove file-ignore results*/ + rc = virNetDevSetMAC(linkdev, oldmac); + ignore_value(unlink(path)); + VIR_FREE(macstr); + + return rc; +} + + #ifdef SIOCGIFMTU /** * virNetDevGetMTU: diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index de98553..f4e0108 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -51,6 +51,18 @@ int virNetDevSetMAC(const char *ifname, int virNetDevGetMAC(const char *ifname, unsigned char *macaddr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int virNetDevReplaceMacAddress(const char *linkdev, + const unsigned char *macaddress, + const char *stateDir) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_RETURN_CHECK; + +int virNetDevRestoreMacAddress(const char *linkdev, + const char *stateDir) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + + int virNetDevSetMTU(const char *ifname, int mtu) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Rename the ifaceGetIndex method to virNetDevGetIndex and ifaceGetVlanID to virNetDevGetVLanID. Also change the error reporting behaviour to always raise errors and return -1 on failure * util/interface.c, util/interface.h: Rename ifaceGetIndex and ifaceGetVLAN * nwfilter/nwfilter_gentech_driver.c, nwfilter/nwfilter_learnipaddr.c, nwfilter/nwfilter_learnipaddr.c, util/virnetdevvportprofile.c: Update for API renames and error handling changes --- src/libvirt_private.syms | 4 +- src/nwfilter/nwfilter_gentech_driver.c | 13 +++-- src/nwfilter/nwfilter_learnipaddr.c | 22 ++++--- src/util/interface.c | 103 ++++++++++++++++---------------- src/util/interface.h | 6 +- src/util/virnetdevmacvlan.c | 17 ++++-- src/util/virnetdevvportprofile.c | 6 +- 7 files changed, 92 insertions(+), 79 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 9706efc..8206b23 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 899bd32..9f44aef 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -903,9 +903,10 @@ _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 (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 +1022,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 +1049,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 68bdcfc..9a51fc2 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); + if (virNetDevGetIndex(ifname, &ifindex) < 0) { + virResetLastError(); + return rc; + } - virMutexLock(&pendingLearnReqLock); + IFINDEX2STR(ifindex_str, ifindex); - req = virHashLookup(pendingLearnReq, ifindex_str); - if (req) { - rc = 0; - req->terminate = true; - } + virMutexLock(&pendingLearnReqLock); - virMutexUnlock(&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 ebe537e..af1def2 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 e322a21..51d5c28 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 6e09440..a832f06 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(tgifname)) < 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 1e826db..3649033 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; -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Move virNetDevGetIndex & virNetDevGetVLanID to virnetdev.c to suit their functional purpose * util/interface.c, util/interface.h: Remove virNetDevGetIndex & virNetDevGetVLanID * util/virnetdev.c, util/virnetdev.h: Add virNetDevGetIndex & virNetDevGetVLanID --- src/nwfilter/nwfilter_learnipaddr.c | 1 + src/util/interface.c | 111 ----------------------------------- src/util/interface.h | 6 -- src/util/virnetdev.c | 109 ++++++++++++++++++++++++++++++++++ src/util/virnetdev.h | 7 ++ 5 files changed, 117 insertions(+), 117 deletions(-) diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c index 9a51fc2..319f317 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -46,6 +46,7 @@ #include "logging.h" #include "datatypes.h" #include "interface.h" +#include "virnetdev.h" #include "virterror_internal.h" #include "threads.h" #include "conf/nwfilter_params.h" diff --git a/src/util/interface.c b/src/util/interface.c index af1def2..9762145 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -142,117 +142,6 @@ ifaceCheck(bool reportError ATTRIBUTE_UNUSED, /** - * 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, -1 on failure - */ -#ifdef __linux__ -int -virNetDevGetIndex(const char *ifname, int *ifindex) -{ - int ret = -1; - struct ifreq ifreq; - int fd = socket(PF_PACKET, SOCK_DGRAM, 0); - - 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) { - virReportSystemError(ERANGE, - _("invalid interface name %s"), - ifname); - goto cleanup; - } - - 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 ret; -} - -#else - -int -virNetDevGetIndex(const char *ifname ATTRIBUTE_UNUSED, - int *ifindex ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", - _("Unable to get interface index on this platform")); - return -1; -} - -#endif /* __linux__ */ - -#ifdef __linux__ -int -virNetDevGetVLanID(const char *ifname, int *vlanid) -{ - struct vlan_ioctl_args vlanargs = { - .cmd = GET_VLAN_VID_CMD, - }; - int ret = -1; - int fd = socket(PF_PACKET, SOCK_DGRAM, 0); - - if (fd < 0) { - virReportSystemError(errno, "%s", - _("Unable to open control socket")); - return -1; - } - - if (virStrcpyStatic(vlanargs.device1, ifname) == NULL) { - virReportSystemError(ERANGE, - _("invalid interface name %s"), - ifname); - goto cleanup; - } - - if (ioctl(fd, SIOCGIFVLAN, &vlanargs) != 0) { - virReportSystemError(errno, - _("Unable to get VLAN for interface %s"), ifname); - goto cleanup; - } - - *vlanid = vlanargs.u.VID; - ret = 0; - - cleanup: - VIR_FORCE_CLOSE(fd); - - return ret; -} - -#else - -int -virNetDevGetVLanID(const char *ifname ATTRIBUTE_UNUSED, - int *vlanid ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", - _("Unable to get VLAN on this platform")); - return -1; -} -#endif /* __linux__ */ - - -/** * ifaceGetIPAddress: * @ifname: name of the interface whose IP address we want * @macaddr: MAC address (VIR_MAC_BUFLEN in size) diff --git a/src/util/interface.h b/src/util/interface.h index 51d5c28..aa70192 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -33,12 +33,6 @@ struct nlattr; int ifaceCheck(bool reportError, const char *ifname, const unsigned char *macaddr, int ifindex); -int virNetDevGetIndex(const char *ifname, int *ifindex) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - -int virNetDevGetVLanID(const char *ifname, int *vlanid) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - int ifaceGetIPAddress(const char *ifname, virSocketAddrPtr addr); int ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 9674391..b25235a 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -34,6 +34,11 @@ #endif #include <fcntl.h> +#ifdef __linux__ +# include <linux/sockios.h> +# include <linux/if_vlan.h> +#endif + #define VIR_FROM_THIS VIR_FROM_NONE #define virNetDevError(code, ...) \ virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \ @@ -612,6 +617,110 @@ int virNetDevIsOnline(const char *ifname, /** + * 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, -1 on failure + */ +#ifdef __linux__ +int virNetDevGetIndex(const char *ifname, int *ifindex) +{ + int ret = -1; + struct ifreq ifreq; + int fd = socket(PF_PACKET, SOCK_DGRAM, 0); + + 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) { + virReportSystemError(ERANGE, + _("invalid interface name %s"), + ifname); + goto cleanup; + } + + 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 ret; +} +#else /* ! __linux__ */ +int virNetDevGetIndex(const char *ifname ATTRIBUTE_UNUSED, + int *ifindex ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to get interface index on this platform")); + return -1; +} +#endif /* ! __linux__ */ + + +#ifdef __linux__ +int virNetDevGetVLanID(const char *ifname, int *vlanid) +{ + struct vlan_ioctl_args vlanargs = { + .cmd = GET_VLAN_VID_CMD, + }; + int ret = -1; + int fd = socket(PF_PACKET, SOCK_DGRAM, 0); + + if (fd < 0) { + virReportSystemError(errno, "%s", + _("Unable to open control socket")); + return -1; + } + + if (virStrcpyStatic(vlanargs.device1, ifname) == NULL) { + virReportSystemError(ERANGE, + _("invalid interface name %s"), + ifname); + goto cleanup; + } + + if (ioctl(fd, SIOCGIFVLAN, &vlanargs) != 0) { + virReportSystemError(errno, + _("Unable to get VLAN for interface %s"), ifname); + goto cleanup; + } + + *vlanid = vlanargs.u.VID; + ret = 0; + + cleanup: + VIR_FORCE_CLOSE(fd); + + return ret; +} +#else /* ! __linux__ */ +int virNetDevGetVLanID(const char *ifname ATTRIBUTE_UNUSED, + int *vlanid ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to get VLAN on this platform")); + return -1; +} +#endif /* ! __linux__ */ + + + +/** * virNetDevSetIPv4Addres: * @ifname: the interface name * @addr: the IP address (IPv4 or IPv6) diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index f4e0108..c89516c 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -76,4 +76,11 @@ int virNetDevSetNamespace(const char *ifname, int pidInNs) int virNetDevSetName(const char *ifname, const char *newifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetIndex(const char *ifname, int *ifindex) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + +int virNetDevGetVLanID(const char *ifname, int *vlanid) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + + #endif /* __VIR_NETDEV_H__ */ -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> To match up with the existing virNetDevSetIPv4Address, rename ifaceGetIPAddress to virNetDevGetIPv4Address * util/interface.h, util/interface.c: Rename API * network/bridge_driver.c: Update for API rename --- src/libvirt_private.syms | 2 +- src/network/bridge_driver.c | 11 +++------ src/util/interface.c | 46 +++++++++++++++++++++++------------------- src/util/interface.h | 3 +- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8206b23..183e4f5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -577,7 +577,7 @@ virHookPresent; # interface.h ifaceCheck; virNetDevGetIndex; -ifaceGetIPAddress; +virNetDevGetIPv4Address; ifaceGetNthParent; ifaceGetPhysicalFunction; ifaceGetVirtualFunctionIndex; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index bad5337..3f8c8c4 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -3147,13 +3147,10 @@ networkGetNetworkAddress(const char *netname, char **netaddr) } if (dev_name) { - if (ifaceGetIPAddress(dev_name, &addr)) { - virReportSystemError(errno, - _("Failed to get IP address for '%s' (network '%s')"), - dev_name, netdef->name); - } else { - addrptr = &addr; - } + if (virNetDevGetIPv4Address(dev_name, &addr) < 0) + goto cleanup; + + addrptr = &addr; } if (addrptr && diff --git a/src/util/interface.c b/src/util/interface.c index 9762145..4e1ee25 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -142,60 +142,64 @@ ifaceCheck(bool reportError ATTRIBUTE_UNUSED, /** - * ifaceGetIPAddress: + * virNetDevGetIPv4Address: * @ifname: name of the interface whose IP address we want - * @macaddr: MAC address (VIR_MAC_BUFLEN in size) + * @addr: filled with the IPv4 address * - * This function gets the @macaddr for a given interface @ifname. + * This function gets the IPv4 address for the interface @ifname + * and stores it in @addr * * Returns 0 on success, -errno on failure. */ #ifdef __linux__ -int -ifaceGetIPAddress(const char *ifname, - virSocketAddrPtr addr) +int virNetDevGetIPv4Address(const char *ifname, + virSocketAddrPtr addr) { struct ifreq ifr; int fd; int rc = 0; - if (!ifname || !addr) - return -EINVAL; - memset (addr, 0, sizeof(*addr)); addr->data.stor.ss_family = AF_UNSPEC; fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) - return -errno; + if (fd < 0) { + virReportSystemError(errno, "%s", + _("Unable to open control socket")); + return -1; + } memset(&ifr, 0, sizeof(struct ifreq)); if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { - rc = -EINVAL; - goto err_exit; + virReportSystemError(ERANGE, + _("invalid interface name %s"), + ifname); + goto cleanup; } - if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) != 0) { - rc = -errno; - goto err_exit; + if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { + virReportSystemError(errno, + _("Unable to get IPv4 address for interface %s"), ifname); + goto cleanup; } addr->data.stor.ss_family = AF_INET; addr->len = sizeof(addr->data.inet4); memcpy(&addr->data.inet4, &ifr.ifr_addr, addr->len); -err_exit: +cleanup: VIR_FORCE_CLOSE(fd); return rc; } #else -int -ifaceGetIPAddress(const char *ifname ATTRIBUTE_UNUSED, - virSocketAddrPtr addr ATTRIBUTE_UNUSED) +int virNetDevGetIPv4Address(const char *ifname ATTRIBUTE_UNUSED, + virSocketAddrPtr addr ATTRIBUTE_UNUSED) { - return -ENOSYS; + virReportSystemError(ENOSYS, "%s", + _("Unable to get IPv4 address on this platform")); + return -1; } #endif /* __linux__ */ diff --git a/src/util/interface.h b/src/util/interface.h index aa70192..0a11ecd 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -33,7 +33,8 @@ struct nlattr; int ifaceCheck(bool reportError, const char *ifname, const unsigned char *macaddr, int ifindex); -int ifaceGetIPAddress(const char *ifname, virSocketAddrPtr addr); +int virNetDevGetIPv4Address(const char *ifname, virSocketAddrPtr addr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, struct nlattr **tb, unsigned char **recvbuf, -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Move the virNetDevGetIPv4Address function to virnetdev.c * util/interface.c, util/interface.h: Remove virNetDevGetIPv4Address * util/virnetdev.c, util/virnetdev.h: Add virNetDevGetIPv4Address --- src/util/interface.c | 63 -------------------------------------------------- src/util/interface.h | 3 -- src/util/virnetdev.c | 53 ++++++++++++++++++++++++++++++++++++++++++ src/util/virnetdev.h | 2 + 4 files changed, 55 insertions(+), 66 deletions(-) diff --git a/src/util/interface.c b/src/util/interface.c index 4e1ee25..e86d183 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -141,69 +141,6 @@ ifaceCheck(bool reportError ATTRIBUTE_UNUSED, #endif /* __linux__ */ -/** - * virNetDevGetIPv4Address: - * @ifname: name of the interface whose IP address we want - * @addr: filled with the IPv4 address - * - * This function gets the IPv4 address for the interface @ifname - * and stores it in @addr - * - * Returns 0 on success, -errno on failure. - */ -#ifdef __linux__ -int virNetDevGetIPv4Address(const char *ifname, - virSocketAddrPtr addr) -{ - struct ifreq ifr; - int fd; - int rc = 0; - - memset (addr, 0, sizeof(*addr)); - addr->data.stor.ss_family = AF_UNSPEC; - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) { - virReportSystemError(errno, "%s", - _("Unable to open control socket")); - return -1; - } - - memset(&ifr, 0, sizeof(struct ifreq)); - if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL) { - virReportSystemError(ERANGE, - _("invalid interface name %s"), - ifname); - goto cleanup; - } - - if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { - virReportSystemError(errno, - _("Unable to get IPv4 address for interface %s"), ifname); - goto cleanup; - } - - addr->data.stor.ss_family = AF_INET; - addr->len = sizeof(addr->data.inet4); - memcpy(&addr->data.inet4, &ifr.ifr_addr, addr->len); - -cleanup: - VIR_FORCE_CLOSE(fd); - return rc; -} - -#else - -int virNetDevGetIPv4Address(const char *ifname ATTRIBUTE_UNUSED, - virSocketAddrPtr addr ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", - _("Unable to get IPv4 address on this platform")); - return -1; -} - -#endif /* __linux__ */ - #if defined(__linux__) && defined(IFLA_PORT_MAX) diff --git a/src/util/interface.h b/src/util/interface.h index 0a11ecd..afe417d 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -33,9 +33,6 @@ struct nlattr; int ifaceCheck(bool reportError, const char *ifname, const unsigned char *macaddr, int ifindex); -int virNetDevGetIPv4Address(const char *ifname, virSocketAddrPtr addr) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) 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 b25235a..b272d31 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -803,3 +803,56 @@ cleanup: virCommandFree(cmd); return ret; } + + +/** + * virNetDevGetIPv4Address: + * @ifname: name of the interface whose IP address we want + * @addr: filled with the IPv4 address + * + * This function gets the IPv4 address for the interface @ifname + * and stores it in @addr + * + * Returns 0 on success, -errno on failure. + */ +#ifdef __linux__ +int virNetDevGetIPv4Address(const char *ifname, + virSocketAddrPtr addr) +{ + int fd = -1; + int ret = -1; + struct ifreq ifr; + + memset(addr, 0, sizeof(*addr)); + addr->data.stor.ss_family = AF_UNSPEC; + + if ((fd = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { + virReportSystemError(errno, + _("Unable to get IPv4 address for interface %s"), ifname); + goto cleanup; + } + + addr->data.stor.ss_family = AF_INET; + addr->len = sizeof(addr->data.inet4); + memcpy(&addr->data.inet4, &ifr.ifr_addr, addr->len); + ret = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + return ret; +} + +#else + +int virNetDevGetIPv4Address(const char *ifname ATTRIBUTE_UNUSED, + virSocketAddrPtr addr ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to get IPv4 address on this platform")); + return -1; +} + +#endif /* __linux__ */ diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index c89516c..70ac1a3 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -43,6 +43,8 @@ int virNetDevClearIPv4Address(const char *ifname, virSocketAddr *addr, unsigned int prefix) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetIPv4Address(const char *ifname, virSocketAddrPtr addr) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevSetMAC(const char *ifname, -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Rename the ifaceCheck method to virNetDevValidateConfig and change so that it always raises an error and returns -1 on error. * src/util/interface.c, src/util/interface.h: Rename ifaceCheck to virNetDevValidateConfig * src/nwfilter/nwfilter_gentech_driver.c, src/nwfilter/nwfilter_learnipaddr.c: Update for API rename --- src/libvirt_private.syms | 2 +- src/nwfilter/nwfilter_gentech_driver.c | 6 ++- src/nwfilter/nwfilter_learnipaddr.c | 6 ++- src/util/interface.c | 83 ++++++++++++++++--------------- src/util/interface.h | 5 +- 5 files changed, 55 insertions(+), 47 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 183e4f5..6b7e231 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 9f44aef..9dffdc5 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; @@ -963,8 +964,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 319f317..03716ea 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 e86d183..16ad155 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 afe417d..c230264 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, -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> * src/util/interface.c, src/util/interface.h: Remove virNetDevValidateConfig * src/util/virnetdev.c, src/util/virnetdev.h: Add virNetDevValidateConfig --- src/util/interface.c | 89 -------------------------------------------------- src/util/interface.h | 4 -- src/util/virnetdev.c | 77 +++++++++++++++++++++++++++++++++++++++++++ src/util/virnetdev.h | 4 ++ 4 files changed, 81 insertions(+), 93 deletions(-) diff --git a/src/util/interface.c b/src/util/interface.c index 16ad155..8264e7c 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 c230264..4256f29 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 b272d31..453c343 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 70ac1a3..d2059af 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__ */ -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Rename ifaceIsVirtualFunction to virNetDevIsVirtualFunction, ifaceGetVirtualFunctionIndex to virNetDevGetVirtualFunctionIndex and ifaceGetPhysicalFunction to virNetDevGetPhysicalFunction * src/util/interface.c, src/util/interface.h: Rename APIs * src/util/virnetdevvportprofile.c: Update for API rename --- src/libvirt_private.syms | 6 ++-- src/util/interface.c | 54 +++++++++++++++++-------------------- src/util/interface.h | 12 +++++--- src/util/virnetdevvportprofile.c | 6 ++-- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6b7e231..8f58105 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -579,10 +579,10 @@ virNetDevValidateConfig; virNetDevGetIndex; virNetDevGetIPv4Address; ifaceGetNthParent; -ifaceGetPhysicalFunction; -ifaceGetVirtualFunctionIndex; +virNetDevGetPhysicalFunction; +virNetDevGetVirtualFunctionIndex; virNetDevGetVLanID; -ifaceIsVirtualFunction; +virNetDevIsVirtualFunction; virNetDevMacVLanCreate; virNetDevMacVLanDelete; ifaceMacvtapLinkDump; diff --git a/src/util/interface.c b/src/util/interface.c index 8264e7c..2882511 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -299,7 +299,7 @@ ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, #ifdef __linux__ static int -ifaceSysfsFile(char **pf_sysfs_device_link, const char *ifname, +virNetDevSysfsFile(char **pf_sysfs_device_link, const char *ifname, const char *file) { @@ -313,7 +313,7 @@ ifaceSysfsFile(char **pf_sysfs_device_link, const char *ifname, } static int -ifaceSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname, +virNetDevSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname, const char *file) { @@ -327,8 +327,7 @@ ifaceSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname, } /** - * ifaceIsVirtualFunction - * + * virNetDevIsVirtualFunction: * @ifname : name of the interface * * Checks if an interface is a SRIOV virtual function. @@ -337,12 +336,12 @@ ifaceSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname, * */ int -ifaceIsVirtualFunction(const char *ifname) +virNetDevIsVirtualFunction(const char *ifname) { char *if_sysfs_device_link = NULL; int ret = -1; - if (ifaceSysfsFile(&if_sysfs_device_link, ifname, "device") < 0) + if (virNetDevSysfsFile(&if_sysfs_device_link, ifname, "device") < 0) return ret; ret = pciDeviceIsVirtualFunction(if_sysfs_device_link); @@ -353,7 +352,7 @@ ifaceIsVirtualFunction(const char *ifname) } /** - * ifaceGetVirtualFunctionIndex + * virNetDevGetVirtualFunctionIndex * * @pfname : name of the physical function interface name * @vfname : name of the virtual function interface name @@ -364,16 +363,16 @@ ifaceIsVirtualFunction(const char *ifname) * */ int -ifaceGetVirtualFunctionIndex(const char *pfname, const char *vfname, - int *vf_index) +virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname, + int *vf_index) { char *pf_sysfs_device_link = NULL, *vf_sysfs_device_link = NULL; int ret = -1; - if (ifaceSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0) + if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0) return ret; - if (ifaceSysfsFile(&vf_sysfs_device_link, vfname, "device") < 0) { + if (virNetDevSysfsFile(&vf_sysfs_device_link, vfname, "device") < 0) { VIR_FREE(pf_sysfs_device_link); return ret; } @@ -389,7 +388,7 @@ ifaceGetVirtualFunctionIndex(const char *pfname, const char *vfname, } /** - * ifaceGetPhysicalFunction + * virNetDevGetPhysicalFunction * * @ifname : name of the physical function interface name * @pfname : Contains sriov physical function for interface ifname @@ -399,12 +398,12 @@ ifaceGetVirtualFunctionIndex(const char *pfname, const char *vfname, * */ int -ifaceGetPhysicalFunction(const char *ifname, char **pfname) +virNetDevGetPhysicalFunction(const char *ifname, char **pfname) { char *physfn_sysfs_path = NULL; int ret = -1; - if (ifaceSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0) + if (virNetDevSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0) return ret; ret = pciDeviceNetName(physfn_sysfs_path, pfname); @@ -413,34 +412,31 @@ ifaceGetPhysicalFunction(const char *ifname, char **pfname) return ret; } -#else +#else /* !__linux__ */ int -ifaceIsVirtualFunction(const char *ifname ATTRIBUTE_UNUSED) +virNetDevIsVirtualFunction(const char *ifname ATTRIBUTE_UNUSED) { - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("ifaceIsVirtualFunction is not supported on non-linux " - "platforms")); + virReportSystemError(ENOSYS, "%s", + _("Unable to check virtual function status on this platfornm")); return -1; } int -ifaceGetVirtualFunctionIndex(const char *pfname ATTRIBUTE_UNUSED, +virNetDevGetVirtualFunctionIndex(const char *pfname ATTRIBUTE_UNUSED, const char *vfname ATTRIBUTE_UNUSED, int *vf_index ATTRIBUTE_UNUSED) { - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("ifaceGetVirtualFunctionIndex is not supported on non-linux " - "platforms")); + virReportSystemError(ENOSYS, "%s", + _("Unable to get virtual function index on this platfornm")); return -1; } int -ifaceGetPhysicalFunction(const char *ifname ATTRIBUTE_UNUSED, - char **pfname ATTRIBUTE_UNUSED) +virNetDevGetPhysicalFunction(const char *ifname ATTRIBUTE_UNUSED, + char **pfname ATTRIBUTE_UNUSED) { - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("ifaceGetPhysicalFunction is not supported on non-linux " - "platforms")); + virReportSystemError(ENOSYS, "%s", + _("Unable to get physical function status on this platfornm")); return -1; } -#endif /* __linux__ */ +#endif /* !__linux__ */ diff --git a/src/util/interface.h b/src/util/interface.h index 4256f29..86f9aac 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -40,11 +40,15 @@ int ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent, ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6); -int ifaceIsVirtualFunction(const char *ifname); +int virNetDevIsVirtualFunction(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int ifaceGetVirtualFunctionIndex(const char *pfname, const char *vfname, - int *vf_index); +int virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname, + int *vf_index) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_RETURN_CHECK; -int ifaceGetPhysicalFunction(const char *ifname, char **pfname); +int virNetDevGetPhysicalFunction(const char *ifname, char **pfname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; #endif /* __VIR_INTERFACE_H__ */ diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c index 3649033..dbf1cf4 100644 --- a/src/util/virnetdevvportprofile.c +++ b/src/util/virnetdevvportprofile.c @@ -630,13 +630,13 @@ virNetDevVPortProfileGetPhysfnDev(const char *linkdev, { int rc = -1; - if (ifaceIsVirtualFunction(linkdev) == 1) { + if (virNetDevIsVirtualFunction(linkdev) == 1) { /* if linkdev is SR-IOV VF, then set vf = VF index */ /* and set linkdev = PF device */ - rc = ifaceGetPhysicalFunction(linkdev, physfndev); + rc = virNetDevGetPhysicalFunction(linkdev, physfndev); if (!rc) - rc = ifaceGetVirtualFunctionIndex(*physfndev, linkdev, vf); + rc = virNetDevGetVirtualFunctionIndex(*physfndev, linkdev, vf); } else { /* Not SR-IOV VF: physfndev is linkdev and VF index -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Move virNetDevIsVirtualFunction, virNetDevGetVirtualFunctionIndex and virNetDevGetPhysicalFunction to virnetdev.c * src/util/interface.c, src/util/interface.h, src/util/virnetdev.c, src/util/virnetdev.h: Move APIs --- src/util/interface.c | 146 ------------------------------------------------- src/util/interface.h | 13 ----- src/util/virnetdev.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/util/virnetdev.h | 10 ++++ 4 files changed, 158 insertions(+), 159 deletions(-) diff --git a/src/util/interface.c b/src/util/interface.c index 2882511..00a873e 100644 --- a/src/util/interface.c +++ b/src/util/interface.c @@ -45,7 +45,6 @@ #include "virfile.h" #include "memory.h" #include "netlink.h" -#include "pci.h" #include "logging.h" #include "virnetdev.h" @@ -295,148 +294,3 @@ ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, } #endif - - -#ifdef __linux__ -static int -virNetDevSysfsFile(char **pf_sysfs_device_link, const char *ifname, - const char *file) -{ - - if (virAsprintf(pf_sysfs_device_link, NET_SYSFS "%s/%s", - ifname, file) < 0) { - virReportOOMError(); - return -1; - } - - return 0; -} - -static int -virNetDevSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname, - const char *file) -{ - - if (virAsprintf(pf_sysfs_device_link, NET_SYSFS "%s/device/%s", - ifname, file) < 0) { - virReportOOMError(); - return -1; - } - - return 0; -} - -/** - * virNetDevIsVirtualFunction: - * @ifname : name of the interface - * - * Checks if an interface is a SRIOV virtual function. - * - * Returns 1 if interface is SRIOV virtual function, 0 if not and -1 if error - * - */ -int -virNetDevIsVirtualFunction(const char *ifname) -{ - char *if_sysfs_device_link = NULL; - int ret = -1; - - if (virNetDevSysfsFile(&if_sysfs_device_link, ifname, "device") < 0) - return ret; - - ret = pciDeviceIsVirtualFunction(if_sysfs_device_link); - - VIR_FREE(if_sysfs_device_link); - - return ret; -} - -/** - * virNetDevGetVirtualFunctionIndex - * - * @pfname : name of the physical function interface name - * @vfname : name of the virtual function interface name - * @vf_index : Pointer to int. Contains vf index of interface upon successful - * return - * - * Returns 0 on success, -1 on failure - * - */ -int -virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname, - int *vf_index) -{ - char *pf_sysfs_device_link = NULL, *vf_sysfs_device_link = NULL; - int ret = -1; - - if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0) - return ret; - - if (virNetDevSysfsFile(&vf_sysfs_device_link, vfname, "device") < 0) { - VIR_FREE(pf_sysfs_device_link); - return ret; - } - - ret = pciGetVirtualFunctionIndex(pf_sysfs_device_link, - vf_sysfs_device_link, - vf_index); - - VIR_FREE(pf_sysfs_device_link); - VIR_FREE(vf_sysfs_device_link); - - return ret; -} - -/** - * virNetDevGetPhysicalFunction - * - * @ifname : name of the physical function interface name - * @pfname : Contains sriov physical function for interface ifname - * upon successful return - * - * Returns 0 on success, -1 on failure - * - */ -int -virNetDevGetPhysicalFunction(const char *ifname, char **pfname) -{ - char *physfn_sysfs_path = NULL; - int ret = -1; - - if (virNetDevSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0) - return ret; - - ret = pciDeviceNetName(physfn_sysfs_path, pfname); - - VIR_FREE(physfn_sysfs_path); - - return ret; -} -#else /* !__linux__ */ -int -virNetDevIsVirtualFunction(const char *ifname ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", - _("Unable to check virtual function status on this platfornm")); - return -1; -} - -int -virNetDevGetVirtualFunctionIndex(const char *pfname ATTRIBUTE_UNUSED, - const char *vfname ATTRIBUTE_UNUSED, - int *vf_index ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", - _("Unable to get virtual function index on this platfornm")); - return -1; -} - -int -virNetDevGetPhysicalFunction(const char *ifname ATTRIBUTE_UNUSED, - char **pfname ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", - _("Unable to get physical function status on this platfornm")); - return -1; -} -#endif /* !__linux__ */ diff --git a/src/util/interface.h b/src/util/interface.h index 86f9aac..141d19c 100644 --- a/src/util/interface.h +++ b/src/util/interface.h @@ -27,8 +27,6 @@ struct nlattr; # include "datatypes.h" # include "virsocketaddr.h" -# define NET_SYSFS "/sys/class/net/" - int ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, struct nlattr **tb, unsigned char **recvbuf, @@ -40,15 +38,4 @@ int ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent, ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6); -int virNetDevIsVirtualFunction(const char *ifname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; - -int virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname, - int *vf_index) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) - ATTRIBUTE_RETURN_CHECK; - -int virNetDevGetPhysicalFunction(const char *ifname, char **pfname) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; - #endif /* __VIR_INTERFACE_H__ */ diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 453c343..20cb0c2 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -27,6 +27,7 @@ #include "virterror_internal.h" #include "command.h" #include "memory.h" +#include "pci.h" #include <sys/ioctl.h> #ifdef HAVE_NET_IF_H @@ -933,3 +934,150 @@ int virNetDevValidateConfig(const char *ifname ATTRIBUTE_UNUSED, return -1; } #endif /* ! __linux__ */ + + +#ifdef __linux__ +# define NET_SYSFS "/sys/class/net/" + +static int +virNetDevSysfsFile(char **pf_sysfs_device_link, const char *ifname, + const char *file) +{ + + if (virAsprintf(pf_sysfs_device_link, NET_SYSFS "%s/%s", + ifname, file) < 0) { + virReportOOMError(); + return -1; + } + + return 0; +} + +static int +virNetDevSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname, + const char *file) +{ + + if (virAsprintf(pf_sysfs_device_link, NET_SYSFS "%s/device/%s", + ifname, file) < 0) { + virReportOOMError(); + return -1; + } + + return 0; +} + +/** + * virNetDevIsVirtualFunction: + * @ifname : name of the interface + * + * Checks if an interface is a SRIOV virtual function. + * + * Returns 1 if interface is SRIOV virtual function, 0 if not and -1 if error + * + */ +int +virNetDevIsVirtualFunction(const char *ifname) +{ + char *if_sysfs_device_link = NULL; + int ret = -1; + + if (virNetDevSysfsFile(&if_sysfs_device_link, ifname, "device") < 0) + return ret; + + ret = pciDeviceIsVirtualFunction(if_sysfs_device_link); + + VIR_FREE(if_sysfs_device_link); + + return ret; +} + +/** + * virNetDevGetVirtualFunctionIndex + * + * @pfname : name of the physical function interface name + * @vfname : name of the virtual function interface name + * @vf_index : Pointer to int. Contains vf index of interface upon successful + * return + * + * Returns 0 on success, -1 on failure + * + */ +int +virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname, + int *vf_index) +{ + char *pf_sysfs_device_link = NULL, *vf_sysfs_device_link = NULL; + int ret = -1; + + if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0) + return ret; + + if (virNetDevSysfsFile(&vf_sysfs_device_link, vfname, "device") < 0) { + VIR_FREE(pf_sysfs_device_link); + return ret; + } + + ret = pciGetVirtualFunctionIndex(pf_sysfs_device_link, + vf_sysfs_device_link, + vf_index); + + VIR_FREE(pf_sysfs_device_link); + VIR_FREE(vf_sysfs_device_link); + + return ret; +} + +/** + * virNetDevGetPhysicalFunction + * + * @ifname : name of the physical function interface name + * @pfname : Contains sriov physical function for interface ifname + * upon successful return + * + * Returns 0 on success, -1 on failure + * + */ +int +virNetDevGetPhysicalFunction(const char *ifname, char **pfname) +{ + char *physfn_sysfs_path = NULL; + int ret = -1; + + if (virNetDevSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0) + return ret; + + ret = pciDeviceNetName(physfn_sysfs_path, pfname); + + VIR_FREE(physfn_sysfs_path); + + return ret; +} +#else /* !__linux__ */ +int +virNetDevIsVirtualFunction(const char *ifname ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to check virtual function status on this platfornm")); + return -1; +} + +int +virNetDevGetVirtualFunctionIndex(const char *pfname ATTRIBUTE_UNUSED, + const char *vfname ATTRIBUTE_UNUSED, + int *vf_index ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to get virtual function index on this platfornm")); + return -1; +} + +int +virNetDevGetPhysicalFunction(const char *ifname ATTRIBUTE_UNUSED, + char **pfname ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Unable to get physical function status on this platfornm")); + return -1; +} +#endif /* !__linux__ */ diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index d2059af..6914b2a 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -88,5 +88,15 @@ int virNetDevValidateConfig(const char *ifname, const unsigned char *macaddr, int ifindex) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; +int virNetDevIsVirtualFunction(const char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + +int virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname, + int *vf_index) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_RETURN_CHECK; + +int virNetDevGetPhysicalFunction(const char *ifname, char **pfname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; #endif /* __VIR_NETDEV_H__ */ -- 1.7.6.4

From: "Daniel P. Berrange" <berrange@redhat.com> Move the ifaceMacvtapLinkDump and ifaceGetNthParent functions into virnetdevvportprofile.c since they are specific to that code. This avoids polluting the headers with the Linux specific netlink data types * src/util/interface.c, src/util/interface.h: Move ifaceMacvtapLinkDump and ifaceGetNthParent functions and delete remaining file * src/util/virnetdevvportprofile.c: Add ifaceMacvtapLinkDump and ifaceGetNthParent functions * src/network/bridge_driver.c, src/nwfilter/nwfilter_gentech_driver.c, src/nwfilter/nwfilter_learnipaddr.c, src/util/virnetdevmacvlan.c: Remove include of interface.h --- po/POTFILES.in | 1 - src/Makefile.am | 1 - src/libvirt_private.syms | 2 - src/network/bridge_driver.c | 1 - src/nwfilter/nwfilter_gentech_driver.c | 2 +- src/nwfilter/nwfilter_learnipaddr.c | 1 - src/util/interface.c | 296 -------------------------------- src/util/interface.h | 41 ----- src/util/virnetdevmacvlan.c | 3 +- src/util/virnetdevvportprofile.c | 199 +++++++++++++++++++++- 10 files changed, 196 insertions(+), 351 deletions(-) delete mode 100644 src/util/interface.c delete mode 100644 src/util/interface.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 6797298..403d94b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -112,7 +112,6 @@ src/util/hash.c src/util/hooks.c src/util/hostusb.c src/util/iohelper.c -src/util/interface.c src/util/iptables.c src/util/json.c src/util/netlink.c diff --git a/src/Makefile.am b/src/Makefile.am index 6703bc1..bb45ab6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -70,7 +70,6 @@ UTIL_SOURCES = \ util/pci.c util/pci.h \ util/processinfo.c util/processinfo.h \ util/hostusb.c util/hostusb.h \ - util/interface.c util/interface.h \ util/qparams.c util/qparams.h \ util/sexpr.c util/sexpr.h \ util/stats_linux.c util/stats_linux.h \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8f58105..7baaf77 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -578,14 +578,12 @@ virHookPresent; virNetDevValidateConfig; virNetDevGetIndex; virNetDevGetIPv4Address; -ifaceGetNthParent; virNetDevGetPhysicalFunction; virNetDevGetVirtualFunctionIndex; virNetDevGetVLanID; virNetDevIsVirtualFunction; virNetDevMacVLanCreate; virNetDevMacVLanDelete; -ifaceMacvtapLinkDump; virNetDevReplaceMacAddress; virNetDevRestoreMacAddress; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 3f8c8c4..b8a96b9 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -56,7 +56,6 @@ #include "memory.h" #include "uuid.h" #include "iptables.h" -#include "interface.h" #include "logging.h" #include "dnsmasq.h" #include "configmake.h" diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 9dffdc5..c9c1415 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -28,13 +28,13 @@ #include "memory.h" #include "logging.h" -#include "interface.h" #include "domain_conf.h" #include "virterror_internal.h" #include "nwfilter_gentech_driver.h" #include "nwfilter_ebiptables_driver.h" #include "nwfilter_learnipaddr.h" #include "virnetdev.h" +#include "datatypes.h" #define VIR_FROM_THIS VIR_FROM_NWFILTER diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c index 03716ea..1843c98 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -45,7 +45,6 @@ #include "memory.h" #include "logging.h" #include "datatypes.h" -#include "interface.h" #include "virnetdev.h" #include "virterror_internal.h" #include "threads.h" diff --git a/src/util/interface.c b/src/util/interface.c deleted file mode 100644 index 00a873e..0000000 --- a/src/util/interface.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * interface.c: interface support functions - * - * Copyright (C) 2011 Red Hat, Inc. - * Copyright (C) 2010 IBM Corp. - * Copyright (C) 2010 Stefan Berger - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * chgIfaceFlags originated from bridge.c - * - * Author: Stefan Berger <stefanb@us.ibm.com> - */ - -#include <config.h> - -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <netinet/in.h> - -#ifdef __linux__ -# include <linux/if.h> -# include <linux/sockios.h> -# include <linux/if_vlan.h> -#endif - -#include "internal.h" - -#include "util.h" -#include "interface.h" -#include "virterror_internal.h" -#include "virfile.h" -#include "memory.h" -#include "netlink.h" -#include "logging.h" -#include "virnetdev.h" - -#define VIR_FROM_THIS VIR_FROM_NET - -#define ifaceError(code, ...) \ - virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \ - __FUNCTION__, __LINE__, __VA_ARGS__) - - -#if defined(__linux__) && defined(IFLA_PORT_MAX) - -static struct nla_policy ifla_policy[IFLA_MAX + 1] = -{ - [IFLA_VF_PORTS] = { .type = NLA_NESTED }, -}; - -/** - * ifaceMacvtapLinkDump - * - * @nltarget_kernel: whether to send the message to the kernel or another - * process - * @ifname: The name of the interface; only use if ifindex < 0 - * @ifindex: The interface index; may be < 0 if ifname is given - * @nlattr: pointer to a pointer of netlink attributes that will contain - * the results - * @recvbuf: Pointer to the buffer holding the returned netlink response - * message; free it, once not needed anymore - * @getPidFunc: Pointer to a function that will be invoked if the kernel - * is not the target of the netlink message but it is to be - * sent to another process. - * - * Get information about an interface given its name or index. - * - * Returns 0 on success, -1 on fatal error. - */ -int -ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, - struct nlattr **tb, unsigned char **recvbuf, - uint32_t (*getPidFunc)(void)) -{ - int rc = 0; - struct nlmsghdr *resp; - struct nlmsgerr *err; - struct ifinfomsg ifinfo = { - .ifi_family = AF_UNSPEC, - .ifi_index = ifindex - }; - unsigned int recvbuflen; - uint32_t pid = 0; - struct nl_msg *nl_msg; - - *recvbuf = NULL; - - nl_msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST); - if (!nl_msg) { - virReportOOMError(); - return -1; - } - - if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) - goto buffer_too_small; - - if (ifindex < 0 && ifname) { - if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) - goto buffer_too_small; - } - - if (!nltarget_kernel) { - pid = getPidFunc(); - if (pid == 0) { - rc = -1; - goto cleanup; - } - } - - if (nlComm(nl_msg, recvbuf, &recvbuflen, pid) < 0) { - rc = -1; - goto cleanup; - } - - if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL) - goto malformed_resp; - - resp = (struct nlmsghdr *)*recvbuf; - - switch (resp->nlmsg_type) { - case NLMSG_ERROR: - err = (struct nlmsgerr *)NLMSG_DATA(resp); - if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) - goto malformed_resp; - - if (err->error) { - virReportSystemError(-err->error, - _("error dumping %s (%d) interface"), - ifname, ifindex); - rc = -1; - } - break; - - case GENL_ID_CTRL: - case NLMSG_DONE: - if (nlmsg_parse(resp, sizeof(struct ifinfomsg), - tb, IFLA_MAX, ifla_policy)) { - goto malformed_resp; - } - break; - - default: - goto malformed_resp; - } - - if (rc != 0) - VIR_FREE(*recvbuf); - -cleanup: - nlmsg_free(nl_msg); - - return rc; - -malformed_resp: - nlmsg_free(nl_msg); - - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("malformed netlink response message")); - VIR_FREE(*recvbuf); - return -1; - -buffer_too_small: - nlmsg_free(nl_msg); - - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("allocated netlink buffer is too small")); - return -1; -} - -#else - -int -ifaceMacvtapLinkDump(bool nltarget_kernel ATTRIBUTE_UNUSED, - const char *ifname ATTRIBUTE_UNUSED, - int ifindex ATTRIBUTE_UNUSED, - struct nlattr **tb ATTRIBUTE_UNUSED, - unsigned char **recvbuf ATTRIBUTE_UNUSED, - uint32_t (*getPidFunc)(void) ATTRIBUTE_UNUSED) -{ - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", -# if defined(__linux__) && !defined(IFLA_PORT_MAX) - _("ifaceMacvtapLinkDump is not supported since the include " - "files were too old")); -# else - _("ifaceMacvtapLinkDump is not supported on non-linux " - "platforms")); -# endif - - return -1; -} - -#endif - - -/** - * ifaceGetNthParent - * - * @ifindex : the index of the interface or -1 if ifname is given - * @ifname : the name of the interface; ignored if ifindex is valid - * @nthParent : the nth parent interface to get - * @parent_ifindex : pointer to int - * @parent_ifname : pointer to buffer of size IFNAMSIZ - * @nth : the nth parent that is actually returned; if for example eth0.100 - * was given and the 100th parent is to be returned, then eth0 will - * most likely be returned with nth set to 1 since the chain does - * not have more interfaces - * - * Get the nth parent interface of the given interface. 0 is the interface - * itself. - * - * Return 0 on success, < 0 otherwise - */ -#if defined(__linux__) && WITH_MACVTAP -int -ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent, - int *parent_ifindex, char *parent_ifname, - unsigned int *nth) -{ - int rc; - struct nlattr *tb[IFLA_MAX + 1] = { NULL, }; - unsigned char *recvbuf = NULL; - bool end = false; - unsigned int i = 0; - - *nth = 0; - - if (ifindex <= 0 && virNetDevGetIndex(ifname, &ifindex) < 0) - return -1; - - while (!end && i <= nthParent) { - rc = ifaceMacvtapLinkDump(true, ifname, ifindex, tb, &recvbuf, NULL); - if (rc < 0) - break; - - if (tb[IFLA_IFNAME]) { - if (!virStrcpy(parent_ifname, (char*)RTA_DATA(tb[IFLA_IFNAME]), - IFNAMSIZ)) { - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", - _("buffer for root interface name is too small")); - VIR_FREE(recvbuf); - return -1; - } - *parent_ifindex = ifindex; - } - - if (tb[IFLA_LINK]) { - ifindex = *(int *)RTA_DATA(tb[IFLA_LINK]); - ifname = NULL; - } else - end = true; - - VIR_FREE(recvbuf); - - i++; - } - - *nth = i - 1; - - return rc; -} - -#else - -int -ifaceGetNthParent(int ifindex ATTRIBUTE_UNUSED, - const char *ifname ATTRIBUTE_UNUSED, - unsigned int nthParent ATTRIBUTE_UNUSED, - int *parent_ifindex ATTRIBUTE_UNUSED, - char *parent_ifname ATTRIBUTE_UNUSED, - unsigned int *nth ATTRIBUTE_UNUSED) -{ - ifaceError(VIR_ERR_INTERNAL_ERROR, "%s", -# if defined(__linux__) && !WITH_MACVTAP - _("ifaceGetNthParent is not supported since the include files " - "were too old")); -# else - _("ifaceGetNthParent is not supported on non-linux platforms")); -# endif - return -1; -} - -#endif diff --git a/src/util/interface.h b/src/util/interface.h deleted file mode 100644 index 141d19c..0000000 --- a/src/util/interface.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * interface.h: interface helper APIs for libvirt - * - * Copyright (C) 2011 Red Hat, Inc. - * Copyright (C) 2010 IBM Corporation, Inc. - * - * See COPYING.LIB for the License of this software - * - * Stefan Berger <stefanb@us.ibm.com> - */ -#ifndef __VIR_INTERFACE_H__ -# define __VIR_INTERFACE_H__ - -# include <stdint.h> - -# if __linux__ - -# include <sys/socket.h> -# include <linux/netlink.h> - -# else - -struct nlattr; - -# endif - -# include "datatypes.h" -# include "virsocketaddr.h" - - -int ifaceMacvtapLinkDump(bool nltarget_kernel, const char *ifname, int ifindex, - struct nlattr **tb, unsigned char **recvbuf, - uint32_t (*getPidFunc)(void)); - -int ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent, - int *parent_ifindex, char *parent_ifname, - unsigned int *nth) - ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) - ATTRIBUTE_NONNULL(6); - -#endif /* __VIR_INTERFACE_H__ */ diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index a832f06..0f409c0 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -34,7 +34,7 @@ #define VIR_FROM_THIS VIR_FROM_NET -#define macvtapError(code, ...) \ +#define virNetDevError(code, ...) \ virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__) @@ -64,7 +64,6 @@ VIR_ENUM_IMPL(virNetDevMacVLanMode, VIR_NETDEV_MACVLAN_MODE_LAST, # include "memory.h" # include "logging.h" -# include "interface.h" # include "uuid.h" # include "virfile.h" # include "netlink.h" diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c index dbf1cf4..a93dc56 100644 --- a/src/util/virnetdevvportprofile.c +++ b/src/util/virnetdevvportprofile.c @@ -58,7 +58,6 @@ VIR_ENUM_IMPL(virNetDevVPortProfileOp, VIR_NETDEV_VPORT_PROFILE_OP_LAST, # include "netlink.h" # include "virfile.h" # include "memory.h" -# include "interface.h" # include "logging.h" # include "virnetdev.h" @@ -127,6 +126,10 @@ static struct nla_policy ifla_port_policy[IFLA_PORT_MAX + 1] = { [IFLA_PORT_RESPONSE] = { .type = NLA_U16 }, }; +static struct nla_policy ifla_policy[IFLA_MAX + 1] = +{ + [IFLA_VF_PORTS] = { .type = NLA_NESTED }, +}; static uint32_t @@ -163,6 +166,125 @@ virNetDevVPortProfileGetLldpadPid(void) { /** + * virNetDevVPortProfileLinkDump: + * + * @ifname: The name of the interface; only use if ifindex < 0 + * @ifindex: The interface index; may be < 0 if ifname is given + * @nltarget_kernel: whether to send the message to the kernel or another + * process + * @nlattr: pointer to a pointer of netlink attributes that will contain + * the results + * @recvbuf: Pointer to the buffer holding the returned netlink response + * message; free it, once not needed anymore + * @getPidFunc: Pointer to a function that will be invoked if the kernel + * is not the target of the netlink message but it is to be + * sent to another process. + * + * Get information about an interface given its name or index. + * + * Returns 0 on success, -1 on fatal error. + */ +static int +virNetDevVPortProfileLinkDump(const char *ifname, int ifindex, bool nltarget_kernel, + struct nlattr **tb, unsigned char **recvbuf, + uint32_t (*getPidFunc)(void)) +{ + int rc = 0; + struct nlmsghdr *resp; + struct nlmsgerr *err; + struct ifinfomsg ifinfo = { + .ifi_family = AF_UNSPEC, + .ifi_index = ifindex + }; + unsigned int recvbuflen; + uint32_t pid = 0; + struct nl_msg *nl_msg; + + *recvbuf = NULL; + + nl_msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_REQUEST); + if (!nl_msg) { + virReportOOMError(); + return -1; + } + + if (nlmsg_append(nl_msg, &ifinfo, sizeof(ifinfo), NLMSG_ALIGNTO) < 0) + goto buffer_too_small; + + if (ifindex < 0 && ifname) { + if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) + goto buffer_too_small; + } + + if (!nltarget_kernel) { + pid = getPidFunc(); + if (pid == 0) { + rc = -1; + goto cleanup; + } + } + + if (nlComm(nl_msg, recvbuf, &recvbuflen, pid) < 0) { + rc = -1; + goto cleanup; + } + + if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL) + goto malformed_resp; + + resp = (struct nlmsghdr *)*recvbuf; + + switch (resp->nlmsg_type) { + case NLMSG_ERROR: + err = (struct nlmsgerr *)NLMSG_DATA(resp); + if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) + goto malformed_resp; + + if (err->error) { + virReportSystemError(-err->error, + _("error dumping %s (%d) interface"), + ifname, ifindex); + rc = -1; + } + break; + + case GENL_ID_CTRL: + case NLMSG_DONE: + if (nlmsg_parse(resp, sizeof(struct ifinfomsg), + tb, IFLA_MAX, ifla_policy)) { + goto malformed_resp; + } + break; + + default: + goto malformed_resp; + } + + if (rc != 0) + VIR_FREE(*recvbuf); + +cleanup: + nlmsg_free(nl_msg); + + return rc; + +malformed_resp: + nlmsg_free(nl_msg); + + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("malformed netlink response message")); + VIR_FREE(*recvbuf); + return -1; + +buffer_too_small: + nlmsg_free(nl_msg); + + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("allocated netlink buffer is too small")); + return -1; +} + +/** * virNetDevVPortProfileGetStatus: * * tb: top level netlink response attributes + values @@ -450,6 +572,73 @@ buffer_too_small: } +/** + * virNetDevVPortProfileGetNthParent + * + * @ifname : the name of the interface; ignored if ifindex is valid + * @ifindex : the index of the interface or -1 if ifname is given + * @nthParent : the nth parent interface to get + * @parent_ifindex : pointer to int + * @parent_ifname : pointer to buffer of size IFNAMSIZ + * @nth : the nth parent that is actually returned; if for example eth0.100 + * was given and the 100th parent is to be returned, then eth0 will + * most likely be returned with nth set to 1 since the chain does + * not have more interfaces + * + * Get the nth parent interface of the given interface. 0 is the interface + * itself. + * + * Return 0 on success, < 0 otherwise + */ +static int +virNetDevVPortProfileGetNthParent(const char *ifname, int ifindex, unsigned int nthParent, + int *parent_ifindex, char *parent_ifname, + unsigned int *nth) +{ + int rc; + struct nlattr *tb[IFLA_MAX + 1] = { NULL, }; + unsigned char *recvbuf = NULL; + bool end = false; + unsigned int i = 0; + + *nth = 0; + + if (ifindex <= 0 && virNetDevGetIndex(ifname, &ifindex) < 0) + return -1; + + while (!end && i <= nthParent) { + rc = virNetDevVPortProfileLinkDump(ifname, ifindex, true, tb, &recvbuf, NULL); + if (rc < 0) + break; + + if (tb[IFLA_IFNAME]) { + if (!virStrcpy(parent_ifname, (char*)RTA_DATA(tb[IFLA_IFNAME]), + IFNAMSIZ)) { + virNetDevError(VIR_ERR_INTERNAL_ERROR, "%s", + _("buffer for root interface name is too small")); + VIR_FREE(recvbuf); + return -1; + } + *parent_ifindex = ifindex; + } + + if (tb[IFLA_LINK]) { + ifindex = *(int *)RTA_DATA(tb[IFLA_LINK]); + ifname = NULL; + } else + end = true; + + VIR_FREE(recvbuf); + + i++; + } + + *nth = i - 1; + + return rc; +} + + /* Returns 0 on success, -1 on general failure, and -2 on timeout */ static int virNetDevVPortProfileOpCommon(const char *ifname, int ifindex, @@ -487,8 +676,8 @@ virNetDevVPortProfileOpCommon(const char *ifname, int ifindex, } while (--repeats >= 0) { - rc = ifaceMacvtapLinkDump(nltarget_kernel, NULL, ifindex, tb, - &recvbuf, virNetDevVPortProfileGetLldpadPid); + rc = virNetDevVPortProfileLinkDump(NULL, ifindex, nltarget_kernel, tb, + &recvbuf, virNetDevVPortProfileGetLldpadPid); if (rc < 0) goto err_exit; @@ -538,8 +727,8 @@ virNetDevVPortProfileGetPhysdevAndVlan(const char *ifname, int *root_ifindex, ch *vlanid = -1; while (1) { - if ((ret = ifaceGetNthParent(ifindex, ifname, 1, - root_ifindex, root_ifname, &nth)) < 0) + if ((ret = virNetDevVPortProfileGetNthParent(ifname, ifindex, 1, + root_ifindex, root_ifname, &nth)) < 0) return ret; if (nth == 0) break; -- 1.7.6.4

On Thu, Nov 03, 2011 at 05:29:56PM +0000, Daniel P. Berrange wrote:
This series is a major re-arrangement and de-duplication of internal code for dealing with physical network interfaces.
Thanks for the reviews so far. I have pushed patches 01->10, with the relevant review fixes applied. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
participants (3)
-
Daniel P. Berrange
-
Laine Stump
-
Stefan Berger