mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03: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>
|
||||
])
|
||||
|
||||
# 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
|
||||
# or Coverity-prevent's cov-build. Define STATIC_ANALYSIS accordingly.
|
||||
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)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_BSD_BRIDGE_MGMT)
|
||||
# include <net/ethernet.h>
|
||||
# include <net/if_bridgevar.h>
|
||||
#endif
|
||||
|
||||
#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__)
|
||||
# define SYSFS_NET_DIR "/sys/class/net"
|
||||
/*
|
||||
@ -322,6 +365,28 @@ cleanup:
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
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
|
||||
int virNetDevBridgeAddPort(const char *brname,
|
||||
const char *ifname)
|
||||
@ -370,6 +435,28 @@ cleanup:
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
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
|
||||
int virNetDevBridgeRemovePort(const char *brname,
|
||||
const char *ifname)
|
||||
@ -501,7 +588,50 @@ cleanup:
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
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 delay ATTRIBUTE_UNUSED)
|
||||
{
|
||||
@ -536,4 +666,4 @@ int virNetDevBridgeGetSTP(const char *brname,
|
||||
brname);
|
||||
return -1;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user