From af37ce3dc7350419773bc2201a3e830b9fa06a1c Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Tue, 22 Nov 2011 15:12:03 -0500 Subject: [PATCH] Add a 'mac' chain With hunks borrowed from one of David Steven's previous patches, we now add the capability of having a 'mac' chain which is useful to filter for multiple valid MAC addresses. Signed-off-by: David L Stevens Signed-off-by: Stefan Berger --- docs/schemas/nwfilter.rng | 3 +++ src/conf/nwfilter_conf.c | 2 ++ src/conf/nwfilter_conf.h | 2 ++ src/nwfilter/nwfilter_ebiptables_driver.c | 23 +++++++++++++++++++++-- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/docs/schemas/nwfilter.rng b/docs/schemas/nwfilter.rng index 46b8d4f0b9..5fd4860b26 100644 --- a/docs/schemas/nwfilter.rng +++ b/docs/schemas/nwfilter.rng @@ -296,6 +296,9 @@ root + + mac[a-zA-Z0-9_\.:-]{0,9} + vlan[a-zA-Z0-9_\.:-]{0,8} diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index 59132d9a69..1321f8b1c0 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -82,6 +82,7 @@ VIR_ENUM_IMPL(virNWFilterEbtablesTable, VIR_NWFILTER_EBTABLES_TABLE_LAST, VIR_ENUM_IMPL(virNWFilterChainSuffix, VIR_NWFILTER_CHAINSUFFIX_LAST, "root", + "mac", "vlan", "arp", "rarp", @@ -128,6 +129,7 @@ struct int_map { static const struct int_map chain_priorities[] = { INTMAP_ENTRY(NWFILTER_ROOT_FILTER_PRI, "root"), + INTMAP_ENTRY(NWFILTER_MAC_FILTER_PRI, "mac"), INTMAP_ENTRY(NWFILTER_VLAN_FILTER_PRI, "vlan"), INTMAP_ENTRY(NWFILTER_IPV4_FILTER_PRI, "ipv4"), INTMAP_ENTRY(NWFILTER_IPV6_FILTER_PRI, "ipv6"), diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 1d568dc3ff..a7e7a13dc2 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -378,6 +378,7 @@ enum virNWFilterEbtablesTableType { # define NWFILTER_MAX_FILTER_PRIORITY MAX_RULE_PRIORITY # define NWFILTER_ROOT_FILTER_PRI 0 +# define NWFILTER_MAC_FILTER_PRI -800 # define NWFILTER_VLAN_FILTER_PRI -750 # define NWFILTER_IPV4_FILTER_PRI -700 # define NWFILTER_IPV6_FILTER_PRI -600 @@ -456,6 +457,7 @@ struct _virNWFilterEntry { enum virNWFilterChainSuffixType { VIR_NWFILTER_CHAINSUFFIX_ROOT = 0, + VIR_NWFILTER_CHAINSUFFIX_MAC, VIR_NWFILTER_CHAINSUFFIX_VLAN, VIR_NWFILTER_CHAINSUFFIX_ARP, VIR_NWFILTER_CHAINSUFFIX_RARP, diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index ec7f4f03ce..73b62f43e1 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -188,6 +188,7 @@ enum l3_proto_idx { L3_PROTO_IPV6_IDX, L3_PROTO_ARP_IDX, L3_PROTO_RARP_IDX, + L2_PROTO_MAC_IDX, L2_PROTO_VLAN_IDX, L3_PROTO_LAST_IDX }; @@ -205,6 +206,7 @@ static const struct ushort_map l3_protocols[] = { USHORTMAP_ENTRY_IDX(L3_PROTO_ARP_IDX , ETHERTYPE_ARP , "arp"), USHORTMAP_ENTRY_IDX(L3_PROTO_RARP_IDX, ETHERTYPE_REVARP, "rarp"), USHORTMAP_ENTRY_IDX(L2_PROTO_VLAN_IDX, ETHERTYPE_VLAN , "vlan"), + USHORTMAP_ENTRY_IDX(L2_PROTO_MAC_IDX, 0 , "mac"), USHORTMAP_ENTRY_IDX(L3_PROTO_LAST_IDX, 0 , NULL), }; @@ -2806,11 +2808,26 @@ ebtablesCreateTmpSubChain(ebiptablesRuleInstPtr *inst, char rootchain[MAX_CHAINNAME_LENGTH], chain[MAX_CHAINNAME_LENGTH]; char chainPrefix = (incoming) ? CHAINPREFIX_HOST_IN_TEMP : CHAINPREFIX_HOST_OUT_TEMP; + char *protostr = NULL; PRINT_ROOT_CHAIN(rootchain, chainPrefix, ifname); PRINT_CHAIN(chain, chainPrefix, ifname, (filtername) ? filtername : l3_protocols[protoidx].val); + switch (protoidx) { + case L2_PROTO_MAC_IDX: + protostr = strdup(""); + break; + default: + virAsprintf(&protostr, "-p 0x%04x ", l3_protocols[protoidx].attr); + break; + } + + if (!protostr) { + virReportOOMError(); + return -1; + } + virBufferAsprintf(&buf, CMD_DEF("%s -t %s -F %s") CMD_SEPARATOR CMD_EXEC @@ -2819,7 +2836,7 @@ ebtablesCreateTmpSubChain(ebiptablesRuleInstPtr *inst, CMD_DEF("%s -t %s -N %s") CMD_SEPARATOR CMD_EXEC "%s" - CMD_DEF("%s -t %s -%%c %s %%s -p 0x%x -j %s") + CMD_DEF("%s -t %s -%%c %s %%s %s-j %s") CMD_SEPARATOR CMD_EXEC "%s", @@ -2831,10 +2848,12 @@ ebtablesCreateTmpSubChain(ebiptablesRuleInstPtr *inst, CMD_STOPONERR(stopOnError), ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, - rootchain, l3_protocols[protoidx].attr, chain, + rootchain, protostr, chain, CMD_STOPONERR(stopOnError)); + VIR_FREE(protostr); + if (virBufferError(&buf) || VIR_EXPAND_N(tmp, count, 1) < 0) { virReportOOMError();