summaryrefslogtreecommitdiff
path: root/src/conf_mode
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-xsrc/conf_mode/flow_accounting_conf.py9
-rwxr-xr-xsrc/conf_mode/http-api.py8
-rwxr-xr-xsrc/conf_mode/interfaces-bonding.py23
-rwxr-xr-xsrc/conf_mode/interfaces-bridge.py14
-rwxr-xr-xsrc/conf_mode/interfaces-ethernet.py2
-rwxr-xr-xsrc/conf_mode/interfaces-geneve.py2
-rwxr-xr-xsrc/conf_mode/interfaces-l2tpv3.py2
-rwxr-xr-xsrc/conf_mode/interfaces-macsec.py73
-rwxr-xr-xsrc/conf_mode/interfaces-openvpn.py2
-rwxr-xr-xsrc/conf_mode/interfaces-pseudo-ethernet.py1
-rwxr-xr-xsrc/conf_mode/interfaces-tunnel.py2
-rwxr-xr-xsrc/conf_mode/interfaces-vxlan.py7
-rwxr-xr-xsrc/conf_mode/interfaces-wireguard.py2
-rwxr-xr-xsrc/conf_mode/interfaces-wireless.py2
-rwxr-xr-xsrc/conf_mode/interfaces-wwan.py2
-rwxr-xr-xsrc/conf_mode/protocols_bgp.py21
-rwxr-xr-xsrc/conf_mode/service_ids_fastnetmon.py58
-rwxr-xr-xsrc/conf_mode/system-ip.py5
-rwxr-xr-xsrc/conf_mode/system-login.py2
-rwxr-xr-xsrc/conf_mode/vrf.py6
20 files changed, 162 insertions, 81 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/http-api.py b/src/conf_mode/http-api.py
index 4a7906c17..04113fc09 100755
--- a/src/conf_mode/http-api.py
+++ b/src/conf_mode/http-api.py
@@ -66,14 +66,10 @@ def get_config(config=None):
if conf.exists('debug'):
http_api['debug'] = True
- # this node is not available by CLI by default, and is reserved for
- # the graphql tools. One can enable it for testing, with the warning
- # that this will open an unauthenticated server. To do so
- # mkdir /opt/vyatta/share/vyatta-cfg/templates/service/https/api/gql
- # touch /opt/vyatta/share/vyatta-cfg/templates/service/https/api/gql/node.def
- # and configure; editing the config alone is insufficient.
if conf.exists('gql'):
http_api['gql'] = True
+ if conf.exists('gql introspection'):
+ http_api['introspection'] = True
if conf.exists('socket'):
http_api['socket'] = True
diff --git a/src/conf_mode/interfaces-bonding.py b/src/conf_mode/interfaces-bonding.py
index 4167594e3..7e146f446 100755
--- a/src/conf_mode/interfaces-bonding.py
+++ b/src/conf_mode/interfaces-bonding.py
@@ -36,6 +36,7 @@ from vyos.ifconfig import BondIf
from vyos.ifconfig import Section
from vyos.util import dict_search
from vyos.validate import has_address_configured
+from vyos.validate import has_vrf_configured
from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -109,20 +110,26 @@ def get_config(config=None):
for interface, interface_config in bond['member']['interface'].items():
# Check if member interface is already member of another bridge
tmp = is_member(conf, interface, 'bridge')
- if tmp: interface_config.update({'is_bridge_member' : tmp})
+ if tmp: bond['member']['interface'][interface].update({'is_bridge_member' : tmp})
# Check if member interface is already member of a bond
tmp = is_member(conf, interface, 'bonding')
- if tmp and bond['ifname'] not in tmp:
- interface_config.update({'is_bond_member' : tmp})
+ for tmp in is_member(conf, interface, 'bonding'):
+ if bond['ifname'] == tmp:
+ continue
+ bond['member']['interface'][interface].update({'is_bond_member' : tmp})
# Check if member interface is used as source-interface on another interface
tmp = is_source_interface(conf, interface)
- if tmp: interface_config.update({'is_source_interface' : tmp})
+ if tmp: bond['member']['interface'][interface].update({'is_source_interface' : tmp})
# bond members must not have an assigned address
tmp = has_address_configured(conf, interface)
- if tmp: interface_config.update({'has_address' : ''})
+ if tmp: bond['member']['interface'][interface].update({'has_address' : {}})
+
+ # bond members must not have a VRF attached
+ tmp = has_vrf_configured(conf, interface)
+ if tmp: bond['member']['interface'][interface].update({'has_vrf' : {}})
return bond
@@ -167,11 +174,11 @@ def verify(bond):
raise ConfigError(error_msg + 'it does not exist!')
if 'is_bridge_member' in interface_config:
- tmp = next(iter(interface_config['is_bridge_member']))
+ tmp = interface_config['is_bridge_member']
raise ConfigError(error_msg + f'it is already a member of bridge "{tmp}"!')
if 'is_bond_member' in interface_config:
- tmp = next(iter(interface_config['is_bond_member']))
+ tmp = interface_config['is_bond_member']
raise ConfigError(error_msg + f'it is already a member of bond "{tmp}"!')
if 'is_source_interface' in interface_config:
@@ -181,6 +188,8 @@ def verify(bond):
if 'has_address' in interface_config:
raise ConfigError(error_msg + 'it has an address assigned!')
+ if 'has_vrf' in interface_config:
+ raise ConfigError(error_msg + 'it has a VRF assigned!')
if 'primary' in bond:
if bond['primary'] not in bond['member']['interface']:
diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py
index 38ae727c1..cd0d9003b 100755
--- a/src/conf_mode/interfaces-bridge.py
+++ b/src/conf_mode/interfaces-bridge.py
@@ -31,6 +31,7 @@ from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vrf
from vyos.ifconfig import BridgeIf
from vyos.validate import has_address_configured
+from vyos.validate import has_vrf_configured
from vyos.xml import defaults
from vyos.util import cmd
@@ -93,6 +94,10 @@ def get_config(config=None):
tmp = has_address_configured(conf, interface)
if tmp: bridge['member']['interface'][interface].update({'has_address' : ''})
+ # Bridge members must not have a VRF attached
+ tmp = has_vrf_configured(conf, interface)
+ if tmp: bridge['member']['interface'][interface].update({'has_vrf' : ''})
+
# VLAN-aware bridge members must not have VLAN interface configuration
tmp = has_vlan_subinterface_configured(conf,interface)
if 'enable_vlan' in bridge and tmp:
@@ -118,11 +123,11 @@ def verify(bridge):
raise ConfigError('Loopback interface "lo" can not be added to a bridge')
if 'is_bridge_member' in interface_config:
- tmp = next(iter(interface_config['is_bridge_member']))
+ tmp = interface_config['is_bridge_member']
raise ConfigError(error_msg + f'it is already a member of bridge "{tmp}"!')
if 'is_bond_member' in interface_config:
- tmp = next(iter(interface_config['is_bond_member']))
+ tmp = interface_config['is_bond_member']
raise ConfigError(error_msg + f'it is already a member of bond "{tmp}"!')
if 'is_source_interface' in interface_config:
@@ -132,9 +137,12 @@ def verify(bridge):
if 'has_address' in interface_config:
raise ConfigError(error_msg + 'it has an address assigned!')
+ if 'has_vrf' in interface_config:
+ raise ConfigError(error_msg + 'it has a VRF assigned!')
+
if 'enable_vlan' in bridge:
if 'has_vlan' in interface_config:
- raise ConfigError(error_msg + 'it has an VLAN subinterface assigned!')
+ raise ConfigError(error_msg + 'it has VLAN subinterface(s) assigned!')
if 'wlan' in interface:
raise ConfigError(error_msg + 'VLAN aware cannot be set!')
diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py
index fec4456fb..30e7a2af7 100755
--- a/src/conf_mode/interfaces-ethernet.py
+++ b/src/conf_mode/interfaces-ethernet.py
@@ -31,6 +31,7 @@ from vyos.configverify import verify_mtu
from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
+from vyos.configverify import verify_bond_bridge_member
from vyos.ethtool import Ethtool
from vyos.ifconfig import EthernetIf
from vyos.pki import find_chain
@@ -83,6 +84,7 @@ def verify(ethernet):
verify_dhcpv6(ethernet)
verify_address(ethernet)
verify_vrf(ethernet)
+ verify_bond_bridge_member(ethernet)
verify_eapol(ethernet)
verify_mirror_redirect(ethernet)
diff --git a/src/conf_mode/interfaces-geneve.py b/src/conf_mode/interfaces-geneve.py
index b9cf2fa3c..08cc3a48d 100755
--- a/src/conf_mode/interfaces-geneve.py
+++ b/src/conf_mode/interfaces-geneve.py
@@ -27,6 +27,7 @@ from vyos.configverify import verify_address
from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mirror_redirect
+from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import GeneveIf
from vyos import ConfigError
@@ -64,6 +65,7 @@ def verify(geneve):
verify_mtu_ipv6(geneve)
verify_address(geneve)
+ verify_bond_bridge_member(geneve)
verify_mirror_redirect(geneve)
if 'remote' not in geneve:
diff --git a/src/conf_mode/interfaces-l2tpv3.py b/src/conf_mode/interfaces-l2tpv3.py
index 6a486f969..ca321e01d 100755
--- a/src/conf_mode/interfaces-l2tpv3.py
+++ b/src/conf_mode/interfaces-l2tpv3.py
@@ -26,6 +26,7 @@ from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_mirror_redirect
+from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import L2TPv3If
from vyos.util import check_kmod
from vyos.validate import is_addr_assigned
@@ -77,6 +78,7 @@ def verify(l2tpv3):
verify_mtu_ipv6(l2tpv3)
verify_address(l2tpv3)
+ verify_bond_bridge_member(l2tpv3)
verify_mirror_redirect(l2tpv3)
return None
diff --git a/src/conf_mode/interfaces-macsec.py b/src/conf_mode/interfaces-macsec.py
index 279dd119b..03a010086 100755
--- a/src/conf_mode/interfaces-macsec.py
+++ b/src/conf_mode/interfaces-macsec.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-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
@@ -21,16 +21,20 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import get_interface_dict
-from vyos.ifconfig import MACsecIf
-from vyos.ifconfig import Interface
-from vyos.template import render
-from vyos.util import call
+from vyos.configdict import is_node_changed
from vyos.configverify import verify_vrf
from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_source_interface
+from vyos.configverify import verify_bond_bridge_member
+from vyos.ifconfig import MACsecIf
+from vyos.ifconfig import Interface
+from vyos.template import render
+from vyos.util import call
+from vyos.util import dict_search
+from vyos.util import is_systemd_service_running
from vyos import ConfigError
from vyos import airbag
airbag.enable()
@@ -55,6 +59,12 @@ def get_config(config=None):
source_interface = conf.return_effective_value(['source-interface'])
macsec.update({'source_interface': source_interface})
+ if is_node_changed(conf, base + [ifname, 'security']):
+ macsec.update({'shutdown_required': {}})
+
+ if is_node_changed(conf, base + [ifname, 'source_interface']):
+ macsec.update({'shutdown_required': {}})
+
return macsec
@@ -67,22 +77,15 @@ def verify(macsec):
verify_vrf(macsec)
verify_mtu_ipv6(macsec)
verify_address(macsec)
+ verify_bond_bridge_member(macsec)
verify_mirror_redirect(macsec)
- if not (('security' in macsec) and
- ('cipher' in macsec['security'])):
- raise ConfigError(
- 'Cipher suite must be set for MACsec "{ifname}"'.format(**macsec))
+ if dict_search('security.cipher', macsec) == None:
+ raise ConfigError('Cipher suite must be set for MACsec "{ifname}"'.format(**macsec))
- if (('security' in macsec) and
- ('encrypt' in macsec['security'])):
- tmp = macsec.get('security')
-
- if not (('mka' in tmp) and
- ('cak' in tmp['mka']) and
- ('ckn' in tmp['mka'])):
- raise ConfigError('Missing mandatory MACsec security '
- 'keys as encryption is enabled!')
+ if dict_search('security.encrypt', macsec) != None:
+ if dict_search('security.mka.cak', macsec) == None or dict_search('security.mka.ckn', macsec) == None:
+ raise ConfigError('Missing mandatory MACsec security keys as encryption is enabled!')
if 'source_interface' in macsec:
# MACsec adds a 40 byte overhead (32 byte MACsec + 8 bytes VLAN 802.1ad
@@ -97,33 +100,35 @@ def verify(macsec):
def generate(macsec):
- render(wpa_suppl_conf.format(**macsec),
- 'macsec/wpa_supplicant.conf.j2', macsec)
+ render(wpa_suppl_conf.format(**macsec), 'macsec/wpa_supplicant.conf.j2', macsec)
return None
def apply(macsec):
- # Remove macsec interface
- if 'deleted' in macsec:
- call('systemctl stop wpa_supplicant-macsec@{source_interface}'
- .format(**macsec))
+ systemd_service = 'wpa_supplicant-macsec@{source_interface}'.format(**macsec)
+
+ # Remove macsec interface on deletion or mandatory parameter change
+ if 'deleted' in macsec or 'shutdown_required' in macsec:
+ call(f'systemctl stop {systemd_service}')
if macsec['ifname'] in interfaces():
tmp = MACsecIf(macsec['ifname'])
tmp.remove()
- # delete configuration on interface removal
- if os.path.isfile(wpa_suppl_conf.format(**macsec)):
- os.unlink(wpa_suppl_conf.format(**macsec))
+ if 'deleted' in macsec:
+ # delete configuration on interface removal
+ if os.path.isfile(wpa_suppl_conf.format(**macsec)):
+ os.unlink(wpa_suppl_conf.format(**macsec))
- else:
- # It is safe to "re-create" the interface always, there is a sanity
- # check that the interface will only be create if its non existent
- i = MACsecIf(**macsec)
- i.update(macsec)
+ return None
+
+ # It is safe to "re-create" the interface always, there is a sanity
+ # check that the interface will only be create if its non existent
+ i = MACsecIf(**macsec)
+ i.update(macsec)
- call('systemctl restart wpa_supplicant-macsec@{source_interface}'
- .format(**macsec))
+ if not is_systemd_service_running(systemd_service) or 'shutdown_required' in macsec:
+ call(f'systemctl reload-or-restart {systemd_service}')
return None
diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py
index 280a62b9a..ef745d737 100755
--- a/src/conf_mode/interfaces-openvpn.py
+++ b/src/conf_mode/interfaces-openvpn.py
@@ -36,6 +36,7 @@ from vyos.configdict import is_node_changed
from vyos.configverify import verify_vrf
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mirror_redirect
+from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import VTunIf
from vyos.pki import load_dh_parameters
from vyos.pki import load_private_key
@@ -503,6 +504,7 @@ def verify(openvpn):
raise ConfigError('Username for authentication is missing')
verify_vrf(openvpn)
+ verify_bond_bridge_member(openvpn)
verify_mirror_redirect(openvpn)
return None
diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py
index 1cd3fe276..f26a50a0e 100755
--- a/src/conf_mode/interfaces-pseudo-ethernet.py
+++ b/src/conf_mode/interfaces-pseudo-ethernet.py
@@ -26,6 +26,7 @@ from vyos.configverify import verify_source_interface
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_mtu_parent
from vyos.configverify import verify_mirror_redirect
+from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import MACVLANIf
from vyos import ConfigError
diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py
index eff7f373c..acef1fda7 100755
--- a/src/conf_mode/interfaces-tunnel.py
+++ b/src/conf_mode/interfaces-tunnel.py
@@ -29,6 +29,7 @@ from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vrf
from vyos.configverify import verify_tunnel
+from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import Interface
from vyos.ifconfig import Section
from vyos.ifconfig import TunnelIf
@@ -158,6 +159,7 @@ def verify(tunnel):
verify_mtu_ipv6(tunnel)
verify_address(tunnel)
verify_vrf(tunnel)
+ verify_bond_bridge_member(tunnel)
verify_mirror_redirect(tunnel)
if 'source_interface' in tunnel:
diff --git a/src/conf_mode/interfaces-vxlan.py b/src/conf_mode/interfaces-vxlan.py
index f44d754ba..af2d0588d 100755
--- a/src/conf_mode/interfaces-vxlan.py
+++ b/src/conf_mode/interfaces-vxlan.py
@@ -29,6 +29,7 @@ from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_source_interface
+from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import Interface
from vyos.ifconfig import VXLANIf
from vyos.template import is_ipv6
@@ -117,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} '\
@@ -144,6 +150,7 @@ def verify(vxlan):
verify_mtu_ipv6(vxlan)
verify_address(vxlan)
+ verify_bond_bridge_member(vxlan)
verify_mirror_redirect(vxlan)
return None
diff --git a/src/conf_mode/interfaces-wireguard.py b/src/conf_mode/interfaces-wireguard.py
index 180ffa507..61bab2feb 100755
--- a/src/conf_mode/interfaces-wireguard.py
+++ b/src/conf_mode/interfaces-wireguard.py
@@ -29,6 +29,7 @@ from vyos.configverify import verify_address
from vyos.configverify import verify_bridge_delete
from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_mirror_redirect
+from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import WireGuardIf
from vyos.util import check_kmod
from vyos.util import check_port_availability
@@ -71,6 +72,7 @@ def verify(wireguard):
verify_mtu_ipv6(wireguard)
verify_address(wireguard)
verify_vrf(wireguard)
+ verify_bond_bridge_member(wireguard)
verify_mirror_redirect(wireguard)
if 'private_key' not in wireguard:
diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py
index d34297063..dd798b5a2 100755
--- a/src/conf_mode/interfaces-wireless.py
+++ b/src/conf_mode/interfaces-wireless.py
@@ -30,6 +30,7 @@ from vyos.configverify import verify_source_interface
from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
+from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import WiFiIf
from vyos.template import render
from vyos.util import call
@@ -194,6 +195,7 @@ def verify(wifi):
verify_address(wifi)
verify_vrf(wifi)
+ verify_bond_bridge_member(wifi)
verify_mirror_redirect(wifi)
# use common function to verify VLAN configuration
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 01f14df61..7d3687094 100755
--- a/src/conf_mode/protocols_bgp.py
+++ b/src/conf_mode/protocols_bgp.py
@@ -101,6 +101,17 @@ def verify_remote_as(peer_config, bgp_config):
return None
+def verify_afi(peer_config, bgp_config):
+ if 'address_family' in peer_config:
+ return True
+
+ if 'peer_group' in peer_config:
+ peer_group_name = peer_config['peer_group']
+ tmp = dict_search(f'peer_group.{peer_group_name}.address_family', bgp_config)
+ if tmp: return True
+
+ return False
+
def verify(bgp):
if not bgp or 'deleted' in bgp:
if 'dependent_vrfs' in bgp:
@@ -165,6 +176,9 @@ def verify(bgp):
if not verify_remote_as(peer_config, bgp):
raise ConfigError(f'Neighbor "{peer}" remote-as must be set!')
+ if not verify_afi(peer_config, bgp):
+ Warning(f'BGP neighbor "{peer}" requires address-family!')
+
# Peer-group member cannot override remote-as of peer-group
if 'peer_group' in peer_config:
peer_group = peer_config['peer_group']
@@ -199,8 +213,11 @@ def verify(bgp):
if 'source_interface' in peer_config['interface']:
raise ConfigError(f'"source-interface" option not allowed for neighbor "{peer}"')
- if 'address_family' not in peer_config:
- Warning(f'BGP neighbor "{peer}" requires address-family!')
+ # 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',
diff --git a/src/conf_mode/service_ids_fastnetmon.py b/src/conf_mode/service_ids_fastnetmon.py
index ae7e582ec..c58f8db9a 100755
--- a/src/conf_mode/service_ids_fastnetmon.py
+++ b/src/conf_mode/service_ids_fastnetmon.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2020 VyOS maintainers and contributors
+# Copyright (C) 2018-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
@@ -19,14 +19,17 @@ import os
from sys import exit
from vyos.config import Config
-from vyos import ConfigError
-from vyos.util import call
+from vyos.configdict import dict_merge
from vyos.template import render
+from vyos.util import call
+from vyos.xml import defaults
+from vyos import ConfigError
from vyos import airbag
airbag.enable()
-config_file = r'/etc/fastnetmon.conf'
-networks_list = r'/etc/networks_list'
+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:
@@ -34,50 +37,55 @@ def get_config(config=None):
else:
conf = Config()
base = ['service', 'ids', 'ddos-protection']
+ if not conf.exists(base):
+ return None
+
fastnetmon = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ default_values = defaults(base)
+ fastnetmon = dict_merge(default_values, fastnetmon)
+
return fastnetmon
def verify(fastnetmon):
if not fastnetmon:
return None
- if not "mode" in fastnetmon:
- raise ConfigError('ddos-protection mode is mandatory!')
-
- if not "network" in fastnetmon:
- raise ConfigError('Required define network!')
+ if 'mode' not in fastnetmon:
+ raise ConfigError('Specify operating mode!')
- if not "listen_interface" in fastnetmon:
- raise ConfigError('Define listen-interface is mandatory!')
+ if 'listen_interface' not in fastnetmon:
+ raise ConfigError('Specify interface(s) for traffic capture')
- if "alert_script" in fastnetmon:
- if os.path.isfile(fastnetmon["alert_script"]):
+ if 'alert_script' in fastnetmon:
+ if os.path.isfile(fastnetmon['alert_script']):
# Check script permissions
- if not os.access(fastnetmon["alert_script"], os.X_OK):
- raise ConfigError('Script {0} does not have permissions for execution'.format(fastnetmon["alert_script"]))
+ if not os.access(fastnetmon['alert_script'], os.X_OK):
+ raise ConfigError('Script "{alert_script}" is not executable!'.format(fastnetmon['alert_script']))
else:
- raise ConfigError('File {0} does not exists!'.format(fastnetmon["alert_script"]))
+ raise ConfigError('File "{alert_script}" does not exists!'.format(fastnetmon))
def generate(fastnetmon):
if not fastnetmon:
- if os.path.isfile(config_file):
- os.unlink(config_file)
- if os.path.isfile(networks_list):
- os.unlink(networks_list)
+ for file in [config_file, networks_list]:
+ if os.path.isfile(file):
+ os.unlink(file)
- return
+ return None
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):
+ systemd_service = 'fastnetmon.service'
if not fastnetmon:
# Stop fastnetmon service if removed
- call('systemctl stop fastnetmon.service')
+ call(f'systemctl stop {systemd_service}')
else:
- call('systemctl restart fastnetmon.service')
+ call(f'systemctl reload-or-restart {systemd_service}')
return None
diff --git a/src/conf_mode/system-ip.py b/src/conf_mode/system-ip.py
index 05fc3a97a..0c5063ed3 100755
--- a/src/conf_mode/system-ip.py
+++ b/src/conf_mode/system-ip.py
@@ -64,6 +64,11 @@ def apply(opt):
value = '0' if (tmp != None) else '1'
write_file('/proc/sys/net/ipv4/conf/all/forwarding', value)
+ # enable/disable IPv4 directed broadcast forwarding
+ tmp = dict_search('disable_directed_broadcast', opt)
+ value = '0' if (tmp != None) else '1'
+ write_file('/proc/sys/net/ipv4/conf/all/bc_forwarding', value)
+
# configure multipath
tmp = dict_search('multipath.ignore_unreachable_nexthops', opt)
value = '1' if (tmp != None) else '0'
diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py
index c717286ae..3dcbc995c 100755
--- a/src/conf_mode/system-login.py
+++ b/src/conf_mode/system-login.py
@@ -231,7 +231,7 @@ def apply(login):
if tmp: command += f" --home '{tmp}'"
else: command += f" --home '/home/{user}'"
- command += f' --groups frrvty,vyattacfg,sudo,adm,dip,disk {user}'
+ command += f' --groups frr,frrvty,vyattacfg,sudo,adm,dip,disk {user}'
try:
cmd(command)
diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py
index 972d0289b..1b4156895 100755
--- a/src/conf_mode/vrf.py
+++ b/src/conf_mode/vrf.py
@@ -113,8 +113,14 @@ def verify(vrf):
f'static routes installed!')
if 'name' in vrf:
+ reserved_names = ["add", "all", "broadcast", "default", "delete", "dev", "get", "inet", "mtu", "link", "type",
+ "vrf"]
table_ids = []
for name, config in vrf['name'].items():
+ # Reserved VRF names
+ if name in reserved_names:
+ raise ConfigError(f'VRF name "{name}" is reserved and connot be used!')
+
# table id is mandatory
if 'table' not in config:
raise ConfigError(f'VRF "{name}" table id is mandatory!')