mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
BSD: implement bridge add/remove port and set STP
This commit is contained in:
parent
b9c6b073e6
commit
ce2400676d
11
configure.ac
11
configure.ac
@ -2399,6 +2399,17 @@ AC_CHECK_DECLS([link_addr],
|
|||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
])
|
])
|
||||||
|
|
||||||
|
# Check for BSD approach for bridge management
|
||||||
|
AC_CHECK_DECLS([BRDGSFD, BRDGADD, BRDGDEL],
|
||||||
|
[AC_DEFINE([HAVE_BSD_BRIDGE_MGMT],
|
||||||
|
[1],
|
||||||
|
[whether BSD style bridge management is available])],
|
||||||
|
[],
|
||||||
|
[#include <net/if.h>
|
||||||
|
#include <net/ethernet.h>
|
||||||
|
#include <net/if_bridgevar.h>
|
||||||
|
])
|
||||||
|
|
||||||
# Detect when running under the clang static analyzer's scan-build driver
|
# Detect when running under the clang static analyzer's scan-build driver
|
||||||
# or Coverity-prevent's cov-build. Define STATIC_ANALYSIS accordingly.
|
# or Coverity-prevent's cov-build. Define STATIC_ANALYSIS accordingly.
|
||||||
AC_CACHE_CHECK([whether this build is done by a static analysis tool],
|
AC_CACHE_CHECK([whether this build is done by a static analysis tool],
|
||||||
|
@ -45,9 +45,52 @@
|
|||||||
# define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000)
|
# define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_BSD_BRIDGE_MGMT)
|
||||||
|
# include <net/ethernet.h>
|
||||||
|
# include <net/if_bridgevar.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(HAVE_BSD_BRIDGE_MGMT)
|
||||||
|
static int virNetDevBridgeCmd(const char *brname,
|
||||||
|
u_long op,
|
||||||
|
void *arg,
|
||||||
|
size_t argsize)
|
||||||
|
{
|
||||||
|
int s;
|
||||||
|
int ret = -1;
|
||||||
|
struct ifdrv ifd;
|
||||||
|
|
||||||
|
memset(&ifd, 0, sizeof(ifd));
|
||||||
|
|
||||||
|
if ((s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Cannot open network interface control socket"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virStrcpyStatic(ifd.ifd_name, brname) == NULL) {
|
||||||
|
virReportSystemError(ERANGE,
|
||||||
|
_("Network interface name '%s' is too long"),
|
||||||
|
brname);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ifd.ifd_cmd = op;
|
||||||
|
ifd.ifd_len = argsize;
|
||||||
|
ifd.ifd_data = arg;
|
||||||
|
|
||||||
|
ret = ioctl(s, SIOCSDRVSPEC, &ifd);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FORCE_CLOSE(s);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_STRUCT_IFREQ) && defined(__linux__)
|
#if defined(HAVE_STRUCT_IFREQ) && defined(__linux__)
|
||||||
# define SYSFS_NET_DIR "/sys/class/net"
|
# define SYSFS_NET_DIR "/sys/class/net"
|
||||||
/*
|
/*
|
||||||
@ -322,6 +365,28 @@ cleanup:
|
|||||||
VIR_FORCE_CLOSE(fd);
|
VIR_FORCE_CLOSE(fd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#elif defined(HAVE_BSD_BRIDGE_MGMT)
|
||||||
|
int virNetDevBridgeAddPort(const char *brname,
|
||||||
|
const char *ifname)
|
||||||
|
{
|
||||||
|
struct ifbreq req;
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
if (virStrcpyStatic(req.ifbr_ifsname, ifname) == NULL) {
|
||||||
|
virReportSystemError(ERANGE,
|
||||||
|
_("Network interface name '%s' is too long"),
|
||||||
|
ifname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virNetDevBridgeCmd(brname, BRDGADD, &req, sizeof(req)) < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("Unable to add bridge %s port %s"), brname, ifname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
int virNetDevBridgeAddPort(const char *brname,
|
int virNetDevBridgeAddPort(const char *brname,
|
||||||
const char *ifname)
|
const char *ifname)
|
||||||
@ -370,6 +435,28 @@ cleanup:
|
|||||||
VIR_FORCE_CLOSE(fd);
|
VIR_FORCE_CLOSE(fd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#elif defined(HAVE_BSD_BRIDGE_MGMT)
|
||||||
|
int virNetDevBridgeRemovePort(const char *brname,
|
||||||
|
const char *ifname)
|
||||||
|
{
|
||||||
|
struct ifbreq req;
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
if (virStrcpyStatic(req.ifbr_ifsname, ifname) == NULL) {
|
||||||
|
virReportSystemError(ERANGE,
|
||||||
|
_("Network interface name '%s' is too long"),
|
||||||
|
ifname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virNetDevBridgeCmd(brname, BRDGDEL, &req, sizeof(req)) < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("Unable to remove bridge %s port %s"), brname, ifname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
int virNetDevBridgeRemovePort(const char *brname,
|
int virNetDevBridgeRemovePort(const char *brname,
|
||||||
const char *ifname)
|
const char *ifname)
|
||||||
@ -501,7 +588,50 @@ cleanup:
|
|||||||
VIR_FORCE_CLOSE(fd);
|
VIR_FORCE_CLOSE(fd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#else /* !__linux__ */
|
#elif defined(HAVE_BSD_BRIDGE_MGMT)
|
||||||
|
int virNetDevBridgeSetSTPDelay(const char *brname,
|
||||||
|
int delay)
|
||||||
|
{
|
||||||
|
struct ifbrparam param;
|
||||||
|
|
||||||
|
/* FreeBSD doesn't allow setting STP delay < 4 */
|
||||||
|
delay = delay < 4 ? 4 : delay;
|
||||||
|
param.ifbrp_fwddelay = ((u_long)delay) & 0xff;
|
||||||
|
|
||||||
|
if (virNetDevBridgeCmd(brname, BRDGSFD, ¶m, sizeof(param)) < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("Unable to set STP delay on %s"), brname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int virNetDevBridgeGetSTPDelay(const char *brname,
|
||||||
|
int *delay ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virReportSystemError(ENOSYS,
|
||||||
|
_("Unable to get STP delay on %s on this platform"),
|
||||||
|
brname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virNetDevBridgeSetSTP(const char *brname ATTRIBUTE_UNUSED,
|
||||||
|
bool enable ATTRIBUTE_UNUSED)
|
||||||
|
|
||||||
|
{
|
||||||
|
/* FreeBSD doesn't allow to set STP per bridge,
|
||||||
|
* only per-device in bridge */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int virNetDevBridgeGetSTP(const char *brname,
|
||||||
|
bool *enable ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virReportSystemError(ENOSYS,
|
||||||
|
_("Unable to get STP on %s on this platform"),
|
||||||
|
brname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
int virNetDevBridgeSetSTPDelay(const char *brname,
|
int virNetDevBridgeSetSTPDelay(const char *brname,
|
||||||
int delay ATTRIBUTE_UNUSED)
|
int delay ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
@ -536,4 +666,4 @@ int virNetDevBridgeGetSTP(const char *brname,
|
|||||||
brname);
|
brname);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* __linux__ */
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user