]> xenbits.xensource.com Git - libvirt.git/commitdiff
nwfilter: enable filtering of gratuitous ARP packets
authorStefan Berger <stefanb@us.ibm.com>
Mon, 23 May 2011 23:41:18 +0000 (19:41 -0400)
committerStefan Berger <stefanb@us.ibm.com>
Mon, 23 May 2011 23:41:18 +0000 (19:41 -0400)
This patch enables filtering of gratuitous ARP packets using the following XML:

<rule action='accept' direction='in' priority='425'>
<arp gratuitous='true'/>
</rule>

docs/formatnwfilter.html.in
docs/schemas/nwfilter.rng
examples/xml/nwfilter/no-arp-spoofing.xml
src/conf/nwfilter_conf.c
src/conf/nwfilter_conf.h
src/nwfilter/nwfilter_ebiptables_driver.c
tests/nwfilterxml2xmlin/arp-test.xml
tests/nwfilterxml2xmlout/arp-test.xml

index ecb6b62c04bf91317387b0cfecd2cdae08d47e2c..8df4a930406b42bf4a92cf041e12df3251a71d18 100644 (file)
      <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/>
          <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:
index 662485e2391fef4521b38a95a8af49757e160c0e..bc473919c4ff09688498ce6d764f2fb3c2a8fa02 100644 (file)
           <ref name="uint16range"/>
         </attribute>
       </optional>
+      <optional>
+        <attribute name="gratuitous">
+          <ref name="boolean"/>
+        </attribute>
+      </optional>
    </interleave>
   </define>
 
     </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 -->
index c6c858dad08a25b783cafb24b1a7797f6a7efacb..96c58c153b5a30139e3b1dfc2788e2a9ed0d2cb8 100644 (file)
    <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'/>
index a32bdb3adb3474534fa5980d010af2b665bdc502..3f69c1d9a70d65eb1965339175475bef691405f9 100644 (file)
@@ -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,
index 12e2a5c3881d3f6c18a2938802b92300b04c834c..5306403a78118cc4cac87dc72b965aee7884048b 100644 (file)
@@ -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;
 };
 
index 2ff392d187f485a3e8fbbffef52a96f55972242b..e33d9a187cf3d25191bf7a23a72f2179da51d607 100644 (file)
@@ -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:
index d4484dcb2d47848c6099a6a8f4614afc9acf85ae..e9d376836100ea1239fbeb0aa9617c090bf50522 100644 (file)
@@ -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>
index 2ce46aed3b1ec88b5956d0a8828c089a851df24f..856b4ca2af00abb766d3d599d7d95ad1ecdc855e 100644 (file)
@@ -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>