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
|
|
|
*/
|
|
|
|
|
|
|
|
#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"
|
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"
|
2018-11-20 07:55:49 +00:00
|
|
|
#include "virlog.h"
|
2013-04-03 10:36:23 +00:00
|
|
|
#include "virstring.h"
|
2020-01-14 17:38:59 +00:00
|
|
|
#include "virsocket.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
|
|
|
|
2020-09-01 11:27:44 +00:00
|
|
|
#ifdef WITH_NET_IF_H
|
2020-01-22 11:48:45 +00:00
|
|
|
# include <net/if.h>
|
|
|
|
#endif
|
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__
|
2020-09-01 11:27:44 +00:00
|
|
|
# if defined(WITH_LIBNL)
|
2014-11-20 16:55:50 +00:00
|
|
|
# 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
|
|
|
|
|
2020-09-01 11:27:44 +00:00
|
|
|
#if defined(WITH_BSD_BRIDGE_MGMT)
|
2013-06-19 16:47:31 +00:00
|
|
|
# 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
|
|
|
|
|
2018-11-20 07:55:49 +00:00
|
|
|
VIR_LOG_INIT("util.netdevbridge");
|
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
|
|
|
|
2020-09-01 11:27:44 +00:00
|
|
|
#if defined(WITH_BSD_BRIDGE_MGMT)
|
2013-06-19 16:47:31 +00:00
|
|
|
static int virNetDevBridgeCmd(const char *brname,
|
|
|
|
u_long op,
|
|
|
|
void *arg,
|
|
|
|
size_t argsize)
|
|
|
|
{
|
|
|
|
struct ifdrv ifd;
|
2018-09-12 09:46:37 +00:00
|
|
|
VIR_AUTOCLOSE s = -1;
|
2013-06-19 16:47:31 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-07-20 07:50:37 +00:00
|
|
|
if (virStrcpyStatic(ifd.ifd_name, brname) < 0) {
|
2013-06-19 16:47:31 +00:00
|
|
|
virReportSystemError(ERANGE,
|
|
|
|
_("Network interface name '%s' is too long"),
|
|
|
|
brname);
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
2013-06-19 16:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ifd.ifd_cmd = op;
|
|
|
|
ifd.ifd_len = argsize;
|
|
|
|
ifd.ifd_data = arg;
|
|
|
|
|
2018-09-12 09:46:37 +00:00
|
|
|
return ioctl(s, SIOCSDRVSPEC, &ifd);
|
2013-06-19 16:47:31 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-09-01 11:27:44 +00:00
|
|
|
#if defined(WITH_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...
|
2018-11-20 07:55:49 +00:00
|
|
|
* Fall back to ioctl if sysfs interface is not available or
|
|
|
|
* failing (e.g. due to container isolation).
|
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
|
|
|
*/
|
|
|
|
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 */
|
|
|
|
{
|
2019-10-15 13:16:31 +00:00
|
|
|
g_autofree char *path = NULL;
|
2020-07-28 18:09:22 +00:00
|
|
|
unsigned long args[] = { 0, value, 0, 0 };
|
|
|
|
unsigned long paramid;
|
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
|
|
|
|
2019-10-22 13:26:14 +00:00
|
|
|
path = g_strdup_printf(SYSFS_NET_DIR "%s/bridge/%s", brname, paramname);
|
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 (virFileExists(path)) {
|
2020-01-14 13:30:07 +00:00
|
|
|
g_autofree char *valuestr = g_strdup_printf("%lu", value);
|
2018-11-20 07:55:49 +00:00
|
|
|
if (virFileWriteStr(path, valuestr, 0) >= 0)
|
|
|
|
return 0;
|
|
|
|
VIR_DEBUG("Unable to set bridge %s %s via sysfs", brname, paramname);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (STREQ(paramname, "stp_state")) {
|
|
|
|
paramid = BRCTL_SET_BRIDGE_STP_STATE;
|
|
|
|
} else if (STREQ(paramname, "forward_delay")) {
|
|
|
|
paramid = BRCTL_SET_BRIDGE_FORWARD_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
|
|
|
} else {
|
2018-11-20 07:55:49 +00:00
|
|
|
virReportSystemError(EINVAL,
|
|
|
|
_("Unable to set bridge %s %s via ioctl"),
|
|
|
|
brname, paramname);
|
|
|
|
return -1;
|
|
|
|
}
|
2020-07-28 18:09:22 +00:00
|
|
|
|
|
|
|
args[0] = paramid;
|
2018-11-20 07:55:49 +00:00
|
|
|
ifr->ifr_data = (char*)&args;
|
|
|
|
if (ioctl(fd, SIOCDEVPRIVATE, ifr) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Failed to set bridge %s %s via ioctl"),
|
|
|
|
brname, paramname);
|
|
|
|
return -1;
|
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
|
|
|
}
|
|
|
|
|
2018-08-09 04:12:13 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int virNetDevBridgeGet(const char *brname,
|
|
|
|
const char *paramname, /* sysfs param name */
|
2016-06-01 09:52:53 +00:00
|
|
|
unsigned long *value) /* current value */
|
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
|
|
|
{
|
2016-06-01 09:52:53 +00:00
|
|
|
struct ifreq ifr;
|
2019-10-15 13:16:31 +00:00
|
|
|
g_autofree char *path = NULL;
|
2018-09-12 09:46:37 +00:00
|
|
|
VIR_AUTOCLOSE fd = -1;
|
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
|
|
|
|
2019-10-22 13:26:14 +00:00
|
|
|
path = g_strdup_printf(SYSFS_NET_DIR "%s/bridge/%s", brname, paramname);
|
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 (virFileExists(path)) {
|
2019-10-15 13:16:31 +00:00
|
|
|
g_autofree char *valuestr = NULL;
|
2018-08-09 04:12:13 +00:00
|
|
|
|
2020-01-14 13:30:07 +00:00
|
|
|
if (virFileReadAll(path, VIR_INT64_STR_BUFLEN,
|
2011-11-30 05:57:11 +00:00
|
|
|
&valuestr) < 0)
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
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 (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);
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
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 };
|
2016-06-01 09:52:53 +00:00
|
|
|
|
|
|
|
if ((fd = virNetDevSetupControl(brname, &ifr)) < 0)
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
2016-06-01 09:52:53 +00:00
|
|
|
|
|
|
|
ifr.ifr_data = (char*)&args;
|
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 (ioctl(fd, SIOCDEVPRIVATE, ifr) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to get bridge %s %s"), brname, paramname);
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
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 (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);
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-12 09:46:37 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
#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)
|
|
|
|
{
|
2020-01-14 13:30:07 +00:00
|
|
|
char valuestr[VIR_INT64_STR_BUFLEN];
|
2014-11-19 18:28:57 +00:00
|
|
|
int ret = -1;
|
2019-10-15 13:16:31 +00:00
|
|
|
g_autofree char *path = NULL;
|
2014-11-19 18:28:57 +00:00
|
|
|
|
2019-11-13 13:53:42 +00:00
|
|
|
g_snprintf(valuestr, sizeof(valuestr), "%lu", value);
|
2014-11-19 18:28:57 +00:00
|
|
|
|
2019-10-22 13:26:14 +00:00
|
|
|
path = g_strdup_printf(SYSFS_NET_DIR "%s/brif/%s/%s", brname, ifname,
|
|
|
|
paramname);
|
2014-11-19 18:28:57 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
virNetDevBridgePortGet(const char *brname,
|
|
|
|
const char *ifname,
|
|
|
|
const char *paramname,
|
|
|
|
unsigned long *value)
|
|
|
|
{
|
2019-10-15 13:16:31 +00:00
|
|
|
g_autofree char *path = NULL;
|
|
|
|
g_autofree char *valuestr = NULL;
|
2014-11-19 18:28:57 +00:00
|
|
|
|
2019-10-22 13:26:14 +00:00
|
|
|
path = g_strdup_printf(SYSFS_NET_DIR "%s/brif/%s/%s", brname, ifname,
|
|
|
|
paramname);
|
2014-11-19 18:28:57 +00:00
|
|
|
|
2020-01-14 13:30:07 +00:00
|
|
|
if (virFileReadAll(path, VIR_INT64_STR_BUFLEN, &valuestr) < 0)
|
2018-08-09 04:12:13 +00:00
|
|
|
return -1;
|
2014-11-19 18:28:57 +00:00
|
|
|
|
|
|
|
if (virStrToLong_ul(valuestr, NULL, 10, value) < 0) {
|
|
|
|
virReportSystemError(EINVAL,
|
|
|
|
_("Unable to get bridge %s port %s %s"),
|
|
|
|
brname, ifname, paramname);
|
2018-08-09 04:12:13 +00:00
|
|
|
return -1;
|
2014-11-19 18:28:57 +00:00
|
|
|
}
|
|
|
|
|
2018-08-09 04:12:13 +00:00
|
|
|
return 0;
|
2014-11-19 18:28:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgePortGetLearning(const char *brname,
|
|
|
|
const char *ifname,
|
|
|
|
bool *enable)
|
|
|
|
{
|
|
|
|
unsigned long value;
|
|
|
|
|
|
|
|
if (virNetDevBridgePortGet(brname, ifname, "learning", &value) < 0)
|
2019-10-21 18:19:04 +00:00
|
|
|
return -1;
|
2014-11-19 18:28:57 +00:00
|
|
|
|
|
|
|
*enable = !!value;
|
2019-10-21 18:19:04 +00:00
|
|
|
return 0;
|
2014-11-19 18:28:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
unsigned long value;
|
|
|
|
|
|
|
|
if (virNetDevBridgePortGet(brname, ifname, "unicast_flood", &value) < 0)
|
2019-10-21 18:19:04 +00:00
|
|
|
return -1;
|
2014-11-19 18:28:57 +00:00
|
|
|
|
|
|
|
*enable = !!value;
|
2019-10-21 18:19:04 +00:00
|
|
|
return 0;
|
2014-11-19 18:28:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgePortSetUnicastFlood(const char *brname,
|
|
|
|
const char *ifname,
|
|
|
|
bool enable)
|
|
|
|
{
|
|
|
|
return virNetDevBridgePortSet(brname, ifname, "unicast_flood", enable ? 1 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-01-20 21:27:02 +00:00
|
|
|
int
|
|
|
|
virNetDevBridgePortGetIsolated(const char *brname,
|
|
|
|
const char *ifname,
|
|
|
|
bool *enable)
|
|
|
|
{
|
|
|
|
unsigned long value;
|
|
|
|
|
|
|
|
if (virNetDevBridgePortGet(brname, ifname, "isolated", &value) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
*enable = !!value;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgePortSetIsolated(const char *brname,
|
|
|
|
const char *ifname,
|
|
|
|
bool enable)
|
|
|
|
{
|
|
|
|
return virNetDevBridgePortSet(brname, ifname, "isolated", enable ? 1 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-11-19 18:28:57 +00:00
|
|
|
#else
|
|
|
|
int
|
2019-10-14 12:45:33 +00:00
|
|
|
virNetDevBridgePortGetLearning(const char *brname G_GNUC_UNUSED,
|
|
|
|
const char *ifname G_GNUC_UNUSED,
|
|
|
|
bool *enable G_GNUC_UNUSED)
|
2014-11-19 18:28:57 +00:00
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to get bridge port learning on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2019-10-14 12:45:33 +00:00
|
|
|
virNetDevBridgePortSetLearning(const char *brname G_GNUC_UNUSED,
|
|
|
|
const char *ifname G_GNUC_UNUSED,
|
|
|
|
bool enable G_GNUC_UNUSED)
|
2014-11-19 18:28:57 +00:00
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to set bridge port learning on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2019-10-14 12:45:33 +00:00
|
|
|
virNetDevBridgePortGetUnicastFlood(const char *brname G_GNUC_UNUSED,
|
|
|
|
const char *ifname G_GNUC_UNUSED,
|
|
|
|
bool *enable G_GNUC_UNUSED)
|
2014-11-19 18:28:57 +00:00
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to get bridge port unicast_flood on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2019-10-14 12:45:33 +00:00
|
|
|
virNetDevBridgePortSetUnicastFlood(const char *brname G_GNUC_UNUSED,
|
|
|
|
const char *ifname G_GNUC_UNUSED,
|
|
|
|
bool enable G_GNUC_UNUSED)
|
2014-11-19 18:28:57 +00:00
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to set bridge port unicast_flood on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
2020-01-20 21:27:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgePortGetIsolated(const char *brname G_GNUC_UNUSED,
|
|
|
|
const char *ifname G_GNUC_UNUSED,
|
|
|
|
bool *enable G_GNUC_UNUSED)
|
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to get bridge port isolated on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
virNetDevBridgePortSetIsolated(const char *brname G_GNUC_UNUSED,
|
|
|
|
const char *ifname G_GNUC_UNUSED,
|
|
|
|
bool enable G_GNUC_UNUSED)
|
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to set bridge port isolated on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
2014-11-19 18:28:57 +00:00
|
|
|
#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
|
|
|
|
*/
|
2020-09-01 11:27:44 +00:00
|
|
|
#if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDBR)
|
2015-08-26 00:48:19 +00:00
|
|
|
static int
|
util: set bridge device MAC address explicitly during virNetDevBridgeCreate
When libvirt first implemented a stable and configurable MAC address
for the bridges created for libvirt virtual networks (commit
5754dbd56d, in libvirt v0.8.8) most distro stable releases didn't
support explicitly setting the MAC address of a bridge; the bridge
just always assumed the lowest numbered MAC of all attached
interfaces. Because of this, we stabilized the bridge MAC address by
creating a "dummy" tap interface with a MAC address guaranteed to be
lower than any of the guest tap devices' MACs (which all started with
0xFE, so it's not difficult to do) and attached it to the bridge -
this was the inception of the "virbr0-nic" device that has confused so
many people over the years.
Even though the linux kernel had recently gained support for
explicitly setting a bridge MAC, we deemed it unnecessary to set the
MAC that way, because the other (indirect) method worked everywhere.
But recently there have been reports that the bridge MAC address was
not following the setting in the network config, and mismatched the
MAC of the dummy tap device (which was still correct). It turns out
that this is due to a change in systemd-242 that persists whatever MAC
address is set for a bridge when it's initially started. According to
the systemd NEWS file entry for version 242
(https://github.com/systemd/systemd/blob/master/NEWS):
"if a bridge interface is created without any slaves, and gains
a slave later, then now the bridge does not inherit slave's MAC."
This change was the result of:
https://github.com/systemd/systemd/issues/3374
(apparently if there is no MAC saved for a bridge by the name of a
bridge being created, the random MAC generated during creation is
saved, and then that same MAC is used to explicitly set the MAC each
time it is created). Once a bridge has an explicitly set MAC, the "use
the lowest numbered MAC of attached devices" rule is ignored, so our
dummy tap device is like the goggles - it does nothing! (well, almost).
We could whine about changes in default behavior, etc. etc., but
because the change was in response to actual user problems, that seems
likely a fruitless task. Fortunately, time has marched on, and even
distro releases that are old enough that they are no longer supported
by upstream libvirt (e.g. RHEL6) have support for explicitly setting a
bridge device MAC address, either during creation or with a separate
ioctl after creation, so we can now do that.
To enable explicitly setting the mac during bridge creation, we add a
mac arg to virNetDevBridgeCreate(). In the case of platforms where
the bridge is created with a netlink RTM_NEWLINK message, we just add
that mac to the message. For platforms that still use an ioctl (either
SIOCBRADDBR or SIOCIFCREATE2), we make a separate call to
virNetDevSetMAC() after creating the bridge.
(NB: I was unable to test the calling of virNetDevSetMAC() from the
SIOCIFCREATE2 (BSD) version of virNetDevBridgeCreate(); even though I
managed to get a FreeBSD system setup and libvirt built there, when I
tried to start the default network the SIOCIFCREATE2 ioctl itself
failed, so it never even got to the virNetDevSetMAC(). That leaves the
FreeBSD implementation untested.)
This makes the dummy tap pointless for purposes of setting the MAC
address, but it is still useful for IPv6 DAD initialization (which
apparently requires at least one interface to be attached to the
bridge and online), as well as for setting an initial MTU for the
bridge, so it hasn't been removed.
(NB: we can safely *always* call virNetDevBridgeCreate() with
&def->mac from the network driver because, in spite of the existence
of a "mac_specified" bool in the config suggesting that it may not
always be present, in reality a mac address will always be added to
any network that doesn't have one - this is guaranteed in all cases by
commit a47ae7c004)
https://bugzilla.redhat.com/show_bug.cgi?id=1760851
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2019-10-18 01:12:30 +00:00
|
|
|
virNetDevBridgeCreateWithIoctl(const char *brname,
|
|
|
|
const virMacAddr *mac)
|
2015-08-26 00:48:19 +00:00
|
|
|
{
|
2018-09-12 09:46:37 +00:00
|
|
|
VIR_AUTOCLOSE fd = -1;
|
2015-08-26 00:48:19 +00:00
|
|
|
|
|
|
|
if ((fd = virNetDevSetupControl(NULL, NULL)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (ioctl(fd, SIOCBRADDBR, brname) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to create bridge %s"), brname);
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
2015-08-26 00:48:19 +00:00
|
|
|
}
|
|
|
|
|
util: set bridge device MAC address explicitly during virNetDevBridgeCreate
When libvirt first implemented a stable and configurable MAC address
for the bridges created for libvirt virtual networks (commit
5754dbd56d, in libvirt v0.8.8) most distro stable releases didn't
support explicitly setting the MAC address of a bridge; the bridge
just always assumed the lowest numbered MAC of all attached
interfaces. Because of this, we stabilized the bridge MAC address by
creating a "dummy" tap interface with a MAC address guaranteed to be
lower than any of the guest tap devices' MACs (which all started with
0xFE, so it's not difficult to do) and attached it to the bridge -
this was the inception of the "virbr0-nic" device that has confused so
many people over the years.
Even though the linux kernel had recently gained support for
explicitly setting a bridge MAC, we deemed it unnecessary to set the
MAC that way, because the other (indirect) method worked everywhere.
But recently there have been reports that the bridge MAC address was
not following the setting in the network config, and mismatched the
MAC of the dummy tap device (which was still correct). It turns out
that this is due to a change in systemd-242 that persists whatever MAC
address is set for a bridge when it's initially started. According to
the systemd NEWS file entry for version 242
(https://github.com/systemd/systemd/blob/master/NEWS):
"if a bridge interface is created without any slaves, and gains
a slave later, then now the bridge does not inherit slave's MAC."
This change was the result of:
https://github.com/systemd/systemd/issues/3374
(apparently if there is no MAC saved for a bridge by the name of a
bridge being created, the random MAC generated during creation is
saved, and then that same MAC is used to explicitly set the MAC each
time it is created). Once a bridge has an explicitly set MAC, the "use
the lowest numbered MAC of attached devices" rule is ignored, so our
dummy tap device is like the goggles - it does nothing! (well, almost).
We could whine about changes in default behavior, etc. etc., but
because the change was in response to actual user problems, that seems
likely a fruitless task. Fortunately, time has marched on, and even
distro releases that are old enough that they are no longer supported
by upstream libvirt (e.g. RHEL6) have support for explicitly setting a
bridge device MAC address, either during creation or with a separate
ioctl after creation, so we can now do that.
To enable explicitly setting the mac during bridge creation, we add a
mac arg to virNetDevBridgeCreate(). In the case of platforms where
the bridge is created with a netlink RTM_NEWLINK message, we just add
that mac to the message. For platforms that still use an ioctl (either
SIOCBRADDBR or SIOCIFCREATE2), we make a separate call to
virNetDevSetMAC() after creating the bridge.
(NB: I was unable to test the calling of virNetDevSetMAC() from the
SIOCIFCREATE2 (BSD) version of virNetDevBridgeCreate(); even though I
managed to get a FreeBSD system setup and libvirt built there, when I
tried to start the default network the SIOCIFCREATE2 ioctl itself
failed, so it never even got to the virNetDevSetMAC(). That leaves the
FreeBSD implementation untested.)
This makes the dummy tap pointless for purposes of setting the MAC
address, but it is still useful for IPv6 DAD initialization (which
apparently requires at least one interface to be attached to the
bridge and online), as well as for setting an initial MTU for the
bridge, so it hasn't been removed.
(NB: we can safely *always* call virNetDevBridgeCreate() with
&def->mac from the network driver because, in spite of the existence
of a "mac_specified" bool in the config suggesting that it may not
always be present, in reality a mac address will always be added to
any network that doesn't have one - this is guaranteed in all cases by
commit a47ae7c004)
https://bugzilla.redhat.com/show_bug.cgi?id=1760851
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2019-10-18 01:12:30 +00:00
|
|
|
if (virNetDevSetMAC(brname, mac) < 0) {
|
|
|
|
virErrorPtr savederr;
|
|
|
|
|
|
|
|
virErrorPreserveLast(&savederr);
|
|
|
|
ignore_value(ioctl(fd, SIOCBRDELBR, brname));
|
|
|
|
virErrorRestore(&savederr);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-09-12 09:46:37 +00:00
|
|
|
return 0;
|
2015-08-26 00:48:19 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-09-28 21:29:41 +00:00
|
|
|
#if defined(WITH_LIBNL)
|
2015-08-26 00:48:19 +00:00
|
|
|
int
|
util: set bridge device MAC address explicitly during virNetDevBridgeCreate
When libvirt first implemented a stable and configurable MAC address
for the bridges created for libvirt virtual networks (commit
5754dbd56d, in libvirt v0.8.8) most distro stable releases didn't
support explicitly setting the MAC address of a bridge; the bridge
just always assumed the lowest numbered MAC of all attached
interfaces. Because of this, we stabilized the bridge MAC address by
creating a "dummy" tap interface with a MAC address guaranteed to be
lower than any of the guest tap devices' MACs (which all started with
0xFE, so it's not difficult to do) and attached it to the bridge -
this was the inception of the "virbr0-nic" device that has confused so
many people over the years.
Even though the linux kernel had recently gained support for
explicitly setting a bridge MAC, we deemed it unnecessary to set the
MAC that way, because the other (indirect) method worked everywhere.
But recently there have been reports that the bridge MAC address was
not following the setting in the network config, and mismatched the
MAC of the dummy tap device (which was still correct). It turns out
that this is due to a change in systemd-242 that persists whatever MAC
address is set for a bridge when it's initially started. According to
the systemd NEWS file entry for version 242
(https://github.com/systemd/systemd/blob/master/NEWS):
"if a bridge interface is created without any slaves, and gains
a slave later, then now the bridge does not inherit slave's MAC."
This change was the result of:
https://github.com/systemd/systemd/issues/3374
(apparently if there is no MAC saved for a bridge by the name of a
bridge being created, the random MAC generated during creation is
saved, and then that same MAC is used to explicitly set the MAC each
time it is created). Once a bridge has an explicitly set MAC, the "use
the lowest numbered MAC of attached devices" rule is ignored, so our
dummy tap device is like the goggles - it does nothing! (well, almost).
We could whine about changes in default behavior, etc. etc., but
because the change was in response to actual user problems, that seems
likely a fruitless task. Fortunately, time has marched on, and even
distro releases that are old enough that they are no longer supported
by upstream libvirt (e.g. RHEL6) have support for explicitly setting a
bridge device MAC address, either during creation or with a separate
ioctl after creation, so we can now do that.
To enable explicitly setting the mac during bridge creation, we add a
mac arg to virNetDevBridgeCreate(). In the case of platforms where
the bridge is created with a netlink RTM_NEWLINK message, we just add
that mac to the message. For platforms that still use an ioctl (either
SIOCBRADDBR or SIOCIFCREATE2), we make a separate call to
virNetDevSetMAC() after creating the bridge.
(NB: I was unable to test the calling of virNetDevSetMAC() from the
SIOCIFCREATE2 (BSD) version of virNetDevBridgeCreate(); even though I
managed to get a FreeBSD system setup and libvirt built there, when I
tried to start the default network the SIOCIFCREATE2 ioctl itself
failed, so it never even got to the virNetDevSetMAC(). That leaves the
FreeBSD implementation untested.)
This makes the dummy tap pointless for purposes of setting the MAC
address, but it is still useful for IPv6 DAD initialization (which
apparently requires at least one interface to be attached to the
bridge and online), as well as for setting an initial MTU for the
bridge, so it hasn't been removed.
(NB: we can safely *always* call virNetDevBridgeCreate() with
&def->mac from the network driver because, in spite of the existence
of a "mac_specified" bool in the config suggesting that it may not
always be present, in reality a mac address will always be added to
any network that doesn't have one - this is guaranteed in all cases by
commit a47ae7c004)
https://bugzilla.redhat.com/show_bug.cgi?id=1760851
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2019-10-18 01:12:30 +00:00
|
|
|
virNetDevBridgeCreate(const char *brname,
|
|
|
|
const virMacAddr *mac)
|
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 */
|
2018-09-07 07:17:26 +00:00
|
|
|
int error = 0;
|
util: set bridge device MAC address explicitly during virNetDevBridgeCreate
When libvirt first implemented a stable and configurable MAC address
for the bridges created for libvirt virtual networks (commit
5754dbd56d, in libvirt v0.8.8) most distro stable releases didn't
support explicitly setting the MAC address of a bridge; the bridge
just always assumed the lowest numbered MAC of all attached
interfaces. Because of this, we stabilized the bridge MAC address by
creating a "dummy" tap interface with a MAC address guaranteed to be
lower than any of the guest tap devices' MACs (which all started with
0xFE, so it's not difficult to do) and attached it to the bridge -
this was the inception of the "virbr0-nic" device that has confused so
many people over the years.
Even though the linux kernel had recently gained support for
explicitly setting a bridge MAC, we deemed it unnecessary to set the
MAC that way, because the other (indirect) method worked everywhere.
But recently there have been reports that the bridge MAC address was
not following the setting in the network config, and mismatched the
MAC of the dummy tap device (which was still correct). It turns out
that this is due to a change in systemd-242 that persists whatever MAC
address is set for a bridge when it's initially started. According to
the systemd NEWS file entry for version 242
(https://github.com/systemd/systemd/blob/master/NEWS):
"if a bridge interface is created without any slaves, and gains
a slave later, then now the bridge does not inherit slave's MAC."
This change was the result of:
https://github.com/systemd/systemd/issues/3374
(apparently if there is no MAC saved for a bridge by the name of a
bridge being created, the random MAC generated during creation is
saved, and then that same MAC is used to explicitly set the MAC each
time it is created). Once a bridge has an explicitly set MAC, the "use
the lowest numbered MAC of attached devices" rule is ignored, so our
dummy tap device is like the goggles - it does nothing! (well, almost).
We could whine about changes in default behavior, etc. etc., but
because the change was in response to actual user problems, that seems
likely a fruitless task. Fortunately, time has marched on, and even
distro releases that are old enough that they are no longer supported
by upstream libvirt (e.g. RHEL6) have support for explicitly setting a
bridge device MAC address, either during creation or with a separate
ioctl after creation, so we can now do that.
To enable explicitly setting the mac during bridge creation, we add a
mac arg to virNetDevBridgeCreate(). In the case of platforms where
the bridge is created with a netlink RTM_NEWLINK message, we just add
that mac to the message. For platforms that still use an ioctl (either
SIOCBRADDBR or SIOCIFCREATE2), we make a separate call to
virNetDevSetMAC() after creating the bridge.
(NB: I was unable to test the calling of virNetDevSetMAC() from the
SIOCIFCREATE2 (BSD) version of virNetDevBridgeCreate(); even though I
managed to get a FreeBSD system setup and libvirt built there, when I
tried to start the default network the SIOCIFCREATE2 ioctl itself
failed, so it never even got to the virNetDevSetMAC(). That leaves the
FreeBSD implementation untested.)
This makes the dummy tap pointless for purposes of setting the MAC
address, but it is still useful for IPv6 DAD initialization (which
apparently requires at least one interface to be attached to the
bridge and online), as well as for setting an initial MTU for the
bridge, so it hasn't been removed.
(NB: we can safely *always* call virNetDevBridgeCreate() with
&def->mac from the network driver because, in spite of the existence
of a "mac_specified" bool in the config suggesting that it may not
always be present, in reality a mac address will always be added to
any network that doesn't have one - this is guaranteed in all cases by
commit a47ae7c004)
https://bugzilla.redhat.com/show_bug.cgi?id=1760851
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2019-10-18 01:12:30 +00:00
|
|
|
virNetlinkNewLinkData data = {
|
|
|
|
.mac = mac,
|
|
|
|
};
|
|
|
|
|
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
|
|
|
|
util: set bridge device MAC address explicitly during virNetDevBridgeCreate
When libvirt first implemented a stable and configurable MAC address
for the bridges created for libvirt virtual networks (commit
5754dbd56d, in libvirt v0.8.8) most distro stable releases didn't
support explicitly setting the MAC address of a bridge; the bridge
just always assumed the lowest numbered MAC of all attached
interfaces. Because of this, we stabilized the bridge MAC address by
creating a "dummy" tap interface with a MAC address guaranteed to be
lower than any of the guest tap devices' MACs (which all started with
0xFE, so it's not difficult to do) and attached it to the bridge -
this was the inception of the "virbr0-nic" device that has confused so
many people over the years.
Even though the linux kernel had recently gained support for
explicitly setting a bridge MAC, we deemed it unnecessary to set the
MAC that way, because the other (indirect) method worked everywhere.
But recently there have been reports that the bridge MAC address was
not following the setting in the network config, and mismatched the
MAC of the dummy tap device (which was still correct). It turns out
that this is due to a change in systemd-242 that persists whatever MAC
address is set for a bridge when it's initially started. According to
the systemd NEWS file entry for version 242
(https://github.com/systemd/systemd/blob/master/NEWS):
"if a bridge interface is created without any slaves, and gains
a slave later, then now the bridge does not inherit slave's MAC."
This change was the result of:
https://github.com/systemd/systemd/issues/3374
(apparently if there is no MAC saved for a bridge by the name of a
bridge being created, the random MAC generated during creation is
saved, and then that same MAC is used to explicitly set the MAC each
time it is created). Once a bridge has an explicitly set MAC, the "use
the lowest numbered MAC of attached devices" rule is ignored, so our
dummy tap device is like the goggles - it does nothing! (well, almost).
We could whine about changes in default behavior, etc. etc., but
because the change was in response to actual user problems, that seems
likely a fruitless task. Fortunately, time has marched on, and even
distro releases that are old enough that they are no longer supported
by upstream libvirt (e.g. RHEL6) have support for explicitly setting a
bridge device MAC address, either during creation or with a separate
ioctl after creation, so we can now do that.
To enable explicitly setting the mac during bridge creation, we add a
mac arg to virNetDevBridgeCreate(). In the case of platforms where
the bridge is created with a netlink RTM_NEWLINK message, we just add
that mac to the message. For platforms that still use an ioctl (either
SIOCBRADDBR or SIOCIFCREATE2), we make a separate call to
virNetDevSetMAC() after creating the bridge.
(NB: I was unable to test the calling of virNetDevSetMAC() from the
SIOCIFCREATE2 (BSD) version of virNetDevBridgeCreate(); even though I
managed to get a FreeBSD system setup and libvirt built there, when I
tried to start the default network the SIOCIFCREATE2 ioctl itself
failed, so it never even got to the virNetDevSetMAC(). That leaves the
FreeBSD implementation untested.)
This makes the dummy tap pointless for purposes of setting the MAC
address, but it is still useful for IPv6 DAD initialization (which
apparently requires at least one interface to be attached to the
bridge and online), as well as for setting an initial MTU for the
bridge, so it hasn't been removed.
(NB: we can safely *always* call virNetDevBridgeCreate() with
&def->mac from the network driver because, in spite of the existence
of a "mac_specified" bool in the config suggesting that it may not
always be present, in reality a mac address will always be added to
any network that doesn't have one - this is guaranteed in all cases by
commit a47ae7c004)
https://bugzilla.redhat.com/show_bug.cgi?id=1760851
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2019-10-18 01:12:30 +00:00
|
|
|
if (virNetlinkNewLink(brname, "bridge", &data, &error) < 0) {
|
2020-09-01 11:27:44 +00:00
|
|
|
# if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDBR)
|
2018-09-07 07:17:26 +00:00
|
|
|
if (error == -EOPNOTSUPP) {
|
|
|
|
/* fallback to ioctl if netlink doesn't support creating bridges */
|
util: set bridge device MAC address explicitly during virNetDevBridgeCreate
When libvirt first implemented a stable and configurable MAC address
for the bridges created for libvirt virtual networks (commit
5754dbd56d, in libvirt v0.8.8) most distro stable releases didn't
support explicitly setting the MAC address of a bridge; the bridge
just always assumed the lowest numbered MAC of all attached
interfaces. Because of this, we stabilized the bridge MAC address by
creating a "dummy" tap interface with a MAC address guaranteed to be
lower than any of the guest tap devices' MACs (which all started with
0xFE, so it's not difficult to do) and attached it to the bridge -
this was the inception of the "virbr0-nic" device that has confused so
many people over the years.
Even though the linux kernel had recently gained support for
explicitly setting a bridge MAC, we deemed it unnecessary to set the
MAC that way, because the other (indirect) method worked everywhere.
But recently there have been reports that the bridge MAC address was
not following the setting in the network config, and mismatched the
MAC of the dummy tap device (which was still correct). It turns out
that this is due to a change in systemd-242 that persists whatever MAC
address is set for a bridge when it's initially started. According to
the systemd NEWS file entry for version 242
(https://github.com/systemd/systemd/blob/master/NEWS):
"if a bridge interface is created without any slaves, and gains
a slave later, then now the bridge does not inherit slave's MAC."
This change was the result of:
https://github.com/systemd/systemd/issues/3374
(apparently if there is no MAC saved for a bridge by the name of a
bridge being created, the random MAC generated during creation is
saved, and then that same MAC is used to explicitly set the MAC each
time it is created). Once a bridge has an explicitly set MAC, the "use
the lowest numbered MAC of attached devices" rule is ignored, so our
dummy tap device is like the goggles - it does nothing! (well, almost).
We could whine about changes in default behavior, etc. etc., but
because the change was in response to actual user problems, that seems
likely a fruitless task. Fortunately, time has marched on, and even
distro releases that are old enough that they are no longer supported
by upstream libvirt (e.g. RHEL6) have support for explicitly setting a
bridge device MAC address, either during creation or with a separate
ioctl after creation, so we can now do that.
To enable explicitly setting the mac during bridge creation, we add a
mac arg to virNetDevBridgeCreate(). In the case of platforms where
the bridge is created with a netlink RTM_NEWLINK message, we just add
that mac to the message. For platforms that still use an ioctl (either
SIOCBRADDBR or SIOCIFCREATE2), we make a separate call to
virNetDevSetMAC() after creating the bridge.
(NB: I was unable to test the calling of virNetDevSetMAC() from the
SIOCIFCREATE2 (BSD) version of virNetDevBridgeCreate(); even though I
managed to get a FreeBSD system setup and libvirt built there, when I
tried to start the default network the SIOCIFCREATE2 ioctl itself
failed, so it never even got to the virNetDevSetMAC(). That leaves the
FreeBSD implementation untested.)
This makes the dummy tap pointless for purposes of setting the MAC
address, but it is still useful for IPv6 DAD initialization (which
apparently requires at least one interface to be attached to the
bridge and online), as well as for setting an initial MTU for the
bridge, so it hasn't been removed.
(NB: we can safely *always* call virNetDevBridgeCreate() with
&def->mac from the network driver because, in spite of the existence
of a "mac_specified" bool in the config suggesting that it may not
always be present, in reality a mac address will always be added to
any network that doesn't have one - this is guaranteed in all cases by
commit a47ae7c004)
https://bugzilla.redhat.com/show_bug.cgi?id=1760851
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2019-10-18 01:12:30 +00:00
|
|
|
return virNetDevBridgeCreateWithIoctl(brname, mac);
|
2018-09-07 07:17:26 +00:00
|
|
|
}
|
2015-08-26 00:48:19 +00:00
|
|
|
# endif
|
2018-09-07 07:17:26 +00:00
|
|
|
if (error < 0)
|
|
|
|
virReportSystemError(-error, _("error creating bridge interface %s"),
|
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
|
|
|
brname);
|
|
|
|
|
2018-09-07 07:17:26 +00:00
|
|
|
return -1;
|
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
|
|
|
}
|
|
|
|
|
2018-08-09 04:12:14 +00:00
|
|
|
return 0;
|
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
|
|
|
}
|
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
|
|
|
|
|
|
|
|
2020-09-01 11:27:44 +00:00
|
|
|
#elif defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDBR)
|
2015-08-26 00:48:19 +00:00
|
|
|
int
|
util: set bridge device MAC address explicitly during virNetDevBridgeCreate
When libvirt first implemented a stable and configurable MAC address
for the bridges created for libvirt virtual networks (commit
5754dbd56d, in libvirt v0.8.8) most distro stable releases didn't
support explicitly setting the MAC address of a bridge; the bridge
just always assumed the lowest numbered MAC of all attached
interfaces. Because of this, we stabilized the bridge MAC address by
creating a "dummy" tap interface with a MAC address guaranteed to be
lower than any of the guest tap devices' MACs (which all started with
0xFE, so it's not difficult to do) and attached it to the bridge -
this was the inception of the "virbr0-nic" device that has confused so
many people over the years.
Even though the linux kernel had recently gained support for
explicitly setting a bridge MAC, we deemed it unnecessary to set the
MAC that way, because the other (indirect) method worked everywhere.
But recently there have been reports that the bridge MAC address was
not following the setting in the network config, and mismatched the
MAC of the dummy tap device (which was still correct). It turns out
that this is due to a change in systemd-242 that persists whatever MAC
address is set for a bridge when it's initially started. According to
the systemd NEWS file entry for version 242
(https://github.com/systemd/systemd/blob/master/NEWS):
"if a bridge interface is created without any slaves, and gains
a slave later, then now the bridge does not inherit slave's MAC."
This change was the result of:
https://github.com/systemd/systemd/issues/3374
(apparently if there is no MAC saved for a bridge by the name of a
bridge being created, the random MAC generated during creation is
saved, and then that same MAC is used to explicitly set the MAC each
time it is created). Once a bridge has an explicitly set MAC, the "use
the lowest numbered MAC of attached devices" rule is ignored, so our
dummy tap device is like the goggles - it does nothing! (well, almost).
We could whine about changes in default behavior, etc. etc., but
because the change was in response to actual user problems, that seems
likely a fruitless task. Fortunately, time has marched on, and even
distro releases that are old enough that they are no longer supported
by upstream libvirt (e.g. RHEL6) have support for explicitly setting a
bridge device MAC address, either during creation or with a separate
ioctl after creation, so we can now do that.
To enable explicitly setting the mac during bridge creation, we add a
mac arg to virNetDevBridgeCreate(). In the case of platforms where
the bridge is created with a netlink RTM_NEWLINK message, we just add
that mac to the message. For platforms that still use an ioctl (either
SIOCBRADDBR or SIOCIFCREATE2), we make a separate call to
virNetDevSetMAC() after creating the bridge.
(NB: I was unable to test the calling of virNetDevSetMAC() from the
SIOCIFCREATE2 (BSD) version of virNetDevBridgeCreate(); even though I
managed to get a FreeBSD system setup and libvirt built there, when I
tried to start the default network the SIOCIFCREATE2 ioctl itself
failed, so it never even got to the virNetDevSetMAC(). That leaves the
FreeBSD implementation untested.)
This makes the dummy tap pointless for purposes of setting the MAC
address, but it is still useful for IPv6 DAD initialization (which
apparently requires at least one interface to be attached to the
bridge and online), as well as for setting an initial MTU for the
bridge, so it hasn't been removed.
(NB: we can safely *always* call virNetDevBridgeCreate() with
&def->mac from the network driver because, in spite of the existence
of a "mac_specified" bool in the config suggesting that it may not
always be present, in reality a mac address will always be added to
any network that doesn't have one - this is guaranteed in all cases by
commit a47ae7c004)
https://bugzilla.redhat.com/show_bug.cgi?id=1760851
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2019-10-18 01:12:30 +00:00
|
|
|
virNetDevBridgeCreate(const char *brname,
|
|
|
|
const virMacAddr *mac)
|
2015-08-26 00:48:19 +00:00
|
|
|
{
|
util: set bridge device MAC address explicitly during virNetDevBridgeCreate
When libvirt first implemented a stable and configurable MAC address
for the bridges created for libvirt virtual networks (commit
5754dbd56d, in libvirt v0.8.8) most distro stable releases didn't
support explicitly setting the MAC address of a bridge; the bridge
just always assumed the lowest numbered MAC of all attached
interfaces. Because of this, we stabilized the bridge MAC address by
creating a "dummy" tap interface with a MAC address guaranteed to be
lower than any of the guest tap devices' MACs (which all started with
0xFE, so it's not difficult to do) and attached it to the bridge -
this was the inception of the "virbr0-nic" device that has confused so
many people over the years.
Even though the linux kernel had recently gained support for
explicitly setting a bridge MAC, we deemed it unnecessary to set the
MAC that way, because the other (indirect) method worked everywhere.
But recently there have been reports that the bridge MAC address was
not following the setting in the network config, and mismatched the
MAC of the dummy tap device (which was still correct). It turns out
that this is due to a change in systemd-242 that persists whatever MAC
address is set for a bridge when it's initially started. According to
the systemd NEWS file entry for version 242
(https://github.com/systemd/systemd/blob/master/NEWS):
"if a bridge interface is created without any slaves, and gains
a slave later, then now the bridge does not inherit slave's MAC."
This change was the result of:
https://github.com/systemd/systemd/issues/3374
(apparently if there is no MAC saved for a bridge by the name of a
bridge being created, the random MAC generated during creation is
saved, and then that same MAC is used to explicitly set the MAC each
time it is created). Once a bridge has an explicitly set MAC, the "use
the lowest numbered MAC of attached devices" rule is ignored, so our
dummy tap device is like the goggles - it does nothing! (well, almost).
We could whine about changes in default behavior, etc. etc., but
because the change was in response to actual user problems, that seems
likely a fruitless task. Fortunately, time has marched on, and even
distro releases that are old enough that they are no longer supported
by upstream libvirt (e.g. RHEL6) have support for explicitly setting a
bridge device MAC address, either during creation or with a separate
ioctl after creation, so we can now do that.
To enable explicitly setting the mac during bridge creation, we add a
mac arg to virNetDevBridgeCreate(). In the case of platforms where
the bridge is created with a netlink RTM_NEWLINK message, we just add
that mac to the message. For platforms that still use an ioctl (either
SIOCBRADDBR or SIOCIFCREATE2), we make a separate call to
virNetDevSetMAC() after creating the bridge.
(NB: I was unable to test the calling of virNetDevSetMAC() from the
SIOCIFCREATE2 (BSD) version of virNetDevBridgeCreate(); even though I
managed to get a FreeBSD system setup and libvirt built there, when I
tried to start the default network the SIOCIFCREATE2 ioctl itself
failed, so it never even got to the virNetDevSetMAC(). That leaves the
FreeBSD implementation untested.)
This makes the dummy tap pointless for purposes of setting the MAC
address, but it is still useful for IPv6 DAD initialization (which
apparently requires at least one interface to be attached to the
bridge and online), as well as for setting an initial MTU for the
bridge, so it hasn't been removed.
(NB: we can safely *always* call virNetDevBridgeCreate() with
&def->mac from the network driver because, in spite of the existence
of a "mac_specified" bool in the config suggesting that it may not
always be present, in reality a mac address will always be added to
any network that doesn't have one - this is guaranteed in all cases by
commit a47ae7c004)
https://bugzilla.redhat.com/show_bug.cgi?id=1760851
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2019-10-18 01:12:30 +00:00
|
|
|
return virNetDevBridgeCreateWithIoctl(brname, mac);
|
2015-08-26 00:48:19 +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
|
|
|
|
|
|
|
|
2020-09-01 11:27:44 +00:00
|
|
|
#elif defined(WITH_STRUCT_IFREQ) && defined(SIOCIFCREATE2)
|
2015-08-26 00:48:19 +00:00
|
|
|
int
|
util: set bridge device MAC address explicitly during virNetDevBridgeCreate
When libvirt first implemented a stable and configurable MAC address
for the bridges created for libvirt virtual networks (commit
5754dbd56d, in libvirt v0.8.8) most distro stable releases didn't
support explicitly setting the MAC address of a bridge; the bridge
just always assumed the lowest numbered MAC of all attached
interfaces. Because of this, we stabilized the bridge MAC address by
creating a "dummy" tap interface with a MAC address guaranteed to be
lower than any of the guest tap devices' MACs (which all started with
0xFE, so it's not difficult to do) and attached it to the bridge -
this was the inception of the "virbr0-nic" device that has confused so
many people over the years.
Even though the linux kernel had recently gained support for
explicitly setting a bridge MAC, we deemed it unnecessary to set the
MAC that way, because the other (indirect) method worked everywhere.
But recently there have been reports that the bridge MAC address was
not following the setting in the network config, and mismatched the
MAC of the dummy tap device (which was still correct). It turns out
that this is due to a change in systemd-242 that persists whatever MAC
address is set for a bridge when it's initially started. According to
the systemd NEWS file entry for version 242
(https://github.com/systemd/systemd/blob/master/NEWS):
"if a bridge interface is created without any slaves, and gains
a slave later, then now the bridge does not inherit slave's MAC."
This change was the result of:
https://github.com/systemd/systemd/issues/3374
(apparently if there is no MAC saved for a bridge by the name of a
bridge being created, the random MAC generated during creation is
saved, and then that same MAC is used to explicitly set the MAC each
time it is created). Once a bridge has an explicitly set MAC, the "use
the lowest numbered MAC of attached devices" rule is ignored, so our
dummy tap device is like the goggles - it does nothing! (well, almost).
We could whine about changes in default behavior, etc. etc., but
because the change was in response to actual user problems, that seems
likely a fruitless task. Fortunately, time has marched on, and even
distro releases that are old enough that they are no longer supported
by upstream libvirt (e.g. RHEL6) have support for explicitly setting a
bridge device MAC address, either during creation or with a separate
ioctl after creation, so we can now do that.
To enable explicitly setting the mac during bridge creation, we add a
mac arg to virNetDevBridgeCreate(). In the case of platforms where
the bridge is created with a netlink RTM_NEWLINK message, we just add
that mac to the message. For platforms that still use an ioctl (either
SIOCBRADDBR or SIOCIFCREATE2), we make a separate call to
virNetDevSetMAC() after creating the bridge.
(NB: I was unable to test the calling of virNetDevSetMAC() from the
SIOCIFCREATE2 (BSD) version of virNetDevBridgeCreate(); even though I
managed to get a FreeBSD system setup and libvirt built there, when I
tried to start the default network the SIOCIFCREATE2 ioctl itself
failed, so it never even got to the virNetDevSetMAC(). That leaves the
FreeBSD implementation untested.)
This makes the dummy tap pointless for purposes of setting the MAC
address, but it is still useful for IPv6 DAD initialization (which
apparently requires at least one interface to be attached to the
bridge and online), as well as for setting an initial MTU for the
bridge, so it hasn't been removed.
(NB: we can safely *always* call virNetDevBridgeCreate() with
&def->mac from the network driver because, in spite of the existence
of a "mac_specified" bool in the config suggesting that it may not
always be present, in reality a mac address will always be added to
any network that doesn't have one - this is guaranteed in all cases by
commit a47ae7c004)
https://bugzilla.redhat.com/show_bug.cgi?id=1760851
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2019-10-18 01:12:30 +00:00
|
|
|
virNetDevBridgeCreate(const char *brname,
|
|
|
|
const virMacAddr *mac)
|
2013-06-19 16:47:30 +00:00
|
|
|
{
|
|
|
|
struct ifreq ifr;
|
2018-09-12 09:46:37 +00:00
|
|
|
VIR_AUTOCLOSE s = -1;
|
2013-06-19 16:47:30 +00:00
|
|
|
|
|
|
|
if ((s = virNetDevSetupControl("bridge", &ifr)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) {
|
|
|
|
virReportSystemError(errno, "%s",
|
|
|
|
_("Unable to create bridge device"));
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
2013-06-19 16:47:30 +00:00
|
|
|
}
|
|
|
|
|
2014-11-13 14:28:18 +00:00
|
|
|
if (virNetDevSetName(ifr.ifr_name, brname) == -1)
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
2013-06-19 16:47:30 +00:00
|
|
|
|
util: set bridge device MAC address explicitly during virNetDevBridgeCreate
When libvirt first implemented a stable and configurable MAC address
for the bridges created for libvirt virtual networks (commit
5754dbd56d, in libvirt v0.8.8) most distro stable releases didn't
support explicitly setting the MAC address of a bridge; the bridge
just always assumed the lowest numbered MAC of all attached
interfaces. Because of this, we stabilized the bridge MAC address by
creating a "dummy" tap interface with a MAC address guaranteed to be
lower than any of the guest tap devices' MACs (which all started with
0xFE, so it's not difficult to do) and attached it to the bridge -
this was the inception of the "virbr0-nic" device that has confused so
many people over the years.
Even though the linux kernel had recently gained support for
explicitly setting a bridge MAC, we deemed it unnecessary to set the
MAC that way, because the other (indirect) method worked everywhere.
But recently there have been reports that the bridge MAC address was
not following the setting in the network config, and mismatched the
MAC of the dummy tap device (which was still correct). It turns out
that this is due to a change in systemd-242 that persists whatever MAC
address is set for a bridge when it's initially started. According to
the systemd NEWS file entry for version 242
(https://github.com/systemd/systemd/blob/master/NEWS):
"if a bridge interface is created without any slaves, and gains
a slave later, then now the bridge does not inherit slave's MAC."
This change was the result of:
https://github.com/systemd/systemd/issues/3374
(apparently if there is no MAC saved for a bridge by the name of a
bridge being created, the random MAC generated during creation is
saved, and then that same MAC is used to explicitly set the MAC each
time it is created). Once a bridge has an explicitly set MAC, the "use
the lowest numbered MAC of attached devices" rule is ignored, so our
dummy tap device is like the goggles - it does nothing! (well, almost).
We could whine about changes in default behavior, etc. etc., but
because the change was in response to actual user problems, that seems
likely a fruitless task. Fortunately, time has marched on, and even
distro releases that are old enough that they are no longer supported
by upstream libvirt (e.g. RHEL6) have support for explicitly setting a
bridge device MAC address, either during creation or with a separate
ioctl after creation, so we can now do that.
To enable explicitly setting the mac during bridge creation, we add a
mac arg to virNetDevBridgeCreate(). In the case of platforms where
the bridge is created with a netlink RTM_NEWLINK message, we just add
that mac to the message. For platforms that still use an ioctl (either
SIOCBRADDBR or SIOCIFCREATE2), we make a separate call to
virNetDevSetMAC() after creating the bridge.
(NB: I was unable to test the calling of virNetDevSetMAC() from the
SIOCIFCREATE2 (BSD) version of virNetDevBridgeCreate(); even though I
managed to get a FreeBSD system setup and libvirt built there, when I
tried to start the default network the SIOCIFCREATE2 ioctl itself
failed, so it never even got to the virNetDevSetMAC(). That leaves the
FreeBSD implementation untested.)
This makes the dummy tap pointless for purposes of setting the MAC
address, but it is still useful for IPv6 DAD initialization (which
apparently requires at least one interface to be attached to the
bridge and online), as well as for setting an initial MTU for the
bridge, so it hasn't been removed.
(NB: we can safely *always* call virNetDevBridgeCreate() with
&def->mac from the network driver because, in spite of the existence
of a "mac_specified" bool in the config suggesting that it may not
always be present, in reality a mac address will always be added to
any network that doesn't have one - this is guaranteed in all cases by
commit a47ae7c004)
https://bugzilla.redhat.com/show_bug.cgi?id=1760851
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2019-10-18 01:12:30 +00:00
|
|
|
if (virNetDevSetMAC(brname, mac) < 0) {
|
|
|
|
virErrorPtr savederr;
|
|
|
|
|
|
|
|
virErrorPreserveLast(&savederr);
|
|
|
|
ignore_value(virNetDevBridgeDelete(brname));
|
|
|
|
virErrorRestore(&savederr);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-09-12 09:46:37 +00:00
|
|
|
return 0;
|
2013-06-19 16:47:30 +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
|
|
|
#else
|
util: set bridge device MAC address explicitly during virNetDevBridgeCreate
When libvirt first implemented a stable and configurable MAC address
for the bridges created for libvirt virtual networks (commit
5754dbd56d, in libvirt v0.8.8) most distro stable releases didn't
support explicitly setting the MAC address of a bridge; the bridge
just always assumed the lowest numbered MAC of all attached
interfaces. Because of this, we stabilized the bridge MAC address by
creating a "dummy" tap interface with a MAC address guaranteed to be
lower than any of the guest tap devices' MACs (which all started with
0xFE, so it's not difficult to do) and attached it to the bridge -
this was the inception of the "virbr0-nic" device that has confused so
many people over the years.
Even though the linux kernel had recently gained support for
explicitly setting a bridge MAC, we deemed it unnecessary to set the
MAC that way, because the other (indirect) method worked everywhere.
But recently there have been reports that the bridge MAC address was
not following the setting in the network config, and mismatched the
MAC of the dummy tap device (which was still correct). It turns out
that this is due to a change in systemd-242 that persists whatever MAC
address is set for a bridge when it's initially started. According to
the systemd NEWS file entry for version 242
(https://github.com/systemd/systemd/blob/master/NEWS):
"if a bridge interface is created without any slaves, and gains
a slave later, then now the bridge does not inherit slave's MAC."
This change was the result of:
https://github.com/systemd/systemd/issues/3374
(apparently if there is no MAC saved for a bridge by the name of a
bridge being created, the random MAC generated during creation is
saved, and then that same MAC is used to explicitly set the MAC each
time it is created). Once a bridge has an explicitly set MAC, the "use
the lowest numbered MAC of attached devices" rule is ignored, so our
dummy tap device is like the goggles - it does nothing! (well, almost).
We could whine about changes in default behavior, etc. etc., but
because the change was in response to actual user problems, that seems
likely a fruitless task. Fortunately, time has marched on, and even
distro releases that are old enough that they are no longer supported
by upstream libvirt (e.g. RHEL6) have support for explicitly setting a
bridge device MAC address, either during creation or with a separate
ioctl after creation, so we can now do that.
To enable explicitly setting the mac during bridge creation, we add a
mac arg to virNetDevBridgeCreate(). In the case of platforms where
the bridge is created with a netlink RTM_NEWLINK message, we just add
that mac to the message. For platforms that still use an ioctl (either
SIOCBRADDBR or SIOCIFCREATE2), we make a separate call to
virNetDevSetMAC() after creating the bridge.
(NB: I was unable to test the calling of virNetDevSetMAC() from the
SIOCIFCREATE2 (BSD) version of virNetDevBridgeCreate(); even though I
managed to get a FreeBSD system setup and libvirt built there, when I
tried to start the default network the SIOCIFCREATE2 ioctl itself
failed, so it never even got to the virNetDevSetMAC(). That leaves the
FreeBSD implementation untested.)
This makes the dummy tap pointless for purposes of setting the MAC
address, but it is still useful for IPv6 DAD initialization (which
apparently requires at least one interface to be attached to the
bridge and online), as well as for setting an initial MTU for the
bridge, so it hasn't been removed.
(NB: we can safely *always* call virNetDevBridgeCreate() with
&def->mac from the network driver because, in spite of the existence
of a "mac_specified" bool in the config suggesting that it may not
always be present, in reality a mac address will always be added to
any network that doesn't have one - this is guaranteed in all cases by
commit a47ae7c004)
https://bugzilla.redhat.com/show_bug.cgi?id=1760851
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2019-10-18 01:12:30 +00:00
|
|
|
int
|
|
|
|
virNetDevBridgeCreate(const char *brname,
|
|
|
|
const virMacAddr *mac G_GNUC_UNUSED)
|
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
|
|
|
{
|
|
|
|
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.
|
|
|
|
*/
|
2020-09-01 11:27:44 +00:00
|
|
|
#if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRDELBR)
|
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
|
|
|
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
|
|
|
{
|
2018-09-12 09:46:37 +00:00
|
|
|
VIR_AUTOCLOSE fd = -1;
|
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
|
|
|
|
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);
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
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
|
|
|
}
|
|
|
|
|
2018-09-12 09:46:37 +00:00
|
|
|
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
|
|
|
}
|
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
|
|
|
|
|
|
|
|
|
2020-09-28 21:29:41 +00:00
|
|
|
#if defined(WITH_LIBNL)
|
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)
|
|
|
|
{
|
|
|
|
/* 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.
|
|
|
|
*/
|
2020-09-01 11:27:44 +00:00
|
|
|
# if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRDELBR)
|
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
|
|
|
return virNetlinkDelLink(brname, virNetDevBridgeDeleteWithIoctl);
|
|
|
|
# else
|
|
|
|
return virNetlinkDelLink(brname, NULL);
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-09-01 11:27:44 +00:00
|
|
|
#elif defined(WITH_STRUCT_IFREQ) && defined(SIOCBRDELBR)
|
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)
|
|
|
|
{
|
|
|
|
return virNetDevBridgeDeleteWithIoctl(brname);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-09-01 11:27:44 +00:00
|
|
|
#elif defined(WITH_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
|
|
|
{
|
|
|
|
struct ifreq ifr;
|
2018-09-12 09:46:37 +00:00
|
|
|
VIR_AUTOCLOSE s = -1;
|
2013-06-19 16:47:30 +00:00
|
|
|
|
|
|
|
if ((s = virNetDevSetupControl(brname, &ifr)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (ioctl(s, SIOCIFDESTROY, &ifr) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to remove bridge %s"),
|
|
|
|
brname);
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
2013-06-19 16:47:30 +00:00
|
|
|
}
|
|
|
|
|
2018-09-12 09:46:37 +00:00
|
|
|
return 0;
|
2013-06-19 16:47:30 +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
|
|
|
#else
|
2019-10-14 12:45:33 +00:00
|
|
|
int virNetDevBridgeDelete(const char *brname G_GNUC_UNUSED)
|
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
|
|
|
{
|
|
|
|
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.
|
|
|
|
*/
|
2020-09-01 11:27:44 +00:00
|
|
|
#if defined(WITH_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)
|
|
|
|
{
|
|
|
|
struct ifreq ifr;
|
2018-09-12 09:46:37 +00:00
|
|
|
VIR_AUTOCLOSE fd = -1;
|
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)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) {
|
|
|
|
virReportSystemError(ENODEV,
|
|
|
|
_("Unable to get interface index for %s"), ifname);
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
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 (ioctl(fd, SIOCBRADDIF, &ifr) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to add bridge %s port %s"), brname, ifname);
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
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
|
|
|
}
|
|
|
|
|
2018-09-12 09:46:37 +00:00
|
|
|
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
|
|
|
}
|
2020-09-01 11:27:44 +00:00
|
|
|
#elif defined(WITH_BSD_BRIDGE_MGMT)
|
2013-06-19 16:47:31 +00:00
|
|
|
int virNetDevBridgeAddPort(const char *brname,
|
|
|
|
const char *ifname)
|
|
|
|
{
|
|
|
|
struct ifbreq req;
|
|
|
|
|
|
|
|
memset(&req, 0, sizeof(req));
|
2018-07-20 07:50:37 +00:00
|
|
|
if (virStrcpyStatic(req.ifbr_ifsname, ifname) < 0) {
|
2013-06-19 16:47:31 +00:00
|
|
|
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.
|
|
|
|
*/
|
2020-09-01 11:27:44 +00:00
|
|
|
#if defined(WITH_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)
|
|
|
|
{
|
|
|
|
struct ifreq ifr;
|
2018-09-12 09:46:37 +00:00
|
|
|
VIR_AUTOCLOSE fd = -1;
|
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)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!(ifr.ifr_ifindex = if_nametoindex(ifname))) {
|
|
|
|
virReportSystemError(ENODEV,
|
|
|
|
_("Unable to get interface index for %s"), ifname);
|
|
|
|
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
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 (ioctl(fd, SIOCBRDELIF, &ifr) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Unable to remove bridge %s port %s"), brname, ifname);
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
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
|
|
|
}
|
|
|
|
|
2018-09-12 09:46:37 +00:00
|
|
|
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
|
|
|
}
|
2020-09-01 11:27:44 +00:00
|
|
|
#elif defined(WITH_BSD_BRIDGE_MGMT)
|
2013-06-19 16:47:31 +00:00
|
|
|
int virNetDevBridgeRemovePort(const char *brname,
|
2018-09-19 08:38:14 +00:00
|
|
|
const char *ifname)
|
2013-06-19 16:47:31 +00:00
|
|
|
{
|
|
|
|
struct ifbreq req;
|
|
|
|
|
|
|
|
memset(&req, 0, sizeof(req));
|
2018-07-20 07:50:37 +00:00
|
|
|
if (virStrcpyStatic(req.ifbr_ifsname, ifname) < 0) {
|
2013-06-19 16:47:31 +00:00
|
|
|
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
|
|
|
|
|
|
|
|
|
2020-09-01 11:27:44 +00:00
|
|
|
#if defined(WITH_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)
|
|
|
|
{
|
|
|
|
struct ifreq ifr;
|
2018-09-12 09:46:37 +00:00
|
|
|
VIR_AUTOCLOSE fd = -1;
|
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)
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
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
|
|
|
|
2018-09-12 09:46:37 +00:00
|
|
|
return virNetDevBridgeSet(brname, "forward_delay", MS_TO_JIFFIES(delay),
|
|
|
|
fd, &ifr);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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 ret = -1;
|
2019-04-30 00:29:54 +00:00
|
|
|
unsigned long val = 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
|
|
|
|
2016-06-01 09:52:53 +00:00
|
|
|
ret = virNetDevBridgeGet(brname, "forward_delay", &val);
|
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
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
struct ifreq ifr;
|
2018-09-12 09:46:37 +00:00
|
|
|
VIR_AUTOCLOSE fd = -1;
|
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)
|
2018-09-12 09:46:37 +00:00
|
|
|
return -1;
|
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
|
|
|
|
2018-09-12 09:46:37 +00:00
|
|
|
return virNetDevBridgeSet(brname, "stp_state", enable ? 1 : 0,
|
|
|
|
fd, &ifr);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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 ret = -1;
|
2019-04-08 20:32:14 +00:00
|
|
|
unsigned long val = 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
|
|
|
|
2016-06-01 09:52:53 +00:00
|
|
|
ret = virNetDevBridgeGet(brname, "stp_state", &val);
|
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
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2020-09-01 11:27:44 +00:00
|
|
|
#elif defined(WITH_BSD_BRIDGE_MGMT)
|
2013-06-19 16:47:31 +00:00
|
|
|
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,
|
2019-10-14 12:45:33 +00:00
|
|
|
int *delay G_GNUC_UNUSED)
|
2013-06-19 16:47:31 +00:00
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS,
|
|
|
|
_("Unable to get STP delay on %s on this platform"),
|
|
|
|
brname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-10-14 12:45:33 +00:00
|
|
|
int virNetDevBridgeSetSTP(const char *brname G_GNUC_UNUSED,
|
|
|
|
bool enable G_GNUC_UNUSED)
|
2013-06-19 16:47:31 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
/* FreeBSD doesn't allow to set STP per bridge,
|
|
|
|
* only per-device in bridge */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int virNetDevBridgeGetSTP(const char *brname,
|
2019-10-14 12:45:33 +00:00
|
|
|
bool *enable G_GNUC_UNUSED)
|
2013-06-19 16:47:31 +00:00
|
|
|
{
|
|
|
|
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,
|
2019-10-14 12:45:33 +00:00
|
|
|
int delay G_GNUC_UNUSED)
|
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
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS,
|
|
|
|
_("Unable to set STP delay on %s on this platform"),
|
|
|
|
brname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
int virNetDevBridgeGetSTPDelay(const char *brname,
|
2019-10-14 12:45:33 +00:00
|
|
|
int *delay G_GNUC_UNUSED)
|
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
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS,
|
|
|
|
_("Unable to get STP delay on %s on this platform"),
|
|
|
|
brname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int virNetDevBridgeSetSTP(const char *brname,
|
2019-10-14 12:45:33 +00:00
|
|
|
bool enable G_GNUC_UNUSED)
|
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
|
|
|
|
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS,
|
|
|
|
_("Unable to set STP on %s on this platform"),
|
|
|
|
brname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
int virNetDevBridgeGetSTP(const char *brname,
|
2019-10-14 12:45:33 +00:00
|
|
|
bool *enable G_GNUC_UNUSED)
|
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
|
|
|
{
|
|
|
|
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
|
|
|
|
2020-09-01 11:27:44 +00:00
|
|
|
#if defined(WITH_STRUCT_IFREQ) && defined(__linux__)
|
2014-11-19 18:28:57 +00:00
|
|
|
/**
|
|
|
|
* 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)
|
|
|
|
{
|
|
|
|
unsigned long value;
|
|
|
|
|
2016-06-01 09:52:53 +00:00
|
|
|
if (virNetDevBridgeGet(brname, "vlan_filtering", &value) < 0)
|
2019-10-21 18:19:04 +00:00
|
|
|
return -1;
|
2014-11-19 18:28:57 +00:00
|
|
|
|
|
|
|
*enable = !!value;
|
2019-10-21 18:19:04 +00:00
|
|
|
return 0;
|
2014-11-19 18:28:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
2019-10-14 12:45:33 +00:00
|
|
|
virNetDevBridgeGetVlanFiltering(const char *brname G_GNUC_UNUSED,
|
|
|
|
bool *enable G_GNUC_UNUSED)
|
2014-11-19 18:28:57 +00:00
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to get bridge vlan_filtering on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2019-10-14 12:45:33 +00:00
|
|
|
virNetDevBridgeSetVlanFiltering(const char *brname G_GNUC_UNUSED,
|
|
|
|
bool enable G_GNUC_UNUSED)
|
2014-11-19 18:28:57 +00:00
|
|
|
{
|
|
|
|
virReportSystemError(ENOSYS, "%s",
|
|
|
|
_("Unable to set bridge vlan_filtering on this platform"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif
|
2014-11-20 16:55:50 +00:00
|
|
|
|
|
|
|
|
2020-09-28 21:29:41 +00:00
|
|
|
#if defined(WITH_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)
|
|
|
|
{
|
|
|
|
struct nlmsgerr *err;
|
|
|
|
unsigned int recvbuflen;
|
|
|
|
struct ndmsg ndm = { .ndm_family = PF_BRIDGE, .ndm_state = NUD_NOARP };
|
2019-10-15 12:47:50 +00:00
|
|
|
g_autoptr(virNetlinkMsg) nl_msg = NULL;
|
2019-10-15 13:16:31 +00:00
|
|
|
g_autofree struct nlmsghdr *resp = NULL;
|
2014-11-20 16:55:50 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2021-02-24 08:51:19 +00:00
|
|
|
nl_msg = virNetlinkMsgNew(isAdd ? RTM_NEWNEIGH : RTM_DELNEIGH,
|
|
|
|
NLM_F_REQUEST |
|
|
|
|
(isAdd ? (NLM_F_CREATE | NLM_F_EXCL) : 0));
|
2014-11-20 16:55:50 +00:00
|
|
|
|
|
|
|
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) {
|
2018-08-09 04:12:14 +00:00
|
|
|
return -1;
|
2014-11-20 16:55:50 +00:00
|
|
|
}
|
|
|
|
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);
|
2018-08-09 04:12:14 +00:00
|
|
|
return -1;
|
2014-11-20 16:55:50 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NLMSG_DONE:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
goto malformed_resp;
|
|
|
|
}
|
|
|
|
|
2018-08-09 04:12:14 +00:00
|
|
|
return 0;
|
2014-11-20 16:55:50 +00:00
|
|
|
|
|
|
|
malformed_resp:
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("malformed netlink response message"));
|
2018-08-09 04:12:14 +00:00
|
|
|
return -1;
|
2014-11-20 16:55:50 +00:00
|
|
|
|
|
|
|
buffer_too_small:
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("allocated netlink buffer is too small"));
|
2018-08-09 04:12:14 +00:00
|
|
|
return -1;
|
2014-11-20 16:55:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
static int
|
2019-10-14 12:45:33 +00:00
|
|
|
virNetDevBridgeFDBAddDel(const virMacAddr *mac G_GNUC_UNUSED,
|
|
|
|
const char *ifname G_GNUC_UNUSED,
|
|
|
|
unsigned int fdbFlags G_GNUC_UNUSED,
|
|
|
|
bool isAdd G_GNUC_UNUSED)
|
2014-11-20 16:55:50 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|