Move the QEMU driver & utility files from qemud/ to src/

This commit is contained in:
Daniel P. Berrange
2007-06-27 00:12:29 +00:00
parent a78a6602df
commit a07f0a00da
17 changed files with 32 additions and 1554 deletions

View File

@@ -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

View File

@@ -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:
*/

View File

@@ -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:
*/

File diff suppressed because it is too large Load Diff

View File

@@ -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:
*/

File diff suppressed because it is too large Load Diff

View File

@@ -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:
*/

View File

@@ -30,8 +30,6 @@
#include "protocol.h"
#include "remote_protocol.h"
#include "bridge.h"
#include "iptables.h"
#include "../config.h"
#ifdef __GNUC__

View File

@@ -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:
*/

View File

@@ -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:
*/

View File

@@ -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:
*/

View File

@@ -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__ */