mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 07:17:44 +00:00
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:
parent
85cf8d3899
commit
6cfeb9a766
@ -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]);
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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(¨_driver->lock);
|
virMutexDestroy(¨_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user