summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2020-12-20 11:17:13 +0100
committerGitHub <noreply@github.com>2020-12-20 11:17:13 +0100
commit0cf4694a23b20e7f15fb8b8b349c16dfc3e17ade (patch)
treeb81e963d837d6e9e3acd78ecb28be1e973c7eb73
parentae567b86495bf0bbadf19d396df60186979558a4 (diff)
parentda03caa27446f32eb39c8458d443e9fd94452ad2 (diff)
downloadvyos-1x-0cf4694a23b20e7f15fb8b8b349c16dfc3e17ade.tar.gz
vyos-1x-0cf4694a23b20e7f15fb8b8b349c16dfc3e17ade.zip
Merge pull request #647 from jpbede/feature/flowacc-enable-egress
flow-accounting: T3132: enable egress traffic accounting
-rw-r--r--data/templates/netflow/uacctd.conf.tmpl4
-rw-r--r--interface-definitions/flow-accounting-conf.xml.in6
-rwxr-xr-xsrc/conf_mode/flow_accounting_conf.py42
3 files changed, 41 insertions, 11 deletions
diff --git a/data/templates/netflow/uacctd.conf.tmpl b/data/templates/netflow/uacctd.conf.tmpl
index fdf96e7c3..1938901d2 100644
--- a/data/templates/netflow/uacctd.conf.tmpl
+++ b/data/templates/netflow/uacctd.conf.tmpl
@@ -5,7 +5,11 @@ pidfile: /var/run/uacctd.pid
uacctd_group: 2
uacctd_nl_size: 2097152
snaplen: {{ snaplen }}
+{% if templatecfg['enable-egress'] != none %}
+aggregate: in_iface,out_iface,src_mac,dst_mac,vlan,src_host,dst_host,src_port,dst_port,proto,tos,flows
+{% else %}
aggregate: in_iface,src_mac,dst_mac,vlan,src_host,dst_host,src_port,dst_port,proto,tos,flows
+{% endif %}
plugin_pipe_size: {{ templatecfg['plugin_pipe_size'] }}
plugin_buffer_size: {{ templatecfg['plugin_buffer_size'] }}
{% if templatecfg['syslog-facility'] != none %}
diff --git a/interface-definitions/flow-accounting-conf.xml.in b/interface-definitions/flow-accounting-conf.xml.in
index 904759a56..585322125 100644
--- a/interface-definitions/flow-accounting-conf.xml.in
+++ b/interface-definitions/flow-accounting-conf.xml.in
@@ -21,6 +21,12 @@
</constraint>
</properties>
</leafNode>
+ <leafNode name="enable-egress">
+ <properties>
+ <help>Enable egress flow accounting</help>
+ <valueless />
+ </properties>
+ </leafNode>
<leafNode name="disable-imt">
<properties>
<help>Disable in memory table plugin</help>
diff --git a/src/conf_mode/flow_accounting_conf.py b/src/conf_mode/flow_accounting_conf.py
index b7e73eaeb..0727b47a8 100755
--- a/src/conf_mode/flow_accounting_conf.py
+++ b/src/conf_mode/flow_accounting_conf.py
@@ -42,6 +42,8 @@ default_sflow_agentip = 'auto'
uacctd_conf_path = '/etc/pmacct/uacctd.conf'
iptables_nflog_table = 'raw'
iptables_nflog_chain = 'VYATTA_CT_PREROUTING_HOOK'
+egress_iptables_nflog_table = 'mangle'
+egress_iptables_nflog_chain = 'POSTROUTING'
# helper functions
# check if node exists and return True if this is true
@@ -74,32 +76,38 @@ def _sflow_default_agentip(config):
return None
# get iptables rule dict for chain in table
-def _iptables_get_nflog():
+def _iptables_get_nflog(chain, table):
# define list with rules
rules = []
# prepare regex for parsing rules
- rule_pattern = "^-A (?P<rule_definition>{0} -i (?P<interface>[\w\.\*\-]+).*--comment FLOW_ACCOUNTING_RULE.* -j NFLOG.*$)".format(iptables_nflog_chain)
+ rule_pattern = "^-A (?P<rule_definition>{0} (\-i|\-o) (?P<interface>[\w\.\*\-]+).*--comment FLOW_ACCOUNTING_RULE.* -j NFLOG.*$)".format(chain)
rule_re = re.compile(rule_pattern)
for iptables_variant in ['iptables', 'ip6tables']:
# run iptables, save output and split it by lines
- iptables_command = f'{iptables_variant} -t {iptables_nflog_table} -S {iptables_nflog_chain}'
+ iptables_command = f'{iptables_variant} -t {table} -S {chain}'
tmp = cmd(iptables_command, message='Failed to get flows list')
# parse each line and add information to list
for current_rule in tmp.splitlines():
current_rule_parsed = rule_re.search(current_rule)
if current_rule_parsed:
- rules.append({ 'interface': current_rule_parsed.groupdict()["interface"], 'iptables_variant': iptables_variant, 'table': iptables_nflog_table, 'rule_definition': current_rule_parsed.groupdict()["rule_definition"] })
+ rules.append({ 'interface': current_rule_parsed.groupdict()["interface"], 'iptables_variant': iptables_variant, 'table': table, 'rule_definition': current_rule_parsed.groupdict()["rule_definition"] })
# return list with rules
return rules
# modify iptables rules
-def _iptables_config(configured_ifaces):
+def _iptables_config(configured_ifaces, direction):
# define list of iptables commands to modify settings
iptable_commands = []
+ iptables_chain = iptables_nflog_chain
+ iptables_table = iptables_nflog_table
+
+ if direction == "egress":
+ iptables_chain = egress_iptables_nflog_chain
+ iptables_table = egress_iptables_nflog_table
# prepare extended list with configured interfaces
configured_ifaces_extended = []
@@ -108,7 +116,7 @@ def _iptables_config(configured_ifaces):
configured_ifaces_extended.append({ 'iface': iface, 'iptables_variant': 'ip6tables' })
# get currently configured interfaces with iptables rules
- active_nflog_rules = _iptables_get_nflog()
+ active_nflog_rules = _iptables_get_nflog(iptables_chain, iptables_table)
# compare current active list with configured one and delete excessive interfaces, add missed
active_nflog_ifaces = []
@@ -127,15 +135,19 @@ def _iptables_config(configured_ifaces):
# do not create new rules for already configured interfaces
for iface in active_nflog_ifaces:
- if iface in active_nflog_ifaces:
+ if iface in active_nflog_ifaces and iface in configured_ifaces_extended:
configured_ifaces_extended.remove(iface)
# create missed rules
for iface_extended in configured_ifaces_extended:
iface = iface_extended['iface']
iptables = iface_extended['iptables_variant']
- rule_definition = f'{iptables_nflog_chain} -i {iface} -m comment --comment FLOW_ACCOUNTING_RULE -j NFLOG --nflog-group 2 --nflog-size {default_captured_packet_size} --nflog-threshold 100'
- iptable_commands.append(f'{iptables} -t {iptables_nflog_table} -I {rule_definition}')
+ iptables_op = "-i"
+ if direction == "egress":
+ iptables_op = "-o"
+
+ rule_definition = f'{iptables_chain} {iptables_op} {iface} -m comment --comment FLOW_ACCOUNTING_RULE -j NFLOG --nflog-group 2 --nflog-size {default_captured_packet_size} --nflog-threshold 100'
+ iptable_commands.append(f'{iptables} -t {iptables_table} -I {rule_definition}')
# change iptables
for command in iptable_commands:
@@ -149,6 +161,7 @@ def get_config():
flow_config = {
'flow-accounting-configured': vc.exists('system flow-accounting'),
'buffer-size': vc.return_value('system flow-accounting buffer-size'),
+ 'enable-egress': _node_exists('system flow-accounting enable-egress'),
'disable-imt': _node_exists('system flow-accounting disable-imt'),
'syslog-facility': vc.return_value('system flow-accounting syslog-facility'),
'interfaces': None,
@@ -356,9 +369,16 @@ def apply(config):
# configure iptables rules for defined interfaces
if config['interfaces']:
- _iptables_config(config['interfaces'])
+ _iptables_config(config['interfaces'], 'ingress')
+
+ # configure egress the same way if configured otherwise remove it
+ if config['enable-egress']:
+ _iptables_config(config['interfaces'], 'egress')
+ else:
+ _iptables_config([], 'egress')
else:
- _iptables_config([])
+ _iptables_config([], 'ingress')
+ _iptables_config([], 'egress')
if __name__ == '__main__':
try: