Remove 'brControl' object

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
This commit is contained in:
Daniel P. Berrange 2011-11-02 10:56:38 +00:00
parent 85cf8d3899
commit 6cfeb9a766
10 changed files with 295 additions and 349 deletions

View File

@ -1194,15 +1194,8 @@ static int lxcSetupInterfaces(virConnectPtr conn,
{ {
int rc = -1, i; int rc = -1, i;
char *bridge = NULL; char *bridge = NULL;
brControl *brctl = NULL;
int ret; int ret;
if ((ret = brInit(&brctl)) != 0) {
virReportSystemError(ret, "%s",
_("Unable to initialize bridging"));
return -1;
}
for (i = 0 ; i < def->nnets ; i++) { for (i = 0 ; i < def->nnets ; i++) {
char *parentVeth; char *parentVeth;
char *containerVeth = NULL; char *containerVeth = NULL;
@ -1277,7 +1270,7 @@ static int lxcSetupInterfaces(virConnectPtr conn,
goto error_exit; goto error_exit;
} }
if ((ret = brAddInterface(brctl, bridge, parentVeth)) != 0) { if ((ret = brAddInterface(bridge, parentVeth)) != 0) {
virReportSystemError(ret, virReportSystemError(ret,
_("Failed to add %s device to %s"), _("Failed to add %s device to %s"),
parentVeth, bridge); parentVeth, bridge);
@ -1303,7 +1296,6 @@ static int lxcSetupInterfaces(virConnectPtr conn,
rc = 0; rc = 0;
error_exit: error_exit:
brShutdown(brctl);
if (rc != 0) { if (rc != 0) {
for (i = 0 ; i < def->nnets ; i++) for (i = 0 ; i < def->nnets ; i++)
networkReleaseActualDevice(def->nets[i]); networkReleaseActualDevice(def->nets[i]);

View File

@ -82,7 +82,6 @@ struct network_driver {
virNetworkObjList networks; virNetworkObjList networks;
iptablesContext *iptables; iptablesContext *iptables;
brControl *brctl;
char *networkConfigDir; char *networkConfigDir;
char *networkAutostartDir; char *networkAutostartDir;
char *logDir; char *logDir;
@ -212,7 +211,7 @@ networkFindActiveConfigs(struct network_driver *driver) {
/* If bridge exists, then mark it active */ /* If bridge exists, then mark it active */
if (obj->def->bridge && if (obj->def->bridge &&
brHasBridge(driver->brctl, obj->def->bridge) == 0) { brHasBridge(obj->def->bridge) == 0) {
obj->active = 1; obj->active = 1;
/* Try and read dnsmasq/radvd pids if any */ /* Try and read dnsmasq/radvd pids if any */
@ -263,7 +262,6 @@ static int
networkStartup(int privileged) { networkStartup(int privileged) {
uid_t uid = geteuid(); uid_t uid = geteuid();
char *base = NULL; char *base = NULL;
int err;
if (VIR_ALLOC(driverState) < 0) if (VIR_ALLOC(driverState) < 0)
goto error; goto error;
@ -312,12 +310,6 @@ networkStartup(int privileged) {
VIR_FREE(base); VIR_FREE(base);
if ((err = brInit(&driverState->brctl))) {
virReportSystemError(err, "%s",
_("cannot initialize bridge support"));
goto error;
}
if (!(driverState->iptables = iptablesContextNew())) { if (!(driverState->iptables = iptablesContextNew())) {
goto out_of_memory; goto out_of_memory;
} }
@ -416,8 +408,6 @@ networkShutdown(void) {
VIR_FREE(driverState->networkConfigDir); VIR_FREE(driverState->networkConfigDir);
VIR_FREE(driverState->networkAutostartDir); VIR_FREE(driverState->networkAutostartDir);
if (driverState->brctl)
brShutdown(driverState->brctl);
if (driverState->iptables) if (driverState->iptables)
iptablesContextFree(driverState->iptables); iptablesContextFree(driverState->iptables);
@ -1675,8 +1665,7 @@ out:
} }
static int static int
networkAddAddrToBridge(struct network_driver *driver, networkAddAddrToBridge(virNetworkObjPtr network,
virNetworkObjPtr network,
virNetworkIpDefPtr ipdef) virNetworkIpDefPtr ipdef)
{ {
int prefix = virNetworkIpDefPrefix(ipdef); int prefix = virNetworkIpDefPrefix(ipdef);
@ -1688,7 +1677,7 @@ networkAddAddrToBridge(struct network_driver *driver,
return -1; return -1;
} }
if (brAddInetAddress(driver->brctl, network->def->bridge, if (brAddInetAddress(network->def->bridge,
&ipdef->address, prefix) < 0) { &ipdef->address, prefix) < 0) {
networkReportError(VIR_ERR_INTERNAL_ERROR, networkReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot set IP address on bridge '%s'"), _("cannot set IP address on bridge '%s'"),
@ -1714,7 +1703,7 @@ networkStartNetworkVirtual(struct network_driver *driver,
return -1; return -1;
/* Create and configure the bridge device */ /* Create and configure the bridge device */
if ((err = brAddBridge(driver->brctl, network->def->bridge))) { if ((err = brAddBridge(network->def->bridge))) {
virReportSystemError(err, virReportSystemError(err,
_("cannot create bridge '%s'"), _("cannot create bridge '%s'"),
network->def->bridge); network->def->bridge);
@ -1733,7 +1722,7 @@ networkStartNetworkVirtual(struct network_driver *driver,
virReportOOMError(); virReportOOMError();
goto err0; goto err0;
} }
if ((err = brAddTap(driver->brctl, network->def->bridge, if ((err = brAddTap(network->def->bridge,
&macTapIfName, network->def->mac, 0, false, NULL))) { &macTapIfName, network->def->mac, 0, false, NULL))) {
virReportSystemError(err, virReportSystemError(err,
_("cannot create dummy tap device '%s' to set mac" _("cannot create dummy tap device '%s' to set mac"
@ -1745,7 +1734,7 @@ networkStartNetworkVirtual(struct network_driver *driver,
} }
/* Set bridge options */ /* Set bridge options */
if (brSetForwardDelay(driver->brctl, network->def->bridge, if (brSetForwardDelay(network->def->bridge,
network->def->delay)) { network->def->delay)) {
networkReportError(VIR_ERR_INTERNAL_ERROR, networkReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot set forward delay on bridge '%s'"), _("cannot set forward delay on bridge '%s'"),
@ -1753,7 +1742,7 @@ networkStartNetworkVirtual(struct network_driver *driver,
goto err1; goto err1;
} }
if (brSetEnableSTP(driver->brctl, network->def->bridge, if (brSetEnableSTP(network->def->bridge,
network->def->stp ? 1 : 0)) { network->def->stp ? 1 : 0)) {
networkReportError(VIR_ERR_INTERNAL_ERROR, networkReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot set STP '%s' on bridge '%s'"), _("cannot set STP '%s' on bridge '%s'"),
@ -1780,13 +1769,13 @@ networkStartNetworkVirtual(struct network_driver *driver,
v6present = true; v6present = true;
/* Add the IP address/netmask to the bridge */ /* Add the IP address/netmask to the bridge */
if (networkAddAddrToBridge(driver, network, ipdef) < 0) { if (networkAddAddrToBridge(network, ipdef) < 0) {
goto err2; goto err2;
} }
} }
/* Bring up the bridge interface */ /* Bring up the bridge interface */
if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) { if ((err = brSetInterfaceUp(network->def->bridge, 1))) {
virReportSystemError(err, virReportSystemError(err,
_("failed to bring the bridge '%s' up"), _("failed to bring the bridge '%s' up"),
network->def->bridge); network->def->bridge);
@ -1839,7 +1828,7 @@ networkStartNetworkVirtual(struct network_driver *driver,
err3: err3:
if (!save_err) if (!save_err)
save_err = virSaveLastError(); save_err = virSaveLastError();
if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) { if ((err = brSetInterfaceUp(network->def->bridge, 0))) {
char ebuf[1024]; char ebuf[1024];
VIR_WARN("Failed to bring down bridge '%s' : %s", VIR_WARN("Failed to bring down bridge '%s' : %s",
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
@ -1854,7 +1843,7 @@ networkStartNetworkVirtual(struct network_driver *driver,
if (!save_err) if (!save_err)
save_err = virSaveLastError(); save_err = virSaveLastError();
if ((err = brDeleteTap(driver->brctl, macTapIfName))) { if ((err = brDeleteTap(macTapIfName))) {
char ebuf[1024]; char ebuf[1024];
VIR_WARN("Failed to delete dummy tap device '%s' on bridge '%s' : %s", VIR_WARN("Failed to delete dummy tap device '%s' on bridge '%s' : %s",
macTapIfName, network->def->bridge, macTapIfName, network->def->bridge,
@ -1865,7 +1854,7 @@ networkStartNetworkVirtual(struct network_driver *driver,
err0: err0:
if (!save_err) if (!save_err)
save_err = virSaveLastError(); save_err = virSaveLastError();
if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) { if ((err = brDeleteBridge(network->def->bridge))) {
char ebuf[1024]; char ebuf[1024];
VIR_WARN("Failed to delete bridge '%s' : %s", VIR_WARN("Failed to delete bridge '%s' : %s",
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
@ -1910,7 +1899,7 @@ static int networkShutdownNetworkVirtual(struct network_driver *driver,
if (!macTapIfName) { if (!macTapIfName) {
virReportOOMError(); virReportOOMError();
} else { } else {
if ((err = brDeleteTap(driver->brctl, macTapIfName))) { if ((err = brDeleteTap(macTapIfName))) {
VIR_WARN("Failed to delete dummy tap device '%s' on bridge '%s' : %s", VIR_WARN("Failed to delete dummy tap device '%s' on bridge '%s' : %s",
macTapIfName, network->def->bridge, macTapIfName, network->def->bridge,
virStrerror(err, ebuf, sizeof ebuf)); 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", VIR_WARN("Failed to bring down bridge '%s' : %s",
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
} }
networkRemoveIptablesRules(driver, network); 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", VIR_WARN("Failed to delete bridge '%s' : %s",
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf)); network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
} }

View File

@ -261,12 +261,6 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
return -1; return -1;
} }
if (!driver->brctl && (err = brInit(&driver->brctl))) {
virReportSystemError(err, "%s",
_("cannot initialize bridge support"));
goto cleanup;
}
if (!net->ifname || if (!net->ifname ||
STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) || STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) ||
strchr(net->ifname, '%')) { strchr(net->ifname, '%')) {
@ -285,7 +279,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); memcpy(tapmac, net->mac, VIR_MAC_BUFLEN);
tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ 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); vnet_hdr, true, &tapfd);
virDomainAuditNetDevice(def, net, "/dev/net/tun", tapfd >= 0); virDomainAuditNetDevice(def, net, "/dev/net/tun", tapfd >= 0);
if (err) { if (err) {

View File

@ -69,7 +69,6 @@ struct qemud_driver {
virDomainObjList domains; virDomainObjList domains;
brControl *brctl;
/* These four directories are ones libvirtd uses (so must be root:root /* These four directories are ones libvirtd uses (so must be root:root
* to avoid security risk from QEMU processes */ * to avoid security risk from QEMU processes */
char *configDir; char *configDir;

View File

@ -815,9 +815,6 @@ qemudShutdown(void) {
/* Free domain callback list */ /* Free domain callback list */
virDomainEventStateFree(qemu_driver->domainEventState); virDomainEventStateFree(qemu_driver->domainEventState);
if (qemu_driver->brctl)
brShutdown(qemu_driver->brctl);
virCgroupFree(&qemu_driver->cgroup); virCgroupFree(&qemu_driver->cgroup);
virLockManagerPluginUnref(qemu_driver->lockManager); virLockManagerPluginUnref(qemu_driver->lockManager);

View File

@ -121,17 +121,10 @@ umlConnectTapDevice(virConnectPtr conn,
virDomainNetDefPtr net, virDomainNetDefPtr net,
const char *bridge) const char *bridge)
{ {
brControl *brctl = NULL;
bool template_ifname = false; bool template_ifname = false;
int err; int err;
unsigned char tapmac[VIR_MAC_BUFLEN]; unsigned char tapmac[VIR_MAC_BUFLEN];
if ((err = brInit(&brctl))) {
virReportSystemError(err, "%s",
_("cannot initialize bridge support"));
goto error;
}
if (!net->ifname || if (!net->ifname ||
STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) || STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) ||
strchr(net->ifname, '%')) { strchr(net->ifname, '%')) {
@ -144,8 +137,7 @@ umlConnectTapDevice(virConnectPtr conn,
memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); memcpy(tapmac, net->mac, VIR_MAC_BUFLEN);
tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */
if ((err = brAddTap(brctl, if ((err = brAddTap(bridge,
bridge,
&net->ifname, &net->ifname,
tapmac, tapmac,
0, 0,
@ -183,14 +175,11 @@ umlConnectTapDevice(virConnectPtr conn,
} }
} }
brShutdown(brctl);
return 0; return 0;
no_memory: no_memory:
virReportOOMError(); virReportOOMError();
error: error:
brShutdown(brctl);
return -1; return -1;
} }

View File

@ -52,7 +52,6 @@ struct uml_driver {
virDomainObjList domains; virDomainObjList domains;
brControl *brctl;
char *configDir; char *configDir;
char *autostartDir; char *autostartDir;
char *logDir; char *logDir;

View File

@ -627,9 +627,6 @@ umlShutdown(void) {
umlProcessAutoDestroyShutdown(uml_driver); umlProcessAutoDestroyShutdown(uml_driver);
if (uml_driver->brctl)
brShutdown(uml_driver->brctl);
umlDriverUnlock(uml_driver); umlDriverUnlock(uml_driver);
virMutexDestroy(&uml_driver->lock); virMutexDestroy(&uml_driver->lock);
VIR_FREE(uml_driver); VIR_FREE(uml_driver);
@ -959,10 +956,7 @@ static int umlCleanupTapDevices(virDomainObjPtr vm) {
int i; int i;
int err; int err;
int ret = 0; int ret = 0;
brControl *brctl = NULL;
VIR_ERROR(_("Cleanup tap")); VIR_ERROR(_("Cleanup tap"));
if (brInit(&brctl) < 0)
return -1;
for (i = 0 ; i < vm->def->nnets ; i++) { for (i = 0 ; i < vm->def->nnets ; i++) {
virDomainNetDefPtr def = vm->def->nets[i]; virDomainNetDefPtr def = vm->def->nets[i];
@ -972,14 +966,13 @@ static int umlCleanupTapDevices(virDomainObjPtr vm) {
continue; continue;
VIR_ERROR(_("Cleanup '%s'"), def->ifname); VIR_ERROR(_("Cleanup '%s'"), def->ifname);
err = brDeleteTap(brctl, def->ifname); err = brDeleteTap(def->ifname);
if (err) { if (err) {
VIR_ERROR(_("Cleanup failed %d"), err); VIR_ERROR(_("Cleanup failed %d"), err);
ret = -1; ret = -1;
} }
} }
VIR_ERROR(_("Cleanup tap done")); VIR_ERROR(_("Cleanup tap done"));
brShutdown(brctl);
return ret; return ret;
} }

View File

@ -55,61 +55,45 @@
# define JIFFIES_TO_MS(j) (((j)*1000)/HZ) # define JIFFIES_TO_MS(j) (((j)*1000)/HZ)
# define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000) # define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000)
struct _brControl {
int fd;
};
/** static int brSetupControlFull(const char *ifname,
* brInit: struct ifreq *ifr,
* @ctlp: pointer to bridge control return value int domain,
* int type)
* 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)
{ {
int fd; int fd;
if (!ctlp || *ctlp) if (ifname && ifr) {
return EINVAL; memset(ifr, 0, sizeof(*ifr));
fd = socket(AF_INET, SOCK_STREAM, 0); if (virStrcpyStatic(ifr->ifr_name, ifname) == NULL) {
if (fd < 0 || errno = EINVAL;
virSetCloseExec(fd) < 0 || return -1;
VIR_ALLOC(*ctlp) < 0) { }
VIR_FORCE_CLOSE(fd);
return errno;
} }
(*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;
}
return fd;
} }
/**
* brShutdown: static int brSetupControl(const char *ifname,
* @ctl: pointer to a bridge control struct ifreq *ifr)
*
* Shutdown the bridge layer and deallocate the associated structures
*/
void
brShutdown(brControl *ctl)
{ {
if (!ctl) return brSetupControlFull(ifname, ifr, AF_PACKET, SOCK_DGRAM);
return;
VIR_FORCE_CLOSE(ctl->fd);
VIR_FREE(ctl);
} }
/** /**
* brAddBridge: * brAddBridge:
* @ctl: bridge control pointer * @brname: the bridge name
* @name: the bridge name
* *
* This function register a new bridge * This function register a new bridge
* *
@ -117,20 +101,27 @@ brShutdown(brControl *ctl)
*/ */
# ifdef SIOCBRADDBR # ifdef SIOCBRADDBR
int int
brAddBridge(brControl *ctl, brAddBridge(const char *brname)
const char *name)
{ {
if (!ctl || !ctl->fd || !name) int fd = -1;
return EINVAL; int ret = -1;
if (ioctl(ctl->fd, SIOCBRADDBR, name) == 0) if ((fd = brSetupControl(NULL, NULL)) < 0)
return 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 # else
int brAddBridge (brControl *ctl ATTRIBUTE_UNUSED, int brAddBridge (const char *brname ATTRIBUTE_UNUSED)
const char *name ATTRIBUTE_UNUSED)
{ {
return EINVAL; return EINVAL;
} }
@ -138,32 +129,27 @@ int brAddBridge (brControl *ctl ATTRIBUTE_UNUSED,
# ifdef SIOCBRDELBR # ifdef SIOCBRDELBR
int int
brHasBridge(brControl *ctl, brHasBridge(const char *brname)
const char *name)
{ {
int fd = -1;
int ret = -1;
struct ifreq ifr; struct ifreq ifr;
if (!ctl || !name) { if ((fd = brSetupControl(brname, &ifr)) < 0)
errno = EINVAL; return errno;
return -1;
}
memset(&ifr, 0, sizeof(struct ifreq)); if (ioctl(fd, SIOCGIFFLAGS, &ifr))
goto cleanup;
if (virStrcpyStatic(ifr.ifr_name, name) == NULL) { ret = 0;
errno = EINVAL;
return -1;
}
if (ioctl(ctl->fd, SIOCGIFFLAGS, &ifr)) cleanup:
return -1; VIR_FORCE_CLOSE(fd);
return ret;
return 0;
} }
# else # else
int int
brHasBridge(brControl *ctl ATTRIBUTE_UNUSED, brHasBridge(const char *brname ATTRIBUTE_UNUSED)
const char *name ATTRIBUTE_UNUSED)
{ {
return EINVAL; return EINVAL;
} }
@ -171,8 +157,7 @@ brHasBridge(brControl *ctl ATTRIBUTE_UNUSED,
/** /**
* brDeleteBridge: * brDeleteBridge:
* @ctl: bridge control pointer * @brname: the bridge name
* @name: the bridge name
* *
* Remove a bridge from the layer. * Remove a bridge from the layer.
* *
@ -180,52 +165,37 @@ brHasBridge(brControl *ctl ATTRIBUTE_UNUSED,
*/ */
# ifdef SIOCBRDELBR # ifdef SIOCBRDELBR
int int
brDeleteBridge(brControl *ctl, brDeleteBridge(const char *brname)
const char *name)
{ {
if (!ctl || !ctl->fd || !name) int fd = -1;
return EINVAL; int ret = -1;
return ioctl(ctl->fd, SIOCBRDELBR, name) == 0 ? 0 : errno; if ((fd = brSetupControl(NULL, NULL)) < 0)
return errno;
if (ioctl(fd, SIOCBRDELBR, brname) < 0) {
ret = errno;
goto cleanup;
}
ret = 0;
cleanup:
VIR_FORCE_CLOSE(fd);
return ret;
} }
# else # else
int int
brDeleteBridge(brControl *ctl ATTRIBUTE_UNUSED, brDeleteBridge(const char *brname ATTRIBUTE_UNUSED)
const char *name ATTRIBUTE_UNUSED)
{ {
return EINVAL; return EINVAL;
} }
# endif # 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: * brAddInterface:
* @ctl: bridge control pointer * @brname: the bridge name
* @bridge: the bridge name * @ifname: the network interface name
* @iface: the network interface name
* *
* Adds an interface to a bridge * Adds an interface to a bridge
* *
@ -233,17 +203,35 @@ brAddDelInterface(brControl *ctl,
*/ */
# ifdef SIOCBRADDIF # ifdef SIOCBRADDIF
int int
brAddInterface(brControl *ctl, brAddInterface(const char *brname,
const char *bridge, const char *ifname)
const char *iface)
{ {
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 # else
int int
brAddInterface(brControl *ctl ATTRIBUTE_UNUSED, brAddInterface(const char *brname ATTRIBUTE_UNUSED,
const char *bridge ATTRIBUTE_UNUSED, const char *ifname ATTRIBUTE_UNUSED)
const char *iface ATTRIBUTE_UNUSED)
{ {
return EINVAL; return EINVAL;
} }
@ -251,9 +239,8 @@ brAddInterface(brControl *ctl ATTRIBUTE_UNUSED,
/** /**
* brDeleteInterface: * brDeleteInterface:
* @ctl: bridge control pointer * @brname: the bridge name
* @bridge: the bridge name * @ifname: the network interface name
* @iface: the network interface name
* *
* Removes an interface from a bridge * Removes an interface from a bridge
* *
@ -261,17 +248,35 @@ brAddInterface(brControl *ctl ATTRIBUTE_UNUSED,
*/ */
# ifdef SIOCBRDELIF # ifdef SIOCBRDELIF
int int
brDeleteInterface(brControl *ctl, brDeleteInterface(const char *brname,
const char *bridge, const char *ifname)
const char *iface)
{ {
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 # else
int int
brDeleteInterface(brControl *ctl ATTRIBUTE_UNUSED, brDeleteInterface(const char *brname ATTRIBUTE_UNUSED,
const char *bridge ATTRIBUTE_UNUSED, const char *ifname ATTRIBUTE_UNUSED)
const char *iface ATTRIBUTE_UNUSED)
{ {
return EINVAL; return EINVAL;
} }
@ -279,7 +284,6 @@ brDeleteInterface(brControl *ctl ATTRIBUTE_UNUSED,
/** /**
* brSetInterfaceMac: * brSetInterfaceMac:
* @ctl: bridge control pointer
* @ifname: interface name to set MTU for * @ifname: interface name to set MTU for
* @macaddr: MAC address (VIR_MAC_BUFLEN in size) * @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. * Returns 0 in case of success or an errno code in case of failure.
*/ */
int int
brSetInterfaceMac(brControl *ctl, const char *ifname, brSetInterfaceMac(const char *ifname,
const unsigned char *macaddr) const unsigned char *macaddr)
{ {
int fd = -1;
int ret = -1;
struct ifreq ifr; struct ifreq ifr;
if (!ctl || !ifname) if ((fd = brSetupControl(ifname, &ifr)) < 0)
return EINVAL; return errno;
memset(&ifr, 0, sizeof(struct ifreq));
if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL)
return EINVAL;
/* To fill ifr.ifr_hdaddr.sa_family field */ /* To fill ifr.ifr_hdaddr.sa_family field */
if (ioctl(ctl->fd, SIOCGIFHWADDR, &ifr) != 0) if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
return errno; ret = errno;
goto cleanup;
}
memcpy(ifr.ifr_hwaddr.sa_data, macaddr, VIR_MAC_BUFLEN); 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 * ifGetMtu
* @ctl: bridge control pointer
* @ifname: interface name get MTU for * @ifname: interface name get MTU for
* *
* This function gets the @mtu value set for a given interface @ifname. * 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. * Returns the MTU value in case of success.
* On error, returns -1 and sets errno accordingly * 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; struct ifreq ifr;
if (!ctl || !ifname) { if ((fd = brSetupControl(ifname, &ifr)) < 0)
errno = EINVAL;
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; return -1;
return ifr.ifr_mtu; if (ioctl(fd, SIOCGIFMTU, &ifr) < 0)
goto cleanup;
ret = ifr.ifr_mtu;
cleanup:
VIR_FORCE_CLOSE(fd);
return ret;
} }
/** /**
* ifSetMtu: * ifSetMtu:
* @ctl: bridge control pointer
* @ifname: interface name to set MTU for * @ifname: interface name to set MTU for
* @mtu: MTU value * @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. * 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; struct ifreq ifr;
if (!ctl || !ifname) if ((fd = brSetupControl(ifname, &ifr)) < 0)
return EINVAL; return errno;
memset(&ifr, 0, sizeof(struct ifreq));
if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL)
return EINVAL;
ifr.ifr_mtu = mtu; 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 * brSetInterfaceMtu
* @ctl: bridge control pointer * @brname: name of the bridge interface
* @bridge: name of the bridge interface
* @ifname: name of the interface whose MTU we want to set * @ifname: name of the interface whose MTU we want to set
* *
* Sets the interface mtu to the same MTU of the bridge * 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 an errno code in case of failure.
*/ */
static int brSetInterfaceMtu(brControl *ctl, static int brSetInterfaceMtu(const char *brname,
const char *bridge,
const char *ifname) const char *ifname)
{ {
int mtu = ifGetMtu(ctl, bridge); int mtu = ifGetMtu(brname);
if (mtu < 0) if (mtu < 0)
return errno; return errno;
return ifSetMtu(ctl, ifname, mtu); return ifSetMtu(ifname, mtu);
} }
/** /**
@ -453,8 +465,7 @@ brProbeVnetHdr(int tapfd)
/** /**
* brAddTap: * brAddTap:
* @ctl: bridge control pointer * @brname: the bridge name
* @bridge: the bridge name
* @ifname: the interface name (or name template) * @ifname: the interface name (or name template)
* @macaddr: desired MAC address (VIR_MAC_BUFLEN long) * @macaddr: desired MAC address (VIR_MAC_BUFLEN long)
* @vnet_hdr: whether to try enabling IFF_VNET_HDR * @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. * Returns 0 in case of success or an errno code in case of failure.
*/ */
int int
brAddTap(brControl *ctl, brAddTap(const char *brname,
const char *bridge,
char **ifname, char **ifname,
const unsigned char *macaddr, const unsigned char *macaddr,
int vnet_hdr, int vnet_hdr,
bool up, bool up,
int *tapfd) int *tapfd)
{ {
if (!ctl || !ctl->fd || !bridge || !ifname) errno = brCreateTap(ifname, vnet_hdr, tapfd);
return EINVAL;
errno = brCreateTap(ctl, ifname, vnet_hdr, tapfd);
/* fd has been closed in brCreateTap() when it failed. */ /* fd has been closed in brCreateTap() when it failed. */
if (errno) if (errno)
@ -494,18 +501,19 @@ brAddTap(brControl *ctl,
* seeing the kernel allocate random MAC for the TAP * seeing the kernel allocate random MAC for the TAP
* device before we set our static MAC. * device before we set our static MAC.
*/ */
if ((errno = brSetInterfaceMac(ctl, *ifname, macaddr))) if ((errno = brSetInterfaceMac(*ifname, macaddr)))
goto close_fd; goto close_fd;
/* We need to set the interface MTU before adding it /* We need to set the interface MTU before adding it
* to the bridge, because the bridge will have its * to the bridge, because the bridge will have its
* MTU adjusted automatically when we add the new interface. * MTU adjusted automatically when we add the new interface.
*/ */
if ((errno = brSetInterfaceMtu(ctl, bridge, *ifname))) if ((errno = brSetInterfaceMtu(brname, *ifname)))
goto close_fd; goto close_fd;
if ((errno = brAddInterface(ctl, bridge, *ifname))) if ((errno = brAddInterface(brname, *ifname)))
goto close_fd; goto close_fd;
if (up && ((errno = brSetInterfaceUp(ctl, *ifname, 1)))) if (up && ((errno = brSetInterfaceUp(*ifname, 1))))
goto close_fd; goto close_fd;
return 0; return 0;
close_fd: close_fd:
@ -515,15 +523,11 @@ error:
return errno; return errno;
} }
int brDeleteTap(brControl *ctl, int brDeleteTap(const char *ifname)
const char *ifname)
{ {
struct ifreq try; struct ifreq try;
int fd; int fd;
if (!ctl || !ctl->fd || !ifname)
return EINVAL;
if ((fd = open("/dev/net/tun", O_RDWR)) < 0) if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
return errno; return errno;
@ -549,7 +553,6 @@ int brDeleteTap(brControl *ctl,
/** /**
* brSetInterfaceUp: * brSetInterfaceUp:
* @ctl: bridge control pointer
* @ifname: the interface name * @ifname: the interface name
* @up: 1 for up, 0 for down * @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. * Returns 0 in case of success or an errno code in case of failure.
*/ */
int int
brSetInterfaceUp(brControl *ctl, brSetInterfaceUp(const char *ifname,
const char *ifname,
int up) int up)
{ {
int fd = -1;
int ret = -1;
struct ifreq ifr; struct ifreq ifr;
int ifflags; int ifflags;
if (!ctl || !ifname) if ((fd = brSetupControl(ifname, &ifr)) < 0)
return EINVAL;
memset(&ifr, 0, sizeof(struct ifreq));
if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL)
return EINVAL;
if (ioctl(ctl->fd, SIOCGIFFLAGS, &ifr) < 0)
return errno; 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) { if (ifr.ifr_flags != ifflags) {
ifr.ifr_flags = ifflags; ifr.ifr_flags = ifflags;
if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
if (ioctl(ctl->fd, SIOCSIFFLAGS, &ifr) < 0) ret = errno;
return errno; goto cleanup;
}
} }
return 0; ret = 0;
cleanup:
VIR_FORCE_CLOSE(fd);
return ret;
} }
/** /**
* brGetInterfaceUp: * brGetInterfaceUp:
* @ctl: bridge control pointer
* @ifname: the interface name * @ifname: the interface name
* @up: where to store the status * @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. * Returns 0 in case of success or an errno code in case of failure.
*/ */
int int
brGetInterfaceUp(brControl *ctl, brGetInterfaceUp(const char *ifname,
const char *ifname,
int *up) int *up)
{ {
int fd = -1;
int ret = -1;
struct ifreq ifr; struct ifreq ifr;
if (!ctl || !ifname || !up) if ((fd = brSetupControl(ifname, &ifr)) < 0)
return EINVAL;
memset(&ifr, 0, sizeof(struct ifreq));
if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL)
return EINVAL;
if (ioctl(ctl->fd, SIOCGIFFLAGS, &ifr) < 0)
return errno; return errno;
*up = (ifr.ifr_flags & IFF_UP) ? 1 : 0; if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
ret = errno;
goto cleanup;
}
return 0; *up = (ifr.ifr_flags & IFF_UP) ? 1 : 0;
ret = 0;
cleanup:
VIR_FORCE_CLOSE(fd);
return ret;
} }
/** /**
* brAddInetAddress: * brAddInetAddress:
* @ctl: bridge control pointer
* @ifname: the interface name * @ifname: the interface name
* @addr: the IP address (IPv4 or IPv6) * @addr: the IP address (IPv4 or IPv6)
* @prefix: number of 1 bits in the netmask * @prefix: number of 1 bits in the netmask
@ -636,8 +644,7 @@ brGetInterfaceUp(brControl *ctl,
*/ */
int int
brAddInetAddress(brControl *ctl ATTRIBUTE_UNUSED, brAddInetAddress(const char *ifname,
const char *ifname,
virSocketAddr *addr, virSocketAddr *addr,
unsigned int prefix) unsigned int prefix)
{ {
@ -674,7 +681,6 @@ cleanup:
/** /**
* brDelInetAddress: * brDelInetAddress:
* @ctl: bridge control pointer
* @ifname: the interface name * @ifname: the interface name
* @addr: the IP address (IPv4 or IPv6) * @addr: the IP address (IPv4 or IPv6)
* @prefix: number of 1 bits in the netmask * @prefix: number of 1 bits in the netmask
@ -685,8 +691,7 @@ cleanup:
*/ */
int int
brDelInetAddress(brControl *ctl ATTRIBUTE_UNUSED, brDelInetAddress(const char *ifname,
const char *ifname,
virSocketAddr *addr, virSocketAddr *addr,
unsigned int prefix) unsigned int prefix)
{ {
@ -713,8 +718,7 @@ cleanup:
/** /**
* brSetForwardDelay: * brSetForwardDelay:
* @ctl: bridge control pointer * @brname: the bridge name
* @bridge: the bridge name
* @delay: delay in seconds * @delay: delay in seconds
* *
* Set the bridge forward delay * Set the bridge forward delay
@ -723,15 +727,14 @@ cleanup:
*/ */
int int
brSetForwardDelay(brControl *ctl ATTRIBUTE_UNUSED, brSetForwardDelay(const char *brname,
const char *bridge,
int delay) int delay)
{ {
virCommandPtr cmd; virCommandPtr cmd;
int ret = -1; int ret = -1;
cmd = virCommandNew(BRCTL); cmd = virCommandNew(BRCTL);
virCommandAddArgList(cmd, "setfd", bridge, NULL); virCommandAddArgList(cmd, "setfd", brname, NULL);
virCommandAddArgFormat(cmd, "%d", delay); virCommandAddArgFormat(cmd, "%d", delay);
if (virCommandRun(cmd, NULL) < 0) if (virCommandRun(cmd, NULL) < 0)
@ -745,8 +748,7 @@ cleanup:
/** /**
* brSetEnableSTP: * brSetEnableSTP:
* @ctl: bridge control pointer * @brname: the bridge name
* @bridge: the bridge name
* @enable: 1 to enable, 0 to disable * @enable: 1 to enable, 0 to disable
* *
* Control whether the bridge participates in the spanning tree protocol, * 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 * Returns 0 in case of success or -1 on failure
*/ */
int int
brSetEnableSTP(brControl *ctl ATTRIBUTE_UNUSED, brSetEnableSTP(const char *brname,
const char *bridge,
int enable) int enable)
{ {
virCommandPtr cmd; virCommandPtr cmd;
int ret = -1; int ret = -1;
cmd = virCommandNew(BRCTL); cmd = virCommandNew(BRCTL);
virCommandAddArgList(cmd, "stp", bridge, virCommandAddArgList(cmd, "stp", brname,
enable ? "on" : "off", enable ? "on" : "off",
NULL); NULL);
@ -778,7 +779,6 @@ cleanup:
/** /**
* brCreateTap: * brCreateTap:
* @ctl: bridge control pointer
* @ifname: the interface name * @ifname: the interface name
* @vnet_hr: whether to try enabling IFF_VNET_HDR * @vnet_hr: whether to try enabling IFF_VNET_HDR
* @tapfd: file descriptor return value for the new tap device * @tapfd: file descriptor return value for the new tap device
@ -793,17 +793,13 @@ cleanup:
*/ */
int int
brCreateTap(brControl *ctl ATTRIBUTE_UNUSED, brCreateTap(char **ifname,
char **ifname,
int vnet_hdr ATTRIBUTE_UNUSED, int vnet_hdr ATTRIBUTE_UNUSED,
int *tapfd) int *tapfd)
{ {
int fd; int fd;
struct ifreq ifr; struct ifreq ifr;
if (!ifname)
return EINVAL;
if ((fd = open("/dev/net/tun", O_RDWR)) < 0) if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
return errno; return errno;

View File

@ -42,78 +42,76 @@
*/ */
# define BR_INET_ADDR_MAXLEN INET_ADDRSTRLEN # 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); int brAddInterface (const char *brname,
void brShutdown (brControl *ctl); const char *ifname)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int brAddBridge (brControl *ctl, int brDeleteInterface (const char *brname,
const char *name); const char *ifname)
int brDeleteBridge (brControl *ctl, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
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);
enum { enum {
BR_TAP_VNET_HDR = (1 << 0), BR_TAP_VNET_HDR = (1 << 0),
BR_TAP_PERSIST = (1 << 1), BR_TAP_PERSIST = (1 << 1),
}; };
int brAddTap (brControl *ctl, int brAddTap (const char *brname,
const char *bridge,
char **ifname, char **ifname,
const unsigned char *macaddr, const unsigned char *macaddr,
int vnet_hdr, int vnet_hdr,
bool up, 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 brSetInterfaceUp (brControl *ctl, int brDeleteTap (const char *ifname)
const char *ifname, ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
int up);
int brGetInterfaceUp (brControl *ctl,
const char *ifname,
int *up);
int brAddInetAddress (brControl *ctl, int brSetInterfaceUp (const char *ifname,
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 (const char *ifname,
virSocketAddr *addr, virSocketAddr *addr,
unsigned int prefix); unsigned int prefix)
int brDelInetAddress (brControl *ctl, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
const char *ifname, int brDelInetAddress (const char *ifname,
virSocketAddr *addr, virSocketAddr *addr,
unsigned int prefix); unsigned int prefix)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int brSetForwardDelay (brControl *ctl, int brSetForwardDelay (const char *brname,
const char *bridge, int delay)
int delay); ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
int brGetForwardDelay (brControl *ctl, int brGetForwardDelay (const char *brname,
const char *bridge, int *delay)
int *delay); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int brSetEnableSTP (brControl *ctl, int brSetEnableSTP (const char *brname,
const char *bridge, int enable)
int enable); ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
int brGetEnableSTP (brControl *ctl, int brGetEnableSTP (const char *brname,
const char *bridge, int *enable)
int *enable); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
int brCreateTap (brControl *ctl, int brCreateTap (char **ifname,
char **ifname,
int vnet_hdr, int vnet_hdr,
int *tapfd); int *tapfd)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
int brSetInterfaceMac (brControl *ctl, int brSetInterfaceMac (const char *ifname,
const char *ifname, const unsigned char *macaddr)
const unsigned char *macaddr); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
# endif /* WITH_BRIDGE */ # endif /* WITH_BRIDGE */