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

Re: [libvirt] [PATCH V3] nwfilter: Add support for ipset



On 05/14/2012 06:20 PM, Eric Blake wrote:
On 04/23/2012 06:00 AM, Stefan Berger wrote:
This patch adds support for the recent ipset iptables extension
to libvirt's nwfilter subsystem. Ipset allows to maintain 'sets'
of IP addresses, ports and other packet parameters and allows for
faster lookup (in the order of O(1) vs. O(n)) and rule evaluation
to achieve higher throughput than what can be achieved with
individual iptables rules.

On the command line iptables supports ipset using

iptables ... -m set --match-set<ipset name>  <flags>  -j ...
How will this interact with firewalld in Fedora 17?  But adding things
incrementally is okay by me, so I'll still review this.

Firewalld's firewall-cmd has a passthrough mode where the command line for iptables referencing an ipset would just be written like this:

firewall-cmd --direct --passthrough ipv4 ... -m set --match-set <ipset name> <flagse> -j ...

So this is not the real problem. Unfortunately using firewall-cmd makes everything much slower, i.e., the TCK testsuite runs probably at least 8 times slower and starting a VM referencing a filter also takes considerably longer to start. So the solution may be to either find an intermediate format for creating the commands by the ebiptables driver so the 'scripts' can be converted to either bash or direct Dbus execution or, as I have done, to parse today's generated scripts and convert them to DBus commands. This works fine so far as long as one doesn't encounter comments, which we have assign to a variable (comment), and has its own challenges to parse. The speedup for the TCK testsuite was so far maybe 40% with scripts containing comments or the 'other' embedded scripts containing loops left to running them using firewall-cmd. Any comments on this? The code so far parsing the script doesn't look 'too bad'...


+# define VALID_IPSETNAME \
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.:-+ "
Brave to allow a space; are we sure it will always be properly shell-quoted?

Yes, I payed attention. ;-)


@@ -346,6 +349,44 @@ _printDataType(virNWFilterVarCombIterPtr
          }
      break;

+    case DATATYPE_IPSETNAME:
+        snprintf(buf, bufsize, "%s", item->u.ipset.setname);
Are we sure that it is safe to ignore the return value of snprintf here?
  And a format of "%s" is generally an indication that you should really
be using virStrncpy instead.

Right, converting it.


@@ -927,6 +975,7 @@ iptablesHandleIpHdr(virBufferPtr buf,
      char ipaddr[INET6_ADDRSTRLEN],
           number[MAX(INT_BUFSIZE_BOUND(uint32_t),
                      INT_BUFSIZE_BOUND(int))];
+    char str[200];
Why 200?  A comment, or even a composition of #define'd macros, instead
of a magic number, would make me feel better.

Introducing MAX_IPSET_NAME_LENGTH.


@@ -1060,4 +1068,19 @@
        <param name="pattern">((SYN|ACK|URG|PSH|FIN|RST)(,(SYN|ACK|URG|PSH|FIN|RST))*|ALL|NONE)/((SYN|ACK|URG|PSH|FIN|RST)(,(SYN|ACK|URG|PSH|FIN|RST))*|ALL|NONE)</param>
      </data>
    </define>
+
+<define name='ipset-type'>
+<choice>
+<ref name="variable-name-type"/>
+<data type="string">
+<param name="pattern">[a-zA-Z0-9_\.:\-\+]{1,31}</param>
Hmm, no space in this pattern; it doesn't match your VALID_IPSETNAME
#define above.

Ooops, I will add it.


Index: libvirt-acl/docs/formatnwfilter.html.in
===================================================================
--- libvirt-acl.orig/docs/formatnwfilter.html.in
+++ libvirt-acl/docs/formatnwfilter.html.in
@@ -528,6 +528,10 @@
       <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>
+<li>IPSETFLAGS: The source and destination flags of the ipset described
+         by up to 6 'src' or 'dst' elements selecting features from either
+         the source or destination part of the packet header; example:
+         src,src,dst</li>
Do we have a mapping of _which_ elements are selected?  If I say
'src,dst', is it always the first two elements of a packet header (and
which two elements are they), or does the choice of which two elements
depend on other context?

It depends on the type of ipset that is referenced by a rule, i.e., the ipset hash:ip,port would allow to select IP address and port in the source or destination part of the packet independently, while the ipset hash:ip,port,ip would allow IP address to be selected in the source and/or destination part and the port in the sort or destination part.



      </ul>
      <p>
       <br/><br/>
@@ -1169,6 +1173,16 @@
           <td>STRING</td>
           <td>TCP-only: format of mask/flags with mask and flags each being a comma separated list of SYN,ACK,URG,PSH,FIN,RST or NONE or ALL</td>
         </tr>
+<tr>
+<td>ipset<span class="since">(Since 0.9.12)</span></td>
0.9.13, now.

Yes, will replace.

+<tr>
+<td>ipsetflags<span class="since">(Since 0.9.12)</span></td>
+<td>IPSETFLAGS</td>
+<td>flags for the IPSet; requires ipset attributed</td>
I think you meant:
s/attributed/attribute/
(several instances)

Overall, the patch seems reasonable (sorry for delaying the review until
after 0.9.12).  But I do think it's worth a v4 to rebase to latest and
fix the nits above.

Thanks for the review. I will post v4 shortly.

   Stefan


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