[Libvir] [patch 4/5] iptables: maintain rules in memory even when not writing to disk
by Mark McLoughlin
Re-factor things a little for the next patch so that we maintain
the rules in memory even when we're not going to write them to
disk.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/iptables.c
===================================================================
--- libvirt.orig/qemud/iptables.c
+++ libvirt/qemud/iptables.c
@@ -51,14 +51,14 @@ typedef struct
char *table;
char *chain;
+ int nrules;
+ char **rules;
+
#ifdef IPTABLES_DIR
char dir[PATH_MAX];
char path[PATH_MAX];
- int nrules;
- char **rules;
-
#endif /* IPTABLES_DIR */
} iptRules;
@@ -171,13 +171,13 @@ buildPath(const char *table,
else
return 0;
}
+#endif /* IPTABLES_DIR */
static int
iptRulesAppend(iptRules *rules,
const char *rule)
{
char **r;
- int err;
if (!(r = (char **)realloc(rules->rules, sizeof(char *) * (rules->nrules+1))))
return ENOMEM;
@@ -189,24 +189,29 @@ iptRulesAppend(iptRules *rules,
rules->nrules++;
- if ((err = ensureDir(rules->dir)))
- return err;
+#ifdef IPTABLES_DIR
+ {
+ int err;
- if ((err = writeRules(rules->path, rules->rules, rules->nrules)))
- return 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,
- const char *rule)
+ char *rule)
{
int i;
- int err;
for (i = 0; i < rules->nrules; i++)
- if (!strcmp(rules->rules[i], rule))
+ if (!strcmp(rules->rules[i], strdup(rule)))
break;
if (i >= rules->nrules)
@@ -220,16 +225,23 @@ iptRulesRemove(iptRules *rules,
rules->nrules--;
- if ((err = writeRules(rules->path, rules->rules, rules->nrules)))
- return err;
+#ifdef IPTABLES_DIR
+ {
+ int err;
+
+ if ((err = writeRules(rules->path, rules->rules, rules->nrules)))
+ return err;
+ }
+#endif /* IPTABLES_DIR */
return 0;
}
-#endif /* IPTABLES_DIR */
static void
iptRulesFree(iptRules *rules)
{
+ int i;
+
if (rules->table) {
free(rules->table);
rules->table = NULL;
@@ -240,25 +252,22 @@ iptRulesFree(iptRules *rules)
rules->chain = NULL;
}
-#ifdef IPTABLES_DIR
- {
- int i;
- rules->dir[0] = '\0';
- rules->path[0] = '\0';
-
- for (i = 0; i < rules->nrules; i++) {
- free(rules->rules[i]);
- rules->rules[i] = NULL;
- }
+ for (i = 0; i < rules->nrules; i++) {
+ free(rules->rules[i]);
+ rules->rules[i] = NULL;
+ }
- rules->nrules = 0;
+ rules->nrules = 0;
- if (rules->rules) {
- free(rules->rules);
- rules->rules = NULL;
- }
+ if (rules->rules) {
+ free(rules->rules);
+ rules->rules = NULL;
}
+
+#ifdef IPTABLES_DIR
+ rules->dir[0] = '\0';
+ rules->path[0] = '\0';
#endif /* IPTABLES_DIR */
free(rules);
@@ -279,15 +288,15 @@ iptRulesNew(const char *table,
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;
-
- rules->rules = NULL;
- rules->nrules = 0;
#endif /* IPTABLES_DIR */
return rules;
@@ -464,12 +473,10 @@ iptablesAddRemoveRule(iptRules *rules, i
(retval = iptablesAddRemoveChain(rules, action)))
goto error;
-#ifdef IPTABLES_DIR
if (action == ADD)
retval = iptRulesAppend(rules, rule);
else
retval = iptRulesRemove(rules, rule);
-#endif /* IPTABLES_DIR */
error:
if (rule)
--
17 years, 9 months
[Libvir] [patch 3/5] iptables: fix iptablesPhysdevForward()
by Mark McLoughlin
Remove the target interface parameter from iptablesPhysdevForward().
This rule is intended to allow frames to be forwarded across the
bridge from the supplied bridge port. In this context, the --out
parameter would match the outgoing bridge port, which will never
be network->def->forwardDev.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/iptables.c
===================================================================
--- libvirt.orig/qemud/iptables.c
+++ libvirt/qemud/iptables.c
@@ -577,41 +577,28 @@ iptablesRemoveUdpInput(iptablesContext *
static int
iptablesPhysdevForward(iptablesContext *ctx,
const char *iface,
- const char *target,
int action)
{
- if (target && target[0]) {
- return iptablesAddRemoveRule(ctx->forward_filter,
- action,
- "--match", "physdev",
- "--physdev-in", iface,
- "--out", target,
- "--jump", "ACCEPT",
- NULL);
- } else {
- return iptablesAddRemoveRule(ctx->forward_filter,
- action,
- "--match", "physdev",
- "--physdev-in", iface,
- "--jump", "ACCEPT",
- NULL);
- }
+ return iptablesAddRemoveRule(ctx->forward_filter,
+ action,
+ "--match", "physdev",
+ "--physdev-in", iface,
+ "--jump", "ACCEPT",
+ NULL);
}
int
iptablesAddPhysdevForward(iptablesContext *ctx,
- const char *iface,
- const char *target)
+ const char *iface)
{
- return iptablesPhysdevForward(ctx, iface, target, ADD);
+ return iptablesPhysdevForward(ctx, iface, ADD);
}
int
iptablesRemovePhysdevForward(iptablesContext *ctx,
- const char *iface,
- const char *target)
+ const char *iface)
{
- return iptablesPhysdevForward(ctx, iface, target, REMOVE);
+ return iptablesPhysdevForward(ctx, iface, REMOVE);
}
static int
Index: libvirt/qemud/iptables.h
===================================================================
--- libvirt.orig/qemud/iptables.h
+++ libvirt/qemud/iptables.h
@@ -42,11 +42,9 @@ int iptablesRemoveUdpInput
int port);
int iptablesAddPhysdevForward (iptablesContext *ctx,
- const char *iface,
- const char *target);
+ const char *iface);
int iptablesRemovePhysdevForward (iptablesContext *ctx,
- const char *iface,
- const char *target);
+ const char *iface);
int iptablesAddInterfaceForward (iptablesContext *ctx,
const char *iface,
Index: libvirt/qemud/conf.c
===================================================================
--- libvirt.orig/qemud/conf.c
+++ libvirt/qemud/conf.c
@@ -1128,7 +1128,7 @@ qemudNetworkIfaceConnect(struct qemud_se
}
if (net->type == QEMUD_NET_NETWORK && network->def->forward) {
- if ((err = iptablesAddPhysdevForward(server->iptables, ifname, network->def->forwardDev))) {
+ if ((err = iptablesAddPhysdevForward(server->iptables, ifname))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"Failed to add iptables rule to allow bridging from '%s' :%s",
ifname, strerror(err));
@@ -1152,7 +1152,7 @@ qemudNetworkIfaceConnect(struct qemud_se
no_memory:
if (net->type == QEMUD_NET_NETWORK && network->def->forward)
- iptablesRemovePhysdevForward(server->iptables, ifname, network->def->forwardDev);
+ iptablesRemovePhysdevForward(server->iptables, ifname);
qemudReportError(server, VIR_ERR_NO_MEMORY, "tapfds");
error:
if (retval)
Index: libvirt/qemud/qemud.c
===================================================================
--- libvirt.orig/qemud/qemud.c
+++ libvirt/qemud/qemud.c
@@ -1042,8 +1042,7 @@ qemudNetworkIfaceDisconnect(struct qemud
return;
}
- if (network->def->forward)
- iptablesRemovePhysdevForward(server->iptables, net->dst.network.ifname, network->def->forwardDev);
+ iptablesRemovePhysdevForward(server->iptables, net->dst.network.ifname);
}
int qemudShutdownVMDaemon(struct qemud_server *server, struct qemud_vm *vm) {
@@ -1242,83 +1241,87 @@ qemudAddIptablesRules(struct qemud_serve
}
/* allow bridging from the bridge interface itself */
- if ((err = iptablesAddPhysdevForward(server->iptables, network->bridge, network->def->forwardDev))) {
+ if ((err = iptablesAddPhysdevForward(server->iptables, network->bridge))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to add iptables rule to allow bridging from '%s' : %s\n",
network->bridge, strerror(err));
goto err1;
}
- /* allow forwarding packets from the bridge interface */
- if ((err = iptablesAddInterfaceForward(server->iptables, network->bridge, network->def->forwardDev))) {
+ /* allow DHCP requests through to dnsmasq */
+ if ((err = iptablesAddTcpInput(server->iptables, network->bridge, 67))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
- "failed to add iptables rule to allow forwarding from '%s' : %s\n",
+ "failed to add iptables rule to allow DHCP requests from '%s' : %s\n",
network->bridge, strerror(err));
goto err2;
}
- /* allow forwarding packets to the bridge interface if they are part of an existing connection */
- if ((err = iptablesAddStateForward(server->iptables, network->bridge, network->def->forwardDev))) {
+ if ((err = iptablesAddUdpInput(server->iptables, network->bridge, 67))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
- "failed to add iptables rule to allow forwarding to '%s' : %s\n",
+ "failed to add iptables rule to allow DHCP requests from '%s' : %s\n",
network->bridge, strerror(err));
goto err3;
}
- /* enable masquerading */
- if ((err = iptablesAddNonBridgedMasq(server->iptables, network->def->forwardDev))) {
+ /* allow DNS requests through to dnsmasq */
+ if ((err = iptablesAddTcpInput(server->iptables, network->bridge, 53))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
- "failed to add iptables rule to enable masquerading : %s\n",
- strerror(err));
+ "failed to add iptables rule to allow DNS requests from '%s' : %s\n",
+ network->bridge, strerror(err));
goto err4;
}
- /* allow DHCP requests through to dnsmasq */
- if ((err = iptablesAddTcpInput(server->iptables, network->bridge, 67))) {
+ if ((err = iptablesAddUdpInput(server->iptables, network->bridge, 53))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
- "failed to add iptables rule to allow DHCP requests from '%s' : %s\n",
+ "failed to add iptables rule to allow DNS requests from '%s' : %s\n",
network->bridge, strerror(err));
goto err5;
}
- if ((err = iptablesAddUdpInput(server->iptables, network->bridge, 67))) {
+ /* The remaining rules are only needed for IP forwarding */
+ if (!network->def->forward)
+ return 1;
+
+ /* allow forwarding packets from the bridge interface */
+ if ((err = iptablesAddInterfaceForward(server->iptables, network->bridge, network->def->forwardDev))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
- "failed to add iptables rule to allow DHCP requests from '%s' : %s\n",
+ "failed to add iptables rule to allow forwarding from '%s' : %s\n",
network->bridge, strerror(err));
goto err6;
}
- /* allow DNS requests through to dnsmasq */
- if ((err = iptablesAddTcpInput(server->iptables, network->bridge, 53))) {
+ /* allow forwarding packets to the bridge interface if they are part of an existing connection */
+ if ((err = iptablesAddStateForward(server->iptables, network->bridge, network->def->forwardDev))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
- "failed to add iptables rule to allow DNS requests from '%s' : %s\n",
+ "failed to add iptables rule to allow forwarding to '%s' : %s\n",
network->bridge, strerror(err));
goto err7;
}
- if ((err = iptablesAddUdpInput(server->iptables, network->bridge, 53))) {
+ /* enable masquerading */
+ if ((err = iptablesAddNonBridgedMasq(server->iptables, network->def->forwardDev))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
- "failed to add iptables rule to allow DNS requests from '%s' : %s\n",
- network->bridge, strerror(err));
+ "failed to add iptables rule to enable masquerading : %s\n",
+ strerror(err));
goto err8;
}
return 1;
err8:
- iptablesRemoveTcpInput(server->iptables, network->bridge, 53);
+ iptablesRemoveStateForward(server->iptables, network->bridge, network->def->forwardDev);
err7:
- iptablesRemoveUdpInput(server->iptables, network->bridge, 67);
+ iptablesRemoveInterfaceForward(server->iptables, network->bridge, network->def->forwardDev);
err6:
- iptablesRemoveTcpInput(server->iptables, network->bridge, 67);
+ iptablesRemoveUdpInput(server->iptables, network->bridge, 53);
err5:
- iptablesRemoveNonBridgedMasq(server->iptables, network->def->forwardDev);
+ iptablesRemoveTcpInput(server->iptables, network->bridge, 53);
err4:
- iptablesRemoveStateForward(server->iptables, network->bridge, network->def->forwardDev);
+ iptablesRemoveUdpInput(server->iptables, network->bridge, 67);
err3:
- iptablesRemoveInterfaceForward(server->iptables, network->bridge, network->def->forwardDev);
+ iptablesRemoveTcpInput(server->iptables, network->bridge, 67);
err2:
- iptablesRemovePhysdevForward(server->iptables, network->bridge, network->def->forwardDev);
+ iptablesRemovePhysdevForward(server->iptables, network->bridge);
err1:
return 0;
}
@@ -1327,15 +1330,15 @@ static void
qemudRemoveIptablesRules(struct qemud_server *server,
struct qemud_network *network) {
if (network->def->forward) {
- iptablesRemoveUdpInput(server->iptables, network->bridge, 53);
- iptablesRemoveTcpInput(server->iptables, network->bridge, 53);
- iptablesRemoveUdpInput(server->iptables, network->bridge, 67);
- iptablesRemoveTcpInput(server->iptables, network->bridge, 67);
iptablesRemoveNonBridgedMasq(server->iptables, network->def->forwardDev);
iptablesRemoveStateForward(server->iptables, network->bridge, network->def->forwardDev);
iptablesRemoveInterfaceForward(server->iptables, network->bridge, network->def->forwardDev);
- iptablesRemovePhysdevForward(server->iptables, network->bridge, network->def->forwardDev);
}
+ iptablesRemoveUdpInput(server->iptables, network->bridge, 53);
+ iptablesRemoveTcpInput(server->iptables, network->bridge, 53);
+ iptablesRemoveUdpInput(server->iptables, network->bridge, 67);
+ iptablesRemoveTcpInput(server->iptables, network->bridge, 67);
+ iptablesRemovePhysdevForward(server->iptables, network->bridge);
}
static int
@@ -1412,8 +1415,7 @@ int qemudStartNetworkDaemon(struct qemud
goto err_delbr;
}
- if (network->def->forward &&
- !qemudAddIptablesRules(server, network))
+ if (!qemudAddIptablesRules(server, network))
goto err_delbr1;
if (network->def->forward &&
--
17 years, 9 months
[Libvir] [patch 2/5] iptables: use calloc() instead of malloc()/memset()
by Mark McLoughlin
Replace a few instances of malloc() followed by memset(0) with
calloc()
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/iptables.c
===================================================================
--- libvirt.orig/qemud/iptables.c
+++ libvirt/qemud/iptables.c
@@ -270,11 +270,9 @@ iptRulesNew(const char *table,
{
iptRules *rules;
- if (!(rules = (iptRules *)malloc(sizeof (iptRules))))
+ if (!(rules = (iptRules *)calloc(1, sizeof (iptRules))))
return NULL;
- memset (rules, 0, sizeof (iptRules));
-
if (!(rules->table = strdup(table)))
goto error;
@@ -353,11 +351,9 @@ iptablesAddRemoveChain(iptRules *rules,
2 + /* --table foo */
2; /* --new-chain bar */
- if (!(argv = (char **)malloc(sizeof(char *) * (n+1))))
+ if (!(argv = (char **)calloc(n + 1, sizeof(char *))))
goto error;
- memset(argv, 0, sizeof(char *) * (n + 1));
-
n = 0;
if (!(argv[n++] = strdup(IPTABLES_PATH)))
@@ -413,14 +409,12 @@ iptablesAddRemoveRule(iptRules *rules, i
va_end(args);
- if (!(argv = (char **)malloc(sizeof(char *) * (n + 1))))
+ if (!(argv = (char **)calloc(n + 1, sizeof(char *))))
goto error;
if (!(rule = (char *)malloc(rulelen)))
goto error;
- memset(argv, 0, sizeof(char *) * (n + 1));
-
n = 0;
if (!(argv[n++] = strdup(IPTABLES_PATH)))
--
17 years, 9 months
[Libvir] [patch 1/5] iptables: fix invalid free
by Mark McLoughlin
In iptablesContextNew(), make sure we don't try and free an invalid
pointer if one of the iptRulesNew() fails.
Signed-off-by: Mark McLoughlin <markmc(a)redhat.com>
Index: libvirt/qemud/iptables.c
===================================================================
--- libvirt.orig/qemud/iptables.c
+++ libvirt/qemud/iptables.c
@@ -496,7 +496,7 @@ iptablesContextNew(void)
{
iptablesContext *ctx;
- if (!(ctx = (iptablesContext *) malloc(sizeof (iptablesContext))))
+ if (!(ctx = (iptablesContext *) calloc(1, sizeof (iptablesContext))))
return NULL;
if (!(ctx->input_filter = iptRulesNew("filter", IPTABLES_PREFIX "INPUT")))
@@ -518,9 +518,12 @@ iptablesContextNew(void)
void
iptablesContextFree(iptablesContext *ctx)
{
- iptRulesFree(ctx->input_filter);
- iptRulesFree(ctx->forward_filter);
- iptRulesFree(ctx->nat_postrouting);
+ 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);
}
--
17 years, 9 months
[Libvir] A whole tonne of networking fixes / enhancements
by Daniel P. Berrange
I've been testing the networking support and found various bugs / missing
features that I thought we really need to have in the release - some of
them impact the XML so we have to get this right now.
- Build up in memory linked-list of network devices & disk devices in
same order as they are listed in XML. Currently they are built up
in reversed order, which makes the XML not be idempotent, and also
means that if you have multiple NICs, what you think is eth0 ends
up being eth4 and what you think is eth4 is eth0. This patch fixes
the ordering to match XML.
- Set the 'vlan' attribute in command line args to QEMU. This ensures
that separate network devices are in fact separated. Previously if
you had multiple NICs, QEMU connected them all to the same VLAN so
any traffic on one NIC got sent to all NICs. Most definitely not
what you want in any usual scenario, and created a traffic storm
from the resultant network loops !
- Added support for networking of type='bridge'. This gives parity
with equivalent Xen networking, eg
<interface type='bridge'>
<source dev='xenbr0'/>
<target dev='vnet3'/>
</interface>
Will create a tap device called vnet3 and bridge it into xenbr0
- Added support for networking of type='ethernet'. This give parity
with equivlent Xen networking, eg
<interface type='ethernet'>
<script path='/etc/qemu-ifup'/>
<target dev='vnet5'/>
</interface>
Will create a tap device called vnet5 and run 'qemu-ifup' to setup
its configuration. Think the various non-bridge Xen networking configs.
- Added support for 'client', 'server', 'mcast' networking types. These
are QEMU specific types, allowing unprivileged (or privileged) users
to create virtual networks without TAP devices.
eg two machines, one with
<interface type='server'>
<source address="127.0.0.1" port="5555"/>
</interface>
And the other with
<interface type='client'>
<source address="127.0.0.1" port="5555"/>
</interface>
Or both using multicast:
<interface type='mcast'>
<source address="230.0.0.1" port="5558"/>
</interface>
Both these options allow QEMU instancs on different physical machines
to talk to each other. The multicast protocol is also compatible with
the UserModeLinux multicast protocol.
- Fix the 'type=network' config use the <target dev='vnet3'> element
instead of a custom tapifname=vnet3 attribute - this gives consistent
way to name tap devices that - most importantly - matches the
Xen XML format for specifying vifname, eg
<interface type='network'>
<source network='default'/>
<target dev='vnet2'/>
</interface>
Will create a tapdevice called vnet2 and connect it to the bridge
device associated with the network 'default'.
- Removed references to 'vde' - we're not using this explicitly - at
some time in the future, we'll perhaps use VDE for doing virtual
networking for unprivileged users where bridge devices are not
available
- Removed references to 'tap' network type - this is basically handled
by the 'ethernet' network type to give XML compatability with the
same functionality in the Xen backend.
- The virtual network configuration currently always adds whole bunch
of IPTables rules to the FORWARD/POSTROUTING chain which allow traffic
from the virtual network to be masqueraded out through any active
physical interface. This may be correct thing todo for the default
network, but we also need the ability to create totally isolated
networks (no forwarding at all), or directed networks (eg forwarding
to an explicit physical device).
To deal with this scenario I introduce a new element in the network
XML called '<forward>'. If this is not present, then no forwarding
rules are added at all. If it is present, but with no attributes
then a generic rule allowing forwarding to any interface is added.
If it is present and the 'dev' attribute is specific then forwarding
is only allowed to that named interface. The default network XML thus
now includes
<forward/>
So that by default we have a virtual network connected to all physical
devices.
- MAC addreses were not be autogenerated inside libvirt_qemud. If you
don't provide a MAC address, QEMU (insanely) uses a hardcoded default.
So all NICs end up with an identical MAC. We now always autogenerate
a MAC address if not explicitly listed in XML.
One final thing to be aware of - the Fedora Core 6 Xen kernel currently has
totally fubar TCP checksum offland. So if you try to bridge a Xen guest into
the libvirt virtual networking, it'll fail to get a DHCP address from dnsmasq.
Even if you fix that by turning off TX checksums in Dom0, you'll get checksum
failures for the actual TCP data transmission too. The only solution is to
either upgrade the Dom0 kernel to a RHEL-5 vintage, or to also turn off
checksumming in the guest. A new FC6 xen kernel is in the works which should
hopefully fix this for real.
With fixed kernel, I can easily setup virtual networks connecting both
Xen PV, Xen FV and QEMU instances together.
Anyway, the upshot of all this, is that we can now trivially create really
complicated & fun networking layouts across QEMU & Xen, using a mixture of
bridging, NAT, isolated LANs, and tunnelled VLANS :-) We really ought to
document it a little though
Since Mark is off on vacation for a while, I'd appreciate people taking a
close look at this / actually giving it a try if you can.
It is possible to create a totally isolated network using
<network>
<name>private</name>
<uuid>d237ce44-8efa-452c-b8e6-1ae9cf53aeb1</uuid>
<bridge name="virbr0" />
<ip address="192.168.122.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.122.2" end="192.168.122.254" />
</dhcp>
</ip>
</network>
And a QEMU guest with 5 (yes, 5) network cards
<domain type='qemu'>
<name>QEMUFirewall</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219200</memory>
<currentMemory>219200</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda'/>
</disk>
<interface type='network'>
<source network='private'/>
<target dev='vnet1'/>
</interface>
<interface type='bridge'>
<source dev='xenbr0'/>
<target dev='vnet2'/>
</interface>
<interface type='ethernet'>
<script path='/etc/dan-test-ifup'/>
<target dev='vnet3'/>
</interface>
<interface type='server'>
<source address="127.0.0.1" port="5555"/>
</interface>
<interface type='mcast'>
<source address="230.0.0.1" port="5558"/>
</interface>
<graphics type='vnc' port='-1'/>
</devices>
</domain>
In this XML, only eth1 is connected to the hosts public facing network.
The other NICs are all on various private networks. So this QEMU guest
is in essence a router/firewall box. eg, you could connected various
other guests to the 'private' virtual network, and the only way they
could reach the outside world is via this QEMU instance doing routing.
Regards,
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
17 years, 9 months
[Libvir] Turn on compiler buffer checks
by Daniel P. Berrange
Since testing the latest Fedora RPMs I've hit a number of buffer overflow
issues which were caught by the extra compiler checks Fedora turns on. It
would be much better if we caught these before release, so the attached
patch modifies the configure script so that the following options are always
turned on if the compiler supports them:
-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
--param=ssp-buffer-size=4 -fasynchronous-unwind-tables
Since all our production builds use these flags & the patch only enables
them if the compiler has support I don't see any issue with having them
turned on by default.
In addition I altered the existing configure compiler flag checks so that
every compiler flag we turned on is explicitly checked to see if supported
by the current compiler rather than doing a crude $CC=gcc heuristic which
doesn't take account of differing gcc version numbers.
If we wanted super-extra paranoia we could also turn on -fstack-protector-all
possibly only with --enable-compiler-warnings=maximum since it adds more
non-trivial performance overhead
Regards,
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
17 years, 9 months
[Libvir] Fix for buffer overflow in network setup
by Daniel P. Berrange
There was a buffer overflow in teh code to deal with building command line
arguments which was only exposed when the Fedora RPM builds uses the
stack protector args to GCC. The attached patch increases the buffer size
and uses snprintf() instead of sprintf().
BTW, if anyone is looking for a patch to write - removing all other calls
to sprintf() would be a worthy task :-)
Regards,
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
17 years, 9 months
[Libvir] [PATCH] Add error message to virsh setmem/setmaxmem
by Masayuki Sunou
Hi
Virsh setmem/setmaxmem doesn't output an error message when an invalid
value is set to "bytes".
This patch outputs an error message, when an invalid value is set as
"bytes" of virsh setmem/setmaxmem.
Signed-off-by: Masayuki Sunou <fj1826dm(a)aa.jp.fujitsu.com>
Thanks,
Masayuki Sunou.
Index: src/virsh.c
===================================================================
RCS file: /data/cvs/libvirt/src/virsh.c,v
retrieving revision 1.66
diff -u -p -r1.66 virsh.c
--- src/virsh.c 19 Mar 2007 14:20:30 -0000 1.66
+++ src/virsh.c 19 Mar 2007 23:29:14 -0000
@@ -1461,6 +1461,7 @@ cmdSetmem(vshControl * ctl, vshCmd * cmd
bytes = vshCommandOptInt(cmd, "bytes", &bytes);
if (bytes <= 0) {
virDomainFree(dom);
+ vshError(ctl, FALSE, _("Invalid value of \"bytes\""));
return FALSE;
}
@@ -1504,6 +1505,7 @@ cmdSetmaxmem(vshControl * ctl, vshCmd *
bytes = vshCommandOptInt(cmd, "bytes", &bytes);
if (bytes <= 0) {
virDomainFree(dom);
+ vshError(ctl, FALSE, _("Invalid value of \"bytes\""));
return FALSE;
}
17 years, 9 months
[Libvir] RPM upgrades interaction with default networking
by Daniel P. Berrange
I've been thinking about the tricky issue of RPM upgrades and how they
interact with the new networking stuff and don't think we've currently
got quite the optimal setup.
The current approach is that 'make install' puts a default.xml file
into /etc/libvirt/qemu/networks and also symlinks that file into the
autostart directory. So if someone builds from tar.gz and does make
install they'll get a default network config installed & turned on
out of the box. This is fine for tar.gz scenario.
When we build an RPM we also include the default.xml file in the
/etc/libvirt/qemu/networks directory, as well as the autostart symlink.
So anyone installing the libvirt RPM gets the default network, whether
they're doing an upgrade or fresh install. This is reasonable for the
new install, or the first time you upgrade to a new neworking-enabled
libvirt. If you subsequently delete the default network, or turn off
autostarting, then along comes the next libvirt RPM update and autostart
gets turned back on, and/or the default network recreated. This will be
considered to be rather unpleasant by many people because no matter
what they do, they will always be given a virbr0, a dnsmasq process
and a bunch of extra iptables rules whether they want them or not.
So I think we need to figure out a way to deploy a default network out
of the box, but at the same time ensure that if the turn it off / delete
it, upgrades won't re-introduce it. Ideally if someone upgrades from
FC6 -> FC7 they will also get the default network created (once only).
One way we can address this is to put the default.xml into the docs
directory /usr/share/doc/libvirt-X.Y.Z (or perhaps stuff is into a dir
like /usr/share/libvirt instead) and then have a RPM %post script which
copies it into /etc/libvirt/qemu/networks. If we make the %post script
conditional on '$1 == 1' then it will only be run for completely new
libvirt installs. This doesn't address the upgrade question though -
so someone updating from FC6 -> FC7 won't get the default network. Perhaps
we shouldn't worry about them ?
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
17 years, 9 months