This patch adds the ebtables wrapper to the network driver.
Signed-off-by: Gerhard Stenzel <gerhard.stenzel(a)de.ibm.com>
---
src/conf/network_conf.h | 10 ++
src/libvirt_private.syms | 26 ++++++
src/network/bridge_driver.c | 179 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 215 insertions(+), 0 deletions(-)
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index e983a01..2f7d536 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -55,6 +55,13 @@ struct _virNetworkDHCPHostDef {
char *ip;
};
+typedef struct _virNetworkBridgePortDef virNetworkBridgePortDef;
+typedef virNetworkBridgePortDef *virNetworkBridgePortDefPtr;
+struct _virNetworkBridgePortDef {
+ char *mac;
+ char *name;
+};
+
typedef struct _virNetworkDef virNetworkDef;
typedef virNetworkDef *virNetworkDefPtr;
struct _virNetworkDef {
@@ -79,6 +86,9 @@ struct _virNetworkDef {
unsigned int nhosts; /* Zero or more dhcp hosts */
virNetworkDHCPHostDefPtr hosts;
+ unsigned int nports; /* Zero or more filtered ports */
+ virNetworkBridgePortDefPtr ports;
+
char *tftproot;
char *bootfile;
};
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b699fb2..f92f646 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -227,6 +227,32 @@ iptablesRemoveTcpInput;
iptablesRemoveUdpInput;
iptablesSaveRules;
+# ebtables.h
+ebtablesAddForwardAllowCross;
+ebtablesAddForwardAllowIn;
+ebtablesAddForwardAllowOut;
+ebtablesAddForwardAllowRelatedIn;
+ebtablesAddForwardMasquerade;
+ebtablesAddForwardRejectIn;
+ebtablesAddForwardRejectOut;
+ebtablesAddTcpInput;
+ebtablesAddUdpInput;
+ebtablesContextFree;
+ebtablesContextNew;
+ebtablesReloadRules;
+ebtablesRemoveForwardAllowCross;
+ebtablesRemoveForwardAllowIn;
+ebtablesRemoveForwardAllowOut;
+ebtablesRemoveForwardAllowRelatedIn;
+ebtablesRemoveForwardMasquerade;
+ebtablesRemoveForwardRejectIn;
+ebtablesRemoveForwardRejectOut;
+ebtablesRemoveTcpInput;
+ebtablesRemoveUdpInput;
+ebtablesSaveRules;
+ebtablesAddForwardPolicyReject;
+ebtablesRemoveForwardPolicyReject;
+ebtablesForwardPolicyReject;
# libvirt_internal.h
virStateInitialize;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 95bc810..acd7afe 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -54,6 +54,7 @@
#include "util.h"
#include "memory.h"
#include "uuid.h"
+#include "ebtables.h"
#include "iptables.h"
#include "bridge.h"
#include "logging.h"
@@ -70,6 +71,7 @@ struct network_driver {
virNetworkObjList networks;
iptablesContext *iptables;
+ ebtablesContext *ebtables;
brControl *brctl;
char *networkConfigDir;
char *networkAutostartDir;
@@ -245,6 +247,10 @@ networkStartup(int privileged) {
goto out_of_memory;
}
+ if (!(driverState->ebtables = ebtablesContextNew())) {
+ goto out_of_memory;
+ }
+
if (virNetworkLoadAllConfigs(NULL,
&driverState->networks,
@@ -293,6 +299,11 @@ networkReload(void) {
iptablesReloadRules(driverState->iptables);
}
+ if (driverState->ebtables) {
+ VIR_INFO0(_("Reloading ebtables rules\n"));
+ ebtablesReloadRules(driverState->ebtables);
+ }
+
networkAutostartConfigs(driverState);
networkDriverUnlock(driverState);
return 0;
@@ -350,6 +361,9 @@ networkShutdown(void) {
if (driverState->iptables)
iptablesContextFree(driverState->iptables);
+ if (driverState->ebtables)
+ ebtablesContextFree(driverState->ebtables);
+
networkDriverUnlock(driverState);
virMutexDestroy(&driverState->lock);
@@ -573,6 +587,168 @@ cleanup:
return ret;
}
+
+static int
+networkAddEbtablesRules(virConnectPtr conn,
+ struct network_driver *driver) {
+ int err;
+
+ /* Catch all rules to block forwarding to/from bridges */
+/*
+ if ((err = ebtablesAddForwardRejectOut(driver->ebtables,
network->def->bridge))) {
+ virReportSystemError(conn, err,
+ _("failed to add ebtables rule to block outbound
traffic from '%s'"),
+ network->def->bridge);
+ goto err5;
+ }
+
+ if ((err = ebtablesAddForwardRejectIn(driver->ebtables,
network->def->bridge))) {
+ virReportSystemError(conn, err,
+ _("failed to add ebtables rule to block inbound traffic
to '%s'"),
+ network->def->bridge);
+ goto err6;
+ }
+*/
+ /* Set forward policy to DROP */
+ if ((err = ebtablesAddForwardPolicyReject(driver->ebtables))) {
+ virReportSystemError(conn, err,
+ _("failed to add ebtables rule to set default policy to
drop on '%s'"),
+ __FILE__);
+ return err;
+ }
+ /* Allow traffic between guests on the same bridge */
+/*
+ if ((err = ebtablesAddForwardAllowCross(driver->ebtables,
network->def->bridge))) {
+ virReportSystemError(conn, err,
+ _("failed to add ebtables rule to allow cross bridge
traffic on '%s'"),
+ network->def->bridge);
+ goto err7;
+ }
+*/
+
+ /* if routing is enabled, set up the rules*/
+/*
+ networkAddRoutingEbtablesRules(conn, driver, network);
+ if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE &&
+ !networkAddRoutingEbtablesRules(conn, driver, network))
+ goto err8;
+*/
+/*
+ for (r = 0 ; r < network->def->nports ; r++) {
+ virNetworkBridgePortDefPtr port = &(network->def->ports[r]);
+ if ((port->mac) && (port->name)) {
+ fprintf(stderr, "mac %s,name %s\n",
+ port->mac, port->name);
+ }
+ }
+
+*/
+ ebtablesSaveRules(driver->ebtables);
+
+ return 1;
+/*
+ err8:
+ ebtablesRemoveForwardAllowCross(driver->ebtables,
+ network->def->bridge);
+ err7:
+ ebtablesRemoveForwardRejectIn(driver->ebtables,
+ network->def->bridge);
+ err6:
+ ebtablesRemoveForwardRejectOut(driver->ebtables,
+ network->def->bridge);
+ err5:
+ */
+ return 0;
+}
+
+
+static int
+networkDisableAllFrames(virConnectPtr conn) {
+ int err;
+ struct network_driver *netdriver = conn->networkPrivateData;
+
+ /* Set forward policy to DROP */
+ if ((err = !networkAddEbtablesRules(conn, netdriver))) {
+ virReportSystemError(conn, err,
+ _("cannot filter mac addresses on bridge
'%s'"),
+ __FILE__);
+ return err;
+ }
+/* if ((err = ebtablesAddForwardPolicyReject(netdriver->ebtables,
"dummy"))) {
+ virReportSystemError(conn, err,
+ _("failed to add ebtables rule to set default policy to
drop on '%s'"),
+ "dummy");
+ }
+*/
+ return 0;
+}
+
+static int
+networkDisallowMacOnPort(virConnectPtr conn,
+ char * brname,
+ char * ifname,
+ unsigned char * mac) {
+
+ int err;
+ char *macaddr;
+ struct network_driver *netdriver = conn->networkPrivateData;
+
+ if (virAsprintf(&macaddr,
+ "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1],
+ mac[2], mac[3],
+ mac[4], mac[5]) < 0) {
+ virReportOOMError(conn);
+ return -1;
+ }
+ /* allow this combination of macaddr and ifname */
+
+ ebtablesContext * ebtablescontext = netdriver->ebtables;
+ if ((err = ebtablesRemoveForwardAllowIn(ebtablescontext,
+ brname,
+ ifname,
+ macaddr))) {
+ virReportSystemError(conn, err,
+ _("failed to add ebtables rule to allow routing to
'%s'"),
+ ifname);
+ }
+
+ return 0;
+}
+
+static int
+networkAllowMacOnPort(virConnectPtr conn,
+ char * brname,
+ char * ifname,
+ unsigned char * mac) {
+
+ int err;
+ char *macaddr;
+ struct network_driver *netdriver = conn->networkPrivateData;
+
+ if (virAsprintf(&macaddr,
+ "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1],
+ mac[2], mac[3],
+ mac[4], mac[5]) < 0) {
+ virReportOOMError(conn);
+ return -1;
+ }
+ /* allow this combination of macaddr and ifname */
+
+ ebtablesContext * ebtablescontext = netdriver->ebtables;
+ if ((err = ebtablesAddForwardAllowIn(ebtablescontext,
+ brname,
+ ifname,
+ macaddr))) {
+ virReportSystemError(conn, err,
+ _("failed to add ebtables rule to allow routing to
'%s'"),
+ ifname);
+ }
+
+ return 0;
+}
+
static int
networkAddMasqueradingIptablesRules(virConnectPtr conn,
struct network_driver *driver,
@@ -1497,6 +1673,9 @@ static virNetworkDriver networkDriver = {
networkGetBridgeName, /* networkGetBridgeName */
networkGetAutostart, /* networkGetAutostart */
networkSetAutostart, /* networkSetAutostart */
+ networkAllowMacOnPort, /* networkAllowMacOnPort */
+ networkDisallowMacOnPort, /* networkDisallowMacOnPort */
+ networkDisableAllFrames, /* networkDisableAllFrames */
};
static virStateDriver networkStateDriver = {