mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Move the QEMU driver & utility files from qemud/ to src/
This commit is contained in:
@@ -51,12 +51,7 @@ EXTRA_DIST = libvirtd.init.in libvirtd.sysconf default-network.xml \
|
||||
remote_generate_stubs.pl rpcgen_fix.pl \
|
||||
remote_dispatch_prototypes.h \
|
||||
remote_dispatch_localvars.h \
|
||||
remote_dispatch_proc_switch.h \
|
||||
driver.c driver.h \
|
||||
conf.c conf.h \
|
||||
iptables.c iptables.h \
|
||||
bridge.c bridge.h \
|
||||
uuid.c uuid.h
|
||||
remote_dispatch_proc_switch.h
|
||||
|
||||
.x.c:
|
||||
rm -f $@
|
||||
@@ -96,9 +91,9 @@ uninstall-init:
|
||||
|
||||
libvirtd.init: libvirtd.init.in
|
||||
sed \
|
||||
-e s!\@localstatedir\@!@localstatedir@! \
|
||||
-e s!\@sbindir\@!@sbindir@! \
|
||||
-e s!\@sysconfdir\@!@sysconfdir@! \
|
||||
-e s!\@localstatedir\@!@localstatedir@!g \
|
||||
-e s!\@sbindir\@!@sbindir@!g \
|
||||
-e s!\@sysconfdir\@!@sysconfdir@!g \
|
||||
< $< > $@
|
||||
chmod a+x libvirtd.init
|
||||
|
||||
|
||||
568
qemud/bridge.c
568
qemud/bridge.c
@@ -1,568 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Mark McLoughlin <markmc@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "bridge.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <paths.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <linux/param.h> /* HZ */
|
||||
#include <linux/sockios.h> /* SIOCBRADDBR etc. */
|
||||
#include <linux/if_bridge.h> /* SYSFS_BRIDGE_ATTR */
|
||||
#include <linux/if_tun.h> /* IFF_TUN, IFF_NO_PI */
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#define MAX_BRIDGE_ID 256
|
||||
|
||||
#define BRCTL_PATH "/usr/sbin/brctl"
|
||||
#define JIFFIES_TO_MS(j) (((j)*1000)/HZ)
|
||||
#define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000)
|
||||
|
||||
struct _brControl {
|
||||
int fd;
|
||||
};
|
||||
|
||||
int
|
||||
brInit(brControl **ctlp)
|
||||
{
|
||||
int fd;
|
||||
int flags;
|
||||
|
||||
if (!ctlp || *ctlp)
|
||||
return EINVAL;
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
return errno;
|
||||
|
||||
if ((flags = fcntl(fd, F_GETFD)) < 0 ||
|
||||
fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
|
||||
int err = errno;
|
||||
close(fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
*ctlp = (brControl *)malloc(sizeof(struct _brControl));
|
||||
if (!*ctlp)
|
||||
return ENOMEM;
|
||||
|
||||
(*ctlp)->fd = fd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
brShutdown(brControl *ctl)
|
||||
{
|
||||
if (!ctl)
|
||||
return;
|
||||
|
||||
close(ctl->fd);
|
||||
ctl->fd = 0;
|
||||
|
||||
free(ctl);
|
||||
}
|
||||
|
||||
int
|
||||
brAddBridge(brControl *ctl,
|
||||
const char *nameOrFmt,
|
||||
char *name,
|
||||
int maxlen)
|
||||
{
|
||||
int id, subst;
|
||||
|
||||
if (!ctl || !ctl->fd || !nameOrFmt || !name)
|
||||
return EINVAL;
|
||||
|
||||
if (maxlen >= BR_IFNAME_MAXLEN)
|
||||
maxlen = BR_IFNAME_MAXLEN;
|
||||
|
||||
subst = id = 0;
|
||||
|
||||
if (strstr(nameOrFmt, "%d"))
|
||||
subst = 1;
|
||||
|
||||
do {
|
||||
char try[BR_IFNAME_MAXLEN];
|
||||
int len;
|
||||
|
||||
if (subst) {
|
||||
len = snprintf(try, maxlen, nameOrFmt, id);
|
||||
if (len >= maxlen)
|
||||
return EADDRINUSE;
|
||||
} else {
|
||||
len = strlen(nameOrFmt);
|
||||
if (len >= maxlen - 1)
|
||||
return EINVAL;
|
||||
|
||||
strncpy(try, nameOrFmt, len);
|
||||
try[len] = '\0';
|
||||
}
|
||||
|
||||
if (ioctl(ctl->fd, SIOCBRADDBR, try) == 0) {
|
||||
strncpy(name, try, maxlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
id++;
|
||||
} while (subst && id <= MAX_BRIDGE_ID);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
int
|
||||
brDeleteBridge(brControl *ctl,
|
||||
const char *name)
|
||||
{
|
||||
if (!ctl || !ctl->fd || !name)
|
||||
return EINVAL;
|
||||
|
||||
return ioctl(ctl->fd, SIOCBRDELBR, name) == 0 ? 0 : errno;
|
||||
}
|
||||
|
||||
static int
|
||||
brAddDelInterface(brControl *ctl,
|
||||
int cmd,
|
||||
const char *bridge,
|
||||
const char *iface)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int len;
|
||||
|
||||
if (!ctl || !ctl->fd || !bridge || !iface)
|
||||
return EINVAL;
|
||||
|
||||
if ((len = strlen(bridge)) >= BR_IFNAME_MAXLEN)
|
||||
return EINVAL;
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
|
||||
strncpy(ifr.ifr_name, bridge, len);
|
||||
ifr.ifr_name[len] = '\0';
|
||||
|
||||
if (!(ifr.ifr_ifindex = if_nametoindex(iface)))
|
||||
return ENODEV;
|
||||
|
||||
return ioctl(ctl->fd, cmd, &ifr) == 0 ? 0 : errno;
|
||||
}
|
||||
|
||||
int
|
||||
brAddInterface(brControl *ctl,
|
||||
const char *bridge,
|
||||
const char *iface)
|
||||
{
|
||||
return brAddDelInterface(ctl, SIOCBRADDIF, bridge, iface);
|
||||
}
|
||||
|
||||
int
|
||||
brDeleteInterface(brControl *ctl,
|
||||
const char *bridge,
|
||||
const char *iface)
|
||||
{
|
||||
return brAddDelInterface(ctl, SIOCBRDELIF, bridge, iface);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
brAddTap(brControl *ctl,
|
||||
const char *bridge,
|
||||
char *ifname,
|
||||
int maxlen,
|
||||
int *tapfd)
|
||||
{
|
||||
int id, subst, fd;
|
||||
|
||||
if (!ctl || !ctl->fd || !bridge || !ifname || !tapfd)
|
||||
return EINVAL;
|
||||
|
||||
subst = id = 0;
|
||||
|
||||
if (strstr(ifname, "%d"))
|
||||
subst = 1;
|
||||
|
||||
if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
|
||||
return errno;
|
||||
|
||||
do {
|
||||
struct ifreq try;
|
||||
int len;
|
||||
|
||||
memset(&try, 0, sizeof(struct ifreq));
|
||||
|
||||
try.ifr_flags = IFF_TAP|IFF_NO_PI;
|
||||
|
||||
if (subst) {
|
||||
len = snprintf(try.ifr_name, maxlen, ifname, id);
|
||||
if (len >= maxlen) {
|
||||
errno = EADDRINUSE;
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
len = strlen(ifname);
|
||||
if (len >= maxlen - 1) {
|
||||
errno = EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
strncpy(try.ifr_name, ifname, len);
|
||||
try.ifr_name[len] = '\0';
|
||||
}
|
||||
|
||||
if (ioctl(fd, TUNSETIFF, &try) == 0) {
|
||||
if ((errno = brAddInterface(ctl, bridge, try.ifr_name)))
|
||||
goto error;
|
||||
if ((errno = brSetInterfaceUp(ctl, try.ifr_name, 1)))
|
||||
goto error;
|
||||
if (ifname)
|
||||
strncpy(ifname, try.ifr_name, maxlen);
|
||||
*tapfd = fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
id++;
|
||||
} while (subst && id <= MAX_BRIDGE_ID);
|
||||
|
||||
error:
|
||||
close(fd);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
int
|
||||
brSetInterfaceUp(brControl *ctl,
|
||||
const char *ifname,
|
||||
int up)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int len;
|
||||
int flags;
|
||||
|
||||
if (!ctl || !ifname)
|
||||
return EINVAL;
|
||||
|
||||
if ((len = strlen(ifname)) >= BR_IFNAME_MAXLEN)
|
||||
return EINVAL;
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, len);
|
||||
ifr.ifr_name[len] = '\0';
|
||||
|
||||
if (ioctl(ctl->fd, SIOCGIFFLAGS, &ifr) < 0)
|
||||
return errno;
|
||||
|
||||
flags = up ? (ifr.ifr_flags | IFF_UP) : (ifr.ifr_flags & ~IFF_UP);
|
||||
|
||||
if (ifr.ifr_flags != flags) {
|
||||
ifr.ifr_flags = flags;
|
||||
|
||||
if (ioctl(ctl->fd, SIOCSIFFLAGS, &ifr) < 0)
|
||||
return errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
brGetInterfaceUp(brControl *ctl,
|
||||
const char *ifname,
|
||||
int *up)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int len;
|
||||
|
||||
if (!ctl || !ifname)
|
||||
return EINVAL;
|
||||
|
||||
if ((len = strlen(ifname)) >= BR_IFNAME_MAXLEN)
|
||||
return EINVAL;
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, len);
|
||||
ifr.ifr_name[len] = '\0';
|
||||
|
||||
if (ioctl(ctl->fd, SIOCGIFFLAGS, &ifr) < 0)
|
||||
return errno;
|
||||
|
||||
*up = (ifr.ifr_flags & IFF_UP) ? 1 : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
brSetInetAddr(brControl *ctl,
|
||||
const char *ifname,
|
||||
int cmd,
|
||||
const char *addr)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct in_addr inaddr;
|
||||
int len, ret;
|
||||
|
||||
if (!ctl || !ctl->fd || !ifname || !addr)
|
||||
return EINVAL;
|
||||
|
||||
if ((len = strlen(ifname)) >= BR_IFNAME_MAXLEN)
|
||||
return EINVAL;
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, len);
|
||||
ifr.ifr_name[len] = '\0';
|
||||
|
||||
if ((ret = inet_pton(AF_INET, addr, &inaddr)) < 0)
|
||||
return errno;
|
||||
else if (ret == 0)
|
||||
return EINVAL;
|
||||
|
||||
((struct sockaddr_in *)&ifr.ifr_data)->sin_family = AF_INET;
|
||||
((struct sockaddr_in *)&ifr.ifr_data)->sin_addr = inaddr;
|
||||
|
||||
if (ioctl(ctl->fd, cmd, &ifr) < 0)
|
||||
return errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
brGetInetAddr(brControl *ctl,
|
||||
const char *ifname,
|
||||
int cmd,
|
||||
char *addr,
|
||||
int maxlen)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct in_addr *inaddr;
|
||||
int len;
|
||||
|
||||
if (!ctl || !ctl->fd || !ifname || !addr)
|
||||
return EINVAL;
|
||||
|
||||
if ((len = strlen(ifname)) >= BR_IFNAME_MAXLEN)
|
||||
return EINVAL;
|
||||
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
|
||||
strncpy(ifr.ifr_name, ifname, len);
|
||||
ifr.ifr_name[len] = '\0';
|
||||
|
||||
if (ioctl(ctl->fd, cmd, &ifr) < 0)
|
||||
return errno;
|
||||
|
||||
if (maxlen < BR_INET_ADDR_MAXLEN || ifr.ifr_addr.sa_family != AF_INET)
|
||||
return EFAULT;
|
||||
|
||||
inaddr = &((struct sockaddr_in *)&ifr.ifr_data)->sin_addr;
|
||||
|
||||
if (!inet_ntop(AF_INET, inaddr, addr, maxlen))
|
||||
return errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
brSetInetAddress(brControl *ctl,
|
||||
const char *ifname,
|
||||
const char *addr)
|
||||
{
|
||||
return brSetInetAddr(ctl, ifname, SIOCSIFADDR, addr);
|
||||
}
|
||||
|
||||
int
|
||||
brGetInetAddress(brControl *ctl,
|
||||
const char *ifname,
|
||||
char *addr,
|
||||
int maxlen)
|
||||
{
|
||||
return brGetInetAddr(ctl, ifname, SIOCGIFADDR, addr, maxlen);
|
||||
}
|
||||
|
||||
int
|
||||
brSetInetNetmask(brControl *ctl,
|
||||
const char *ifname,
|
||||
const char *addr)
|
||||
{
|
||||
return brSetInetAddr(ctl, ifname, SIOCSIFNETMASK, addr);
|
||||
}
|
||||
|
||||
int
|
||||
brGetInetNetmask(brControl *ctl,
|
||||
const char *ifname,
|
||||
char *addr,
|
||||
int maxlen)
|
||||
{
|
||||
return brGetInetAddr(ctl, ifname, SIOCGIFNETMASK, addr, maxlen);
|
||||
}
|
||||
|
||||
static int
|
||||
brctlSpawn(char * const *argv)
|
||||
{
|
||||
pid_t pid, ret;
|
||||
int status;
|
||||
int null = -1;
|
||||
|
||||
if ((null = open(_PATH_DEVNULL, O_RDONLY)) < 0)
|
||||
return errno;
|
||||
|
||||
pid = fork();
|
||||
if (pid == -1) {
|
||||
int saved_errno = errno;
|
||||
close(null);
|
||||
return saved_errno;
|
||||
}
|
||||
|
||||
if (pid == 0) { /* child */
|
||||
dup2(null, STDIN_FILENO);
|
||||
dup2(null, STDOUT_FILENO);
|
||||
dup2(null, STDERR_FILENO);
|
||||
close(null);
|
||||
|
||||
execvp(argv[0], argv);
|
||||
|
||||
_exit (1);
|
||||
}
|
||||
|
||||
close(null);
|
||||
|
||||
while ((ret = waitpid(pid, &status, 0) == -1) && errno == EINTR);
|
||||
if (ret == -1)
|
||||
return errno;
|
||||
|
||||
return (WIFEXITED(status) && WEXITSTATUS(status) == 0) ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
int
|
||||
brSetForwardDelay(brControl *ctl ATTRIBUTE_UNUSED,
|
||||
const char *bridge,
|
||||
int delay)
|
||||
{
|
||||
char **argv;
|
||||
int retval = ENOMEM;
|
||||
int n;
|
||||
char delayStr[30];
|
||||
|
||||
n = 1 + /* brctl */
|
||||
1 + /* setfd */
|
||||
1 + /* brige name */
|
||||
1; /* value */
|
||||
|
||||
snprintf(delayStr, sizeof(delayStr), "%d", delay);
|
||||
|
||||
if (!(argv = (char **)calloc(n + 1, sizeof(char *))))
|
||||
goto error;
|
||||
|
||||
n = 0;
|
||||
|
||||
if (!(argv[n++] = strdup(BRCTL_PATH)))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup("setfd")))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup(bridge)))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup(delayStr)))
|
||||
goto error;
|
||||
|
||||
argv[n++] = NULL;
|
||||
|
||||
retval = brctlSpawn(argv);
|
||||
|
||||
error:
|
||||
if (argv) {
|
||||
n = 0;
|
||||
while (argv[n])
|
||||
free(argv[n++]);
|
||||
free(argv);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
brSetEnableSTP(brControl *ctl ATTRIBUTE_UNUSED,
|
||||
const char *bridge,
|
||||
int enable)
|
||||
{
|
||||
char **argv;
|
||||
int retval = ENOMEM;
|
||||
int n;
|
||||
|
||||
n = 1 + /* brctl */
|
||||
1 + /* setfd */
|
||||
1 + /* brige name */
|
||||
1; /* value */
|
||||
|
||||
if (!(argv = (char **)calloc(n + 1, sizeof(char *))))
|
||||
goto error;
|
||||
|
||||
n = 0;
|
||||
|
||||
if (!(argv[n++] = strdup(BRCTL_PATH)))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup("setfd")))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup(bridge)))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup(enable ? "on" : "off")))
|
||||
goto error;
|
||||
|
||||
argv[n++] = NULL;
|
||||
|
||||
retval = brctlSpawn(argv);
|
||||
|
||||
error:
|
||||
if (argv) {
|
||||
n = 0;
|
||||
while (argv[n])
|
||||
free(argv[n++]);
|
||||
free(argv);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* c-indent-level: 4
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
*/
|
||||
100
qemud/bridge.h
100
qemud/bridge.h
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Mark McLoughlin <markmc@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __QEMUD_BRIDGE_H__
|
||||
#define __QEMUD_BRIDGE_H__
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define BR_IFNAME_MAXLEN IF_NAMESIZE
|
||||
#define BR_INET_ADDR_MAXLEN INET_ADDRSTRLEN
|
||||
|
||||
typedef struct _brControl brControl;
|
||||
|
||||
int brInit (brControl **ctl);
|
||||
void brShutdown (brControl *ctl);
|
||||
|
||||
int brAddBridge (brControl *ctl,
|
||||
const char *nameOrFmt,
|
||||
char *name,
|
||||
int maxlen);
|
||||
int brDeleteBridge (brControl *ctl,
|
||||
const char *name);
|
||||
|
||||
int brAddInterface (brControl *ctl,
|
||||
const char *bridge,
|
||||
const char *iface);
|
||||
int brDeleteInterface (brControl *ctl,
|
||||
const char *bridge,
|
||||
const char *iface);
|
||||
|
||||
int brAddTap (brControl *ctl,
|
||||
const char *bridge,
|
||||
char *ifname,
|
||||
int maxlen,
|
||||
int *tapfd);
|
||||
|
||||
int brSetInterfaceUp (brControl *ctl,
|
||||
const char *ifname,
|
||||
int up);
|
||||
int brGetInterfaceUp (brControl *ctl,
|
||||
const char *ifname,
|
||||
int *up);
|
||||
|
||||
int brSetInetAddress (brControl *ctl,
|
||||
const char *ifname,
|
||||
const char *addr);
|
||||
int brGetInetAddress (brControl *ctl,
|
||||
const char *ifname,
|
||||
char *addr,
|
||||
int maxlen);
|
||||
int brSetInetNetmask (brControl *ctl,
|
||||
const char *ifname,
|
||||
const char *netmask);
|
||||
int brGetInetNetmask (brControl *ctl,
|
||||
const char *ifname,
|
||||
char *netmask,
|
||||
int maxlen);
|
||||
|
||||
int brSetForwardDelay (brControl *ctl,
|
||||
const char *bridge,
|
||||
int delay);
|
||||
int brGetForwardDelay (brControl *ctl,
|
||||
const char *bridge,
|
||||
int *delay);
|
||||
int brSetEnableSTP (brControl *ctl,
|
||||
const char *bridge,
|
||||
int enable);
|
||||
int brGetEnableSTP (brControl *ctl,
|
||||
const char *bridge,
|
||||
int *enable);
|
||||
|
||||
#endif /* __QEMUD_BRIDGE_H__ */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* c-indent-level: 4
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
*/
|
||||
2890
qemud/conf.c
2890
qemud/conf.c
File diff suppressed because it is too large
Load Diff
371
qemud/conf.h
371
qemud/conf.h
@@ -1,371 +0,0 @@
|
||||
/*
|
||||
* config.h: VM configuration management
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Red Hat, Inc.
|
||||
* Copyright (C) 2006 Daniel P. Berrange
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __QEMUD_CONF_H
|
||||
#define __QEMUD_CONF_H
|
||||
|
||||
#include "../src/internal.h"
|
||||
#include "bridge.h"
|
||||
#include "iptables.h"
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define qemudDebug(fmt, ...) do {} while(0)
|
||||
|
||||
/* Different types of QEMU acceleration possible */
|
||||
enum qemud_vm_virt_type {
|
||||
QEMUD_VIRT_QEMU,
|
||||
QEMUD_VIRT_KQEMU,
|
||||
QEMUD_VIRT_KVM,
|
||||
};
|
||||
|
||||
/* Two types of disk backends */
|
||||
enum qemud_vm_disk_type {
|
||||
QEMUD_DISK_BLOCK,
|
||||
QEMUD_DISK_FILE
|
||||
};
|
||||
|
||||
/* Three types of disk frontend */
|
||||
enum qemud_vm_disk_device {
|
||||
QEMUD_DISK_DISK,
|
||||
QEMUD_DISK_CDROM,
|
||||
QEMUD_DISK_FLOPPY,
|
||||
};
|
||||
|
||||
/* Stores the virtual disk configuration */
|
||||
struct qemud_vm_disk_def {
|
||||
int type;
|
||||
int device;
|
||||
char src[PATH_MAX];
|
||||
char dst[NAME_MAX];
|
||||
int readonly;
|
||||
|
||||
struct qemud_vm_disk_def *next;
|
||||
};
|
||||
|
||||
#define QEMUD_MAC_ADDRESS_LEN 6
|
||||
#define QEMUD_OS_TYPE_MAX_LEN 10
|
||||
#define QEMUD_OS_ARCH_MAX_LEN 10
|
||||
#define QEMUD_OS_MACHINE_MAX_LEN 10
|
||||
|
||||
/* 5 different types of networking config */
|
||||
enum qemud_vm_net_type {
|
||||
QEMUD_NET_USER,
|
||||
QEMUD_NET_ETHERNET,
|
||||
QEMUD_NET_SERVER,
|
||||
QEMUD_NET_CLIENT,
|
||||
QEMUD_NET_MCAST,
|
||||
QEMUD_NET_NETWORK,
|
||||
QEMUD_NET_BRIDGE,
|
||||
};
|
||||
|
||||
#define QEMUD_UUID_RAW_LEN 16
|
||||
#define QEMUD_MAX_NAME_LEN 50
|
||||
#define QEMUD_MAX_XML_LEN 4096
|
||||
#define QEMUD_MAX_ERROR_LEN 1024
|
||||
|
||||
/* Stores the virtual network interface configuration */
|
||||
struct qemud_vm_net_def {
|
||||
int type;
|
||||
unsigned char mac[QEMUD_MAC_ADDRESS_LEN];
|
||||
union {
|
||||
struct {
|
||||
char ifname[BR_IFNAME_MAXLEN];
|
||||
char script[PATH_MAX];
|
||||
} ethernet;
|
||||
struct {
|
||||
char address[BR_INET_ADDR_MAXLEN];
|
||||
int port;
|
||||
} socket; /* any of NET_CLIENT or NET_SERVER or NET_MCAST */
|
||||
struct {
|
||||
char name[QEMUD_MAX_NAME_LEN];
|
||||
char ifname[BR_IFNAME_MAXLEN];
|
||||
} network;
|
||||
struct {
|
||||
char brname[BR_IFNAME_MAXLEN];
|
||||
char ifname[BR_IFNAME_MAXLEN];
|
||||
} bridge;
|
||||
} dst;
|
||||
|
||||
struct qemud_vm_net_def *next;
|
||||
};
|
||||
|
||||
#define QEMUD_MAX_BOOT_DEVS 4
|
||||
|
||||
/* 3 possible boot devices */
|
||||
enum qemud_vm_boot_order {
|
||||
QEMUD_BOOT_FLOPPY,
|
||||
QEMUD_BOOT_CDROM,
|
||||
QEMUD_BOOT_DISK,
|
||||
QEMUD_BOOT_NET,
|
||||
};
|
||||
/* 3 possible graphics console modes */
|
||||
enum qemud_vm_grapics_type {
|
||||
QEMUD_GRAPHICS_NONE,
|
||||
QEMUD_GRAPHICS_SDL,
|
||||
QEMUD_GRAPHICS_VNC,
|
||||
};
|
||||
|
||||
/* Internal flags to keep track of qemu command line capabilities */
|
||||
enum qemud_cmd_flags {
|
||||
QEMUD_CMD_FLAG_KQEMU = 1,
|
||||
QEMUD_CMD_FLAG_VNC_COLON = 2,
|
||||
QEMUD_CMD_FLAG_NO_REBOOT = 4,
|
||||
};
|
||||
|
||||
|
||||
enum qemud_vm_features {
|
||||
QEMUD_FEATURE_ACPI = 1,
|
||||
};
|
||||
|
||||
/* Operating system configuration data & machine / arch */
|
||||
struct qemud_vm_os_def {
|
||||
char type[QEMUD_OS_TYPE_MAX_LEN];
|
||||
char arch[QEMUD_OS_ARCH_MAX_LEN];
|
||||
char machine[QEMUD_OS_MACHINE_MAX_LEN];
|
||||
int nBootDevs;
|
||||
int bootDevs[QEMUD_MAX_BOOT_DEVS];
|
||||
char kernel[PATH_MAX];
|
||||
char initrd[PATH_MAX];
|
||||
char cmdline[PATH_MAX];
|
||||
char binary[PATH_MAX];
|
||||
};
|
||||
|
||||
/* Guest VM main configuration */
|
||||
struct qemud_vm_def {
|
||||
int virtType;
|
||||
unsigned char uuid[QEMUD_UUID_RAW_LEN];
|
||||
char name[QEMUD_MAX_NAME_LEN];
|
||||
|
||||
int memory;
|
||||
int maxmem;
|
||||
int vcpus;
|
||||
|
||||
int noReboot;
|
||||
|
||||
struct qemud_vm_os_def os;
|
||||
|
||||
int features;
|
||||
int graphicsType;
|
||||
int vncPort;
|
||||
int vncActivePort;
|
||||
|
||||
int ndisks;
|
||||
struct qemud_vm_disk_def *disks;
|
||||
|
||||
int nnets;
|
||||
struct qemud_vm_net_def *nets;
|
||||
};
|
||||
|
||||
/* Guest VM runtime state */
|
||||
struct qemud_vm {
|
||||
int stdout;
|
||||
int stderr;
|
||||
int monitor;
|
||||
int logfile;
|
||||
int pid;
|
||||
int id;
|
||||
int state;
|
||||
|
||||
int *tapfds;
|
||||
int ntapfds;
|
||||
|
||||
char configFile[PATH_MAX];
|
||||
char autostartLink[PATH_MAX];
|
||||
|
||||
struct qemud_vm_def *def; /* The current definition */
|
||||
struct qemud_vm_def *newDef; /* New definition to activate at shutdown */
|
||||
|
||||
unsigned int autostart : 1;
|
||||
|
||||
struct qemud_vm *next;
|
||||
};
|
||||
|
||||
/* Store start and end addresses of a dhcp range */
|
||||
struct qemud_dhcp_range_def {
|
||||
char start[BR_INET_ADDR_MAXLEN];
|
||||
char end[BR_INET_ADDR_MAXLEN];
|
||||
|
||||
struct qemud_dhcp_range_def *next;
|
||||
};
|
||||
|
||||
/* Virtual Network main configuration */
|
||||
struct qemud_network_def {
|
||||
unsigned char uuid[QEMUD_UUID_RAW_LEN];
|
||||
char name[QEMUD_MAX_NAME_LEN];
|
||||
|
||||
char bridge[BR_IFNAME_MAXLEN];
|
||||
int disableSTP;
|
||||
int forwardDelay;
|
||||
|
||||
int forward;
|
||||
char forwardDev[BR_IFNAME_MAXLEN];
|
||||
|
||||
char ipAddress[BR_INET_ADDR_MAXLEN];
|
||||
char netmask[BR_INET_ADDR_MAXLEN];
|
||||
char network[BR_INET_ADDR_MAXLEN+BR_INET_ADDR_MAXLEN+1];
|
||||
|
||||
int nranges;
|
||||
struct qemud_dhcp_range_def *ranges;
|
||||
};
|
||||
|
||||
/* Virtual Network runtime state */
|
||||
struct qemud_network {
|
||||
char configFile[PATH_MAX];
|
||||
char autostartLink[PATH_MAX];
|
||||
|
||||
struct qemud_network_def *def; /* The current definition */
|
||||
struct qemud_network_def *newDef; /* New definition to activate at shutdown */
|
||||
|
||||
char bridge[BR_IFNAME_MAXLEN];
|
||||
int dnsmasqPid;
|
||||
|
||||
unsigned int active : 1;
|
||||
unsigned int autostart : 1;
|
||||
|
||||
struct qemud_network *next;
|
||||
};
|
||||
|
||||
|
||||
/* Main driver state */
|
||||
struct qemud_driver {
|
||||
int qemuVersion;
|
||||
int qemuCmdFlags; /* values from enum qemud_cmd_flags */
|
||||
int nactivevms;
|
||||
int ninactivevms;
|
||||
struct qemud_vm *vms;
|
||||
int nextvmid;
|
||||
int nactivenetworks;
|
||||
int ninactivenetworks;
|
||||
struct qemud_network *networks;
|
||||
brControl *brctl;
|
||||
iptablesContext *iptables;
|
||||
char *configDir;
|
||||
char *autostartDir;
|
||||
char *networkConfigDir;
|
||||
char *networkAutostartDir;
|
||||
char logDir[PATH_MAX];
|
||||
};
|
||||
|
||||
|
||||
static inline int
|
||||
qemudIsActiveVM(struct qemud_vm *vm)
|
||||
{
|
||||
return vm->id != -1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
qemudIsActiveNetwork(struct qemud_network *network)
|
||||
{
|
||||
return network->active;
|
||||
}
|
||||
|
||||
void qemudReportError(virConnectPtr conn,
|
||||
virDomainPtr dom,
|
||||
virNetworkPtr net,
|
||||
int code, const char *fmt, ...)
|
||||
ATTRIBUTE_FORMAT(printf,5,6);
|
||||
|
||||
|
||||
|
||||
struct qemud_vm *qemudFindVMByID(const struct qemud_driver *driver,
|
||||
int id);
|
||||
struct qemud_vm *qemudFindVMByUUID(const struct qemud_driver *driver,
|
||||
const unsigned char *uuid);
|
||||
struct qemud_vm *qemudFindVMByName(const struct qemud_driver *driver,
|
||||
const char *name);
|
||||
|
||||
struct qemud_network *qemudFindNetworkByUUID(const struct qemud_driver *driver,
|
||||
const unsigned char *uuid);
|
||||
struct qemud_network *qemudFindNetworkByName(const struct qemud_driver *driver,
|
||||
const char *name);
|
||||
|
||||
int qemudExtractVersion (struct qemud_driver *driver);
|
||||
int qemudBuildCommandLine (struct qemud_driver *driver,
|
||||
struct qemud_vm *vm,
|
||||
char ***argv);
|
||||
|
||||
int qemudScanConfigs (struct qemud_driver *driver);
|
||||
int qemudDeleteConfig (struct qemud_driver *driver,
|
||||
const char *configFile,
|
||||
const char *name);
|
||||
int qemudEnsureDir (const char *path);
|
||||
|
||||
void qemudFreeVMDef (struct qemud_vm_def *vm);
|
||||
void qemudFreeVM (struct qemud_vm *vm);
|
||||
|
||||
struct qemud_vm *
|
||||
qemudAssignVMDef (struct qemud_driver *driver,
|
||||
struct qemud_vm_def *def);
|
||||
void qemudRemoveInactiveVM (struct qemud_driver *driver,
|
||||
struct qemud_vm *vm);
|
||||
|
||||
struct qemud_vm_def *
|
||||
qemudParseVMDef (struct qemud_driver *driver,
|
||||
const char *xmlStr,
|
||||
const char *displayName);
|
||||
int qemudSaveVMDef (struct qemud_driver *driver,
|
||||
struct qemud_vm *vm,
|
||||
struct qemud_vm_def *def);
|
||||
char * qemudGenerateXML (struct qemud_driver *driver,
|
||||
struct qemud_vm *vm,
|
||||
struct qemud_vm_def *def,
|
||||
int live);
|
||||
|
||||
void qemudFreeNetworkDef (struct qemud_network_def *def);
|
||||
void qemudFreeNetwork (struct qemud_network *network);
|
||||
|
||||
struct qemud_network *
|
||||
qemudAssignNetworkDef (struct qemud_driver *driver,
|
||||
struct qemud_network_def *def);
|
||||
void qemudRemoveInactiveNetwork (struct qemud_driver *driver,
|
||||
struct qemud_network *network);
|
||||
|
||||
struct qemud_network_def *
|
||||
qemudParseNetworkDef (struct qemud_driver *driver,
|
||||
const char *xmlStr,
|
||||
const char *displayName);
|
||||
int qemudSaveNetworkDef (struct qemud_driver *driver,
|
||||
struct qemud_network *network,
|
||||
struct qemud_network_def *def);
|
||||
char * qemudGenerateNetworkXML (struct qemud_driver *driver,
|
||||
struct qemud_network *network,
|
||||
struct qemud_network_def *def);
|
||||
|
||||
struct qemu_arch_info {
|
||||
const char *arch;
|
||||
int wordsize;
|
||||
const char **machines;
|
||||
const char *binary;
|
||||
};
|
||||
extern struct qemu_arch_info qemudArchs[];
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* c-indent-level: 4
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
*/
|
||||
2536
qemud/driver.c
2536
qemud/driver.c
File diff suppressed because it is too large
Load Diff
123
qemud/driver.h
123
qemud/driver.h
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* driver.h: core driver methods for managing qemu guests
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Red Hat, Inc.
|
||||
* Copyright (C) 2006 Daniel P. Berrange
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef QEMUD_DRIVER_H
|
||||
#define QEMUD_DRIVER_H
|
||||
|
||||
#include "../src/internal.h"
|
||||
|
||||
int qemudStartup(void);
|
||||
int qemudReload(void);
|
||||
int qemudShutdown(void);
|
||||
int qemudActive(void);
|
||||
int qemudRegister(void);
|
||||
|
||||
virDrvOpenStatus qemudOpen(virConnectPtr conn,
|
||||
const char *name,
|
||||
int flags);
|
||||
|
||||
int qemudGetNodeInfo(virConnectPtr conn,
|
||||
virNodeInfoPtr info);
|
||||
|
||||
char *qemudGetCapabilities(virConnectPtr conn);
|
||||
|
||||
virDomainPtr qemudDomainLookupByID(virConnectPtr conn,
|
||||
int id);
|
||||
virDomainPtr qemudDomainLookupByUUID(virConnectPtr conn,
|
||||
const unsigned char *uuid);
|
||||
virDomainPtr qemudDomainLookupByName(virConnectPtr conn,
|
||||
const char *name);
|
||||
|
||||
int qemudGetVersion(virConnectPtr conn, unsigned long *version);
|
||||
int qemudListDomains(virConnectPtr conn,
|
||||
int *ids,
|
||||
int nids);
|
||||
int qemudNumDomains(virConnectPtr conn);
|
||||
virDomainPtr qemudDomainCreate(virConnectPtr conn,
|
||||
const char *xml,
|
||||
unsigned int flags);
|
||||
int qemudDomainSuspend(virDomainPtr dom);
|
||||
int qemudDomainResume(virDomainPtr dom);
|
||||
int qemudDomainDestroy(virDomainPtr dom);
|
||||
int qemudDomainGetInfo(virDomainPtr dom,
|
||||
virDomainInfoPtr info);
|
||||
int qemudDomainSave(virDomainPtr dom,
|
||||
const char *path);
|
||||
int qemudDomainRestore(virConnectPtr conn,
|
||||
const char *path);
|
||||
char *qemudDomainDumpXML(virDomainPtr dom,
|
||||
int flags);
|
||||
int qemudListDefinedDomains(virConnectPtr conn,
|
||||
char **const names,
|
||||
int nnames);
|
||||
int qemudNumDefinedDomains(virConnectPtr conn);
|
||||
int qemudDomainStart(virDomainPtr dom);
|
||||
virDomainPtr qemudDomainDefine(virConnectPtr conn,
|
||||
const char *xml);
|
||||
int qemudDomainUndefine(virDomainPtr dom);
|
||||
int qemudDomainGetAutostart(virDomainPtr dom,
|
||||
int *autostart);
|
||||
int qemudDomainSetAutostart(virDomainPtr dom,
|
||||
int autostart);
|
||||
|
||||
|
||||
virNetworkPtr qemudNetworkLookupByUUID(virConnectPtr conn,
|
||||
const unsigned char *uuid);
|
||||
virNetworkPtr qemudNetworkLookupByName(virConnectPtr conn,
|
||||
const char *name);
|
||||
|
||||
int qemudNumNetworks(virConnectPtr conn);
|
||||
int qemudListNetworks(virConnectPtr conn,
|
||||
char **const names,
|
||||
int nnames);
|
||||
int qemudNumDefinedNetworks(virConnectPtr conn);
|
||||
int qemudListDefinedNetworks(virConnectPtr conn,
|
||||
char **const names,
|
||||
int nnames);
|
||||
virNetworkPtr qemudNetworkCreate(virConnectPtr conn,
|
||||
const char *xml);
|
||||
virNetworkPtr qemudNetworkDefine(virConnectPtr conn,
|
||||
const char *xml);
|
||||
int qemudNetworkStart(virNetworkPtr net);
|
||||
int qemudNetworkUndefine(virNetworkPtr net);
|
||||
int qemudNetworkDestroy(virNetworkPtr net);
|
||||
char *qemudNetworkDumpXML(virNetworkPtr net,
|
||||
int flags);
|
||||
char *qemudNetworkGetBridgeName(virNetworkPtr net);
|
||||
int qemudNetworkGetAutostart(virNetworkPtr net,
|
||||
int *autostart);
|
||||
int qemudNetworkSetAutostart(virNetworkPtr net,
|
||||
int autostart);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* c-indent-level: 4
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
*/
|
||||
@@ -30,8 +30,6 @@
|
||||
|
||||
#include "protocol.h"
|
||||
#include "remote_protocol.h"
|
||||
#include "bridge.h"
|
||||
#include "iptables.h"
|
||||
#include "../config.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
899
qemud/iptables.c
899
qemud/iptables.c
@@ -1,899 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Mark McLoughlin <markmc@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "iptables.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#define qemudLog(level, msg...) fprintf(stderr, msg)
|
||||
|
||||
enum {
|
||||
ADD = 0,
|
||||
REMOVE
|
||||
};
|
||||
|
||||
enum {
|
||||
WITH_ERRORS = 0,
|
||||
NO_ERRORS
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *rule;
|
||||
char **argv;
|
||||
int flipflop;
|
||||
} iptRule;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *table;
|
||||
char *chain;
|
||||
|
||||
int nrules;
|
||||
iptRule *rules;
|
||||
|
||||
#ifdef IPTABLES_DIR
|
||||
|
||||
char dir[PATH_MAX];
|
||||
char path[PATH_MAX];
|
||||
|
||||
#endif /* IPTABLES_DIR */
|
||||
|
||||
} iptRules;
|
||||
|
||||
struct _iptablesContext
|
||||
{
|
||||
iptRules *input_filter;
|
||||
iptRules *forward_filter;
|
||||
iptRules *nat_postrouting;
|
||||
};
|
||||
|
||||
#ifdef IPTABLES_DIR
|
||||
static int
|
||||
writeRules(const char *path,
|
||||
const iptRules *rules,
|
||||
int nrules)
|
||||
{
|
||||
char tmp[PATH_MAX];
|
||||
FILE *f;
|
||||
int istmp;
|
||||
int i;
|
||||
|
||||
if (nrules == 0 && unlink(path) == 0)
|
||||
return 0;
|
||||
|
||||
if (snprintf(tmp, PATH_MAX, "%s.new", path) >= PATH_MAX)
|
||||
return EINVAL;
|
||||
|
||||
istmp = 1;
|
||||
|
||||
if (!(f = fopen(tmp, "w"))) {
|
||||
istmp = 0;
|
||||
if (!(f = fopen(path, "w")))
|
||||
return errno;
|
||||
}
|
||||
|
||||
for (i = 0; i < nrules; i++) {
|
||||
if (fputs(rules[i].rule, f) == EOF ||
|
||||
fputc('\n', f) == EOF) {
|
||||
fclose(f);
|
||||
if (istmp)
|
||||
unlink(tmp);
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
if (istmp && rename(tmp, path) < 0) {
|
||||
unlink(tmp);
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (istmp)
|
||||
unlink(tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ensureDir(const char *path)
|
||||
{
|
||||
struct stat st;
|
||||
char parent[PATH_MAX];
|
||||
char *p;
|
||||
int err;
|
||||
|
||||
if (stat(path, &st) >= 0)
|
||||
return 0;
|
||||
|
||||
strncpy(parent, path, PATH_MAX);
|
||||
parent[PATH_MAX - 1] = '\0';
|
||||
|
||||
if (!(p = strrchr(parent, '/')))
|
||||
return EINVAL;
|
||||
|
||||
if (p == parent)
|
||||
return EPERM;
|
||||
|
||||
*p = '\0';
|
||||
|
||||
if ((err = ensureDir(parent)))
|
||||
return err;
|
||||
|
||||
if (mkdir(path, 0700) < 0 && errno != EEXIST)
|
||||
return errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
buildDir(const char *table,
|
||||
char *path,
|
||||
int maxlen)
|
||||
{
|
||||
if (snprintf(path, maxlen, IPTABLES_DIR "/%s", table) >= maxlen)
|
||||
return EINVAL;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
buildPath(const char *table,
|
||||
const char *chain,
|
||||
char *path,
|
||||
int maxlen)
|
||||
{
|
||||
if (snprintf(path, maxlen, IPTABLES_DIR "/%s/%s.chain", table, chain) >= maxlen)
|
||||
return EINVAL;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif /* IPTABLES_DIR */
|
||||
|
||||
static void
|
||||
iptRuleFree(iptRule *rule)
|
||||
{
|
||||
if (rule->rule)
|
||||
free(rule->rule);
|
||||
rule->rule = NULL;
|
||||
|
||||
if (rule->argv) {
|
||||
int i = 0;
|
||||
while (rule->argv[i])
|
||||
free(rule->argv[i++]);
|
||||
free(rule->argv);
|
||||
rule->argv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
iptRulesAppend(iptRules *rules,
|
||||
char *rule,
|
||||
char **argv,
|
||||
int flipflop)
|
||||
{
|
||||
iptRule *r;
|
||||
|
||||
if (!(r = (iptRule *)realloc(rules->rules, sizeof(iptRule) * (rules->nrules+1)))) {
|
||||
int i = 0;
|
||||
while (argv[i])
|
||||
free(argv[i++]);
|
||||
free(argv);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
rules->rules = r;
|
||||
|
||||
rules->rules[rules->nrules].rule = rule;
|
||||
rules->rules[rules->nrules].argv = argv;
|
||||
rules->rules[rules->nrules].flipflop = flipflop;
|
||||
|
||||
rules->nrules++;
|
||||
|
||||
#ifdef IPTABLES_DIR
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = ensureDir(rules->dir)))
|
||||
return err;
|
||||
|
||||
if ((err = writeRules(rules->path, rules->rules, rules->nrules)))
|
||||
return err;
|
||||
}
|
||||
#endif /* IPTABLES_DIR */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iptRulesRemove(iptRules *rules,
|
||||
char *rule)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rules->nrules; i++)
|
||||
if (!strcmp(rules->rules[i].rule, strdup(rule)))
|
||||
break;
|
||||
|
||||
if (i >= rules->nrules)
|
||||
return EINVAL;
|
||||
|
||||
iptRuleFree(&rules->rules[i]);
|
||||
|
||||
memmove(&rules->rules[i],
|
||||
&rules->rules[i+1],
|
||||
(rules->nrules - i - 1) * sizeof (iptRule));
|
||||
|
||||
rules->nrules--;
|
||||
|
||||
#ifdef IPTABLES_DIR
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = writeRules(rules->path, rules->rules, rules->nrules)))
|
||||
return err;
|
||||
}
|
||||
#endif /* IPTABLES_DIR */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
iptRulesFree(iptRules *rules)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (rules->table) {
|
||||
free(rules->table);
|
||||
rules->table = NULL;
|
||||
}
|
||||
|
||||
if (rules->chain) {
|
||||
free(rules->chain);
|
||||
rules->chain = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (rules->rules) {
|
||||
for (i = 0; i < rules->nrules; i++)
|
||||
iptRuleFree(&rules->rules[i]);
|
||||
|
||||
free(rules->rules);
|
||||
rules->rules = NULL;
|
||||
|
||||
rules->nrules = 0;
|
||||
}
|
||||
|
||||
#ifdef IPTABLES_DIR
|
||||
rules->dir[0] = '\0';
|
||||
rules->path[0] = '\0';
|
||||
#endif /* IPTABLES_DIR */
|
||||
|
||||
free(rules);
|
||||
}
|
||||
|
||||
static iptRules *
|
||||
iptRulesNew(const char *table,
|
||||
const char *chain)
|
||||
{
|
||||
iptRules *rules;
|
||||
|
||||
if (!(rules = (iptRules *)calloc(1, sizeof (iptRules))))
|
||||
return NULL;
|
||||
|
||||
if (!(rules->table = strdup(table)))
|
||||
goto error;
|
||||
|
||||
if (!(rules->chain = strdup(chain)))
|
||||
goto error;
|
||||
|
||||
rules->rules = NULL;
|
||||
rules->nrules = 0;
|
||||
|
||||
#ifdef IPTABLES_DIR
|
||||
if (buildDir(table, rules->dir, sizeof(rules->dir)))
|
||||
goto error;
|
||||
|
||||
if (buildPath(table, chain, rules->path, sizeof(rules->path)))
|
||||
goto error;
|
||||
#endif /* IPTABLES_DIR */
|
||||
|
||||
return rules;
|
||||
|
||||
error:
|
||||
iptRulesFree(rules);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
iptablesSpawn(int errors, char * const *argv)
|
||||
{
|
||||
pid_t pid, ret;
|
||||
int status;
|
||||
int null = -1;
|
||||
|
||||
if (errors == NO_ERRORS && (null = open(_PATH_DEVNULL, O_RDONLY)) < 0)
|
||||
return errno;
|
||||
|
||||
pid = fork();
|
||||
if (pid == -1) {
|
||||
if (errors == NO_ERRORS)
|
||||
close(null);
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (pid == 0) { /* child */
|
||||
if (errors == NO_ERRORS) {
|
||||
dup2(null, STDIN_FILENO);
|
||||
dup2(null, STDOUT_FILENO);
|
||||
dup2(null, STDERR_FILENO);
|
||||
close(null);
|
||||
}
|
||||
|
||||
execvp(argv[0], argv);
|
||||
|
||||
_exit (1);
|
||||
}
|
||||
|
||||
if (errors == NO_ERRORS)
|
||||
close(null);
|
||||
|
||||
while ((ret = waitpid(pid, &status, 0) == -1) && errno == EINTR);
|
||||
if (ret == -1)
|
||||
return errno;
|
||||
|
||||
if (errors == NO_ERRORS)
|
||||
return 0;
|
||||
else
|
||||
return (WIFEXITED(status) && WEXITSTATUS(status) == 0) ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
iptablesAddRemoveChain(iptRules *rules, int action)
|
||||
{
|
||||
char **argv;
|
||||
int retval = ENOMEM;
|
||||
int n;
|
||||
|
||||
n = 1 + /* /sbin/iptables */
|
||||
2 + /* --table foo */
|
||||
2; /* --new-chain bar */
|
||||
|
||||
if (!(argv = (char **)calloc(n + 1, sizeof(char *))))
|
||||
goto error;
|
||||
|
||||
n = 0;
|
||||
|
||||
if (!(argv[n++] = strdup(IPTABLES_PATH)))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup("--table")))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup(rules->table)))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup(action == ADD ? "--new-chain" : "--delete-chain")))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup(rules->chain)))
|
||||
goto error;
|
||||
|
||||
retval = iptablesSpawn(NO_ERRORS, argv);
|
||||
|
||||
error:
|
||||
if (argv) {
|
||||
n = 0;
|
||||
while (argv[n])
|
||||
free(argv[n++]);
|
||||
free(argv);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
iptablesAddRemoveRule(iptRules *rules, int action, const char *arg, ...)
|
||||
{
|
||||
va_list args;
|
||||
int retval = ENOMEM;
|
||||
char **argv;
|
||||
char *rule = NULL, *p;
|
||||
const char *s;
|
||||
int n, rulelen, flipflop;
|
||||
|
||||
n = 1 + /* /sbin/iptables */
|
||||
2 + /* --table foo */
|
||||
2 + /* --insert bar */
|
||||
1; /* arg */
|
||||
|
||||
rulelen = strlen(arg) + 1;
|
||||
|
||||
va_start(args, arg);
|
||||
while ((s = va_arg(args, const char *))) {
|
||||
n++;
|
||||
rulelen += strlen(s) + 1;
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
if (!(argv = (char **)calloc(n + 1, sizeof(char *))))
|
||||
goto error;
|
||||
|
||||
if (!(rule = (char *)malloc(rulelen)))
|
||||
goto error;
|
||||
|
||||
n = 0;
|
||||
|
||||
if (!(argv[n++] = strdup(IPTABLES_PATH)))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup("--table")))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup(rules->table)))
|
||||
goto error;
|
||||
|
||||
flipflop = n;
|
||||
|
||||
if (!(argv[n++] = strdup(action == ADD ? "--insert" : "--delete")))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup(rules->chain)))
|
||||
goto error;
|
||||
|
||||
if (!(argv[n++] = strdup(arg)))
|
||||
goto error;
|
||||
|
||||
p = strcpy(rule, arg);
|
||||
p += strlen(arg);
|
||||
|
||||
va_start(args, arg);
|
||||
|
||||
while ((s = va_arg(args, const char *))) {
|
||||
if (!(argv[n++] = strdup(s)))
|
||||
goto error;
|
||||
|
||||
*(p++) = ' ';
|
||||
strcpy(p, s);
|
||||
p += strlen(s);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
*p = '\0';
|
||||
|
||||
if (action == ADD &&
|
||||
(retval = iptablesAddRemoveChain(rules, action)))
|
||||
goto error;
|
||||
|
||||
if ((retval = iptablesSpawn(WITH_ERRORS, argv)))
|
||||
goto error;
|
||||
|
||||
if (action == REMOVE &&
|
||||
(retval = iptablesAddRemoveChain(rules, action)))
|
||||
goto error;
|
||||
|
||||
if (action == ADD) {
|
||||
retval = iptRulesAppend(rules, rule, argv, flipflop);
|
||||
rule = NULL;
|
||||
argv = NULL;
|
||||
} else {
|
||||
retval = iptRulesRemove(rules, rule);
|
||||
}
|
||||
|
||||
error:
|
||||
if (rule)
|
||||
free(rule);
|
||||
|
||||
if (argv) {
|
||||
n = 0;
|
||||
while (argv[n])
|
||||
free(argv[n++]);
|
||||
free(argv);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
iptablesContext *
|
||||
iptablesContextNew(void)
|
||||
{
|
||||
iptablesContext *ctx;
|
||||
|
||||
if (!(ctx = (iptablesContext *) calloc(1, sizeof (iptablesContext))))
|
||||
return NULL;
|
||||
|
||||
if (!(ctx->input_filter = iptRulesNew("filter", IPTABLES_PREFIX "INPUT")))
|
||||
goto error;
|
||||
|
||||
if (!(ctx->forward_filter = iptRulesNew("filter", IPTABLES_PREFIX "FORWARD")))
|
||||
goto error;
|
||||
|
||||
if (!(ctx->nat_postrouting = iptRulesNew("nat", IPTABLES_PREFIX "POSTROUTING")))
|
||||
goto error;
|
||||
|
||||
return ctx;
|
||||
|
||||
error:
|
||||
iptablesContextFree(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
iptablesContextFree(iptablesContext *ctx)
|
||||
{
|
||||
if (ctx->input_filter)
|
||||
iptRulesFree(ctx->input_filter);
|
||||
if (ctx->forward_filter)
|
||||
iptRulesFree(ctx->forward_filter);
|
||||
if (ctx->nat_postrouting)
|
||||
iptRulesFree(ctx->nat_postrouting);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
iptRulesReload(iptRules *rules)
|
||||
{
|
||||
int i;
|
||||
int retval;
|
||||
|
||||
for (i = 0; i < rules->nrules; i++) {
|
||||
iptRule *rule = &rules->rules[i];
|
||||
char *orig;
|
||||
|
||||
orig = rule->argv[rule->flipflop];
|
||||
rule->argv[rule->flipflop] = (char *) "--delete";
|
||||
|
||||
if ((retval = iptablesSpawn(WITH_ERRORS, rule->argv)))
|
||||
qemudLog(QEMUD_WARN, "Failed to remove iptables rule '%s' from chain '%s' in table '%s': %s",
|
||||
rule->rule, rules->chain, rules->table, strerror(errno));
|
||||
|
||||
rule->argv[rule->flipflop] = orig;
|
||||
}
|
||||
|
||||
if ((retval = iptablesAddRemoveChain(rules, REMOVE)) ||
|
||||
(retval = iptablesAddRemoveChain(rules, ADD)))
|
||||
qemudLog(QEMUD_WARN, "Failed to re-create chain '%s' in table '%s': %s",
|
||||
rules->chain, rules->table, strerror(retval));
|
||||
|
||||
for (i = 0; i < rules->nrules; i++)
|
||||
if ((retval = iptablesSpawn(WITH_ERRORS, rules->rules[i].argv)))
|
||||
qemudLog(QEMUD_WARN, "Failed to add iptables rule '%s' to chain '%s' in table '%s': %s",
|
||||
rules->rules[i].rule, rules->chain, rules->table, strerror(retval));
|
||||
}
|
||||
|
||||
void
|
||||
iptablesReloadRules(iptablesContext *ctx)
|
||||
{
|
||||
iptRulesReload(ctx->input_filter);
|
||||
iptRulesReload(ctx->forward_filter);
|
||||
iptRulesReload(ctx->nat_postrouting);
|
||||
}
|
||||
|
||||
static int
|
||||
iptablesInput(iptablesContext *ctx,
|
||||
const char *iface,
|
||||
int port,
|
||||
int action,
|
||||
int tcp)
|
||||
{
|
||||
char portstr[32];
|
||||
|
||||
snprintf(portstr, sizeof(portstr), "%d", port);
|
||||
portstr[sizeof(portstr) - 1] = '\0';
|
||||
|
||||
return iptablesAddRemoveRule(ctx->input_filter,
|
||||
action,
|
||||
"--in-interface", iface,
|
||||
"--protocol", tcp ? "tcp" : "udp",
|
||||
"--destination-port", portstr,
|
||||
"--jump", "ACCEPT",
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesAddTcpInput(iptablesContext *ctx,
|
||||
const char *iface,
|
||||
int port)
|
||||
{
|
||||
return iptablesInput(ctx, iface, port, ADD, 1);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesRemoveTcpInput(iptablesContext *ctx,
|
||||
const char *iface,
|
||||
int port)
|
||||
{
|
||||
return iptablesInput(ctx, iface, port, REMOVE, 1);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesAddUdpInput(iptablesContext *ctx,
|
||||
const char *iface,
|
||||
int port)
|
||||
{
|
||||
return iptablesInput(ctx, iface, port, ADD, 0);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesRemoveUdpInput(iptablesContext *ctx,
|
||||
const char *iface,
|
||||
int port)
|
||||
{
|
||||
return iptablesInput(ctx, iface, port, REMOVE, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Allow all traffic coming from the bridge, with a valid network address
|
||||
* to proceed to WAN
|
||||
*/
|
||||
static int
|
||||
iptablesForwardAllowOut(iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *iface,
|
||||
const char *physdev,
|
||||
int action)
|
||||
{
|
||||
if (physdev && physdev[0]) {
|
||||
return iptablesAddRemoveRule(ctx->forward_filter,
|
||||
action,
|
||||
"--source", network,
|
||||
"--in-interface", iface,
|
||||
"--out-interface", physdev,
|
||||
"--jump", "ACCEPT",
|
||||
NULL);
|
||||
} else {
|
||||
return iptablesAddRemoveRule(ctx->forward_filter,
|
||||
action,
|
||||
"--source", network,
|
||||
"--in-interface", iface,
|
||||
"--jump", "ACCEPT",
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
iptablesAddForwardAllowOut(iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *iface,
|
||||
const char *physdev)
|
||||
{
|
||||
return iptablesForwardAllowOut(ctx, network, iface, physdev, ADD);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesRemoveForwardAllowOut(iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *iface,
|
||||
const char *physdev)
|
||||
{
|
||||
return iptablesForwardAllowOut(ctx, network, iface, physdev, REMOVE);
|
||||
}
|
||||
|
||||
|
||||
/* Allow all traffic destined to the bridge, with a valid network address
|
||||
* and associated with an existing connection
|
||||
*/
|
||||
static int
|
||||
iptablesForwardAllowIn(iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *iface,
|
||||
const char *physdev,
|
||||
int action)
|
||||
{
|
||||
if (physdev && physdev[0]) {
|
||||
return iptablesAddRemoveRule(ctx->forward_filter,
|
||||
action,
|
||||
"--destination", network,
|
||||
"--in-interface", physdev,
|
||||
"--out-interface", iface,
|
||||
"--match", "state",
|
||||
"--state", "ESTABLISHED,RELATED",
|
||||
"--jump", "ACCEPT",
|
||||
NULL);
|
||||
} else {
|
||||
return iptablesAddRemoveRule(ctx->forward_filter,
|
||||
action,
|
||||
"--destination", network,
|
||||
"--out-interface", iface,
|
||||
"--match", "state",
|
||||
"--state", "ESTABLISHED,RELATED",
|
||||
"--jump", "ACCEPT",
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
iptablesAddForwardAllowIn(iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *iface,
|
||||
const char *physdev)
|
||||
{
|
||||
return iptablesForwardAllowIn(ctx, network, iface, physdev, ADD);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesRemoveForwardAllowIn(iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *iface,
|
||||
const char *physdev)
|
||||
{
|
||||
return iptablesForwardAllowIn(ctx, network, iface, physdev, REMOVE);
|
||||
}
|
||||
|
||||
|
||||
/* Allow all traffic between guests on the same bridge,
|
||||
* with a valid network address
|
||||
*/
|
||||
static int
|
||||
iptablesForwardAllowCross(iptablesContext *ctx,
|
||||
const char *iface,
|
||||
int action)
|
||||
{
|
||||
return iptablesAddRemoveRule(ctx->forward_filter,
|
||||
action,
|
||||
"--in-interface", iface,
|
||||
"--out-interface", iface,
|
||||
"--jump", "ACCEPT",
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesAddForwardAllowCross(iptablesContext *ctx,
|
||||
const char *iface) {
|
||||
return iptablesForwardAllowCross(ctx, iface, ADD);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesRemoveForwardAllowCross(iptablesContext *ctx,
|
||||
const char *iface) {
|
||||
return iptablesForwardAllowCross(ctx, iface, REMOVE);
|
||||
}
|
||||
|
||||
|
||||
/* Drop all traffic trying to forward from the bridge.
|
||||
* ie the bridge is the in interface
|
||||
*/
|
||||
static int
|
||||
iptablesForwardRejectOut(iptablesContext *ctx,
|
||||
const char *iface,
|
||||
int action)
|
||||
{
|
||||
return iptablesAddRemoveRule(ctx->forward_filter,
|
||||
action,
|
||||
"--in-interface", iface,
|
||||
"--jump", "REJECT",
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesAddForwardRejectOut(iptablesContext *ctx,
|
||||
const char *iface)
|
||||
{
|
||||
return iptablesForwardRejectOut(ctx, iface, ADD);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesRemoveForwardRejectOut(iptablesContext *ctx,
|
||||
const char *iface)
|
||||
{
|
||||
return iptablesForwardRejectOut(ctx, iface, REMOVE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Drop all traffic trying to forward to the bridge.
|
||||
* ie the bridge is the out interface
|
||||
*/
|
||||
static int
|
||||
iptablesForwardRejectIn(iptablesContext *ctx,
|
||||
const char *iface,
|
||||
int action)
|
||||
{
|
||||
return iptablesAddRemoveRule(ctx->forward_filter,
|
||||
action,
|
||||
"--out-interface", iface,
|
||||
"--jump", "REJECT",
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesAddForwardRejectIn(iptablesContext *ctx,
|
||||
const char *iface)
|
||||
{
|
||||
return iptablesForwardRejectIn(ctx, iface, ADD);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesRemoveForwardRejectIn(iptablesContext *ctx,
|
||||
const char *iface)
|
||||
{
|
||||
return iptablesForwardRejectIn(ctx, iface, REMOVE);
|
||||
}
|
||||
|
||||
|
||||
/* Masquerade all traffic coming from the network associated
|
||||
* with the bridge
|
||||
*/
|
||||
static int
|
||||
iptablesForwardMasquerade(iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *physdev,
|
||||
int action)
|
||||
{
|
||||
if (physdev && physdev[0]) {
|
||||
return iptablesAddRemoveRule(ctx->nat_postrouting,
|
||||
action,
|
||||
"--source", network,
|
||||
"--out-interface", physdev,
|
||||
"--jump", "MASQUERADE",
|
||||
NULL);
|
||||
} else {
|
||||
return iptablesAddRemoveRule(ctx->nat_postrouting,
|
||||
action,
|
||||
"--source", network,
|
||||
"--jump", "MASQUERADE",
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
iptablesAddForwardMasquerade(iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *physdev)
|
||||
{
|
||||
return iptablesForwardMasquerade(ctx, network, physdev, ADD);
|
||||
}
|
||||
|
||||
int
|
||||
iptablesRemoveForwardMasquerade(iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *physdev)
|
||||
{
|
||||
return iptablesForwardMasquerade(ctx, network, physdev, REMOVE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* c-indent-level: 4
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
*/
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Mark McLoughlin <markmc@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __QEMUD_IPTABLES_H__
|
||||
#define __QEMUD_IPTABLES_H__
|
||||
|
||||
typedef struct _iptablesContext iptablesContext;
|
||||
|
||||
iptablesContext *iptablesContextNew (void);
|
||||
void iptablesContextFree (iptablesContext *ctx);
|
||||
|
||||
void iptablesReloadRules (iptablesContext *ctx);
|
||||
|
||||
int iptablesAddTcpInput (iptablesContext *ctx,
|
||||
const char *iface,
|
||||
int port);
|
||||
int iptablesRemoveTcpInput (iptablesContext *ctx,
|
||||
const char *iface,
|
||||
int port);
|
||||
|
||||
int iptablesAddUdpInput (iptablesContext *ctx,
|
||||
const char *iface,
|
||||
int port);
|
||||
int iptablesRemoveUdpInput (iptablesContext *ctx,
|
||||
const char *iface,
|
||||
int port);
|
||||
|
||||
int iptablesAddForwardAllowOut (iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *iface,
|
||||
const char *physdev);
|
||||
int iptablesRemoveForwardAllowOut (iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *iface,
|
||||
const char *physdev);
|
||||
|
||||
int iptablesAddForwardAllowIn (iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *iface,
|
||||
const char *physdev);
|
||||
int iptablesRemoveForwardAllowIn (iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *iface,
|
||||
const char *physdev);
|
||||
|
||||
int iptablesAddForwardAllowCross (iptablesContext *ctx,
|
||||
const char *iface);
|
||||
int iptablesRemoveForwardAllowCross (iptablesContext *ctx,
|
||||
const char *iface);
|
||||
|
||||
int iptablesAddForwardRejectOut (iptablesContext *ctx,
|
||||
const char *iface);
|
||||
int iptablesRemoveForwardRejectOut (iptablesContext *ctx,
|
||||
const char *iface);
|
||||
|
||||
int iptablesAddForwardRejectIn (iptablesContext *ctx,
|
||||
const char *iface);
|
||||
int iptablesRemoveForwardRejectIn (iptablesContext *ctx,
|
||||
const char *iface);
|
||||
|
||||
int iptablesAddForwardMasquerade (iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *physdev);
|
||||
int iptablesRemoveForwardMasquerade (iptablesContext *ctx,
|
||||
const char *network,
|
||||
const char *physdev);
|
||||
|
||||
#endif /* __QEMUD_IPTABLES_H__ */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* c-indent-level: 4
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
*/
|
||||
149
qemud/uuid.c
149
qemud/uuid.c
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Mark McLoughlin <markmc@redhat.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "uuid.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#define qemudLog(level, msg...) fprintf(stderr, msg)
|
||||
|
||||
static int
|
||||
virUUIDGenerateRandomBytes(unsigned char *buf,
|
||||
int buflen)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if ((fd = open("/dev/urandom", O_RDONLY)) < 0)
|
||||
return errno;
|
||||
|
||||
while (buflen > 0) {
|
||||
int n;
|
||||
|
||||
if ((n = read(fd, buf, buflen)) <= 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
close(fd);
|
||||
return n < 0 ? errno : ENODATA;
|
||||
}
|
||||
|
||||
buf += n;
|
||||
buflen -= n;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
virUUIDGeneratePseudoRandomBytes(unsigned char *buf,
|
||||
int buflen)
|
||||
{
|
||||
srand(time(NULL));
|
||||
while (buflen > 0) {
|
||||
*buf = (int) (255.0 * (rand() / (double) RAND_MAX));
|
||||
buflen--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
virUUIDGenerate(unsigned char *uuid)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = virUUIDGenerateRandomBytes(uuid, VIR_UUID_RAW_LEN)))
|
||||
qemudLog(QEMUD_WARN,
|
||||
"Falling back to pseudorandom UUID, "
|
||||
"failed to generate random bytes: %s", strerror(err));
|
||||
|
||||
return virUUIDGeneratePseudoRandomBytes(uuid, VIR_UUID_RAW_LEN);
|
||||
}
|
||||
|
||||
int
|
||||
virUUIDParse(const char *uuid, unsigned char *rawuuid) {
|
||||
const char *cur;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* do a liberal scan allowing '-' and ' ' anywhere between character
|
||||
* pairs as long as there is 32 of them in the end.
|
||||
*/
|
||||
cur = uuid;
|
||||
for (i = 0;i < 16;) {
|
||||
rawuuid[i] = 0;
|
||||
if (*cur == 0)
|
||||
goto error;
|
||||
if ((*cur == '-') || (*cur == ' ')) {
|
||||
cur++;
|
||||
continue;
|
||||
}
|
||||
if ((*cur >= '0') && (*cur <= '9'))
|
||||
rawuuid[i] = *cur - '0';
|
||||
else if ((*cur >= 'a') && (*cur <= 'f'))
|
||||
rawuuid[i] = *cur - 'a' + 10;
|
||||
else if ((*cur >= 'A') && (*cur <= 'F'))
|
||||
rawuuid[i] = *cur - 'A' + 10;
|
||||
else
|
||||
goto error;
|
||||
rawuuid[i] *= 16;
|
||||
cur++;
|
||||
if (*cur == 0)
|
||||
goto error;
|
||||
if ((*cur >= '0') && (*cur <= '9'))
|
||||
rawuuid[i] += *cur - '0';
|
||||
else if ((*cur >= 'a') && (*cur <= 'f'))
|
||||
rawuuid[i] += *cur - 'a' + 10;
|
||||
else if ((*cur >= 'A') && (*cur <= 'F'))
|
||||
rawuuid[i] += *cur - 'A' + 10;
|
||||
else
|
||||
goto error;
|
||||
i++;
|
||||
cur++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* c-indent-level: 4
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* End:
|
||||
*/
|
||||
|
||||
32
qemud/uuid.h
32
qemud/uuid.h
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Mark McLoughlin <markmc@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __VIR_UUID_H__
|
||||
#define __VIR_UUID_H__
|
||||
|
||||
#define VIR_UUID_RAW_LEN 16
|
||||
|
||||
int virUUIDGenerate(unsigned char *uuid);
|
||||
|
||||
int virUUIDParse(const char *uuid,
|
||||
unsigned char *rawuuid);
|
||||
|
||||
#endif /* __VIR_UUID_H__ */
|
||||
Reference in New Issue
Block a user