[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH V2 07/10] Enable chains with names having a known prefix



This patch enables chains that have a known prefix in their name.
Known prefixes are: 'ipv4', 'ipv6', 'arp', 'rarp'. All prefixes
are also protocols that can be evaluated on the ebtables level.

Following the prefix they will be automatically connected to an interface's
'root' chain and jumped into following the protocol they evalute, i.e.,
a table 'arp-xyz' will be accessed from the root table using

ebtables -t nat -A <iface root table> -p arp -j I-<ifname>-arp-xyz

thus generating a 'root' chain like this one here:

Bridge chain: libvirt-O-vnet0, entries: 5, policy: ACCEPT
-p IPv4 -j O-vnet0-ipv4
-p ARP -j O-vnet0-arp
-p 0x8035 -j O-vnet0-rarp
-p ARP -j O-vnet0-arp-xyz
-j DROP 

where the chain 'arp-xyz' is accessed for filtering of ARP packets.

Signed-off-by: Stefan Berger <stefanb linux vnet ibm com>

---
 docs/schemas/nwfilter.rng |   16 ++++++---
 src/conf/nwfilter_conf.c  |   79 +++++++++++++++++++++++++++++++++++++++++++---
 src/conf/nwfilter_conf.h  |    3 +
 3 files changed, 90 insertions(+), 8 deletions(-)

Index: libvirt-acl/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.c
+++ libvirt-acl/src/conf/nwfilter_conf.c
@@ -2005,6 +2005,80 @@ err_exit:
     goto cleanup;
 }
 
+static bool
+virNWFilterIsValidChainName(const char *chainname)
+{
+    return chainname[strspn(chainname, VALID_CHAINNAME)] == 0;
+}
+
+/*
+ * Test whether the name of the chain is supported.
+ * It current has to have a prefix of either one of the strings found in
+ * virNWFilterChainSuffixTypeToString().
+ */
+static bool
+virNWFilterIsAllowedChain(const char *chainname)
+{
+    enum virNWFilterChainSuffixType i;
+    const char *name, *msg;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    bool printed = false;
+
+    if (!virNWFilterIsValidChainName(chainname)) {
+        virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("Chain name contains illegal characters"));
+        return false;
+    }
+
+    if (strlen(chainname) > MAX_CHAIN_SUFFIX_SIZE) {
+        virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("name of chain is longer than %u characters"),
+                               MAX_CHAIN_SUFFIX_SIZE);
+        return false;
+    }
+
+    for (i = 0; i < VIR_NWFILTER_CHAINSUFFIX_LAST; i++) {
+        name = virNWFilterChainSuffixTypeToString(i);
+        if (i == VIR_NWFILTER_CHAINSUFFIX_ROOT) {
+            /* allow 'root' as a complete name but not as a prefix */
+            if (STREQ(chainname, name))
+                return true;
+            if (STRPREFIX(chainname, name))
+                return false;
+        }
+        if (STRPREFIX(chainname, name))
+            return true;
+    }
+
+    virBufferAsprintf(&buf,
+                      _("Illegal chain name '%s'. Please use a chain name "
+                      "called '%s' or either one of the following prefixes: "),
+                      virNWFilterChainSuffixTypeToString(
+                          VIR_NWFILTER_CHAINSUFFIX_ROOT),
+                      chainname);
+    for (i = 0; i < VIR_NWFILTER_CHAINSUFFIX_LAST; i++) {
+        if (i == VIR_NWFILTER_CHAINSUFFIX_ROOT)
+            continue;
+        if (printed)
+            virBufferAddLit(&buf, ", ");
+        virBufferAdd(&buf, virNWFilterChainSuffixTypeToString(i), -1);
+        printed = true;
+    }
+
+    if (virBufferError(&buf)) {
+        virReportOOMError();
+        virBufferFreeAndReset(&buf);
+        goto err_exit;
+    }
+
+    msg = virBufferContentAndReset(&buf);
+
+    virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, _("%s"), msg);
+    VIR_FREE(msg);
+
+err_exit:
+    return false;
+}
 
 static virNWFilterDefPtr
 virNWFilterDefParseXML(xmlXPathContextPtr ctxt) {
@@ -2050,11 +2124,8 @@ virNWFilterDefParseXML(xmlXPathContextPt
 
     chain = virXPathString("string(./@chain)", ctxt);
     if (chain) {
-        if (virNWFilterChainSuffixTypeFromString(chain) < 0) {
-            virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
-                                   _("unknown chain suffix '%s'"), chain);
+        if (virNWFilterIsAllowedChain(chain) != true)
             goto cleanup;
-        }
         ret->chainsuffix = chain;
 
         if (chain_pri_s) {
Index: libvirt-acl/src/conf/nwfilter_conf.h
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.h
+++ libvirt-acl/src/conf/nwfilter_conf.h
@@ -444,6 +444,9 @@ enum virNWFilterChainSuffixType {
     VIR_NWFILTER_CHAINSUFFIX_LAST,
 };
 
+# define VALID_CHAINNAME \
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.:-"
+
 typedef int32_t virNWFilterChainPriority;
 
 typedef struct _virNWFilterDef virNWFilterDef;
Index: libvirt-acl/docs/schemas/nwfilter.rng
===================================================================
--- libvirt-acl.orig/docs/schemas/nwfilter.rng
+++ libvirt-acl/docs/schemas/nwfilter.rng
@@ -286,10 +286,18 @@
       <attribute name="chain">
         <choice>
           <value>root</value>
-          <value>arp</value>
-          <value>rarp</value>
-          <value>ipv4</value>
-          <value>ipv6</value>
+          <data type="string">
+            <param name="pattern">arp[a-zA-Z0-9_\.:-]*</param>
+          </data>
+          <data type="string">
+            <param name="pattern">rarp[a-zA-Z0-9_\.:-]*</param>
+          </data>
+          <data type="string">
+            <param name="pattern">ipv4[a-zA-Z0-9_\.:-]*</param>
+          </data>
+          <data type="string">
+            <param name="pattern">ipv6[a-zA-Z0-9_\.:-]*</param>
+          </data>
         </choice>
       </attribute>
     </optional>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]