Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
/*
|
2015-03-17 19:45:01 +00:00
|
|
|
* Copyright (C) 2007-2015 Red Hat, Inc.
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
*
|
|
|
|
* 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
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 10:06:23 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Mark McLoughlin <markmc@redhat.com>
|
|
|
|
* Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "virnetdevbridge.h"
|
2013-06-19 16:47:30 +00:00
|
|
|
#include "virnetdev.h"
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2012-12-13 17:44:57 +00:00
|
|
|
#include "virutil.h"
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
#include "virfile.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
#include "intprops.h"
|
2013-04-03 10:36:23 +00:00
|
|
|
#include "virstring.h"
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
|
|
|
|
#include <sys/ioctl.h>
|
2012-09-04 14:57:09 +00:00
|
|
|
#include <sys/socket.h>
|
2012-09-05 22:27:42 +00:00
|
|
|
#include <net/if.h>
|
2013-01-14 17:47:41 +00:00
|
|
|
#include <netinet/in.h>
|
2012-09-04 14:57:09 +00:00
|
|
|
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
#ifdef __linux__
|
2014-11-20 16:55:50 +00:00
|
|
|
# if defined(HAVE_LIBNL)
|
|
|
|
# include "virnetlink.h"
|
|
|
|
# endif
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
# include <linux/sockios.h>
|
|
|
|
# include <linux/param.h> /* HZ */
|
2013-09-13 16:11:26 +00:00
|
|
|
# if NETINET_LINUX_WORKAROUND
|
2013-07-23 23:45:21 +00:00
|
|
|
/* Depending on the version of kernel vs. glibc, there may be a collision
|
|
|
|
* between <net/in.h> and kernel IPv6 structures. The different types
|
|
|
|
* are ABI compatible, but choke the C type system; work around it by
|
|
|
|
* using temporary redefinitions. */
|
2013-09-13 16:11:26 +00:00
|
|
|
# define in6_addr in6_addr_
|
|
|
|
# define sockaddr_in6 sockaddr_in6_
|
|
|
|
# define ipv6_mreq ipv6_mreq_
|
|
|
|
# define in6addr_any in6addr_any_
|
|
|
|
# define in6addr_loopback in6addr_loopback_
|
|
|
|
# endif
|
2013-07-23 23:45:21 +00:00
|
|
|
# include <linux/in6.h>
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
# include <linux/if_bridge.h> /* SYSFS_BRIDGE_ATTR */
|
2013-09-13 16:11:26 +00:00
|
|
|
# if NETINET_LINUX_WORKAROUND
|
|
|
|
# undef in6_addr
|
|
|
|
# undef sockaddr_in6
|
|
|
|
# undef ipv6_mreq
|
|
|
|
# undef in6addr_any
|
|
|
|
# undef in6addr_loopback
|
|
|
|
# endif
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
|
|
|
|
# define JIFFIES_TO_MS(j) (((j)*1000)/HZ)
|
|
|
|
# define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000)
|
|
|
|
#endif
|
|
|
|
|
2013-06-19 16:47:31 +00:00
|
|
|
#if defined(HAVE_BSD_BRIDGE_MGMT)
|
|
|
|
# include <net/ethernet.h>
|
|
|
|
# include <net/if_bridgevar.h>
|
|
|
|
#endif
|
|
|
|
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
|
|
|
|
|
|
2013-06-19 16:47:31 +00:00
|
|
|
#if defined(HAVE_BSD_BRIDGE_MGMT)
|
|
|
|
static int virNetDevBridgeCmd(const char *brname,
|
|
|
|
u_long op,
|
|
|
|
void *arg,
|
|
|
|
size_t argsize)
|
|
|
|
{
|
|
|
|
int s;
|
|
|
|
int ret = -1;
|
|
|
|
struct ifdrv ifd;
|
|
|
|
|
|
|
|
memset(&ifd, 0, sizeof(ifd));
|
|
|
|
|
|
|
|
if ((s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) {
|
|
|
|
virReportSystemError(errno, "%s",
|
|
|
|
_("Cannot open network interface control socket"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virStrcpyStatic(ifd.ifd_name, brname) == NULL) {
|
|
|
|
virReportSystemError(ERANGE,
|
|
|
|
_("Network interface name '%s' is too long"),
|
|
|
|
brname);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ifd.ifd_cmd = op;
|
|
|
|
ifd.ifd_len = argsize;
|
|
|
|
ifd.ifd_data = arg;
|
|
|
|
|
|
|
|
ret = ioctl(s, SIOCSDRVSPEC, &ifd);
|
|
|
|
|
2014-03-25 06:53:22 +00:00
|
|
|
cleanup:
|
2013-06-19 16:47:31 +00:00
|
|
|
VIR_FORCE_CLOSE(s);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-03-07 16:36:57 +00:00
|
|
|
#if defined(HAVE_STRUCT_IFREQ) && defined(__linux__)
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2015-04-15 09:45:47 +00:00
|
|
|
if (virAsprintf(&path, SYSFS_NET_DIR "%s/bridge/%s", brname, paramname) < 0)
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
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;
|
2014-03-25 06:53:22 +00:00
|
|
|
cleanup:
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
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;
|
|
|
|
|
2015-04-15 09:45:47 +00:00
|
|
|
if (virAsprintf(&path, SYSFS_NET_DIR "%s/bridge/%s", brname, paramname) < 0)
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (virFileExists(path)) {
|
|
|
|
char *valuestr;
|
2011-11-30 05:57:11 +00:00
|
|
|
if (virFileReadAll(path, INT_BUFSIZE_BOUND(unsigned long),
|
|
|
|
&valuestr) < 0)
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virStrToLong_ul(valuestr, NULL, 10, value) < 0) {
|
|
|
|
virReportSystemError(EINVAL,
|
2011-11-30 05:57:11 +00:00
|
|
|
_("Unable to get bridge %s %s"),
|
|
|
|
brname, paramname);
|
|
|
|
VIR_FREE(valuestr);
|
|
|
|
goto cleanup;
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
}
|
2011-11-30 05:57:11 +00:00
|
|
|
VIR_FREE(valuestr);
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
} 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;
|
2014-03-25 06:53:22 +00:00
|
|
|
cleanup:
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
VIR_FREE(path);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif /* __linux__ */
|
|
|
|
|
2014-11-19 18:28:57 +00:00
|
|
|
#if defined(__linux__)
|
|
|
|
static int
|
|
|
|
virNetDevBridgePortSet(const char *brname,
|
|
|
|
const char *ifname,
|
|
|
|
const char *paramname,
|
|
|
|
unsigned long value)
|
|
|
|
{
|
|
|
|
char *path = NULL;
|
|
|
|
char valuestr[INT_BUFSIZE_BOUND(value)];
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
snprintf(valuestr, sizeof(valuestr), "%lu", value);
|
|
|
|
|
2015-04-15 09:45:47 +00:00
|
|
|
if (virAsprintf(&path, SYSFS_NET_DIR "%s/brif/%s/%s",
|
|
|
|
brname, ifname, paramname) < 0)
|
2014-11-19 18:28:57 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!virFileExists(path))
|
|
|
|
errno = EINVAL;
|
|
|
|
else
|
|
|
|
ret = virFileWriteStr(path, valuestr, 0);
|
|
|
|
|
|
|
|
if (ret < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to set bridge %s port %s %s to %s"),
|
|
|
|
brname, ifname, paramname, valuestr);
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(path);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
virNetDevBridgePortGet(const char *brname,
|
|
|
|
const char *ifname,
|
|
|
|
const char *paramname,
|
|
|
|
unsigned long *value)
|
|
|
|
{
|
|
|
|
char *path = NULL;
|
|
|
|
char *valuestr = NULL;
|
|
|
|
int ret = -1;
|
|
|
|
|
2015-04-15 09:45:47 +00:00
|
|
|
if (virAsprintf(&path, SYSFS_NET_DIR "%s/brif/%s/%s",
|
|
|
|
brname, ifname, paramname) < 0)
|
2014-11-19 18:28:57 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
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 port %s %s"),
|
|
|
|
brname, ifname, paramname);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(path);
|
|
|
|
VIR_FREE(valuestr);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgePortGetLearning(const char *brname,
|
|
|
|
const char *ifname,
|
|
|
|
bool *enable)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
unsigned long value;
|
|
|
|
|
|
|
|
if (virNetDevBridgePortGet(brname, ifname, "learning", &value) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
*enable = !!value;
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgePortSetLearning(const char *brname,
|
|
|
|
const char *ifname,
|
|
|
|
bool enable)
|
|
|
|
{
|
|
|
|
return virNetDevBridgePortSet(brname, ifname, "learning", enable ? 1 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgePortGetUnicastFlood(const char *brname,
|
|
|
|
const char *ifname,
|
|
|
|
bool *enable)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
unsigned long value;
|
|
|
|
|
|
|
|
if (virNetDevBridgePortGet(brname, ifname, "unicast_flood", &value) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
*enable = !!value;
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgePortSetUnicastFlood(const char *brname,
|
|
|
|
const char *ifname,
|
|
|
|
bool enable)
|
|
|
|
{
|
|
|
|
return virNetDevBridgePortSet(brname, ifname, "unicast_flood", enable ? 1 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
int
|
|
|
|
virNetDevBridgePortGetLearning(const char *brname ATTRIBUTE_UNUSED,
|
|
|
|
const char *ifname ATTRIBUTE_UNUSED,
|
|
|
|
bool *enable ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to get bridge port learning on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgePortSetLearning(const char *brname ATTRIBUTE_UNUSED,
|
|
|
|
const char *ifname ATTRIBUTE_UNUSED,
|
2014-12-08 21:47:24 +00:00
|
|
|
bool enable ATTRIBUTE_UNUSED)
|
2014-11-19 18:28:57 +00:00
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to set bridge port learning on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgePortGetUnicastFlood(const char *brname ATTRIBUTE_UNUSED,
|
|
|
|
const char *ifname ATTRIBUTE_UNUSED,
|
|
|
|
bool *enable ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to get bridge port unicast_flood on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgePortSetUnicastFlood(const char *brname ATTRIBUTE_UNUSED,
|
|
|
|
const char *ifname ATTRIBUTE_UNUSED,
|
|
|
|
bool enable ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to set bridge port unicast_flood on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* virNetDevBridgeCreate:
|
|
|
|
* @brname: the bridge name
|
|
|
|
*
|
|
|
|
* This function register a new bridge
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success or -1 on failure
|
|
|
|
*/
|
2015-08-26 00:48:19 +00:00
|
|
|
#if defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRADDBR)
|
|
|
|
static int
|
|
|
|
virNetDevBridgeCreateWithIoctl(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;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
util: use netlink to create bridge devices
Just as it is possible to delete a bridge device with the netlink
RTM_DELLINK message, one can be created with the RTM_NEWLINK
message. Because of differences in the format of the message, it's not
as straightforward as with virNetlinkDelLink() to create a single
utility function that can be used to create any type of interface, so
the new netlink version of virNetDevBridgeCreate() does its own
construction of the netlink message and calls virNetlinkCommand()
itself.
This doesn't provide any extra functionality, just provides symmetry
with the previous commit.
NB: We *could* alter the API of virNetDevBridgeCreate() to take a MAC
address, and directly program that mac address into the bridge (by
adding an IFLA_ADDRESS attribute, as is done in
virNetDevMacVLanCreate()) rather than separately creating the "dummy
tap" (e.g. virbr0-nic) to maintain a fixed mac address on the bridge,
but the commit history of virnetdevbridge.c shows that the presence of
this dummy tap is essential in some older versions of the kernel
(between 2.6.39 and 3.1 or 3.2, possibly?) to proper operation of IPv6
DAD, and I don't want to take the chance of breaking something that I
don't have the time/setup to test (my RHEL6 box is at kernel
2.6.32-544, and the next lowest kernel I have is 3.17)
2015-03-23 18:17:44 +00:00
|
|
|
#if defined(__linux__) && defined(HAVE_LIBNL)
|
2015-08-26 00:48:19 +00:00
|
|
|
int
|
|
|
|
virNetDevBridgeCreate(const char *brname)
|
util: use netlink to create bridge devices
Just as it is possible to delete a bridge device with the netlink
RTM_DELLINK message, one can be created with the RTM_NEWLINK
message. Because of differences in the format of the message, it's not
as straightforward as with virNetlinkDelLink() to create a single
utility function that can be used to create any type of interface, so
the new netlink version of virNetDevBridgeCreate() does its own
construction of the netlink message and calls virNetlinkCommand()
itself.
This doesn't provide any extra functionality, just provides symmetry
with the previous commit.
NB: We *could* alter the API of virNetDevBridgeCreate() to take a MAC
address, and directly program that mac address into the bridge (by
adding an IFLA_ADDRESS attribute, as is done in
virNetDevMacVLanCreate()) rather than separately creating the "dummy
tap" (e.g. virbr0-nic) to maintain a fixed mac address on the bridge,
but the commit history of virnetdevbridge.c shows that the presence of
this dummy tap is essential in some older versions of the kernel
(between 2.6.39 and 3.1 or 3.2, possibly?) to proper operation of IPv6
DAD, and I don't want to take the chance of breaking something that I
don't have the time/setup to test (my RHEL6 box is at kernel
2.6.32-544, and the next lowest kernel I have is 3.17)
2015-03-23 18:17:44 +00:00
|
|
|
{
|
|
|
|
/* use a netlink RTM_NEWLINK message to create the bridge */
|
|
|
|
const char *type = "bridge";
|
|
|
|
int rc = -1;
|
|
|
|
struct nlmsghdr *resp = NULL;
|
|
|
|
struct nlmsgerr *err;
|
|
|
|
struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
|
|
|
|
unsigned int recvbuflen;
|
|
|
|
struct nl_msg *nl_msg;
|
|
|
|
struct nlattr *linkinfo;
|
|
|
|
|
|
|
|
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(nl_msg, IFLA_IFNAME, strlen(brname)+1, brname) < 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;
|
|
|
|
nla_nest_end(nl_msg, linkinfo);
|
|
|
|
|
|
|
|
if (virNetlinkCommand(nl_msg, &resp, &recvbuflen, 0, 0,
|
|
|
|
NETLINK_ROUTE, 0) < 0) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (recvbuflen < NLMSG_LENGTH(0) || resp == NULL)
|
|
|
|
goto malformed_resp;
|
|
|
|
|
|
|
|
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;
|
2015-08-26 00:48:19 +00:00
|
|
|
case -EOPNOTSUPP:
|
|
|
|
# if defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRADDBR)
|
|
|
|
/* fallback to ioctl if netlink doesn't support creating
|
|
|
|
* bridges
|
|
|
|
*/
|
|
|
|
rc = virNetDevBridgeCreateWithIoctl(brname);
|
|
|
|
goto cleanup;
|
|
|
|
# endif
|
|
|
|
/* intentionally fall through if virNetDevBridgeCreateWithIoctl()
|
|
|
|
* isn't available.
|
|
|
|
*/
|
util: use netlink to create bridge devices
Just as it is possible to delete a bridge device with the netlink
RTM_DELLINK message, one can be created with the RTM_NEWLINK
message. Because of differences in the format of the message, it's not
as straightforward as with virNetlinkDelLink() to create a single
utility function that can be used to create any type of interface, so
the new netlink version of virNetDevBridgeCreate() does its own
construction of the netlink message and calls virNetlinkCommand()
itself.
This doesn't provide any extra functionality, just provides symmetry
with the previous commit.
NB: We *could* alter the API of virNetDevBridgeCreate() to take a MAC
address, and directly program that mac address into the bridge (by
adding an IFLA_ADDRESS attribute, as is done in
virNetDevMacVLanCreate()) rather than separately creating the "dummy
tap" (e.g. virbr0-nic) to maintain a fixed mac address on the bridge,
but the commit history of virnetdevbridge.c shows that the presence of
this dummy tap is essential in some older versions of the kernel
(between 2.6.39 and 3.1 or 3.2, possibly?) to proper operation of IPv6
DAD, and I don't want to take the chance of breaking something that I
don't have the time/setup to test (my RHEL6 box is at kernel
2.6.32-544, and the next lowest kernel I have is 3.17)
2015-03-23 18:17:44 +00:00
|
|
|
default:
|
|
|
|
virReportSystemError(-err->error,
|
|
|
|
_("error creating bridge interface %s"),
|
|
|
|
brname);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NLMSG_DONE:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
goto malformed_resp;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
cleanup:
|
|
|
|
nlmsg_free(nl_msg);
|
|
|
|
VIR_FREE(resp);
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
malformed_resp:
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("malformed netlink response message"));
|
|
|
|
goto cleanup;
|
|
|
|
buffer_too_small:
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("allocated netlink buffer is too small"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
|
|
|
|
|
2015-08-26 00:48:19 +00:00
|
|
|
#elif defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRADDBR)
|
|
|
|
int
|
|
|
|
virNetDevBridgeCreate(const char *brname)
|
|
|
|
{
|
|
|
|
return virNetDevBridgeCreateWithIoctl(brname);
|
|
|
|
}
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
|
|
|
|
|
2013-06-19 16:47:30 +00:00
|
|
|
#elif defined(HAVE_STRUCT_IFREQ) && defined(SIOCIFCREATE2)
|
2015-08-26 00:48:19 +00:00
|
|
|
int
|
|
|
|
virNetDevBridgeCreate(const char *brname)
|
2013-06-19 16:47:30 +00:00
|
|
|
{
|
|
|
|
int s;
|
|
|
|
struct ifreq ifr;
|
|
|
|
int ret = - 1;
|
|
|
|
|
|
|
|
if ((s = virNetDevSetupControl("bridge", &ifr)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) {
|
|
|
|
virReportSystemError(errno, "%s",
|
|
|
|
_("Unable to create bridge device"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2014-11-13 14:28:18 +00:00
|
|
|
if (virNetDevSetName(ifr.ifr_name, brname) == -1)
|
2013-06-19 16:47:30 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:53:22 +00:00
|
|
|
cleanup:
|
2013-06-19 16:47:30 +00:00
|
|
|
VIR_FORCE_CLOSE(s);
|
|
|
|
return ret;
|
|
|
|
}
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
#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.
|
|
|
|
*/
|
util: fallback to ioctl(SIOCBRDELBR) if netlink RTM_DELLINK fails
commit 09778e09 switched from using ioctl(SIOCBRDELBR) for bridge
device deletion to using a netlink RTM_DELLINK message, which is the
more modern way to delete a bridge (and also doesn't require the
bridge to be ~IFF_UP to succeed). However, although older kernels
(e.g. 2.6.32, in RHEL6/CentOS6) support deleting *some* link types
with RTM_NEWLINK, they don't support deleting bridges, and there is no
compile-time way to figure this out.
This patch moves the body of the SIOCBRDELBR version of
virNetDevBridgeDelete() into a static function, calls the new function
from the original, and also calls the new function from the
RTM_DELLINK version if the RTM_DELLINK message generates an EOPNOTSUPP
error. Since RTM_DELLINK is done from the subordinate function
virNetlinkDelLink, which is also called for other purposes (deleting a
macvtap interface), a function pointer called "fallback" has been
added to the arglist of virNetlinkDelLink() - if that arg != NULL, the
provided function will be called when (and only when) RTM_DELLINK
fails with EOPNOTSUPP.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1252780 (part 2)
2015-08-26 03:19:03 +00:00
|
|
|
#if defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRDELBR)
|
|
|
|
static int
|
|
|
|
virNetDevBridgeDeleteWithIoctl(const char *brname)
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
{
|
|
|
|
int fd = -1;
|
|
|
|
int ret = -1;
|
|
|
|
|
util: fallback to ioctl(SIOCBRDELBR) if netlink RTM_DELLINK fails
commit 09778e09 switched from using ioctl(SIOCBRDELBR) for bridge
device deletion to using a netlink RTM_DELLINK message, which is the
more modern way to delete a bridge (and also doesn't require the
bridge to be ~IFF_UP to succeed). However, although older kernels
(e.g. 2.6.32, in RHEL6/CentOS6) support deleting *some* link types
with RTM_NEWLINK, they don't support deleting bridges, and there is no
compile-time way to figure this out.
This patch moves the body of the SIOCBRDELBR version of
virNetDevBridgeDelete() into a static function, calls the new function
from the original, and also calls the new function from the
RTM_DELLINK version if the RTM_DELLINK message generates an EOPNOTSUPP
error. Since RTM_DELLINK is done from the subordinate function
virNetlinkDelLink, which is also called for other purposes (deleting a
macvtap interface), a function pointer called "fallback" has been
added to the arglist of virNetlinkDelLink() - if that arg != NULL, the
provided function will be called when (and only when) RTM_DELLINK
fails with EOPNOTSUPP.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1252780 (part 2)
2015-08-26 03:19:03 +00:00
|
|
|
ignore_value(virNetDevSetOnline(brname, false));
|
|
|
|
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
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;
|
|
|
|
|
2014-03-25 06:53:22 +00:00
|
|
|
cleanup:
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
VIR_FORCE_CLOSE(fd);
|
|
|
|
return ret;
|
|
|
|
}
|
util: fallback to ioctl(SIOCBRDELBR) if netlink RTM_DELLINK fails
commit 09778e09 switched from using ioctl(SIOCBRDELBR) for bridge
device deletion to using a netlink RTM_DELLINK message, which is the
more modern way to delete a bridge (and also doesn't require the
bridge to be ~IFF_UP to succeed). However, although older kernels
(e.g. 2.6.32, in RHEL6/CentOS6) support deleting *some* link types
with RTM_NEWLINK, they don't support deleting bridges, and there is no
compile-time way to figure this out.
This patch moves the body of the SIOCBRDELBR version of
virNetDevBridgeDelete() into a static function, calls the new function
from the original, and also calls the new function from the
RTM_DELLINK version if the RTM_DELLINK message generates an EOPNOTSUPP
error. Since RTM_DELLINK is done from the subordinate function
virNetlinkDelLink, which is also called for other purposes (deleting a
macvtap interface), a function pointer called "fallback" has been
added to the arglist of virNetlinkDelLink() - if that arg != NULL, the
provided function will be called when (and only when) RTM_DELLINK
fails with EOPNOTSUPP.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1252780 (part 2)
2015-08-26 03:19:03 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(__linux__) && defined(HAVE_LIBNL)
|
|
|
|
int
|
|
|
|
virNetDevBridgeDelete(const char *brname)
|
|
|
|
{
|
|
|
|
/* If netlink is available, use it, as it is successful at
|
|
|
|
* deleting a bridge even if it is currently IFF_UP. fallback to
|
|
|
|
* using ioctl(SIOCBRDELBR) if netlink fails with EOPNOTSUPP.
|
|
|
|
*/
|
|
|
|
# if defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRDELBR)
|
|
|
|
return virNetlinkDelLink(brname, virNetDevBridgeDeleteWithIoctl);
|
|
|
|
# else
|
|
|
|
return virNetlinkDelLink(brname, NULL);
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#elif defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRDELBR)
|
|
|
|
int
|
|
|
|
virNetDevBridgeDelete(const char *brname)
|
|
|
|
{
|
|
|
|
return virNetDevBridgeDeleteWithIoctl(brname);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-19 16:47:30 +00:00
|
|
|
#elif defined(HAVE_STRUCT_IFREQ) && defined(SIOCIFDESTROY)
|
util: fallback to ioctl(SIOCBRDELBR) if netlink RTM_DELLINK fails
commit 09778e09 switched from using ioctl(SIOCBRDELBR) for bridge
device deletion to using a netlink RTM_DELLINK message, which is the
more modern way to delete a bridge (and also doesn't require the
bridge to be ~IFF_UP to succeed). However, although older kernels
(e.g. 2.6.32, in RHEL6/CentOS6) support deleting *some* link types
with RTM_NEWLINK, they don't support deleting bridges, and there is no
compile-time way to figure this out.
This patch moves the body of the SIOCBRDELBR version of
virNetDevBridgeDelete() into a static function, calls the new function
from the original, and also calls the new function from the
RTM_DELLINK version if the RTM_DELLINK message generates an EOPNOTSUPP
error. Since RTM_DELLINK is done from the subordinate function
virNetlinkDelLink, which is also called for other purposes (deleting a
macvtap interface), a function pointer called "fallback" has been
added to the arglist of virNetlinkDelLink() - if that arg != NULL, the
provided function will be called when (and only when) RTM_DELLINK
fails with EOPNOTSUPP.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1252780 (part 2)
2015-08-26 03:19:03 +00:00
|
|
|
int
|
|
|
|
virNetDevBridgeDelete(const char *brname)
|
2013-06-19 16:47:30 +00:00
|
|
|
{
|
|
|
|
int s;
|
|
|
|
struct ifreq ifr;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if ((s = virNetDevSetupControl(brname, &ifr)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (ioctl(s, SIOCIFDESTROY, &ifr) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to remove bridge %s"),
|
|
|
|
brname);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:53:22 +00:00
|
|
|
cleanup:
|
2013-06-19 16:47:30 +00:00
|
|
|
VIR_FORCE_CLOSE(s);
|
|
|
|
return ret;
|
|
|
|
}
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
#else
|
|
|
|
int virNetDevBridgeDelete(const char *brname ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS,
|
|
|
|
_("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.
|
|
|
|
*/
|
2013-03-07 16:36:57 +00:00
|
|
|
#if defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRADDIF)
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
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(ENODEV,
|
|
|
|
_("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;
|
2014-03-25 06:53:22 +00:00
|
|
|
cleanup:
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
VIR_FORCE_CLOSE(fd);
|
|
|
|
return ret;
|
|
|
|
}
|
2013-06-19 16:47:31 +00:00
|
|
|
#elif defined(HAVE_BSD_BRIDGE_MGMT)
|
|
|
|
int virNetDevBridgeAddPort(const char *brname,
|
|
|
|
const char *ifname)
|
|
|
|
{
|
|
|
|
struct ifbreq req;
|
|
|
|
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
|
|
if (virStrcpyStatic(req.ifbr_ifsname, ifname) == NULL) {
|
|
|
|
virReportSystemError(ERANGE,
|
|
|
|
_("Network interface name '%s' is too long"),
|
|
|
|
ifname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virNetDevBridgeCmd(brname, BRDGADD, &req, sizeof(req)) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to add bridge %s port %s"), brname, ifname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
#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.
|
|
|
|
*/
|
2013-03-07 16:36:57 +00:00
|
|
|
#if defined(HAVE_STRUCT_IFREQ) && defined(SIOCBRDELIF)
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
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(ENODEV,
|
|
|
|
_("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;
|
2014-03-25 06:53:22 +00:00
|
|
|
cleanup:
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
VIR_FORCE_CLOSE(fd);
|
|
|
|
return ret;
|
|
|
|
}
|
2013-06-19 16:47:31 +00:00
|
|
|
#elif defined(HAVE_BSD_BRIDGE_MGMT)
|
|
|
|
int virNetDevBridgeRemovePort(const char *brname,
|
|
|
|
const char *ifname)
|
|
|
|
{
|
|
|
|
struct ifbreq req;
|
|
|
|
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
|
|
if (virStrcpyStatic(req.ifbr_ifsname, ifname) == NULL) {
|
|
|
|
virReportSystemError(ERANGE,
|
|
|
|
_("Network interface name '%s' is too long"),
|
|
|
|
ifname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virNetDevBridgeCmd(brname, BRDGDEL, &req, sizeof(req)) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to remove bridge %s port %s"), brname, ifname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
#else
|
|
|
|
int virNetDevBridgeRemovePort(const char *brname,
|
|
|
|
const char *ifname)
|
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS,
|
|
|
|
_("Unable to remove bridge %s port %s"), brname, ifname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2013-03-07 16:36:57 +00:00
|
|
|
#if defined(HAVE_STRUCT_IFREQ) && defined(__linux__)
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
/**
|
|
|
|
* virNetDevBridgeSetSTPDelay:
|
|
|
|
* @brname: the bridge name
|
2012-08-23 15:21:47 +00:00
|
|
|
* @delay: delay in milliseconds
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
*
|
|
|
|
* 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;
|
|
|
|
|
2011-12-09 12:04:14 +00:00
|
|
|
ret = virNetDevBridgeSet(brname, "forward_delay", MS_TO_JIFFIES(delay),
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
fd, &ifr);
|
|
|
|
|
2014-03-25 06:53:22 +00:00
|
|
|
cleanup:
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
VIR_FORCE_CLOSE(fd);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virNetDevBridgeGetSTPDelay:
|
|
|
|
* @brname: the bridge device name
|
|
|
|
* @delayms: the forward delay in milliseconds
|
|
|
|
*
|
2014-11-19 18:28:57 +00:00
|
|
|
* Retrieves the forward delay for the bridge device @brname
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
* 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;
|
Convert 'int i' to 'size_t i' in src/util/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
unsigned long val;
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
|
|
|
|
if ((fd = virNetDevSetupControl(brname, &ifr)) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/util/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
ret = virNetDevBridgeGet(brname, "forward_delay", &val,
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
fd, &ifr);
|
Convert 'int i' to 'size_t i' in src/util/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
*delayms = JIFFIES_TO_MS(val);
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
|
2014-03-25 06:53:22 +00:00
|
|
|
cleanup:
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
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);
|
|
|
|
|
2014-03-25 06:53:22 +00:00
|
|
|
cleanup:
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
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;
|
Convert 'int i' to 'size_t i' in src/util/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
unsigned long val;
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
|
|
|
|
if ((fd = virNetDevSetupControl(brname, &ifr)) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/util/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
ret = virNetDevBridgeGet(brname, "stp_state", &val,
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
fd, &ifr);
|
Convert 'int i' to 'size_t i' in src/util/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
*enabled = val ? true : false;
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
|
2014-03-25 06:53:22 +00:00
|
|
|
cleanup:
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
VIR_FORCE_CLOSE(fd);
|
|
|
|
return ret;
|
|
|
|
}
|
2013-06-19 16:47:31 +00:00
|
|
|
#elif defined(HAVE_BSD_BRIDGE_MGMT)
|
|
|
|
int virNetDevBridgeSetSTPDelay(const char *brname,
|
|
|
|
int delay)
|
|
|
|
{
|
|
|
|
struct ifbrparam param;
|
2013-06-25 10:49:34 +00:00
|
|
|
u_long delay_seconds = delay / 1000;
|
2013-06-19 16:47:31 +00:00
|
|
|
|
|
|
|
/* FreeBSD doesn't allow setting STP delay < 4 */
|
2013-06-25 10:49:34 +00:00
|
|
|
delay_seconds = delay_seconds < 4 ? 4 : delay_seconds;
|
|
|
|
param.ifbrp_fwddelay = delay_seconds & 0xff;
|
2013-06-19 16:47:31 +00:00
|
|
|
|
|
|
|
if (virNetDevBridgeCmd(brname, BRDGSFD, ¶m, sizeof(param)) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to set STP delay on %s"), brname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
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 ATTRIBUTE_UNUSED,
|
|
|
|
bool enable ATTRIBUTE_UNUSED)
|
|
|
|
|
|
|
|
{
|
|
|
|
/* FreeBSD doesn't allow to set STP per bridge,
|
|
|
|
* only per-device in bridge */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int virNetDevBridgeGetSTP(const char *brname,
|
|
|
|
bool *enable ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS,
|
|
|
|
_("Unable to get STP on %s on this platform"),
|
|
|
|
brname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#else
|
Split bridge.h into three separate files
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
2011-11-02 13:41:58 +00:00
|
|
|
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;
|
|
|
|
}
|
2013-06-19 16:47:31 +00:00
|
|
|
#endif
|
2014-11-19 18:28:57 +00:00
|
|
|
|
|
|
|
#if defined(HAVE_STRUCT_IFREQ) && defined(__linux__)
|
|
|
|
/**
|
|
|
|
* virNetDevBridgeGetVlanFiltering:
|
|
|
|
* @brname: the bridge device name
|
|
|
|
* @enable: true or false
|
|
|
|
*
|
|
|
|
* Retrieves the vlan_filtering setting for the bridge device @brname
|
|
|
|
* storing it in @enable.
|
|
|
|
*
|
|
|
|
* Returns 0 on success, -1 on error
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virNetDevBridgeGetVlanFiltering(const char *brname,
|
|
|
|
bool *enable)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
unsigned long value;
|
|
|
|
|
|
|
|
if (virNetDevBridgeGet(brname, "vlan_filtering", &value, -1, NULL) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
*enable = !!value;
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virNetDevBridgeSetVlanFiltering:
|
|
|
|
* @brname: the bridge name
|
|
|
|
* @enable: true or false
|
|
|
|
*
|
|
|
|
* Set the bridge vlan_filtering mode
|
|
|
|
*
|
|
|
|
* Returns 0 in case of success or -1 on failure
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgeSetVlanFiltering(const char *brname,
|
|
|
|
bool enable)
|
|
|
|
{
|
|
|
|
return virNetDevBridgeSet(brname, "vlan_filtering", enable ? 1 : 0, -1, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
int
|
|
|
|
virNetDevBridgeGetVlanFiltering(const char *brname ATTRIBUTE_UNUSED,
|
|
|
|
bool *enable ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to get bridge vlan_filtering on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgeSetVlanFiltering(const char *brname ATTRIBUTE_UNUSED,
|
|
|
|
bool enable ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to set bridge vlan_filtering on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif
|
2014-11-20 16:55:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
#if defined(__linux__) && defined(HAVE_LIBNL)
|
2014-12-09 06:36:23 +00:00
|
|
|
|
|
|
|
# ifndef NTF_SELF
|
|
|
|
# define NTF_SELF 0x02
|
|
|
|
# endif
|
|
|
|
|
|
|
|
# ifndef NTF_MASTER
|
|
|
|
# define NTF_MASTER 0x04
|
|
|
|
# endif
|
|
|
|
|
2014-11-20 16:55:50 +00:00
|
|
|
/* virNetDevBridgeFDBAddDel:
|
|
|
|
* @mac: the MAC address being added to the table
|
|
|
|
* @ifname: name of the port (interface) of the bridge that wants this MAC
|
|
|
|
* @flags: any of virNetDevBridgeFDBFlags ORed together.
|
|
|
|
* @isAdd: true if adding the entry, fals if deleting
|
|
|
|
*
|
|
|
|
* Use netlink RTM_NEWNEIGH and RTM_DELNEIGH messages to add and
|
|
|
|
* delete entries from a bridge's fdb. The bridge itself is not
|
|
|
|
* referenced in the arguments to the function, only the name of the
|
|
|
|
* device that is attached to the bridge (since a device can only be
|
|
|
|
* attached to one bridge at a time, and must be attached for this
|
|
|
|
* function to make sense, the kernel easily infers which bridge's fdb
|
|
|
|
* is being modified by looking at the device name/index).
|
|
|
|
*
|
|
|
|
* Attempting to add an existing entry, or delete a non-existing entry
|
|
|
|
* *is* an error.
|
|
|
|
*
|
|
|
|
* returns 0 on success, -1 on failure.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
virNetDevBridgeFDBAddDel(const virMacAddr *mac, const char *ifname,
|
|
|
|
unsigned int flags, bool isAdd)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
struct nlmsghdr *resp = NULL;
|
|
|
|
struct nlmsgerr *err;
|
|
|
|
unsigned int recvbuflen;
|
|
|
|
struct nl_msg *nl_msg;
|
|
|
|
struct ndmsg ndm = { .ndm_family = PF_BRIDGE, .ndm_state = NUD_NOARP };
|
|
|
|
|
|
|
|
if (virNetDevGetIndex(ifname, &ndm.ndm_ifindex) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (flags & VIR_NETDEVBRIDGE_FDB_FLAG_ROUTER)
|
|
|
|
ndm.ndm_flags |= NTF_ROUTER;
|
|
|
|
if (flags & VIR_NETDEVBRIDGE_FDB_FLAG_SELF)
|
|
|
|
ndm.ndm_flags |= NTF_SELF;
|
|
|
|
if (flags & VIR_NETDEVBRIDGE_FDB_FLAG_MASTER)
|
|
|
|
ndm.ndm_flags |= NTF_MASTER;
|
|
|
|
/* default self (same as iproute2's bridge command */
|
|
|
|
if (!(ndm.ndm_flags & (NTF_MASTER | NTF_SELF)))
|
|
|
|
ndm.ndm_flags |= NTF_SELF;
|
|
|
|
|
|
|
|
if (flags & VIR_NETDEVBRIDGE_FDB_FLAG_PERMANENT)
|
|
|
|
ndm.ndm_state |= NUD_PERMANENT;
|
|
|
|
if (flags & VIR_NETDEVBRIDGE_FDB_FLAG_TEMP)
|
|
|
|
ndm.ndm_state |= NUD_REACHABLE;
|
|
|
|
/* default permanent, same as iproute2's bridge command */
|
|
|
|
if (!(ndm.ndm_state & (NUD_PERMANENT | NUD_REACHABLE)))
|
|
|
|
ndm.ndm_state |= NUD_PERMANENT;
|
|
|
|
|
|
|
|
nl_msg = nlmsg_alloc_simple(isAdd ? RTM_NEWNEIGH : RTM_DELNEIGH,
|
|
|
|
NLM_F_REQUEST |
|
|
|
|
(isAdd ? (NLM_F_CREATE | NLM_F_EXCL) : 0));
|
|
|
|
if (!nl_msg) {
|
|
|
|
virReportOOMError();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nlmsg_append(nl_msg, &ndm, sizeof(ndm), NLMSG_ALIGNTO) < 0)
|
|
|
|
goto buffer_too_small;
|
|
|
|
if (nla_put(nl_msg, NDA_LLADDR, VIR_MAC_BUFLEN, mac) < 0)
|
|
|
|
goto buffer_too_small;
|
|
|
|
|
|
|
|
/* NB: this message can also accept a Destination IP, a port, a
|
|
|
|
* vlan tag, and a via (see iproute2/bridge/fdb.c:fdb_modify()),
|
|
|
|
* but those aren't required for our application
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (virNetlinkCommand(nl_msg, &resp, &recvbuflen, 0, 0,
|
|
|
|
NETLINK_ROUTE, 0) < 0) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (recvbuflen < NLMSG_LENGTH(0) || resp == NULL)
|
|
|
|
goto malformed_resp;
|
|
|
|
|
|
|
|
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 adding fdb entry for %s"), ifname);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NLMSG_DONE:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
goto malformed_resp;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
cleanup:
|
|
|
|
nlmsg_free(nl_msg);
|
|
|
|
VIR_FREE(resp);
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
malformed_resp:
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("malformed netlink response message"));
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
buffer_too_small:
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("allocated netlink buffer is too small"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
static int
|
|
|
|
virNetDevBridgeFDBAddDel(const virMacAddr *mac ATTRIBUTE_UNUSED,
|
|
|
|
const char *ifname ATTRIBUTE_UNUSED,
|
|
|
|
unsigned int fdbFlags ATTRIBUTE_UNUSED,
|
|
|
|
bool isAdd ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to add/delete fdb entries on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgeFDBAdd(const virMacAddr *mac, const char *ifname,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
return virNetDevBridgeFDBAddDel(mac, ifname, flags, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgeFDBDel(const virMacAddr *mac, const char *ifname,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
return virNetDevBridgeFDBAddDel(mac, ifname, flags, false);
|
|
|
|
}
|