]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Add method to get iptables traffic counters
authorSylvain Afchain <sylvain.afchain@enovance.com>
Thu, 4 Jul 2013 09:44:25 +0000 (11:44 +0200)
committerSylvain Afchain <sylvain.afchain@enovance.com>
Mon, 2 Sep 2013 10:39:01 +0000 (12:39 +0200)
Add methods to iptables_manager to get traffic counters.
this is a part of the blueprint bandwidth-router-measurement

Change-Id: I6485d1239085e46398126c81e674e399952a4597

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

index 50fb79d4a73bc5001a08dd8fc951c202d83b0c19..acb32b821914cbaad6daef8aca3cd59ff49cffad 100644 (file)
@@ -567,3 +567,49 @@ class IptablesManager(object):
             remove_rules.remove(rule)
 
         return new_filter
+
+    def _get_traffic_counters_cmd_tables(self, chain, wrap=True):
+        name = get_chain_name(chain, wrap)
+
+        cmd_tables = [('iptables', key) for key, table in self.ipv4.items()
+                      if name in table._select_chain_set(wrap)]
+
+        cmd_tables += [('ip6tables', key) for key, table in self.ipv6.items()
+                       if name in table._select_chain_set(wrap)]
+
+        return cmd_tables
+
+    def get_traffic_counters(self, chain, wrap=True, zero=False):
+        """Return the sum of the traffic counters of all rules of a chain."""
+        cmd_tables = self._get_traffic_counters_cmd_tables(chain, wrap)
+        if not cmd_tables:
+            LOG.warn(_('Attempted to get traffic counters of chain %s which '
+                       'does not exist'), chain)
+            return
+
+        name = get_chain_name(chain, wrap)
+        acc = {'pkts': 0, 'bytes': 0}
+
+        for cmd, table in cmd_tables:
+            args = [cmd, '-t', table, '-L', name, '-n', '-v', '-x']
+            if zero:
+                args.append('-Z')
+            if self.namespace:
+                args = ['ip', 'netns', 'exec', self.namespace] + args
+            current_table = (self.execute(args,
+                             root_helper=self.root_helper))
+            current_lines = current_table.split('\n')
+
+            for line in current_lines[2:]:
+                if not line:
+                    break
+                data = line.split()
+                if (len(data) < 2 or
+                        not data[0].isdigit() or
+                        not data[1].isdigit()):
+                    break
+
+                acc['pkts'] += int(data[0])
+                acc['bytes'] += int(data[1])
+
+        return acc
index 9deaab570e28c44c924408759a17eb2212213232..615a72c30f1e4eeff4f5616b58453673bf576b7e 100644 (file)
@@ -464,6 +464,95 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         self.iptables.ipv4['filter'].remove_rule('nonexistent', '-j DROP')
         self.mox.VerifyAll()
 
+    def test_get_traffic_counters_chain_notexists(self):
+        iptables_dump = (
+            'Chain OUTPUT (policy ACCEPT 400 packets, 65901 bytes)\n'
+            '    pkts      bytes target     prot opt in     out     source'
+            '               destination         \n'
+            '     400   65901 chain1     all  --  *      *       0.0.0.0/0'
+            '            0.0.0.0/0           \n'
+            '     400   65901 chain2     all  --  *      *       0.0.0.0/0'
+            '            0.0.0.0/0           \n')
+
+        self.iptables.execute(['iptables', '-t', 'filter', '-L', 'OUTPUT',
+                               '-n', '-v', '-x'],
+                              root_helper=self.root_helper
+                              ).AndReturn(iptables_dump)
+        self.iptables.execute(['iptables', '-t', 'nat', '-L', 'OUTPUT', '-n',
+                               '-v', '-x'],
+                              root_helper=self.root_helper
+                              ).AndReturn('')
+        self.iptables.execute(['ip6tables', '-t', 'filter', '-L', 'OUTPUT',
+                               '-n', '-v', '-x'],
+                              root_helper=self.root_helper
+                              ).AndReturn(iptables_dump)
+
+        self.mox.ReplayAll()
+        acc = self.iptables.get_traffic_counters('chain1')
+        self.assertIsNone(acc)
+
+    def test_get_traffic_counters(self):
+        iptables_dump = (
+            'Chain OUTPUT (policy ACCEPT 400 packets, 65901 bytes)\n'
+            '    pkts      bytes target     prot opt in     out     source'
+            '               destination         \n'
+            '     400   65901 chain1     all  --  *      *       0.0.0.0/0'
+            '            0.0.0.0/0           \n'
+            '     400   65901 chain2     all  --  *      *       0.0.0.0/0'
+            '            0.0.0.0/0           \n')
+
+        self.iptables.execute(['iptables', '-t', 'filter', '-L', 'OUTPUT',
+                               '-n', '-v', '-x'],
+                              root_helper=self.root_helper
+                              ).AndReturn(iptables_dump)
+        self.iptables.execute(['iptables', '-t', 'nat', '-L', 'OUTPUT', '-n',
+                               '-v', '-x'],
+                              root_helper=self.root_helper
+                              ).AndReturn('')
+
+        self.iptables.execute(['ip6tables', '-t', 'filter', '-L', 'OUTPUT',
+                               '-n', '-v', '-x'],
+                              root_helper=self.root_helper
+                              ).AndReturn(iptables_dump)
+
+        self.mox.ReplayAll()
+        acc = self.iptables.get_traffic_counters('OUTPUT')
+        self.assertEquals(acc['pkts'], 1600)
+        self.assertEquals(acc['bytes'], 263604)
+
+        self.mox.VerifyAll()
+
+    def test_get_traffic_counters_with_zero(self):
+        iptables_dump = (
+            'Chain OUTPUT (policy ACCEPT 400 packets, 65901 bytes)\n'
+            '    pkts      bytes target     prot opt in     out     source'
+            '               destination         \n'
+            '     400   65901 chain1     all  --  *      *       0.0.0.0/0'
+            '            0.0.0.0/0           \n'
+            '     400   65901 chain2     all  --  *      *       0.0.0.0/0'
+            '            0.0.0.0/0           \n')
+
+        self.iptables.execute(['iptables', '-t', 'filter', '-L', 'OUTPUT',
+                               '-n', '-v', '-x', '-Z'],
+                              root_helper=self.root_helper
+                              ).AndReturn(iptables_dump)
+        self.iptables.execute(['iptables', '-t', 'nat', '-L', 'OUTPUT', '-n',
+                               '-v', '-x', '-Z'],
+                              root_helper=self.root_helper
+                              ).AndReturn('')
+
+        self.iptables.execute(['ip6tables', '-t', 'filter', '-L', 'OUTPUT',
+                               '-n', '-v', '-x', '-Z'],
+                              root_helper=self.root_helper
+                              ).AndReturn(iptables_dump)
+
+        self.mox.ReplayAll()
+        acc = self.iptables.get_traffic_counters('OUTPUT', zero=True)
+        self.assertEquals(acc['pkts'], 1600)
+        self.assertEquals(acc['bytes'], 263604)
+
+        self.mox.VerifyAll()
+
 
 class IptablesManagerStateLessTestCase(base.BaseTestCase):