diff options
-rw-r--r-- | docs/formatnwfilter.html.in | 6 | ||||
-rw-r--r-- | docs/schemas/nwfilter.rng | 16 | ||||
-rw-r--r-- | examples/xml/nwfilter/no-arp-spoofing.xml | 6 | ||||
-rw-r--r-- | src/conf/nwfilter_conf.c | 23 | ||||
-rw-r--r-- | src/conf/nwfilter_conf.h | 5 | ||||
-rw-r--r-- | src/nwfilter/nwfilter_ebiptables_driver.c | 7 | ||||
-rw-r--r-- | tests/nwfilterxml2xmlin/arp-test.xml | 4 | ||||
-rw-r--r-- | 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 ecb6b62c0..8df4a9304 100644 --- a/docs/formatnwfilter.html.in +++ b/docs/formatnwfilter.html.in @@ -321,6 +321,7 @@ <li>IPV6_ADDR: IPv6 address in numbers format, i.e., FFFF::1</li> <li>IPV6_MASK: IPv6 mask in numbers format (FFFF:FFFF:FC00::) or CIDR mask (0-128)</li> <li>STRING: A string</li> + <li>BOOLEAN: 'true', 'yes', '1' or 'false', 'no', '0'</li> </ul> <p> <br/><br/> @@ -476,6 +477,11 @@ <td>STRING</td> <td>text with max. 256 characters</td> </tr> + <tr> + <td>gratuitous <span class="since">(Since 0.9.2)</span></td> + <td>BOOLEAN</td> + <td>boolean indicating whether to check for gratuitous ARP packet</td> + </tr> </table> <p> Valid strings for the <code>Opcode</code> field are: diff --git a/docs/schemas/nwfilter.rng b/docs/schemas/nwfilter.rng index 662485e23..bc473919c 100644 --- a/docs/schemas/nwfilter.rng +++ b/docs/schemas/nwfilter.rng @@ -581,6 +581,11 @@ <ref name="uint16range"/> </attribute> </optional> + <optional> + <attribute name="gratuitous"> + <ref name="boolean"/> + </attribute> + </optional> </interleave> </define> @@ -784,6 +789,17 @@ </choice> </define> + <define name="boolean"> + <choice> + <value>yes</value> + <value>no</value> + <value>true</value> + <value>false</value> + <value>1</value> + <value>0</value> + </choice> + </define> + <define name="arpOpcodeType"> <choice> <!-- variable --> diff --git a/examples/xml/nwfilter/no-arp-spoofing.xml b/examples/xml/nwfilter/no-arp-spoofing.xml index c6c858dad..96c58c153 100644 --- a/examples/xml/nwfilter/no-arp-spoofing.xml +++ b/examples/xml/nwfilter/no-arp-spoofing.xml @@ -12,7 +12,11 @@ <rule action='drop' direction='out' priority='400' > <arp match='no' arpsrcipaddr='$IP' /> </rule> - <!-- drop if ipaddr or macaddr odes not belong to guest --> + <!-- allow gratuitous arp --> + <rule action='accept' direction='in' priority='425'> + <arp gratuitous='true'/> + </rule> + <!-- drop if ipaddr or macaddr does not belong to guest --> <rule action='drop' direction='in' priority='450' > <arp match='no' arpdstmacaddr='$MAC'/> <arp opcode='reply'/> diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index a32bdb3ad..3f69c1d9a 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 12e2a5c38..5306403a7 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 2ff392d18..e33d9a187 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 d4484dcb2..e9d376836 100644 --- a/tests/nwfilterxml2xmlin/arp-test.xml +++ b/tests/nwfilterxml2xmlin/arp-test.xml @@ -30,4 +30,8 @@ <arp srcmacaddr='1:2:3:4:5:6' srcmacmask='ff:ff:ff:ff:ff:ff' opcode='65536' hwtype='65536' protocoltype='65536' /> </rule> + + <rule action='accept' direction='in'> + <arp gratuitous='true'/> + </rule> </filter> diff --git a/tests/nwfilterxml2xmlout/arp-test.xml b/tests/nwfilterxml2xmlout/arp-test.xml index 2ce46aed3..856b4ca2a 100644 --- a/tests/nwfilterxml2xmlout/arp-test.xml +++ b/tests/nwfilterxml2xmlout/arp-test.xml @@ -15,4 +15,7 @@ <rule action='accept' direction='out' priority='500'> <arp srcmacaddr='01:02:03:04:05:06' srcmacmask='ff:ff:ff:ff:ff:ff'/> </rule> + <rule action='accept' direction='in' priority='500'> + <arp gratuitous='true'/> + </rule> </filter> |