From fcb0e8c2275f108b595f37defbe3c6de5bfc849e Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Mon, 23 May 2011 19:41:18 -0400 Subject: [PATCH] nwfilter: enable filtering of gratuitous ARP packets This patch enables filtering of gratuitous ARP packets using the following XML: --- docs/formatnwfilter.html.in | 6 ++++++ docs/schemas/nwfilter.rng | 16 ++++++++++++++++ examples/xml/nwfilter/no-arp-spoofing.xml | 6 +++++- src/conf/nwfilter_conf.c | 23 +++++++++++++++++++++++ src/conf/nwfilter_conf.h | 5 ++++- src/nwfilter/nwfilter_ebiptables_driver.c | 7 +++++++ tests/nwfilterxml2xmlin/arp-test.xml | 4 ++++ tests/nwfilterxml2xmlout/arp-test.xml | 3 +++ 8 files changed, 68 insertions(+), 2 deletions(-) diff --git a/docs/formatnwfilter.html.in b/docs/formatnwfilter.html.in index ecb6b62c04..8df4a93040 100644 --- a/docs/formatnwfilter.html.in +++ b/docs/formatnwfilter.html.in @@ -321,6 +321,7 @@
  • IPV6_ADDR: IPv6 address in numbers format, i.e., FFFF::1
  • IPV6_MASK: IPv6 mask in numbers format (FFFF:FFFF:FC00::) or CIDR mask (0-128)
  • STRING: A string
  • +
  • BOOLEAN: 'true', 'yes', '1' or 'false', 'no', '0'


  • @@ -476,6 +477,11 @@ STRING text with max. 256 characters + + gratuitous (Since 0.9.2) + BOOLEAN + boolean indicating whether to check for gratuitous ARP packet +

    Valid strings for the Opcode field are: diff --git a/docs/schemas/nwfilter.rng b/docs/schemas/nwfilter.rng index 662485e239..bc473919c4 100644 --- a/docs/schemas/nwfilter.rng +++ b/docs/schemas/nwfilter.rng @@ -581,6 +581,11 @@ + + + + + @@ -784,6 +789,17 @@ + + + yes + no + true + false + 1 + 0 + + + diff --git a/examples/xml/nwfilter/no-arp-spoofing.xml b/examples/xml/nwfilter/no-arp-spoofing.xml index c6c858dad0..96c58c153b 100644 --- a/examples/xml/nwfilter/no-arp-spoofing.xml +++ b/examples/xml/nwfilter/no-arp-spoofing.xml @@ -12,7 +12,11 @@ - + + + + + diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index a32bdb3adb..3f69c1d9a7 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -970,6 +970,10 @@ static const virXMLAttr2Struct arpAttributes[] = { .name = ARPDSTIPADDR, .datatype = DATATYPE_IPADDR, .dataIdx = offsetof(virNWFilterRuleDef, p.arpHdrFilter.dataARPDstIPAddr), + }, { + .name = "gratuitous", + .datatype = DATATYPE_BOOLEAN, + .dataIdx = offsetof(virNWFilterRuleDef, p.arpHdrFilter.dataGratuitousARP), }, COMMENT_PROP(arpHdrFilter), { @@ -1611,6 +1615,18 @@ virNWFilterRuleDetailsParse(xmlNodePtr node, found = 1; break; + case DATATYPE_BOOLEAN: + if (STREQ(prop, "true") || + STREQ(prop, "1") || + STREQ(prop, "yes")) + item->u.boolean = true; + else + item->u.boolean = false; + + data.ui = item->u.boolean; + found = 1; + break; + case DATATYPE_LAST: default: break; @@ -2744,6 +2760,13 @@ virNWFilterRuleDefDetailsFormat(virBufferPtr buf, virBufferEscapeString(buf, "%s", item->u.string); break; + case DATATYPE_BOOLEAN: + if (item->u.boolean == true) + virBufferAddLit(buf, "true"); + else + virBufferAddLit(buf, "false"); + break; + case DATATYPE_STRING: default: virBufferAsprintf(buf, diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index 12e2a5c388..5306403a78 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -97,8 +97,9 @@ enum attrDatatype { DATATYPE_IPV6ADDR = (1 << 9), DATATYPE_IPV6MASK = (1 << 10), DATATYPE_STRINGCOPY = (1 << 11), + DATATYPE_BOOLEAN = (1 << 12), - DATATYPE_LAST = (1 << 12), + DATATYPE_LAST = (1 << 13), }; @@ -118,6 +119,7 @@ struct _nwItemDesc { union { nwMACAddress macaddr; virSocketAddr ipaddr; + bool boolean; uint8_t u8; uint16_t u16; char protocolID[10]; @@ -160,6 +162,7 @@ struct _arpHdrFilterDef { nwItemDesc dataARPSrcIPAddr; nwItemDesc dataARPDstMACAddr; nwItemDesc dataARPDstIPAddr; + nwItemDesc dataGratuitousARP; nwItemDesc dataComment; }; diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index 2ff392d187..e33d9a187c 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -2033,6 +2033,13 @@ ebtablesCreateRuleInstance(char chainPrefix, ENTRY_GET_NEG_SIGN(&rule->p.arpHdrFilter.dataARPDstMACAddr), macaddr); } + + if (HAS_ENTRY_ITEM(&rule->p.arpHdrFilter.dataGratuitousARP) && + rule->p.arpHdrFilter.dataGratuitousARP.u.boolean) { + virBufferAsprintf(&buf, + " %s --arp-gratuitous", + ENTRY_GET_NEG_SIGN(&rule->p.arpHdrFilter.dataGratuitousARP)); + } break; case VIR_NWFILTER_RULE_PROTOCOL_IP: diff --git a/tests/nwfilterxml2xmlin/arp-test.xml b/tests/nwfilterxml2xmlin/arp-test.xml index d4484dcb2d..e9d3768361 100644 --- a/tests/nwfilterxml2xmlin/arp-test.xml +++ b/tests/nwfilterxml2xmlin/arp-test.xml @@ -30,4 +30,8 @@ + + + + diff --git a/tests/nwfilterxml2xmlout/arp-test.xml b/tests/nwfilterxml2xmlout/arp-test.xml index 2ce46aed3b..856b4ca2af 100644 --- a/tests/nwfilterxml2xmlout/arp-test.xml +++ b/tests/nwfilterxml2xmlout/arp-test.xml @@ -15,4 +15,7 @@ + + +