Add method to get iptables traffic counters

Add methods to iptables_manager to get traffic counters.
this is a part of the blueprint bandwidth-router-measurement

Change-Id: I6485d1239085e46398126c81e674e399952a4597
This commit is contained in:
Sylvain Afchain 2013-07-04 11:44:25 +02:00
parent 5ec6a60602
commit 5619bc7121
2 changed files with 135 additions and 0 deletions

View 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

View 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):