This patch adds the ebtables wrapper to the network driver. Signed-off-by: Gerhard Stenzel <gerhard.stenzel@xxxxxxxxxx> --- 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 = { -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list