diff --git a/docs/schemas/nwfilter.rng b/docs/schemas/nwfilter.rng
index 3bcdd44b8329c4258fc86b335bb5468d60cb8a57..9d9ae7362f744cdb31012b14b535f7da02add284 100644
--- a/docs/schemas/nwfilter.rng
+++ b/docs/schemas/nwfilter.rng
@@ -37,6 +37,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
index 7f68cd62911cc1ac03f9b30d78e9e77f602edada..a8a6a78ab6834eee1405eafbaa2421842f8a9b1b 100644
--- a/src/conf/nwfilter_conf.c
+++ b/src/conf/nwfilter_conf.c
@@ -46,22 +46,6 @@
#include "domain_conf.h"
-/* XXX
- * The config parser/structs should not be using platform specific
- * constants. Win32 lacks these constants, breaking the parser,
- * so temporarily define them until this can be re-written to use
- * locally defined enums for all constants
- */
-#ifndef ETHERTYPE_IP
-# define ETHERTYPE_IP 0x0800
-#endif
-#ifndef ETHERTYPE_ARP
-# define ETHERTYPE_ARP 0x0806
-#endif
-#ifndef ETHERTYPE_IPV6
-# define ETHERTYPE_IPV6 0x86dd
-#endif
-
#define VIR_FROM_THIS VIR_FROM_NWFILTER
@@ -90,6 +74,7 @@ VIR_ENUM_IMPL(virNWFilterEbtablesTable, VIR_NWFILTER_EBTABLES_TABLE_LAST,
VIR_ENUM_IMPL(virNWFilterChainSuffix, VIR_NWFILTER_CHAINSUFFIX_LAST,
"root",
"arp",
+ "rarp",
"ipv4",
"ipv6");
@@ -97,6 +82,7 @@ VIR_ENUM_IMPL(virNWFilterRuleProtocol, VIR_NWFILTER_RULE_PROTOCOL_LAST,
"none",
"mac",
"arp",
+ "rarp",
"ip",
"ipv6",
"tcp",
@@ -412,11 +398,10 @@ struct _virXMLAttr2Struct
static const struct int_map macProtoMap[] = {
- INTMAP_ENTRY(ETHERTYPE_ARP , "arp"),
- INTMAP_ENTRY(ETHERTYPE_IP , "ipv4"),
-#ifdef ETHERTYPE_IPV6
- INTMAP_ENTRY(ETHERTYPE_IPV6, "ipv6"),
-#endif
+ INTMAP_ENTRY(ETHERTYPE_ARP , "arp"),
+ INTMAP_ENTRY(ETHERTYPE_REVARP, "rarp"),
+ INTMAP_ENTRY(ETHERTYPE_IP , "ipv4"),
+ INTMAP_ENTRY(ETHERTYPE_IPV6 , "ipv6"),
INTMAP_ENTRY_LAST
};
@@ -1096,6 +1081,7 @@ struct _virAttributes {
static const virAttributes virAttr[] = {
PROTOCOL_ENTRY("arp" , arpAttributes , VIR_NWFILTER_RULE_PROTOCOL_ARP),
+ PROTOCOL_ENTRY("rarp" , arpAttributes , VIR_NWFILTER_RULE_PROTOCOL_RARP),
PROTOCOL_ENTRY("mac" , macAttributes , VIR_NWFILTER_RULE_PROTOCOL_MAC),
PROTOCOL_ENTRY("ip" , ipAttributes , VIR_NWFILTER_RULE_PROTOCOL_IP),
PROTOCOL_ENTRY("ipv6" , ipv6Attributes , VIR_NWFILTER_RULE_PROTOCOL_IPV6),
@@ -1450,6 +1436,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
break;
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
+ case VIR_NWFILTER_RULE_PROTOCOL_RARP:
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
break;
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index 97b2e6fcad88de7d425a37b045185f2b4ca8a2dd..d54f2ba05b4d29ab012e551ba8e3f1c056739b4d 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -35,6 +35,24 @@
# include "xml.h"
# include "network.h"
+/* XXX
+ * The config parser/structs should not be using platform specific
+ * constants. Win32 lacks these constants, breaking the parser,
+ * so temporarily define them until this can be re-written to use
+ * locally defined enums for all constants
+ */
+# ifndef ETHERTYPE_IP
+# define ETHERTYPE_IP 0x0800
+# endif
+# ifndef ETHERTYPE_ARP
+# define ETHERTYPE_ARP 0x0806
+# endif
+# ifndef ETHERTYPE_REVARP
+# define ETHERTYPE_REVARP 0x8035
+# endif
+# ifndef ETHERTYPE_IPV6
+# define ETHERTYPE_IPV6 0x86dd
+# endif
/**
* Chain suffix size is:
@@ -292,6 +310,7 @@ enum virNWFilterRuleProtocolType {
VIR_NWFILTER_RULE_PROTOCOL_NONE = 0,
VIR_NWFILTER_RULE_PROTOCOL_MAC,
VIR_NWFILTER_RULE_PROTOCOL_ARP,
+ VIR_NWFILTER_RULE_PROTOCOL_RARP,
VIR_NWFILTER_RULE_PROTOCOL_IP,
VIR_NWFILTER_RULE_PROTOCOL_IPV6,
VIR_NWFILTER_RULE_PROTOCOL_TCP,
@@ -336,7 +355,7 @@ struct _virNWFilterRuleDef {
enum virNWFilterRuleProtocolType prtclType;
union {
ethHdrFilterDef ethHdrFilter;
- arpHdrFilterDef arpHdrFilter;
+ arpHdrFilterDef arpHdrFilter; /* also used for rarp */
ipHdrFilterDef ipHdrFilter;
ipv6HdrFilterDef ipv6HdrFilter;
tcpHdrFilterDef tcpHdrFilter;
@@ -373,6 +392,7 @@ struct _virNWFilterEntry {
enum virNWFilterChainSuffixType {
VIR_NWFILTER_CHAINSUFFIX_ROOT = 0,
VIR_NWFILTER_CHAINSUFFIX_ARP,
+ VIR_NWFILTER_CHAINSUFFIX_RARP,
VIR_NWFILTER_CHAINSUFFIX_IPv4,
VIR_NWFILTER_CHAINSUFFIX_IPv6,
diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c
index c2d2269fd06d325fa4fdbc385e9913d753e5e4e2..dcdd938a22926286299624e1d0ce63274a8caf96 100644
--- a/src/nwfilter/nwfilter_ebiptables_driver.c
+++ b/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -32,6 +32,7 @@
#include "logging.h"
#include "virterror_internal.h"
#include "domain_conf.h"
+#include "nwfilter_conf.h"
#include "nwfilter_gentech_driver.h"
#include "nwfilter_ebiptables_driver.h"
@@ -103,11 +104,28 @@ static int ebiptablesDriverInit(void);
static void ebiptablesDriverShutdown(void);
-static const char *supported_protocols[] = {
- "ipv4",
- "ipv6",
- "arp",
- NULL,
+struct ushort_map {
+ unsigned short attr;
+ const char *val;
+};
+
+
+enum l3_proto_idx {
+ L3_PROTO_IPV4_IDX = 0,
+ L3_PROTO_IPV6_IDX,
+ L3_PROTO_ARP_IDX,
+ L3_PROTO_RARP_IDX,
+ L3_PROTO_LAST_IDX
+};
+
+#define USHORTMAP_ENTRY_IDX(IDX, ATT, VAL) [IDX] = { .attr = ATT, .val = VAL }
+
+static const struct ushort_map l3_protocols[] = {
+ USHORTMAP_ENTRY_IDX(L3_PROTO_IPV4_IDX, ETHERTYPE_IP , "ipv4"),
+ USHORTMAP_ENTRY_IDX(L3_PROTO_IPV6_IDX, ETHERTYPE_IPV6 , "ipv6"),
+ USHORTMAP_ENTRY_IDX(L3_PROTO_ARP_IDX , ETHERTYPE_ARP , "arp"),
+ USHORTMAP_ENTRY_IDX(L3_PROTO_RARP_IDX, ETHERTYPE_REVARP, "rarp"),
+ USHORTMAP_ENTRY_IDX(L3_PROTO_LAST_IDX, 0 , NULL),
};
@@ -1611,6 +1629,7 @@ ebtablesCreateRuleInstance(char chainPrefix,
break;
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
+ case VIR_NWFILTER_RULE_PROTOCOL_RARP:
virBufferVSprintf(&buf,
CMD_DEF_PRE "%s -t %s -%%c %s %%s",
@@ -1622,7 +1641,10 @@ ebtablesCreateRuleInstance(char chainPrefix,
reverse))
goto err_exit;
- virBufferAddLit(&buf, " -p arp");
+ virBufferVSprintf(&buf, " -p 0x%x",
+ (rule->prtclType == VIR_NWFILTER_RULE_PROTOCOL_ARP)
+ ? l3_protocols[L3_PROTO_ARP_IDX].attr
+ : l3_protocols[L3_PROTO_RARP_IDX].attr);
if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataHWType)) {
if (printDataType(vars,
@@ -2036,6 +2058,7 @@ ebiptablesCreateRuleInstance(virConnectPtr conn ATTRIBUTE_UNUSED,
case VIR_NWFILTER_RULE_PROTOCOL_IP:
case VIR_NWFILTER_RULE_PROTOCOL_MAC:
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
+ case VIR_NWFILTER_RULE_PROTOCOL_RARP:
case VIR_NWFILTER_RULE_PROTOCOL_NONE:
case VIR_NWFILTER_RULE_PROTOCOL_IPV6:
@@ -2427,7 +2450,7 @@ static int
ebtablesCreateTmpSubChain(virBufferPtr buf,
int incoming,
const char *ifname,
- const char *protocol,
+ enum l3_proto_idx protoidx,
int stopOnError)
{
char rootchain[MAX_CHAINNAME_LENGTH], chain[MAX_CHAINNAME_LENGTH];
@@ -2435,13 +2458,13 @@ ebtablesCreateTmpSubChain(virBufferPtr buf,
: CHAINPREFIX_HOST_OUT_TEMP;
PRINT_ROOT_CHAIN(rootchain, chainPrefix, ifname);
- PRINT_CHAIN(chain, chainPrefix, ifname, protocol);
+ PRINT_CHAIN(chain, chainPrefix, ifname, l3_protocols[protoidx].val);
virBufferVSprintf(buf,
CMD_DEF("%s -t %s -N %s") CMD_SEPARATOR
CMD_EXEC
"%s"
- CMD_DEF("%s -t %s -A %s -p %s -j %s") CMD_SEPARATOR
+ CMD_DEF("%s -t %s -A %s -p 0x%x -j %s") CMD_SEPARATOR
CMD_EXEC
"%s",
@@ -2450,7 +2473,7 @@ ebtablesCreateTmpSubChain(virBufferPtr buf,
CMD_STOPONERR(stopOnError),
ebtables_cmd_path, EBTABLES_DEFAULT_TABLE,
- rootchain, protocol, chain,
+ rootchain, l3_protocols[protoidx].attr, chain,
CMD_STOPONERR(stopOnError));
@@ -2462,11 +2485,12 @@ static int
_ebtablesRemoveSubChain(virBufferPtr buf,
int incoming,
const char *ifname,
- const char *protocol,
+ enum l3_proto_idx protoidx,
int isTempChain)
{
char rootchain[MAX_CHAINNAME_LENGTH], chain[MAX_CHAINNAME_LENGTH];
char chainPrefix;
+
if (isTempChain) {
chainPrefix =(incoming) ? CHAINPREFIX_HOST_IN_TEMP
: CHAINPREFIX_HOST_OUT_TEMP;
@@ -2476,14 +2500,14 @@ _ebtablesRemoveSubChain(virBufferPtr buf,
}
PRINT_ROOT_CHAIN(rootchain, chainPrefix, ifname);
- PRINT_CHAIN(chain, chainPrefix, ifname, protocol);
+ PRINT_CHAIN(chain, chainPrefix, ifname, l3_protocols[protoidx].val);
virBufferVSprintf(buf,
- "%s -t %s -D %s -p %s -j %s" CMD_SEPARATOR
+ "%s -t %s -D %s -p 0x%x -j %s" CMD_SEPARATOR
"%s -t %s -F %s" CMD_SEPARATOR
"%s -t %s -X %s" CMD_SEPARATOR,
ebtables_cmd_path, EBTABLES_DEFAULT_TABLE,
- rootchain, protocol, chain,
+ rootchain, l3_protocols[protoidx].attr, chain,
ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain,
@@ -2497,10 +2521,10 @@ static int
ebtablesRemoveSubChain(virBufferPtr buf,
int incoming,
const char *ifname,
- const char *protocol)
+ enum l3_proto_idx protoidx)
{
return _ebtablesRemoveSubChain(buf,
- incoming, ifname, protocol, 0);
+ incoming, ifname, protoidx, 0);
}
@@ -2508,10 +2532,11 @@ static int
ebtablesRemoveSubChains(virBufferPtr buf,
const char *ifname)
{
- int i;
- for (i = 0; supported_protocols[i]; i++) {
- ebtablesRemoveSubChain(buf, 1, ifname, supported_protocols[i]);
- ebtablesRemoveSubChain(buf, 0, ifname, supported_protocols[i]);
+ enum l3_proto_idx i;
+
+ for (i = 0; i < L3_PROTO_LAST_IDX; i++) {
+ ebtablesRemoveSubChain(buf, 1, ifname, i);
+ ebtablesRemoveSubChain(buf, 0, ifname, i);
}
return 0;
@@ -2522,10 +2547,10 @@ static int
ebtablesRemoveTmpSubChain(virBufferPtr buf,
int incoming,
const char *ifname,
- const char *protocol)
+ enum l3_proto_idx protoidx)
{
return _ebtablesRemoveSubChain(buf,
- incoming, ifname, protocol, 1);
+ incoming, ifname, protoidx, 1);
}
@@ -2533,12 +2558,11 @@ static int
ebtablesRemoveTmpSubChains(virBufferPtr buf,
const char *ifname)
{
- int i;
- for (i = 0; supported_protocols[i]; i++) {
- ebtablesRemoveTmpSubChain(buf, 1, ifname,
- supported_protocols[i]);
- ebtablesRemoveTmpSubChain(buf, 0, ifname,
- supported_protocols[i]);
+ enum l3_proto_idx i;
+
+ for (i = 0; i < L3_PROTO_LAST_IDX; i++) {
+ ebtablesRemoveTmpSubChain(buf, 1, ifname, i);
+ ebtablesRemoveTmpSubChain(buf, 0, ifname, i);
}
return 0;
@@ -2576,12 +2600,11 @@ static int
ebtablesRenameTmpSubChains(virBufferPtr buf,
const char *ifname)
{
- int i;
- for (i = 0; supported_protocols[i]; i++) {
- ebtablesRenameTmpSubChain (buf, 1, ifname,
- supported_protocols[i]);
- ebtablesRenameTmpSubChain (buf, 0, ifname,
- supported_protocols[i]);
+ enum l3_proto_idx i;
+
+ for (i = 0; i < L3_PROTO_LAST_IDX; i++) {
+ ebtablesRenameTmpSubChain (buf, 1, ifname, l3_protocols[i].val);
+ ebtablesRenameTmpSubChain (buf, 0, ifname, l3_protocols[i].val);
}
return 0;
@@ -2911,20 +2934,24 @@ ebiptablesApplyNewRules(virConnectPtr conn ATTRIBUTE_UNUSED,
ebtablesCreateTmpRootChain(&buf, 0, ifname, 1);
if (chains_in & (1 << VIR_NWFILTER_CHAINSUFFIX_IPv4))
- ebtablesCreateTmpSubChain(&buf, 1, ifname, "ipv4", 1);
+ ebtablesCreateTmpSubChain(&buf, 1, ifname, L3_PROTO_IPV4_IDX, 1);
if (chains_out & (1 << VIR_NWFILTER_CHAINSUFFIX_IPv4))
- ebtablesCreateTmpSubChain(&buf, 0, ifname, "ipv4", 1);
+ ebtablesCreateTmpSubChain(&buf, 0, ifname, L3_PROTO_IPV4_IDX, 1);
if (chains_in & (1 << VIR_NWFILTER_CHAINSUFFIX_IPv6))
- ebtablesCreateTmpSubChain(&buf, 1, ifname, "ipv6", 1);
+ ebtablesCreateTmpSubChain(&buf, 1, ifname, L3_PROTO_IPV6_IDX, 1);
if (chains_out & (1 << VIR_NWFILTER_CHAINSUFFIX_IPv6))
- ebtablesCreateTmpSubChain(&buf, 0, ifname, "ipv6", 1);
+ ebtablesCreateTmpSubChain(&buf, 0, ifname, L3_PROTO_IPV6_IDX, 1);
- // keep arp as last
+ // keep arp,rarp as last
if (chains_in & (1 << VIR_NWFILTER_CHAINSUFFIX_ARP))
- ebtablesCreateTmpSubChain(&buf, 1, ifname, "arp", 1);
+ ebtablesCreateTmpSubChain(&buf, 1, ifname, L3_PROTO_ARP_IDX, 1);
if (chains_out & (1 << VIR_NWFILTER_CHAINSUFFIX_ARP))
- ebtablesCreateTmpSubChain(&buf, 0, ifname, "arp", 1);
+ ebtablesCreateTmpSubChain(&buf, 0, ifname, L3_PROTO_ARP_IDX, 1);
+ if (chains_in & (1 << VIR_NWFILTER_CHAINSUFFIX_RARP))
+ ebtablesCreateTmpSubChain(&buf, 1, ifname, L3_PROTO_RARP_IDX, 1);
+ if (chains_out & (1 << VIR_NWFILTER_CHAINSUFFIX_RARP))
+ ebtablesCreateTmpSubChain(&buf, 0, ifname, L3_PROTO_RARP_IDX, 1);
if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0)
goto tear_down_tmpebchains;
diff --git a/tests/nwfilterxml2xmlin/rarp-test.xml b/tests/nwfilterxml2xmlin/rarp-test.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e08722204f439011f02552cf1d3522afedb9904b
--- /dev/null
+++ b/tests/nwfilterxml2xmlin/rarp-test.xml
@@ -0,0 +1,33 @@
+
+ 5c6d49af-b071-6127-b4ec-6f8ed4b55335
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/nwfilterxml2xmlout/rarp-test.xml b/tests/nwfilterxml2xmlout/rarp-test.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3d3d98f77585e5e921622bd8ea3e92a6049550ba
--- /dev/null
+++ b/tests/nwfilterxml2xmlout/rarp-test.xml
@@ -0,0 +1,18 @@
+
+ 5c6d49af-b071-6127-b4ec-6f8ed4b55335
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/nwfilterxml2xmltest.c b/tests/nwfilterxml2xmltest.c
index 1ce3e29b3a87952bd2856c5d30ea1f545e2c42e6..e681b919efc4dde416c5bfab84459c878c0d191f 100644
--- a/tests/nwfilterxml2xmltest.c
+++ b/tests/nwfilterxml2xmltest.c
@@ -90,6 +90,7 @@ mymain(int argc, char **argv)
DO_TEST("mac-test");
DO_TEST("arp-test");
+ DO_TEST("rarp-test");
DO_TEST("ip-test");
DO_TEST("ipv6-test");