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");