[libvirt] [RFC PATCH 3/6] add the ebtables wrapper to network driver

Gerhard Stenzel gstenzel at linux.vnet.ibm.com
Fri Oct 2 13:48:21 UTC 2009


This patch adds the ebtables wrapper to the network driver.

Signed-off-by: Gerhard Stenzel <gerhard.stenzel at 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 = {




More information about the libvir-list mailing list