]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Allow IptablesManager to manage mangle table
authorCedric Brandily <zzelle@gmail.com>
Tue, 18 Nov 2014 09:34:30 +0000 (10:34 +0100)
committerCedric Brandily <zzelle@gmail.com>
Mon, 12 Jan 2015 09:45:01 +0000 (09:45 +0000)
This change enables the IptablesManager to manage mangle table (used
by daughter change).

Partial-Bug: #1187102
Change-Id: Ic2d681f1515aaa541c6d137ce981622f2fff90e5

neutron/agent/linux/iptables_manager.py
neutron/tests/functional/agent/linux/base.py
neutron/tests/functional/agent/linux/test_iptables.py
neutron/tests/unit/test_iptables_manager.py
neutron/tests/unit/test_security_groups_rpc.py

index 8d89a7cdd52dc3b161354ee790828e7150266e26..ce8dae3651d6bffb214f4fc7243b44f6726a5c69 100644 (file)
@@ -316,6 +316,11 @@ class IptablesManager(object):
                           6: {'filter': ['INPUT', 'OUTPUT', 'FORWARD']}}
 
         if not state_less:
+            self.ipv4.update(
+                {'mangle': IptablesTable(binary_name=self.wrap_name)})
+            builtin_chains[4].update(
+                {'mangle': ['PREROUTING', 'INPUT', 'FORWARD', 'OUTPUT',
+                            'POSTROUTING']})
             self.ipv4.update(
                 {'nat': IptablesTable(binary_name=self.wrap_name)})
             builtin_chains[4].update({'nat': ['PREROUTING',
index ed2f25ebff6c5084206710b774b9132bd275246a..e8b2bf8484b79e852eab219640442faac75b70b7 100644 (file)
@@ -28,6 +28,11 @@ from neutron.tests import sub_base
 
 BR_PREFIX = 'test-br'
 PORT_PREFIX = 'test-port'
+MARK_VALUE = '0x1'
+MARK_MASK = '0xffffffff'
+ICMP_MARK_RULE = ('-j MARK --set-xmark %(value)s/%(mask)s'
+                  % {'value': MARK_VALUE, 'mask': MARK_MASK})
+MARKED_BLOCK_RULE = '-m mark --mark %s -j DROP' % MARK_VALUE
 ICMP_BLOCK_RULE = '-p icmp -j DROP'
 VETH_PREFIX = 'tst-vth'
 
index 4e7efb69ce90588b44f23dcb9aa70a80437b2452..71da1d7aecaf3e20291fa3af66cd707f1e33de6f 100644 (file)
@@ -35,3 +35,16 @@ class IptablesManagerTestCase(base.BaseIPVethTestCase):
                                                  base.ICMP_BLOCK_RULE)
         self.iptables.apply()
         self.pinger.assert_ping_from_ns(self.src_ns, self.DST_ADDRESS)
+
+    def test_mangle_icmp(self):
+        self.pinger.assert_ping_from_ns(self.src_ns, self.DST_ADDRESS)
+        self.iptables.ipv4['mangle'].add_rule('INPUT', base.ICMP_MARK_RULE)
+        self.iptables.ipv4['filter'].add_rule('INPUT', base.MARKED_BLOCK_RULE)
+        self.iptables.apply()
+        self.pinger.assert_no_ping_from_ns(self.src_ns, self.DST_ADDRESS)
+        self.iptables.ipv4['mangle'].remove_rule('INPUT',
+                                                 base.ICMP_MARK_RULE)
+        self.iptables.ipv4['filter'].remove_rule('INPUT',
+                                                 base.MARKED_BLOCK_RULE)
+        self.iptables.apply()
+        self.pinger.assert_ping_from_ns(self.src_ns, self.DST_ADDRESS)
index 51c7c4cfade14203f10f11d6935b5b7c324c4e41..54fcf76ddc45df02d2ccd8d49c3e097147892915 100644 (file)
@@ -153,22 +153,23 @@ class IptablesCommentsTestCase(base.BaseTestCase):
         filter_dump_mod = FILTER_WITH_RULES_TEMPLATE % iptables_args
 
         raw_dump = _generate_raw_dump(IPTABLES_ARG)
+        mangle_dump = _generate_mangle_dump(IPTABLES_ARG)
 
         expected_calls_and_values = [
             (mock.call(['iptables-save', '-c'],
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=(
-                           raw_dump + COMMENTED_NAT_DUMP + filter_dump_mod),
+                       process_input=(raw_dump + COMMENTED_NAT_DUMP +
+                                      mangle_dump + filter_dump_mod),
                        root_helper=self.root_helper),
              None),
             (mock.call(['iptables-save', '-c'],
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=(
-                           raw_dump + COMMENTED_NAT_DUMP + FILTER_DUMP),
+                       process_input=(raw_dump + COMMENTED_NAT_DUMP +
+                                      mangle_dump + FILTER_DUMP),
                        root_helper=self.root_helper
                        ),
              None),
@@ -194,6 +195,23 @@ class IptablesCommentsTestCase(base.BaseTestCase):
         tools.verify_mock_calls(self.execute, expected_calls_and_values)
 
 
+def _generate_mangle_dump(iptables_args):
+    return ('# Generated by iptables_manager\n'
+            '*mangle\n'
+            ':%(bn)s-FORWARD - [0:0]\n'
+            ':%(bn)s-INPUT - [0:0]\n'
+            ':%(bn)s-OUTPUT - [0:0]\n'
+            ':%(bn)s-POSTROUTING - [0:0]\n'
+            ':%(bn)s-PREROUTING - [0:0]\n'
+            '[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n'
+            '[0:0] -A INPUT -j %(bn)s-INPUT\n'
+            '[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
+            '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
+            '[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n'
+            'COMMIT\n'
+            '# Completed by iptables_manager\n' % iptables_args)
+
+
 def _generate_raw_dump(iptables_args):
     return ('# Generated by iptables_manager\n'
             '*raw\n'
@@ -204,6 +222,7 @@ def _generate_raw_dump(iptables_args):
             'COMMIT\n'
             '# Completed by iptables_manager\n' % iptables_args)
 
+MANGLE_DUMP = _generate_mangle_dump(IPTABLES_ARG)
 RAW_DUMP = _generate_raw_dump(IPTABLES_ARG)
 
 
@@ -271,20 +290,23 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         nat_dump = NAT_TEMPLATE % iptables_args
 
         raw_dump = _generate_raw_dump(iptables_args)
+        mangle_dump = _generate_mangle_dump(iptables_args)
 
         expected_calls_and_values = [
             (mock.call(['iptables-save', '-c'],
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=raw_dump + nat_dump + filter_dump_mod,
+                       process_input=(raw_dump + nat_dump + mangle_dump +
+                                      filter_dump_mod),
                        root_helper=self.root_helper),
              None),
             (mock.call(['iptables-save', '-c'],
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=raw_dump + nat_dump + filter_dump,
+                       process_input=(raw_dump + nat_dump + mangle_dump +
+                                      filter_dump),
                        root_helper=self.root_helper),
              None),
         ]
@@ -329,20 +351,23 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         nat_dump = NAT_TEMPLATE % iptables_args
 
         raw_dump = _generate_raw_dump(iptables_args)
+        mangle_dump = _generate_mangle_dump(iptables_args)
 
         expected_calls_and_values = [
             (mock.call(['iptables-save', '-c'],
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=raw_dump + nat_dump + filter_dump_mod,
+                       process_input=(raw_dump + nat_dump + mangle_dump +
+                                      filter_dump_mod),
                        root_helper=self.root_helper),
              None),
             (mock.call(['iptables-save', '-c'],
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=raw_dump + nat_dump + filter_dump,
+                       process_input=(raw_dump + nat_dump + mangle_dump +
+                                      filter_dump),
                        root_helper=self.root_helper),
              None),
         ]
@@ -381,14 +406,16 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=RAW_DUMP + NAT_DUMP + filter_dump_mod,
+                       process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
+                                      filter_dump_mod),
                        root_helper=self.root_helper),
              None),
             (mock.call(['iptables-save', '-c'],
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=RAW_DUMP + NAT_DUMP + FILTER_DUMP,
+                       process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
+                                      FILTER_DUMP),
                        root_helper=self.root_helper),
              None),
         ]
@@ -431,14 +458,16 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=RAW_DUMP + NAT_DUMP + filter_dump_mod,
+                       process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
+                                      filter_dump_mod),
                        root_helper=self.root_helper),
              None),
             (mock.call(['iptables-save', '-c'],
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=RAW_DUMP + NAT_DUMP + FILTER_DUMP,
+                       process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
+                                      FILTER_DUMP),
                        root_helper=self.root_helper
                        ),
              None),
@@ -511,14 +540,16 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=RAW_DUMP + NAT_DUMP + filter_dump_mod,
+                       process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
+                                      filter_dump_mod),
                        root_helper=self.root_helper),
              None),
             (mock.call(['iptables-save', '-c'],
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=RAW_DUMP + NAT_DUMP + FILTER_DUMP,
+                       process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
+                                      FILTER_DUMP),
                        root_helper=self.root_helper),
              None),
         ]
@@ -549,6 +580,77 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
     def test_rule_with_wrap_target_with_ipv6(self):
         self._test_rule_with_wrap_target_helper(True)
 
+    def _test_add_mangle_rule_helper(self, use_ipv6):
+        self.iptables = iptables_manager.IptablesManager(
+            root_helper=self.root_helper,
+            use_ipv6=use_ipv6)
+        self.execute = mock.patch.object(self.iptables, "execute").start()
+
+        mangle_dump_mod = (
+            '# Generated by iptables_manager\n'
+            '*mangle\n'
+            ':%(bn)s-FORWARD - [0:0]\n'
+            ':%(bn)s-INPUT - [0:0]\n'
+            ':%(bn)s-OUTPUT - [0:0]\n'
+            ':%(bn)s-POSTROUTING - [0:0]\n'
+            ':%(bn)s-PREROUTING - [0:0]\n'
+            ':%(bn)s-mangle - [0:0]\n'
+            '[0:0] -A PREROUTING -j %(bn)s-PREROUTING\n'
+            '[0:0] -A INPUT -j %(bn)s-INPUT\n'
+            '[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
+            '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
+            '[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING\n'
+            '[0:0] -A %(bn)s-PREROUTING -j MARK --set-xmark 0x1/0xffffffff\n'
+            'COMMIT\n'
+            '# Completed by iptables_manager\n'
+            % IPTABLES_ARG)
+
+        expected_calls_and_values = [
+            (mock.call(['iptables-save', '-c'],
+                       root_helper=self.root_helper),
+             ''),
+            (mock.call(['iptables-restore', '-c'],
+                       process_input=(RAW_DUMP + NAT_DUMP + mangle_dump_mod +
+                                      FILTER_DUMP),
+                       root_helper=self.root_helper),
+             None),
+            (mock.call(['iptables-save', '-c'],
+                       root_helper=self.root_helper),
+             ''),
+            (mock.call(['iptables-restore', '-c'],
+                       process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
+                                      FILTER_DUMP),
+                       root_helper=self.root_helper),
+             None),
+        ]
+        if use_ipv6:
+            self._extend_with_ip6tables_filter(expected_calls_and_values,
+                                               FILTER_DUMP)
+
+        tools.setup_mock_calls(self.execute, expected_calls_and_values)
+
+        self.iptables.ipv4['mangle'].add_chain('mangle')
+        self.iptables.ipv4['mangle'].add_rule(
+            'PREROUTING',
+            '-j MARK --set-xmark 0x1/0xffffffff')
+
+        self.iptables.apply()
+
+        self.iptables.ipv4['mangle'].remove_rule(
+            'PREROUTING',
+            '-j MARK --set-xmark 0x1/0xffffffff')
+        self.iptables.ipv4['mangle'].remove_chain('mangle')
+
+        self.iptables.apply()
+
+        tools.verify_mock_calls(self.execute, expected_calls_and_values)
+
+    def test_add_mangle_rule(self):
+        self._test_add_mangle_rule_helper(False)
+
+    def test_add_mangle_rule_with_ipv6(self):
+        self._test_add_mangle_rule_helper(True)
+
     def _test_add_nat_rule_helper(self, use_ipv6):
         self.iptables = iptables_manager.IptablesManager(
             root_helper=self.root_helper,
@@ -585,14 +687,16 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=RAW_DUMP + nat_dump_mod + FILTER_DUMP,
+                       process_input=(RAW_DUMP + nat_dump_mod + MANGLE_DUMP +
+                                      FILTER_DUMP),
                        root_helper=self.root_helper),
              None),
             (mock.call(['iptables-save', '-c'],
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=RAW_DUMP + nat_dump + FILTER_DUMP,
+                       process_input=(RAW_DUMP + nat_dump + MANGLE_DUMP +
+                                      FILTER_DUMP),
                        root_helper=self.root_helper),
              None),
         ]
@@ -653,14 +757,16 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=raw_dump_mod + NAT_DUMP + FILTER_DUMP,
+                       process_input=(raw_dump_mod + NAT_DUMP + MANGLE_DUMP +
+                                      FILTER_DUMP),
                        root_helper=self.root_helper),
              None),
             (mock.call(['iptables-save', '-c'],
                        root_helper=self.root_helper),
              ''),
             (mock.call(['iptables-restore', '-c'],
-                       process_input=RAW_DUMP + NAT_DUMP + FILTER_DUMP,
+                       process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
+                                      FILTER_DUMP),
                        root_helper=self.root_helper),
              None),
         ]
@@ -799,6 +905,10 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
                         '-v', '-x'],
                        root_helper=self.root_helper),
              ''),
+            (mock.call(['iptables', '-t', 'mangle', '-L', 'OUTPUT', '-n',
+                        '-v', '-x'],
+                       root_helper=self.root_helper),
+             ''),
             (mock.call(['iptables', '-t', 'nat', '-L', 'OUTPUT', '-n',
                         '-v', '-x'],
                        root_helper=self.root_helper),
@@ -845,6 +955,10 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
                         '-v', '-x', '-Z'],
                        root_helper=self.root_helper),
              ''),
+            (mock.call(['iptables', '-t', 'mangle', '-L', 'OUTPUT', '-n',
+                        '-v', '-x', '-Z'],
+                       root_helper=self.root_helper),
+             ''),
             (mock.call(['iptables', '-t', 'nat', '-L', 'OUTPUT', '-n',
                         '-v', '-x', '-Z'],
                        root_helper=self.root_helper),
@@ -909,3 +1023,6 @@ class IptablesManagerStateLessTestCase(base.BaseTestCase):
 
     def test_nat_not_found(self):
         self.assertNotIn('nat', self.iptables.ipv4)
+
+    def test_mangle_not_found(self):
+        self.assertNotIn('mangle', self.iptables.ipv4)
index 865564c0549ffc09654fe06d4ef5c270b17da206..f9b2f0ffa7d84daa9286e341af71274dbd70ed1f 100644 (file)
@@ -1678,6 +1678,25 @@ IPTABLES_ARG = {'bn': iptables_manager.binary_name,
                 'physdev_mod': PHYSDEV_MOD,
                 'physdev_is_bridged': PHYSDEV_IS_BRIDGED}
 
+CHAINS_MANGLE = 'FORWARD|INPUT|OUTPUT|POSTROUTING|PREROUTING'
+IPTABLES_ARG['chains'] = CHAINS_MANGLE
+
+IPTABLES_MANGLE = """# Generated by iptables_manager
+*mangle
+:%(bn)s-(%(chains)s) - [0:0]
+:%(bn)s-(%(chains)s) - [0:0]
+:%(bn)s-(%(chains)s) - [0:0]
+:%(bn)s-(%(chains)s) - [0:0]
+:%(bn)s-(%(chains)s) - [0:0]
+[0:0] -A PREROUTING -j %(bn)s-PREROUTING
+[0:0] -A INPUT -j %(bn)s-INPUT
+[0:0] -A FORWARD -j %(bn)s-FORWARD
+[0:0] -A OUTPUT -j %(bn)s-OUTPUT
+[0:0] -A POSTROUTING -j %(bn)s-POSTROUTING
+COMMIT
+# Completed by iptables_manager
+""" % IPTABLES_ARG
+
 CHAINS_NAT = 'OUTPUT|POSTROUTING|PREROUTING|float-snat|snat'
 
 # These Dicts use the same keys as devices2 and devices3 in
@@ -2630,7 +2649,8 @@ class TestSecurityGroupAgentWithIptables(base.BaseTestCase):
             return_value='')
         self._register_mock_call(
             ['iptables-restore', '-c'],
-            process_input=self._regex(IPTABLES_RAW + IPTABLES_NAT + v4_filter),
+            process_input=self._regex(IPTABLES_RAW + IPTABLES_NAT +
+                                      IPTABLES_MANGLE + v4_filter),
             root_helper=self.root_helper,
             return_value='')
         self._register_mock_call(