]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Add wrap_name param to the iptables_manager class
authorSylvain Afchain <sylvain.afchain@enovance.com>
Wed, 26 Jun 2013 08:18:38 +0000 (10:18 +0200)
committerSylvain Afchain <sylvain.afchain@enovance.com>
Mon, 12 Aug 2013 11:11:24 +0000 (13:11 +0200)
Use this optional parameter instead
of binary_name to wrap the chain names.

Fixes: bug #1194049
Change-Id: I69b4d9043769703248e19184eaedbdbf7a43d96e

neutron/agent/linux/iptables_manager.py
neutron/tests/unit/test_iptables_manager.py

index acd669d59dbdace58175e246e8cf5c5e8dfbded2..50fb79d4a73bc5001a08dd8fc951c202d83b0c19 100644 (file)
@@ -62,11 +62,13 @@ class IptablesRule(object):
 
     """
 
-    def __init__(self, chain, rule, wrap=True, top=False):
+    def __init__(self, chain, rule, wrap=True, top=False,
+                 binary_name=binary_name):
         self.chain = get_chain_name(chain, wrap)
         self.rule = rule
         self.wrap = wrap
         self.top = top
+        self.wrap_name = binary_name[:16]
 
     def __eq__(self, other):
         return ((self.chain == other.chain) and
@@ -79,7 +81,7 @@ class IptablesRule(object):
 
     def __str__(self):
         if self.wrap:
-            chain = '%s-%s' % (binary_name, self.chain)
+            chain = '%s-%s' % (self.wrap_name, self.chain)
         else:
             chain = self.chain
         return '-A %s %s' % (chain, self.rule)
@@ -88,12 +90,13 @@ class IptablesRule(object):
 class IptablesTable(object):
     """An iptables table."""
 
-    def __init__(self):
+    def __init__(self, binary_name=binary_name):
         self.rules = []
         self.remove_rules = []
         self.chains = set()
         self.unwrapped_chains = set()
         self.remove_chains = set()
+        self.wrap_name = binary_name[:16]
 
     def add_chain(self, name, wrap=True):
         """Adds a named chain to the table.
@@ -168,7 +171,7 @@ class IptablesTable(object):
             self.remove_rules += [r for r in self.rules
                                   if jump_snippet in r.rule]
         else:
-            jump_snippet = '-j %s-%s' % (binary_name, name)
+            jump_snippet = '-j %s-%s' % (self.wrap_name, name)
 
         # finally, remove rules from list that have a matching jump chain
         self.rules = [r for r in self.rules
@@ -192,11 +195,11 @@ class IptablesTable(object):
         if '$' in rule:
             rule = ' '.join(map(self._wrap_target_chain, rule.split(' ')))
 
-        self.rules.append(IptablesRule(chain, rule, wrap, top))
+        self.rules.append(IptablesRule(chain, rule, wrap, top, self.wrap_name))
 
     def _wrap_target_chain(self, s):
         if s.startswith('$'):
-            return ('%s-%s' % (binary_name, s[1:]))
+            return ('%s-%s' % (self.wrap_name, s[1:]))
         return s
 
     def remove_rule(self, chain, rule, wrap=True, top=False):
@@ -209,9 +212,11 @@ class IptablesTable(object):
         """
         chain = get_chain_name(chain, wrap)
         try:
-            self.rules.remove(IptablesRule(chain, rule, wrap, top))
+            self.rules.remove(IptablesRule(chain, rule, wrap, top,
+                                           self.wrap_name))
             if not wrap:
-                self.remove_rules.append(IptablesRule(chain, rule, wrap, top))
+                self.remove_rules.append(IptablesRule(chain, rule, wrap, top,
+                                                      self.wrap_name))
         except ValueError:
             LOG.warn(_('Tried to remove rule that was not there:'
                        ' %(chain)r %(rule)r %(wrap)r %(top)r'),
@@ -251,7 +256,8 @@ class IptablesManager(object):
     """
 
     def __init__(self, _execute=None, state_less=False,
-                 root_helper=None, use_ipv6=False, namespace=None):
+                 root_helper=None, use_ipv6=False, namespace=None,
+                 binary_name=binary_name):
         if _execute:
             self.execute = _execute
         else:
@@ -261,9 +267,10 @@ class IptablesManager(object):
         self.root_helper = root_helper
         self.namespace = namespace
         self.iptables_apply_deferred = False
+        self.wrap_name = binary_name[:16]
 
-        self.ipv4 = {'filter': IptablesTable()}
-        self.ipv6 = {'filter': IptablesTable()}
+        self.ipv4 = {'filter': IptablesTable(binary_name=self.wrap_name)}
+        self.ipv6 = {'filter': IptablesTable(binary_name=self.wrap_name)}
 
         # Add a neutron-filter-top chain. It's intended to be shared
         # among the various nova components. It sits at the very top
@@ -284,7 +291,8 @@ class IptablesManager(object):
                           6: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']}}
 
         if not state_less:
-            self.ipv4.update({'nat': IptablesTable()})
+            self.ipv4.update(
+                {'nat': IptablesTable(binary_name=self.wrap_name)})
             builtin_chains[4].update({'nat': ['PREROUTING',
                                       'OUTPUT', 'POSTROUTING']})
 
@@ -298,7 +306,7 @@ class IptablesManager(object):
                 for chain in chains:
                     tables[table].add_chain(chain)
                     tables[table].add_rule(chain, '-j $%s' %
-                                          (chain), wrap=False)
+                                           (chain), wrap=False)
 
         if not state_less:
             # Add a neutron-postrouting-bottom chain. It's intended to be
@@ -412,13 +420,13 @@ class IptablesManager(object):
         # Fill new_filter with any chains or rules without our name in them.
         old_filter, new_filter = [], []
         for line in current_lines:
-            (old_filter if binary_name in line else
+            (old_filter if self.wrap_name in line else
              new_filter).append(line.strip())
 
         rules_index = self._find_rules_index(new_filter)
 
         all_chains = [':%s' % name for name in unwrapped_chains]
-        all_chains += [':%s-%s' % (binary_name, name) for name in chains]
+        all_chains += [':%s-%s' % (self.wrap_name, name) for name in chains]
 
         # Iterate through all the chains, trying to find an existing
         # match.
index 8fd64056334539e03611eaf9900bed7531d8d28b..9deaab570e28c44c924408759a17eb2212213232 100644 (file)
@@ -88,6 +88,182 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         self.assertEqual(iptables_manager.get_chain_name(name, wrap=True),
                          name[:11])
 
+    def test_add_and_remove_chain_custom_binary_name(self):
+        bn = ("abcdef" * 5)
+
+        self.iptables = (iptables_manager.
+                         IptablesManager(root_helper=self.root_helper,
+                                         binary_name=bn))
+        self.mox.StubOutWithMock(self.iptables, "execute")
+
+        self.iptables.execute(['iptables-save', '-c'],
+                              root_helper=self.root_helper).AndReturn('')
+
+        iptables_args = {'bn': bn[:16]}
+
+        filter_dump = ('# Generated by iptables_manager\n'
+                       '*filter\n'
+                       ':neutron-filter-top - [0:0]\n'
+                       ':%(bn)s-FORWARD - [0:0]\n'
+                       ':%(bn)s-INPUT - [0:0]\n'
+                       ':%(bn)s-local - [0:0]\n'
+                       ':%(bn)s-filter - [0:0]\n'
+                       ':%(bn)s-OUTPUT - [0:0]\n'
+                       '[0:0] -A FORWARD -j neutron-filter-top\n'
+                       '[0:0] -A OUTPUT -j neutron-filter-top\n'
+                       '[0:0] -A neutron-filter-top -j %(bn)s-local\n'
+                       '[0:0] -A INPUT -j %(bn)s-INPUT\n'
+                       '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
+                       '[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
+                       'COMMIT\n'
+                       '# Completed by iptables_manager\n' % iptables_args)
+
+        filter_dump_mod = ('# Generated by iptables_manager\n'
+                           '*filter\n'
+                           ':neutron-filter-top - [0:0]\n'
+                           ':%(bn)s-FORWARD - [0:0]\n'
+                           ':%(bn)s-INPUT - [0:0]\n'
+                           ':%(bn)s-local - [0:0]\n'
+                           ':%(bn)s-filter - [0:0]\n'
+                           ':%(bn)s-OUTPUT - [0:0]\n'
+                           '[0:0] -A FORWARD -j neutron-filter-top\n'
+                           '[0:0] -A OUTPUT -j neutron-filter-top\n'
+                           '[0:0] -A neutron-filter-top -j %(bn)s-local\n'
+                           '[0:0] -A INPUT -j %(bn)s-INPUT\n'
+                           '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
+                           '[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
+                           'COMMIT\n'
+                           '# Completed by iptables_manager\n'
+                           % iptables_args)
+
+        nat_dump = ('# Generated by iptables_manager\n'
+                    '*nat\n'
+                    ':neutron-postrouting-bottom - [0:0]\n'
+                    ':%(bn)s-OUTPUT - [0:0]\n'
+                    ':%(bn)s-snat - [0:0]\n'
+                    ':%(bn)s-PREROUTING - [0:0]\n'
+                    ':%(bn)s-float-snat - [0:0]\n'
+                    ':%(bn)s-POSTROUTING - [0:0]\n'
+                    '[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n'
+                    '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
+                    '[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n'
+                    '[0:0] -A POSTROUTING -j neutron-postrouting-bottom\n'
+                    '[0:0] -A neutron-postrouting-bottom -j %(bn)s-snat\n'
+                    '[0:0] -A %(bn)s-snat -j '
+                    '%(bn)s-float-snat\n'
+                    'COMMIT\n'
+                    '# Completed by iptables_manager\n' % iptables_args)
+
+        self.iptables.execute(['iptables-restore', '-c'],
+                              process_input=nat_dump + filter_dump_mod,
+                              root_helper=self.root_helper).AndReturn(None)
+
+        self.iptables.execute(['iptables-save', '-c'],
+                              root_helper=self.root_helper).AndReturn('')
+
+        self.iptables.execute(['iptables-restore', '-c'],
+                              process_input=nat_dump + filter_dump,
+                              root_helper=self.root_helper).AndReturn(None)
+
+        self.mox.ReplayAll()
+
+        self.iptables.ipv4['filter'].add_chain('filter')
+        self.iptables.apply()
+
+        self.iptables.ipv4['filter'].empty_chain('filter')
+        self.iptables.apply()
+
+        self.mox.VerifyAll()
+
+    def test_empty_chain_custom_binary_name(self):
+        bn = ("abcdef" * 5)[:16]
+
+        self.iptables = (iptables_manager.
+                         IptablesManager(root_helper=self.root_helper,
+                                         binary_name=bn))
+        self.mox.StubOutWithMock(self.iptables, "execute")
+
+        self.iptables.execute(['iptables-save', '-c'],
+                              root_helper=self.root_helper).AndReturn('')
+
+        iptables_args = {'bn': bn}
+
+        filter_dump = ('# Generated by iptables_manager\n'
+                       '*filter\n'
+                       ':neutron-filter-top - [0:0]\n'
+                       ':%(bn)s-FORWARD - [0:0]\n'
+                       ':%(bn)s-INPUT - [0:0]\n'
+                       ':%(bn)s-local - [0:0]\n'
+                       ':%(bn)s-OUTPUT - [0:0]\n'
+                       '[0:0] -A FORWARD -j neutron-filter-top\n'
+                       '[0:0] -A OUTPUT -j neutron-filter-top\n'
+                       '[0:0] -A neutron-filter-top -j %(bn)s-local\n'
+                       '[0:0] -A INPUT -j %(bn)s-INPUT\n'
+                       '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
+                       '[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
+                       'COMMIT\n'
+                       '# Completed by iptables_manager\n' % iptables_args)
+
+        filter_dump_mod = ('# Generated by iptables_manager\n'
+                           '*filter\n'
+                           ':neutron-filter-top - [0:0]\n'
+                           ':%(bn)s-FORWARD - [0:0]\n'
+                           ':%(bn)s-INPUT - [0:0]\n'
+                           ':%(bn)s-local - [0:0]\n'
+                           ':%(bn)s-filter - [0:0]\n'
+                           ':%(bn)s-OUTPUT - [0:0]\n'
+                           '[0:0] -A FORWARD -j neutron-filter-top\n'
+                           '[0:0] -A OUTPUT -j neutron-filter-top\n'
+                           '[0:0] -A neutron-filter-top -j %(bn)s-local\n'
+                           '[0:0] -A INPUT -j %(bn)s-INPUT\n'
+                           '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
+                           '[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
+                           '[0:0] -A %(bn)s-filter -s 0/0 -d 192.168.0.2\n'
+                           'COMMIT\n'
+                           '# Completed by iptables_manager\n'
+                           % iptables_args)
+
+        nat_dump = ('# Generated by iptables_manager\n'
+                    '*nat\n'
+                    ':neutron-postrouting-bottom - [0:0]\n'
+                    ':%(bn)s-OUTPUT - [0:0]\n'
+                    ':%(bn)s-snat - [0:0]\n'
+                    ':%(bn)s-PREROUTING - [0:0]\n'
+                    ':%(bn)s-float-snat - [0:0]\n'
+                    ':%(bn)s-POSTROUTING - [0:0]\n'
+                    '[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n'
+                    '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
+                    '[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n'
+                    '[0:0] -A POSTROUTING -j neutron-postrouting-bottom\n'
+                    '[0:0] -A neutron-postrouting-bottom -j %(bn)s-snat\n'
+                    '[0:0] -A %(bn)s-snat -j '
+                    '%(bn)s-float-snat\n'
+                    'COMMIT\n'
+                    '# Completed by iptables_manager\n' % iptables_args)
+
+        self.iptables.execute(['iptables-restore', '-c'],
+                              process_input=nat_dump + filter_dump_mod,
+                              root_helper=self.root_helper).AndReturn(None)
+
+        self.iptables.execute(['iptables-save', '-c'],
+                              root_helper=self.root_helper).AndReturn('')
+
+        self.iptables.execute(['iptables-restore', '-c'],
+                              process_input=nat_dump + filter_dump,
+                              root_helper=self.root_helper).AndReturn(None)
+
+        self.mox.ReplayAll()
+
+        self.iptables.ipv4['filter'].add_chain('filter')
+        self.iptables.ipv4['filter'].add_rule('filter',
+                                              '-s 0/0 -d 192.168.0.2')
+        self.iptables.apply()
+
+        self.iptables.ipv4['filter'].remove_chain('filter')
+        self.iptables.apply()
+
+        self.mox.VerifyAll()
+
     def test_add_and_remove_chain(self):
         self.iptables.execute(['iptables-save', '-c'],
                               root_helper=self.root_helper).AndReturn('')