diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/flow_accounting_conf.py | 9 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-vxlan.py | 5 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-wwan.py | 2 | ||||
-rwxr-xr-x | src/conf_mode/protocols_bgp.py | 6 | ||||
-rwxr-xr-x | src/conf_mode/service_ids_fastnetmon.py | 2 | ||||
-rwxr-xr-x | src/etc/opennhrp/opennhrp-script.py | 2 | ||||
-rw-r--r-- | src/etc/systemd/system/fastnetmon.service.d/override.conf | 2 | ||||
-rwxr-xr-x | src/op_mode/nat.py | 29 | ||||
-rwxr-xr-x | src/op_mode/show_vrf.py | 66 | ||||
-rwxr-xr-x | src/op_mode/vpn_ipsec.py | 5 | ||||
-rwxr-xr-x | src/op_mode/vrf.py | 20 |
11 files changed, 71 insertions, 77 deletions
diff --git a/src/conf_mode/flow_accounting_conf.py b/src/conf_mode/flow_accounting_conf.py index 7750c1247..7e16235c1 100755 --- a/src/conf_mode/flow_accounting_conf.py +++ b/src/conf_mode/flow_accounting_conf.py @@ -192,6 +192,11 @@ def verify(flow_config): raise ConfigError("All sFlow servers must use the same IP protocol") else: sflow_collector_ipver = ip_address(server).version + + # check if vrf is defined for Sflow + sflow_vrf = None + if 'vrf' in flow_config: + sflow_vrf = flow_config['vrf'] # check agent-id for sFlow: we should avoid mixing IPv4 agent-id with IPv6 collectors and vice-versa for server in flow_config['sflow']['server']: @@ -203,12 +208,12 @@ def verify(flow_config): if 'agent_address' in flow_config['sflow']: tmp = flow_config['sflow']['agent_address'] - if not is_addr_assigned(tmp): + if not is_addr_assigned(tmp, sflow_vrf): raise ConfigError(f'Configured "sflow agent-address {tmp}" does not exist in the system!') # Check if configured netflow source-address exist in the system if 'source_address' in flow_config['sflow']: - if not is_addr_assigned(flow_config['sflow']['source_address']): + if not is_addr_assigned(flow_config['sflow']['source_address'], sflow_vrf): tmp = flow_config['sflow']['source_address'] raise ConfigError(f'Configured "sflow source-address {tmp}" does not exist on the system!') diff --git a/src/conf_mode/interfaces-vxlan.py b/src/conf_mode/interfaces-vxlan.py index bf0f6840d..af2d0588d 100755 --- a/src/conf_mode/interfaces-vxlan.py +++ b/src/conf_mode/interfaces-vxlan.py @@ -118,6 +118,11 @@ def verify(vxlan): # in use. vxlan_overhead += 20 + # If source_address is not used - check IPv6 'remote' list + elif 'remote' in vxlan: + if any(is_ipv6(a) for a in vxlan['remote']): + vxlan_overhead += 20 + lower_mtu = Interface(vxlan['source_interface']).get_mtu() if lower_mtu < (int(vxlan['mtu']) + vxlan_overhead): raise ConfigError(f'Underlaying device MTU is to small ({lower_mtu} '\ diff --git a/src/conf_mode/interfaces-wwan.py b/src/conf_mode/interfaces-wwan.py index e275ace84..97b3a6396 100755 --- a/src/conf_mode/interfaces-wwan.py +++ b/src/conf_mode/interfaces-wwan.py @@ -76,7 +76,7 @@ def get_config(config=None): # We need to know the amount of other WWAN interfaces as ModemManager needs # to be started or stopped. conf.set_level(base) - _, wwan['other_interfaces'] = conf.get_config_dict([], key_mangling=('-', '_'), + wwan['other_interfaces'] = conf.get_config_dict([], key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True) diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py index 5aa643476..7d3687094 100755 --- a/src/conf_mode/protocols_bgp.py +++ b/src/conf_mode/protocols_bgp.py @@ -213,6 +213,12 @@ def verify(bgp): if 'source_interface' in peer_config['interface']: raise ConfigError(f'"source-interface" option not allowed for neighbor "{peer}"') + # Local-AS allowed only for EBGP peers + if 'local_as' in peer_config: + remote_as = verify_remote_as(peer_config, bgp) + if remote_as == bgp['local_as']: + raise ConfigError(f'local-as configured for "{peer}", allowed only for eBGP peers!') + for afi in ['ipv4_unicast', 'ipv4_multicast', 'ipv4_labeled_unicast', 'ipv4_flowspec', 'ipv6_unicast', 'ipv6_multicast', 'ipv6_labeled_unicast', 'ipv6_flowspec', 'l2vpn_evpn']: diff --git a/src/conf_mode/service_ids_fastnetmon.py b/src/conf_mode/service_ids_fastnetmon.py index 615658c84..c58f8db9a 100755 --- a/src/conf_mode/service_ids_fastnetmon.py +++ b/src/conf_mode/service_ids_fastnetmon.py @@ -29,6 +29,7 @@ airbag.enable() config_file = r'/run/fastnetmon/fastnetmon.conf' networks_list = r'/run/fastnetmon/networks_list' +excluded_networks_list = r'/run/fastnetmon/excluded_networks_list' def get_config(config=None): if config: @@ -75,6 +76,7 @@ def generate(fastnetmon): render(config_file, 'ids/fastnetmon.j2', fastnetmon) render(networks_list, 'ids/fastnetmon_networks_list.j2', fastnetmon) + render(excluded_networks_list, 'ids/fastnetmon_excluded_networks_list.j2', fastnetmon) return None def apply(fastnetmon): diff --git a/src/etc/opennhrp/opennhrp-script.py b/src/etc/opennhrp/opennhrp-script.py index 5a64dade8..8274e6564 100755 --- a/src/etc/opennhrp/opennhrp-script.py +++ b/src/etc/opennhrp/opennhrp-script.py @@ -62,7 +62,7 @@ def add_peer_route(nbma_src: str, nbma_dst: str, mtu: str) -> None: for route_item in route_info_data: route_dev = route_item.get('dev') route_dst = route_item.get('dst') - route_gateway = route_item.get('route_gateway') + route_gateway = route_item.get('gateway') # Prepare a command to add a route route_add_cmd = 'sudo ip route add' if route_dst: diff --git a/src/etc/systemd/system/fastnetmon.service.d/override.conf b/src/etc/systemd/system/fastnetmon.service.d/override.conf index 8f7f3774f..841666070 100644 --- a/src/etc/systemd/system/fastnetmon.service.d/override.conf +++ b/src/etc/systemd/system/fastnetmon.service.d/override.conf @@ -7,6 +7,6 @@ After=vyos-router.service [Service] Type=simple WorkingDirectory=/run/fastnetmon -PIDFile=/run/fastnetmon/fastnetmon.pid +PIDFile=/run/fastnetmon.pid ExecStart= ExecStart=/usr/sbin/fastnetmon --configuration_file /run/fastnetmon/fastnetmon.conf diff --git a/src/op_mode/nat.py b/src/op_mode/nat.py index f3f79f863..4b54ecf31 100755 --- a/src/op_mode/nat.py +++ b/src/op_mode/nat.py @@ -52,6 +52,9 @@ def _get_raw_data_rules(direction): def _get_formatted_output_rules(data, direction): + # Add default values before loop + sport, dport, proto = 'any', 'any', 'any' + saddr, daddr = '0.0.0.0/0', '0.0.0.0/0' data_entries = [] for rule in data: if 'comment' in rule['rule']: @@ -144,6 +147,24 @@ port {port}''' return output +def _get_formatted_output_statistics(data, direction): + data_entries = [] + for rule in data: + if 'comment' in rule['rule']: + comment = rule.get('rule').get('comment') + rule_number = comment.split('-')[-1] + rule_number = rule_number.split(' ')[0] + if 'expr' in rule['rule']: + interface = rule.get('rule').get('expr')[0].get('match').get('right') \ + if jmespath.search('rule.expr[*].match.left.meta', rule) else 'any' + packets = jmespath.search('rule.expr[*].counter.packets | [0]', rule) + _bytes = jmespath.search('rule.expr[*].counter.bytes | [0]', rule) + data_entries.append([rule_number, packets, _bytes, interface]) + headers = ["Rule", "Packets", "Bytes", "Interface"] + output = tabulate(data_entries, headers, numalign="left") + return output + + def show_rules(raw: bool, direction: str): nat_rules = _get_raw_data_rules(direction) if raw: @@ -152,6 +173,14 @@ def show_rules(raw: bool, direction: str): return _get_formatted_output_rules(nat_rules, direction) +def show_statistics(raw: bool, direction: str): + nat_statistics = _get_raw_data_rules(direction) + if raw: + return nat_statistics + else: + return _get_formatted_output_statistics(nat_statistics, direction) + + if __name__ == '__main__': try: res = vyos.opmode.run(sys.modules[__name__]) diff --git a/src/op_mode/show_vrf.py b/src/op_mode/show_vrf.py deleted file mode 100755 index 3c7a90205..000000000 --- a/src/op_mode/show_vrf.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2020 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 or later as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -import argparse -import jinja2 -from json import loads - -from vyos.util import cmd - -vrf_out_tmpl = """VRF name state mac address flags interfaces --------- ----- ----------- ----- ---------- -{%- for v in vrf %} -{{"%-16s"|format(v.ifname)}} {{ "%-8s"|format(v.operstate | lower())}} {{"%-17s"|format(v.address | lower())}} {{ v.flags|join(',')|lower()}} {{v.members|join(',')|lower()}} -{%- endfor %} - -""" - -def list_vrfs(): - command = 'ip -j -br link show type vrf' - answer = loads(cmd(command)) - return [_ for _ in answer if _] - -def list_vrf_members(vrf): - command = f'ip -j -br link show master {vrf}' - answer = loads(cmd(command)) - return [_ for _ in answer if _] - -parser = argparse.ArgumentParser() -group = parser.add_mutually_exclusive_group() -group.add_argument("-e", "--extensive", action="store_true", - help="provide detailed vrf informatio") -parser.add_argument('interface', metavar='I', type=str, nargs='?', - help='interface to display') - -args = parser.parse_args() - -if args.extensive: - data = { 'vrf': [] } - for vrf in list_vrfs(): - name = vrf['ifname'] - if args.interface and name != args.interface: - continue - - vrf['members'] = [] - for member in list_vrf_members(name): - vrf['members'].append(member['ifname']) - data['vrf'].append(vrf) - - tmpl = jinja2.Template(vrf_out_tmpl) - print(tmpl.render(data)) - -else: - print(" ".join([vrf['ifname'] for vrf in list_vrfs()])) diff --git a/src/op_mode/vpn_ipsec.py b/src/op_mode/vpn_ipsec.py index 8955e5a59..68dc5bc45 100755 --- a/src/op_mode/vpn_ipsec.py +++ b/src/op_mode/vpn_ipsec.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2021 VyOS maintainers and contributors +# Copyright (C) 2021-2022 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -87,6 +87,7 @@ def reset_profile(profile, tunnel): print('Profile reset result: ' + ('success' if result == 0 else 'failed')) def debug_peer(peer, tunnel): + peer = peer.replace(':', '-') if not peer or peer == "all": debug_commands = [ "sudo ipsec statusall", @@ -109,7 +110,7 @@ def debug_peer(peer, tunnel): if not tunnel or tunnel == 'all': tunnel = '' - conn = get_peer_connections(peer, tunnel) + conns = get_peer_connections(peer, tunnel, return_all = (tunnel == '' or tunnel == 'all')) if not conns: print('Peer not found, aborting') diff --git a/src/op_mode/vrf.py b/src/op_mode/vrf.py index 63d9b5ee5..f86516786 100755 --- a/src/op_mode/vrf.py +++ b/src/op_mode/vrf.py @@ -16,6 +16,7 @@ import json import sys +import typing from tabulate import tabulate from vyos.util import cmd @@ -23,12 +24,23 @@ from vyos.util import cmd import vyos.opmode -def _get_raw_data(): +def _get_raw_data(name=None): """ - :return: list + If vrf name is not set - get all VRFs + If vrf name is set - get only this name data + If vrf name set and not found - return [] """ output = cmd('sudo ip --json --brief link show type vrf') data = json.loads(output) + if not data: + return [] + if name: + is_vrf_exists = True if [vrf for vrf in data if vrf.get('ifname') == name] else False + if is_vrf_exists: + output = cmd(f'sudo ip --json --brief link show dev {name}') + data = json.loads(output) + return data + return [] return data @@ -62,8 +74,8 @@ def _get_formatted_output(raw_data): return output -def show(raw: bool): - vrf_data = _get_raw_data() +def show(raw: bool, name: typing.Optional[str]): + vrf_data = _get_raw_data(name=name) if raw: return vrf_data else: |