src/util/hooks.c
src/util/hostusb.c
src/util/interface.c
+src/util/iptables.c
src/util/json.c
src/util/macvtap.c
src/util/network.c
* Author: Daniel P. Berrange <berrange@redhat.com>
*/
-
-
#include <config.h>
#include <unistd.h>
VIR_FREE(def->name);
VIR_FREE(def->bridge);
VIR_FREE(def->forwardDev);
- VIR_FREE(def->ipAddress);
- VIR_FREE(def->network);
- VIR_FREE(def->netmask);
VIR_FREE(def->domain);
- for (i = 0 ; i < def->nranges && def->ranges ; i++) {
- VIR_FREE(def->ranges[i].start);
- VIR_FREE(def->ranges[i].end);
- }
VIR_FREE(def->ranges);
for (i = 0 ; i < def->nhosts && def->hosts ; i++) {
VIR_FREE(def->hosts[i].mac);
- VIR_FREE(def->hosts[i].ip);
VIR_FREE(def->hosts[i].name);
}
VIR_FREE(def->hosts);
VIR_FREE(def->tftproot);
VIR_FREE(def->bootfile);
- VIR_FREE(def->bootserver);
VIR_FREE(def);
}
virReportOOMError();
return -1;
}
- def->ranges[def->nranges].start = (char *)start;
- def->ranges[def->nranges].end = (char *)end;
- def->ranges[def->nranges].size = range;
+ def->ranges[def->nranges].start = saddr;
+ def->ranges[def->nranges].end = eaddr;
def->nranges++;
} else if (cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "host")) {
}
def->hosts[def->nhosts].mac = (char *)mac;
def->hosts[def->nhosts].name = (char *)name;
- def->hosts[def->nhosts].ip = (char *)ip;
+ def->hosts[def->nhosts].ip = inaddr;
def->nhosts++;
} else if (cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "bootp")) {
xmlChar *file;
+ xmlChar *server;
+ virSocketAddr inaddr;
if (!(file = xmlGetProp(cur, BAD_CAST "file"))) {
cur = cur->next;
continue;
}
+ server = xmlGetProp(cur, BAD_CAST "server");
+
+ if (virSocketParseAddr((const char *)server, &inaddr, AF_UNSPEC) < 0)
+ return -1;
def->bootfile = (char *)file;
- def->bootserver = (char *) xmlGetProp(cur, BAD_CAST "server");
+ def->bootserver = inaddr;
}
cur = cur->next;
{
virNetworkDefPtr def;
char *tmp;
+ char *ipAddress;
+ char *netmask;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
if (virXPathULong("string(./bridge[1]/@delay)", ctxt, &def->delay) < 0)
def->delay = 0;
- def->ipAddress = virXPathString("string(./ip[1]/@address)", ctxt);
- def->netmask = virXPathString("string(./ip[1]/@netmask)", ctxt);
- if (def->ipAddress &&
- def->netmask) {
- virSocketAddr inaddress, innetmask;
- char *netaddr;
+ ipAddress = virXPathString("string(./ip[1]/@address)", ctxt);
+ netmask = virXPathString("string(./ip[1]/@netmask)", ctxt);
+ if (ipAddress &&
+ netmask) {
xmlNodePtr ip;
- if (virSocketParseAddr(def->ipAddress, &inaddress, AF_UNSPEC) < 0)
+ if (virSocketParseAddr(ipAddress, &def->ipAddress, AF_UNSPEC) < 0)
goto error;
- if (virSocketParseAddr(def->netmask, &innetmask, AF_UNSPEC) < 0)
+ if (virSocketParseAddr(netmask, &def->netmask, AF_UNSPEC) < 0)
goto error;
/* XXX someday we want IPv6, so will need to relax this */
- if (inaddress.data.sa.sa_family != AF_INET ||
- innetmask.data.sa.sa_family != AF_INET) {
+ if (!VIR_SOCKET_IS_FAMILY(&def->ipAddress, AF_INET) ||
+ !VIR_SOCKET_IS_FAMILY(&def->netmask, AF_INET)) {
virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("Only IPv4 addresses are supported"));
goto error;
}
- inaddress.data.inet4.sin_addr.s_addr &=
- innetmask.data.inet4.sin_addr.s_addr;
- if (!(netaddr = virSocketFormatAddr(&inaddress)))
- goto error;
-
- if (virAsprintf(&def->network, "%s/%s", netaddr, def->netmask) < 0) {
- VIR_FREE(netaddr);
- virReportOOMError();
- goto error;
- }
- VIR_FREE(netaddr);
+ def->network = def->ipAddress;
+ def->network.data.inet4.sin_addr.s_addr &=
+ def->netmask.data.inet4.sin_addr.s_addr;
if ((ip = virXPathNode("./ip[1]", ctxt)) &&
virNetworkIPParseXML(def, ip) < 0)
goto error;
}
+ VIR_FREE(ipAddress);
+ VIR_FREE(netmask);
/* IPv4 forwarding setup */
if (virXPathBoolean("count(./forward) > 0", ctxt)) {
- if (!def->ipAddress ||
- !def->netmask) {
+ if (def->ipAddress.data.sa.sa_family != AF_INET ||
+ def->netmask.data.sa.sa_family != AF_INET) {
virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Forwarding requested, but no IPv4 address/netmask provided"));
goto error;
if (def->domain)
virBufferVSprintf(&buf, " <domain name='%s'/>\n", def->domain);
- if (def->ipAddress || def->netmask) {
+ if (VIR_SOCKET_HAS_ADDR(&def->ipAddress) ||
+ VIR_SOCKET_HAS_ADDR(&def->netmask)) {
virBufferAddLit(&buf, " <ip");
- if (def->ipAddress)
- virBufferVSprintf(&buf, " address='%s'", def->ipAddress);
+ if (VIR_SOCKET_HAS_ADDR(&def->ipAddress)) {
+ char *addr = virSocketFormatAddr(&def->ipAddress);
+ if (!addr)
+ goto error;
+ virBufferVSprintf(&buf, " address='%s'", addr);
+ VIR_FREE(addr);
+ }
- if (def->netmask)
- virBufferVSprintf(&buf, " netmask='%s'", def->netmask);
+ if (VIR_SOCKET_HAS_ADDR(&def->netmask)) {
+ char *addr = virSocketFormatAddr(&def->netmask);
+ if (!addr)
+ goto error;
+ virBufferVSprintf(&buf, " netmask='%s'", addr);
+ VIR_FREE(addr);
+ }
virBufferAddLit(&buf, ">\n");
if ((def->nranges || def->nhosts)) {
int i;
virBufferAddLit(&buf, " <dhcp>\n");
- for (i = 0 ; i < def->nranges ; i++)
+ for (i = 0 ; i < def->nranges ; i++) {
+ char *saddr = virSocketFormatAddr(&def->ranges[i].start);
+ if (!saddr)
+ goto error;
+ char *eaddr = virSocketFormatAddr(&def->ranges[i].end);
+ if (!eaddr) {
+ VIR_FREE(saddr);
+ goto error;
+ }
virBufferVSprintf(&buf, " <range start='%s' end='%s' />\n",
- def->ranges[i].start, def->ranges[i].end);
+ saddr, eaddr);
+ VIR_FREE(saddr);
+ VIR_FREE(eaddr);
+ }
for (i = 0 ; i < def->nhosts ; i++) {
virBufferAddLit(&buf, " <host ");
if (def->hosts[i].mac)
virBufferVSprintf(&buf, "mac='%s' ", def->hosts[i].mac);
if (def->hosts[i].name)
virBufferVSprintf(&buf, "name='%s' ", def->hosts[i].name);
- if (def->hosts[i].ip)
- virBufferVSprintf(&buf, "ip='%s' ", def->hosts[i].ip);
+ if (VIR_SOCKET_HAS_ADDR(&def->hosts[i].ip)) {
+ char *ipaddr = virSocketFormatAddr(&def->hosts[i].ip);
+ if (!ipaddr)
+ goto error;
+ virBufferVSprintf(&buf, "ip='%s' ", ipaddr);
+ VIR_FREE(ipaddr);
+ }
virBufferAddLit(&buf, "/>\n");
}
if (def->bootfile) {
virBufferEscapeString(&buf, " <bootp file='%s' ",
def->bootfile);
- if (def->bootserver) {
- virBufferEscapeString(&buf, "server='%s' ",
- def->bootserver);
+ if (VIR_SOCKET_HAS_ADDR(&def->bootserver)) {
+ char *ipaddr = virSocketFormatAddr(&def->bootserver);
+ if (!ipaddr)
+ goto error;
+ virBufferEscapeString(&buf, "server='%s' ", ipaddr);
+ VIR_FREE(ipaddr);
}
virBufferAddLit(&buf, "/>\n");
}
no_memory:
virReportOOMError();
+ error:
virBufferFreeAndReset(&buf);
return NULL;
}
# include "internal.h"
# include "threads.h"
+# include "network.h"
/* 2 possible types of forwarding */
enum virNetworkForwardType {
typedef struct _virNetworkDHCPRangeDef virNetworkDHCPRangeDef;
typedef virNetworkDHCPRangeDef *virNetworkDHCPRangeDefPtr;
struct _virNetworkDHCPRangeDef {
- char *start;
- char *end;
- int size;
+ virSocketAddr start;
+ virSocketAddr end;
};
typedef struct _virNetworkDHCPHostDef virNetworkDHCPHostDef;
struct _virNetworkDHCPHostDef {
char *mac;
char *name;
- char *ip;
+ virSocketAddr ip;
};
typedef struct _virNetworkDef virNetworkDef;
int forwardType; /* One of virNetworkForwardType constants */
char *forwardDev; /* Destination device for forwarding */
- char *ipAddress; /* Bridge IP address */
- char *netmask;
- char *network;
+ virSocketAddr ipAddress; /* Bridge IP address */
+ virSocketAddr netmask;
+ virSocketAddr network;
unsigned int nranges; /* Zero or more dhcp ranges */
virNetworkDHCPRangeDefPtr ranges;
char *tftproot;
char *bootfile;
- char *bootserver;
+ virSocketAddr bootserver;
};
typedef struct _virNetworkObj virNetworkObj;
obj->active = 1;
/* Finally try and read dnsmasq pid if any */
- if ((obj->def->ipAddress ||
+ if ((VIR_SOCKET_HAS_ADDR(&obj->def->ipAddress) ||
obj->def->nranges) &&
virFileReadPid(NETWORK_PID_DIR, obj->def->name,
&obj->dnsmasqPid) == 0) {
for (i = 0 ; i < network->def->nhosts ; i++) {
virNetworkDHCPHostDefPtr host = &(network->def->hosts[i]);
- if ((host->mac) && (host->ip))
- dnsmasqAddDhcpHost(dctx, host->mac, host->ip, host->name);
+ if ((host->mac) && VIR_SOCKET_HAS_ADDR(&host->ip))
+ dnsmasqAddDhcpHost(dctx, host->mac, &host->ip, host->name);
}
if (dnsmasqSave(dctx) < 0)
char *pidfileArg;
char buf[1024];
unsigned int ranges;
+ char *ipAddr;
/*
* For static-only DHCP, i.e. with no range but at least one host element,
* APPEND_ARG(*argv, i++, network->def->bridge);
*/
APPEND_ARG(*argv, i++, "--listen-address");
- APPEND_ARG(*argv, i++, network->def->ipAddress);
+ if (!(ipAddr = virSocketFormatAddr(&network->def->ipAddress)))
+ goto error;
+ APPEND_ARG_LIT(*argv, i++, ipAddr);
APPEND_ARG(*argv, i++, "--except-interface");
APPEND_ARG(*argv, i++, "lo");
for (r = 0 ; r < network->def->nranges ; r++) {
- snprintf(buf, sizeof(buf), "%s,%s",
- network->def->ranges[r].start,
- network->def->ranges[r].end);
-
+ char *saddr = virSocketFormatAddr(&network->def->ranges[r].start);
+ if (!saddr)
+ goto error;
+ char *eaddr = virSocketFormatAddr(&network->def->ranges[r].end);
+ if (!eaddr) {
+ VIR_FREE(saddr);
+ goto error;
+ }
+ char *range;
+ int rc = virAsprintf(&range, "%s,%s", saddr, eaddr);
+ VIR_FREE(saddr);
+ VIR_FREE(eaddr);
+ if (rc < 0)
+ goto no_memory;
APPEND_ARG(*argv, i++, "--dhcp-range");
- APPEND_ARG(*argv, i++, buf);
- nbleases += network->def->ranges[r].size;
+ APPEND_ARG_LIT(*argv, i++, range);
+ nbleases += virSocketGetRange(&network->def->ranges[r].start,
+ &network->def->ranges[r].end);
}
if (!network->def->nranges && network->def->nhosts) {
- snprintf(buf, sizeof(buf), "%s,static",
- network->def->ipAddress);
+ char *ipaddr = virSocketFormatAddr(&network->def->ipAddress);
+ if (!ipaddr)
+ goto error;
+ char *range;
+ int rc = virAsprintf(&range, "%s,static", ipaddr);
+ VIR_FREE(ipaddr);
+ if (rc < 0)
+ goto no_memory;
APPEND_ARG(*argv, i++, "--dhcp-range");
- APPEND_ARG(*argv, i++, buf);
+ APPEND_ARG_LIT(*argv, i++, range);
}
if (network->def->nranges > 0) {
APPEND_ARG(*argv, i++, network->def->tftproot);
}
if (network->def->bootfile) {
- snprintf(buf, sizeof(buf), "%s%s%s",
- network->def->bootfile,
- network->def->bootserver ? ",," : "",
- network->def->bootserver ? network->def->bootserver : "");
+ char *ipaddr = NULL;
+ if (VIR_SOCKET_HAS_ADDR(&network->def->bootserver)) {
+ if (!(ipaddr = virSocketFormatAddr(&network->def->bootserver)))
+ goto error;
+ }
+ char *boot;
+ int rc = virAsprintf(&boot, "%s%s%s",
+ network->def->bootfile,
+ ipaddr ? ",," : "",
+ ipaddr ? ipaddr : "");
+ VIR_FREE(ipaddr);
+ if (rc < 0)
+ goto no_memory;
APPEND_ARG(*argv, i++, "--dhcp-boot");
- APPEND_ARG(*argv, i++, buf);
+ APPEND_ARG_LIT(*argv, i++, boot);
}
#undef APPEND_ARG
return 0;
no_memory:
+ virReportOOMError();
+ error:
if (*argv) {
for (i = 0; (*argv)[i]; i++)
VIR_FREE((*argv)[i]);
VIR_FREE(*argv);
}
- virReportOOMError();
return -1;
}
network->dnsmasqPid = -1;
- if (network->def->ipAddress == NULL) {
+ if (!VIR_SOCKET_IS_FAMILY(&network->def->ipAddress, AF_INET)) {
networkReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("cannot start dhcp daemon without IP address for server"));
+ "%s", _("cannot start dhcp daemon without IPv4 address for server"));
return -1;
}
int err;
/* allow forwarding packets from the bridge interface */
if ((err = iptablesAddForwardAllowOut(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->bridge,
network->def->forwardDev))) {
virReportSystemError(err,
/* allow forwarding packets to the bridge interface if they are part of an existing connection */
if ((err = iptablesAddForwardAllowRelatedIn(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->bridge,
network->def->forwardDev))) {
virReportSystemError(err,
/* First the generic masquerade rule for other protocols */
if ((err = iptablesAddForwardMasquerade(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->forwardDev,
NULL))) {
virReportSystemError(err,
/* UDP with a source port restriction */
if ((err = iptablesAddForwardMasquerade(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->forwardDev,
"udp"))) {
virReportSystemError(err,
/* TCP with a source port restriction */
if ((err = iptablesAddForwardMasquerade(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->forwardDev,
"tcp"))) {
virReportSystemError(err,
masqerr5:
iptablesRemoveForwardMasquerade(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->forwardDev,
"udp");
masqerr4:
iptablesRemoveForwardMasquerade(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->forwardDev,
NULL);
masqerr3:
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->bridge,
network->def->forwardDev);
masqerr2:
iptablesRemoveForwardAllowOut(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->bridge,
network->def->forwardDev);
masqerr1:
int err;
/* allow routing packets from the bridge interface */
if ((err = iptablesAddForwardAllowOut(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->bridge,
network->def->forwardDev))) {
virReportSystemError(err,
/* allow routing packets to the bridge interface */
if ((err = iptablesAddForwardAllowIn(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->bridge,
network->def->forwardDev))) {
virReportSystemError(err,
routeerr2:
iptablesRemoveForwardAllowOut(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->bridge,
network->def->forwardDev);
routeerr1:
* aborting, since not all iptables implementations support it).
*/
- if ((network->def->ipAddress || network->def->nranges) &&
+ if ((VIR_SOCKET_HAS_ADDR(&network->def->ipAddress) ||
+ network->def->nranges) &&
(iptablesAddOutputFixUdpChecksum(driver->iptables,
network->def->bridge, 68) != 0)) {
VIR_WARN("Could not add rule to fixup DHCP response checksums "
static void
networkRemoveIptablesRules(struct network_driver *driver,
virNetworkObjPtr network) {
- if (network->def->ipAddress || network->def->nranges) {
+ if (VIR_SOCKET_HAS_ADDR(&network->def->ipAddress) ||
+ network->def->nranges) {
iptablesRemoveOutputFixUdpChecksum(driver->iptables,
network->def->bridge, 68);
}
if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE) {
if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) {
iptablesRemoveForwardMasquerade(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->forwardDev,
"tcp");
iptablesRemoveForwardMasquerade(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->forwardDev,
"udp");
iptablesRemoveForwardMasquerade(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->forwardDev,
NULL);
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->bridge,
network->def->forwardDev);
} else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE)
iptablesRemoveForwardAllowIn(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->bridge,
network->def->forwardDev);
iptablesRemoveForwardAllowOut(driver->iptables,
- network->def->network,
+ &network->def->network,
network->def->bridge,
network->def->forwardDev);
}
unsigned int net_dest;
char *cur, *buf = NULL;
enum {MAX_ROUTE_SIZE = 1024*64};
- virSocketAddr inaddress, innetmask;
-
- if (!network->def->ipAddress || !network->def->netmask)
- return 0;
-
- if (virSocketParseAddr(network->def->ipAddress, &inaddress, AF_UNSPEC) < 0)
- goto error;
- if (virSocketParseAddr(network->def->netmask, &innetmask, AF_UNSPEC) < 0)
- goto error;
-
- if (inaddress.data.stor.ss_family != AF_INET ||
- innetmask.data.stor.ss_family != AF_INET) {
+ if (!VIR_SOCKET_IS_FAMILY(&network->def->ipAddress, AF_INET) ||
+ !VIR_SOCKET_IS_FAMILY(&network->def->netmask, AF_INET)) {
/* Only support collision check for IPv4 */
- goto out;
+ return 0;
}
- net_dest = (inaddress.data.inet4.sin_addr.s_addr &
- innetmask.data.inet4.sin_addr.s_addr);
+ net_dest = (network->def->ipAddress.data.inet4.sin_addr.s_addr &
+ network->def->netmask.data.inet4.sin_addr.s_addr);
/* Read whole routing table into memory */
if ((len = virFileReadAll(PROC_NET_ROUTE, MAX_ROUTE_SIZE, &buf)) < 0)
addr_val &= mask_val;
if ((net_dest == addr_val) &&
- (innetmask.data.inet4.sin_addr.s_addr == mask_val)) {
+ (network->def->netmask.data.inet4.sin_addr.s_addr == mask_val)) {
networkReportError(VIR_ERR_INTERNAL_ERROR,
- _("Network %s/%s is already in use by "
- "interface %s"),
- network->def->ipAddress,
- network->def->netmask, iface);
+ _("Network is already in use by interface %s"),
+ iface);
goto error;
}
}
if (brSetEnableSTP(driver->brctl, network->def->bridge, network->def->stp ? 1 : 0) < 0)
goto err_delbr;
- if (network->def->ipAddress &&
- (err = brSetInetAddress(driver->brctl, network->def->bridge, network->def->ipAddress))) {
+ if (VIR_SOCKET_HAS_ADDR(&network->def->ipAddress) &&
+ (err = brSetInetAddress(driver->brctl, network->def->bridge,
+ &network->def->ipAddress))) {
virReportSystemError(err,
- _("cannot set IP address on bridge '%s' to '%s'"),
- network->def->bridge, network->def->ipAddress);
+ _("cannot set IP address on bridge '%s'"),
+ network->def->bridge);
goto err_delbr;
}
- if (network->def->netmask &&
- (err = brSetInetNetmask(driver->brctl, network->def->bridge, network->def->netmask))) {
+ if (VIR_SOCKET_HAS_ADDR(&network->def->netmask) &&
+ (err = brSetInetNetmask(driver->brctl, network->def->bridge,
+ &network->def->netmask))) {
virReportSystemError(err,
- _("cannot set netmask on bridge '%s' to '%s'"),
- network->def->bridge, network->def->netmask);
+ _("cannot set netmask on bridge '%s'"),
+ network->def->bridge);
goto err_delbr;
}
goto err_delbr2;
}
- if ((network->def->ipAddress ||
+ if ((VIR_SOCKET_HAS_ADDR(&network->def->ipAddress) ||
network->def->nranges) &&
dhcpStartDhcpDaemon(network) < 0)
goto err_delbr2;
brSetInetAddr(brControl *ctl,
const char *ifname,
int cmd,
- const char *addr)
+ virSocketAddr *addr)
{
- virSocketAddr sa;
struct ifreq ifr;
if (!ctl || !ctl->fd || !ifname || !addr)
if (virStrcpyStatic(ifr.ifr_name, ifname) == NULL)
return EINVAL;
- if (virSocketParseAddr(addr, &sa, AF_UNSPEC) < 0)
+ if (!VIR_SOCKET_IS_FAMILY(addr, AF_INET))
return EINVAL;
- if (sa.data.sa.sa_family != AF_INET)
- return EINVAL;
-
- ifr.ifr_addr = sa.data.sa;
+ ifr.ifr_addr = addr->data.sa;
if (ioctl(ctl->fd, cmd, &ifr) < 0)
return errno;
int
brSetInetAddress(brControl *ctl,
const char *ifname,
- const char *addr)
+ virSocketAddr *addr)
{
return brSetInetAddr(ctl, ifname, SIOCSIFADDR, addr);
}
int
brSetInetNetmask(brControl *ctl,
const char *ifname,
- const char *addr)
+ virSocketAddr *addr)
{
return brSetInetAddr(ctl, ifname, SIOCSIFNETMASK, addr);
}
# include <net/if.h>
# include <netinet/in.h>
+# include "network.h"
/**
* BR_IFNAME_MAXLEN:
int brSetInetAddress (brControl *ctl,
const char *ifname,
- const char *addr);
+ virSocketAddr *addr);
int brSetInetNetmask (brControl *ctl,
const char *ifname,
- const char *netmask);
+ virSocketAddr *addr);
int brSetForwardDelay (brControl *ctl,
const char *bridge,
static int
hostsfileAdd(dnsmasqHostsfile *hostsfile,
const char *mac,
- const char *ip,
+ virSocketAddr *ip,
const char *name)
{
+ char *ipstr;
if (VIR_REALLOC_N(hostsfile->hosts, hostsfile->nhosts + 1) < 0)
goto alloc_error;
+ if (!(ipstr = virSocketFormatAddr(ip)))
+ return -1;
+
if (name) {
if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,%s,%s",
- mac, ip, name) < 0) {
+ mac, ipstr, name) < 0) {
goto alloc_error;
}
} else {
if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,%s",
- mac, ip) < 0) {
+ mac, ipstr) < 0) {
goto alloc_error;
}
}
+ VIR_FREE(ipstr);
hostsfile->nhosts++;
alloc_error:
virReportOOMError();
-
+ VIR_FREE(ipstr);
return -1;
}
* dnsmasqAddDhcpHost:
* @ctx: pointer to the dnsmasq context for each network
* @mac: pointer to the string contains mac address of the host
- * @ip: pointer to the string contains ip address of the host
+ * @ip: pointer to the socket address contains ip of the host
* @name: pointer to the string contains hostname of the host or NULL
*
* Add dhcp-host entry.
void
dnsmasqAddDhcpHost(dnsmasqContext *ctx,
const char *mac,
- const char *ip,
+ virSocketAddr *ip,
const char *name)
{
if (ctx->hostsfile)
#ifndef __DNSMASQ_H__
# define __DNSMASQ_H__
+# include "network.h"
+
typedef struct
{
/*
void dnsmasqContextFree(dnsmasqContext *ctx);
void dnsmasqAddDhcpHost(dnsmasqContext *ctx,
const char *mac,
- const char *ip,
+ virSocketAddr *ip,
const char *name);
int dnsmasqSave(const dnsmasqContext *ctx);
int dnsmasqDelete(const dnsmasqContext *ctx);
#include "virterror_internal.h"
#include "logging.h"
+#define iptablesError(code, ...) \
+ virReportErrorHelper(NULL, VIR_FROM_NONE, code, __FILE__, \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
+
enum {
ADD = 0,
REMOVE
*/
static int
iptablesForwardAllowOut(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev,
int action)
{
+ int ret;
+ char *networkstr;
+
+ if (!VIR_SOCKET_IS_FAMILY(network, AF_INET)) {
+ iptablesError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Only IPv4 addresses can be used with iptables"));
+ return -1;
+ }
+
+ if (!(networkstr = virSocketFormatAddr(network)))
+ return -1;
+
if (physdev && physdev[0]) {
- return iptablesAddRemoveRule(ctx->forward_filter,
- action,
- "--source", network,
- "--in-interface", iface,
- "--out-interface", physdev,
- "--jump", "ACCEPT",
- NULL);
+ ret = iptablesAddRemoveRule(ctx->forward_filter,
+ action,
+ "--source", networkstr,
+ "--in-interface", iface,
+ "--out-interface", physdev,
+ "--jump", "ACCEPT",
+ NULL);
} else {
- return iptablesAddRemoveRule(ctx->forward_filter,
- action,
- "--source", network,
- "--in-interface", iface,
- "--jump", "ACCEPT",
- NULL);
+ ret = iptablesAddRemoveRule(ctx->forward_filter,
+ action,
+ "--source", networkstr,
+ "--in-interface", iface,
+ "--jump", "ACCEPT",
+ NULL);
}
+ VIR_FREE(networkstr);
+ return ret;
}
/**
*/
int
iptablesAddForwardAllowOut(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev)
{
*/
int
iptablesRemoveForwardAllowOut(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev)
{
*/
static int
iptablesForwardAllowRelatedIn(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev,
int action)
{
+ int ret;
+ char *networkstr;
+
+ if (!VIR_SOCKET_IS_FAMILY(network, AF_INET)) {
+ iptablesError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Only IPv4 addresses can be used with iptables"));
+ return -1;
+ }
+
+ if (!(networkstr = virSocketFormatAddr(network)))
+ return -1;
+
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);
+ ret = iptablesAddRemoveRule(ctx->forward_filter,
+ action,
+ "--destination", networkstr,
+ "--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);
+ ret = iptablesAddRemoveRule(ctx->forward_filter,
+ action,
+ "--destination", networkstr,
+ "--out-interface", iface,
+ "--match", "state",
+ "--state", "ESTABLISHED,RELATED",
+ "--jump", "ACCEPT",
+ NULL);
}
+ VIR_FREE(networkstr);
+ return ret;
}
/**
*/
int
iptablesAddForwardAllowRelatedIn(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev)
{
*/
int
iptablesRemoveForwardAllowRelatedIn(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev)
{
*/
static int
iptablesForwardAllowIn(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev,
int action)
{
+ int ret;
+ char *networkstr;
+
+ if (!VIR_SOCKET_IS_FAMILY(network, AF_INET)) {
+ iptablesError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Only IPv4 addresses can be used with iptables"));
+ return -1;
+ }
+
+ if (!(networkstr = virSocketFormatAddr(network)))
+ return -1;
+
if (physdev && physdev[0]) {
- return iptablesAddRemoveRule(ctx->forward_filter,
- action,
- "--destination", network,
- "--in-interface", physdev,
- "--out-interface", iface,
- "--jump", "ACCEPT",
- NULL);
+ ret = iptablesAddRemoveRule(ctx->forward_filter,
+ action,
+ "--destination", networkstr,
+ "--in-interface", physdev,
+ "--out-interface", iface,
+ "--jump", "ACCEPT",
+ NULL);
} else {
- return iptablesAddRemoveRule(ctx->forward_filter,
- action,
- "--destination", network,
- "--out-interface", iface,
- "--jump", "ACCEPT",
- NULL);
+ ret = iptablesAddRemoveRule(ctx->forward_filter,
+ action,
+ "--destination", networkstr,
+ "--out-interface", iface,
+ "--jump", "ACCEPT",
+ NULL);
}
+ VIR_FREE(networkstr);
+ return ret;
}
/**
*/
int
iptablesAddForwardAllowIn(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev)
{
*/
int
iptablesRemoveForwardAllowIn(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev)
{
*/
static int
iptablesForwardMasquerade(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *physdev,
const char *protocol,
int action)
{
+ int ret;
+ char *networkstr;
+
+ if (!VIR_SOCKET_IS_FAMILY(network, AF_INET)) {
+ iptablesError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Only IPv4 addresses can be used with iptables"));
+ return -1;
+ }
+
+ if (!(networkstr = virSocketFormatAddr(network)))
+ return -1;
+
if (protocol && protocol[0]) {
if (physdev && physdev[0]) {
- return iptablesAddRemoveRule(ctx->nat_postrouting,
- action,
- "--source", network,
- "-p", protocol,
- "!", "--destination", network,
- "--out-interface", physdev,
- "--jump", "MASQUERADE",
- "--to-ports", "1024-65535",
- NULL);
+ ret = iptablesAddRemoveRule(ctx->nat_postrouting,
+ action,
+ "--source", networkstr,
+ "-p", protocol,
+ "!", "--destination", networkstr,
+ "--out-interface", physdev,
+ "--jump", "MASQUERADE",
+ "--to-ports", "1024-65535",
+ NULL);
} else {
- return iptablesAddRemoveRule(ctx->nat_postrouting,
- action,
- "--source", network,
- "-p", protocol,
- "!", "--destination", network,
- "--jump", "MASQUERADE",
- "--to-ports", "1024-65535",
- NULL);
+ ret = iptablesAddRemoveRule(ctx->nat_postrouting,
+ action,
+ "--source", networkstr,
+ "-p", protocol,
+ "!", "--destination", networkstr,
+ "--jump", "MASQUERADE",
+ "--to-ports", "1024-65535",
+ NULL);
}
} else {
if (physdev && physdev[0]) {
- return iptablesAddRemoveRule(ctx->nat_postrouting,
- action,
- "--source", network,
- "!", "--destination", network,
- "--out-interface", physdev,
- "--jump", "MASQUERADE",
- NULL);
+ ret = iptablesAddRemoveRule(ctx->nat_postrouting,
+ action,
+ "--source", networkstr,
+ "!", "--destination", networkstr,
+ "--out-interface", physdev,
+ "--jump", "MASQUERADE",
+ NULL);
} else {
- return iptablesAddRemoveRule(ctx->nat_postrouting,
- action,
- "--source", network,
- "!", "--destination", network,
- "--jump", "MASQUERADE",
- NULL);
+ ret = iptablesAddRemoveRule(ctx->nat_postrouting,
+ action,
+ "--source", networkstr,
+ "!", "--destination", networkstr,
+ "--jump", "MASQUERADE",
+ NULL);
}
}
+ VIR_FREE(networkstr);
+ return ret;
}
/**
*/
int
iptablesAddForwardMasquerade(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *physdev,
const char *protocol)
{
*/
int
iptablesRemoveForwardMasquerade(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *physdev,
const char *protocol)
{
#ifndef __QEMUD_IPTABLES_H__
# define __QEMUD_IPTABLES_H__
+# include "network.h"
+
typedef struct _iptablesContext iptablesContext;
iptablesContext *iptablesContextNew (void);
int port);
int iptablesAddForwardAllowOut (iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev);
int iptablesRemoveForwardAllowOut (iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev);
int iptablesAddForwardAllowRelatedIn(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev);
int iptablesRemoveForwardAllowRelatedIn(iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev);
int iptablesAddForwardAllowIn (iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev);
int iptablesRemoveForwardAllowIn (iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *iface,
const char *physdev);
const char *iface);
int iptablesAddForwardMasquerade (iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *physdev,
const char *protocol);
int iptablesRemoveForwardMasquerade (iptablesContext *ctx,
- const char *network,
+ virSocketAddr *network,
const char *physdev,
const char *protocol);
int iptablesAddOutputFixUdpChecksum (iptablesContext *ctx,
socklen_t len;
} virSocketAddr;
+# define VIR_SOCKET_HAS_ADDR(s) \
+ ((s)->data.sa.sa_family != AF_UNSPEC)
+
+# define VIR_SOCKET_IS_FAMILY(s, f) \
+ ((s)->data.sa.sa_family == f)
+
typedef virSocketAddr *virSocketAddrPtr;
int virSocketParseAddr (const char *val,