diff options
25 files changed, 169 insertions, 201 deletions
diff --git a/interface-definitions/include/accel-auth-mode.xml.i b/interface-definitions/include/accel-auth-mode.xml.i new file mode 100644 index 000000000..e719112db --- /dev/null +++ b/interface-definitions/include/accel-auth-mode.xml.i @@ -0,0 +1,19 @@ +<leafNode name="mode"> + <properties> + <help>Authentication mode used by this server</help> + <valueHelp> + <format>local</format> + <description>Use local username/password configuration</description> + </valueHelp> + <valueHelp> + <format>radius</format> + <description>Use RADIUS server for user autentication</description> + </valueHelp> + <constraint> + <regex>(local|radius)</regex> + </constraint> + <completionHelp> + <list>local radius</list> + </completionHelp> + </properties> +</leafNode> diff --git a/interface-definitions/include/dhcp-dhcpv6-options.xml.i b/interface-definitions/include/dhcp-dhcpv6-options.xml.i index 104b1fbe0..e4387863b 100644 --- a/interface-definitions/include/dhcp-dhcpv6-options.xml.i +++ b/interface-definitions/include/dhcp-dhcpv6-options.xml.i @@ -23,7 +23,6 @@ <node name="dhcpv6-options"> <properties> <help>DHCPv6 options</help> - <priority>319</priority> </properties> <children> <leafNode name="parameters-only"> diff --git a/interface-definitions/interfaces-pseudo-ethernet.xml.in b/interface-definitions/interfaces-pseudo-ethernet.xml.in index d13561232..ea267cf81 100644 --- a/interface-definitions/interfaces-pseudo-ethernet.xml.in +++ b/interface-definitions/interfaces-pseudo-ethernet.xml.in @@ -45,7 +45,7 @@ <help>Physical Interface used for this device</help> <valueHelp> <format>interface</format> - <description>Interface used for VXLAN underlay</description> + <description>Physical interface used for this pseudo device</description> </valueHelp> <completionHelp> <script>${vyos_completion_dir}/list_interfaces.py -t ethernet</script> diff --git a/interface-definitions/interfaces-tunnel.xml.in b/interface-definitions/interfaces-tunnel.xml.in index e1ac60319..a38a73e15 100644 --- a/interface-definitions/interfaces-tunnel.xml.in +++ b/interface-definitions/interfaces-tunnel.xml.in @@ -66,6 +66,14 @@ </constraint> </properties> </leafNode> + <leafNode name="source-interface"> + <properties> + <help>Physical Interface used for underlaying traffic</help> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces.py</script> + </completionHelp> + </properties> + </leafNode> <leafNode name="6rd-prefix"> <properties> <help>6rd network prefix</help> diff --git a/interface-definitions/service_pppoe-server.xml.in b/interface-definitions/service_pppoe-server.xml.in index 0eff18e5c..27669f1c3 100644 --- a/interface-definitions/service_pppoe-server.xml.in +++ b/interface-definitions/service_pppoe-server.xml.in @@ -107,25 +107,7 @@ </tagNode> </children> </node> - <leafNode name="mode"> - <properties> - <help>Authentication mode for PPPoE Server</help> - <valueHelp> - <format>local</format> - <description>Use local username/password configuration</description> - </valueHelp> - <valueHelp> - <format>radius</format> - <description>Use a RADIUS server to autenticate users</description> - </valueHelp> - <constraint> - <regex>(local|radius)</regex> - </constraint> - <completionHelp> - <list>local radius</list> - </completionHelp> - </properties> - </leafNode> + #include <include/accel-auth-mode.xml.i> #include <include/radius-server.xml.i> #include <include/accel-radius-additions.xml.in> <node name="radius"> diff --git a/interface-definitions/vpn_l2tp.xml.in b/interface-definitions/vpn_l2tp.xml.in index 278f52ba6..ab0435172 100644 --- a/interface-definitions/vpn_l2tp.xml.in +++ b/interface-definitions/vpn_l2tp.xml.in @@ -294,25 +294,7 @@ </completionHelp> </properties> </leafNode> - <leafNode name="mode"> - <properties> - <help>Authentication mode for remote access L2TP VPN</help> - <valueHelp> - <format>local</format> - <description>Use local username/password configuration</description> - </valueHelp> - <valueHelp> - <format>radius</format> - <description>Use a RADIUS server to autenticate users</description> - </valueHelp> - <constraint> - <regex>(local|radius)</regex> - </constraint> - <completionHelp> - <list>local radius</list> - </completionHelp> - </properties> - </leafNode> + #include <include/accel-auth-mode.xml.i> <node name="local-users"> <properties> <help>Local user authentication for remote access L2TP VPN</help> diff --git a/interface-definitions/vpn_pptp.xml.in b/interface-definitions/vpn_pptp.xml.in index 5d8ead2aa..439fd7259 100644 --- a/interface-definitions/vpn_pptp.xml.in +++ b/interface-definitions/vpn_pptp.xml.in @@ -162,25 +162,7 @@ </completionHelp> </properties> </leafNode> - <leafNode name="mode"> - <properties> - <help>Authentication mode for remote access PPTP VPN</help> - <valueHelp> - <format>local</format> - <description>Use local username/password configuration</description> - </valueHelp> - <valueHelp> - <format>radius</format> - <description>Use a RADIUS server to autenticate users</description> - </valueHelp> - <constraint> - <regex>(local|radius)</regex> - </constraint> - <completionHelp> - <list>local radius</list> - </completionHelp> - </properties> - </leafNode> + #include <include/accel-auth-mode.xml.i> <node name="local-users"> <properties> <help>Local user authentication for remote access PPTP VPN</help> diff --git a/interface-definitions/vpn_sstp.xml.in b/interface-definitions/vpn_sstp.xml.in index b5a1b6800..7e4471015 100644 --- a/interface-definitions/vpn_sstp.xml.in +++ b/interface-definitions/vpn_sstp.xml.in @@ -66,25 +66,7 @@ </tagNode> </children> </node> - <leafNode name="mode"> - <properties> - <help>Authentication mode for SSTP Server</help> - <valueHelp> - <format>local</format> - <description>Use local username/password configuration</description> - </valueHelp> - <valueHelp> - <format>radius</format> - <description>Use a RADIUS server to autenticate users</description> - </valueHelp> - <constraint> - <regex>(local|radius)</regex> - </constraint> - <completionHelp> - <list>local radius</list> - </completionHelp> - </properties> - </leafNode> + #include <include/accel-auth-mode.xml.i> <leafNode name="protocols"> <properties> <help>Authentication protocol for remote access peer SSTP VPN</help> diff --git a/op-mode-definitions/dhcp.xml b/op-mode-definitions/dhcp.xml index f142cdd0e..2013d0014 100644 --- a/op-mode-definitions/dhcp.xml +++ b/op-mode-definitions/dhcp.xml @@ -149,7 +149,7 @@ <properties> <help>Restart the DHCPv6 server process</help> </properties> - <command>sudo systemctl restart isc-dhcpv6-server.service</command> + <command>sudo systemctl restart isc-dhcp-server6.service</command> </node> <node name="relay-agent"> <properties> diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py index 542de4f59..5b18926c9 100644 --- a/python/vyos/ifconfig/ethernet.py +++ b/python/vyos/ifconfig/ethernet.py @@ -40,6 +40,7 @@ class EthernetIf(Interface): 'bondable': True, 'broadcast': True, 'bridgeable': True, + 'eternal': '(lan|eth|eno|ens|enp|enx)[0-9]+$', } } @@ -76,10 +77,6 @@ class EthernetIf(Interface): }, }} - def _delete(self): - # Ethernet interfaces can not be removed - pass - def get_driver_name(self): """ Return the driver name used by NIC. Some NICs don't support all diff --git a/python/vyos/ifconfig/geneve.py b/python/vyos/ifconfig/geneve.py index 0c1cdade9..145dc268c 100644 --- a/python/vyos/ifconfig/geneve.py +++ b/python/vyos/ifconfig/geneve.py @@ -35,6 +35,8 @@ class GeneveIf(Interface): 'vni': 0, 'remote': '', } + options = Interface.options + \ + ['vni', 'remote'] definition = { **Interface.definition, **{ diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 5b26f8bab..62c30dbf7 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -14,6 +14,7 @@ # License along with this library. If not, see <http://www.gnu.org/licenses/>. import os +import re import json from copy import deepcopy @@ -63,6 +64,7 @@ class Interface(Control): 'bondable': False, 'broadcast': False, 'bridgeable': False, + 'eternal': '', } _command_get = { @@ -249,28 +251,14 @@ class Interface(Control): self.del_addr(addr) # --------------------------------------------------------------------- - # A code refactoring is required as this type check is present as - # Interface implement behaviour for one of it's sub-class. - - # It is required as the current pattern for vlan is: - # Interface('name').remove() to delete an interface - # The code should be modified to have a class method called connect and - # have Interface.connect('name').remove() - - # each subclass should register within Interface the pattern for that - # interface ie: (ethX, etc.) and use this to create an instance of - # the right class (EthernetIf, ...) - - # Ethernet interfaces can not be removed - - # Commented out as nowhere in the code do we call Interface() - # This would also cause an import loop - # if self.__class__ == EthernetIf: - # return - - # --------------------------------------------------------------------- - - self._delete() + # Any class can define an eternal regex in its definition + # interface matching the regex will not be deleted + + eternal = self.definition['eternal'] + if not eternal: + self._delete() + elif not re.match(eternal, self.ifname): + self._delete() def _delete(self): # NOTE (Improvement): diff --git a/python/vyos/ifconfig/macvlan.py b/python/vyos/ifconfig/macvlan.py index 37228e57f..b5481f4a7 100644 --- a/python/vyos/ifconfig/macvlan.py +++ b/python/vyos/ifconfig/macvlan.py @@ -13,6 +13,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with this library. If not, see <http://www.gnu.org/licenses/>. +from copy import deepcopy from vyos.ifconfig.interface import Interface from vyos.ifconfig.vlan import VLAN @@ -27,6 +28,9 @@ class MACVLANIf(Interface): default = { 'type': 'macvlan', + 'address': '', + 'source_interface': '', + 'mode': '', } definition = { **Interface.definition, @@ -39,30 +43,28 @@ class MACVLANIf(Interface): ['source_interface', 'mode'] def _create(self): - cmd = 'ip link add {ifname} link {source_interface} type macvlan mode {mode}'.format( - **self.config) - self._cmd(cmd) + # please do not change the order when assembling the command + cmd = 'ip link add {ifname}' + if self.config['source_interface']: + cmd += ' link {source_interface}' + cmd += ' type macvlan' + if self.config['mode']: + cmd += ' mode {mode}' + self._cmd(cmd.format(**self.config)) - @staticmethod - def get_config(): + def set_mode(self, mode): + ifname = self.config['ifname'] + cmd = f'ip link set dev {ifname} type macvlan mode {mode}' + return self._cmd(cmd) + + @classmethod + def get_config(cls): """ - VXLAN interfaces require a configuration when they are added using - iproute2. This static method will provide the configuration dictionary - used by this class. + MACVLAN interfaces require a configuration when they are added using + iproute2. This method will provide the configuration dictionary used + by this class. Example: >> dict = MACVLANIf().get_config() """ - config = { - 'address': '', - 'source_interface': '', - 'mode': '' - } - return config - - def set_mode(self, mode): - """ - """ - ifname = self.config['ifname'] - cmd = f'ip link set dev {ifname} type macvlan mode {mode}' - return self._cmd(cmd) + return deepcopy(cls.default) diff --git a/python/vyos/ifconfig/tunnel.py b/python/vyos/ifconfig/tunnel.py index 009a53a82..85c22b5b4 100644 --- a/python/vyos/ifconfig/tunnel.py +++ b/python/vyos/ifconfig/tunnel.py @@ -43,7 +43,7 @@ class _Tunnel(Interface): **{ 'section': 'tunnel', 'prefixes': ['tun',], - 'bridgeable': True, + 'bridgeable': False, }, } @@ -135,14 +135,21 @@ class GREIf(_Tunnel): https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/ip/link_gre.c """ + definition = { + **_Tunnel.definition, + **{ + 'bridgeable': True, + }, + } + ip = [IP4, IP6] tunnel = IP4 default = {'type': 'gre'} required = ['local', ] # mGRE is a GRE without remote endpoint - options = ['local', 'remote', 'ttl', 'tos', 'key'] - updates = ['local', 'remote', 'ttl', 'tos', + options = ['local', 'remote', 'dev', 'ttl', 'tos', 'key'] + updates = ['local', 'remote', 'dev', 'ttl', 'tos', 'mtu', 'multicast', 'allmulticast'] create = 'ip tunnel add {ifname} mode {type}' @@ -160,6 +167,13 @@ class GRETapIf(_Tunnel): # no multicast, ttl or tos for gretap + definition = { + **_Tunnel.definition, + **{ + 'bridgeable': True, + }, + } + ip = [IP4, ] tunnel = IP4 @@ -189,9 +203,9 @@ class IP6GREIf(_Tunnel): default = {'type': 'ip6gre'} required = ['local', 'remote'] - options = ['local', 'remote', 'encaplimit', + options = ['local', 'remote', 'dev', 'encaplimit', 'hoplimit', 'tclass', 'flowlabel'] - updates = ['local', 'remote', 'encaplimit', + updates = ['local', 'remote', 'dev', 'encaplimit', 'hoplimit', 'tclass', 'flowlabel', 'mtu', 'multicast', 'allmulticast'] @@ -225,8 +239,8 @@ class IPIPIf(_Tunnel): default = {'type': 'ipip'} required = ['local', 'remote'] - options = ['local', 'remote', 'ttl', 'tos', 'key'] - updates = ['local', 'remote', 'ttl', 'tos', + options = ['local', 'remote', 'dev', 'ttl', 'tos', 'key'] + updates = ['local', 'remote', 'dev', 'ttl', 'tos', 'mtu', 'multicast', 'allmulticast'] create = 'ip tunnel add {ifname} mode {type}' @@ -248,9 +262,9 @@ class IPIP6If(_Tunnel): default = {'type': 'ipip6'} required = ['local', 'remote'] - options = ['local', 'remote', 'encaplimit', + options = ['local', 'remote', 'dev', 'encaplimit', 'hoplimit', 'tclass', 'flowlabel'] - updates = ['local', 'remote', 'encaplimit', + updates = ['local', 'remote', 'dev', 'encaplimit', 'hoplimit', 'tclass', 'flowlabel', 'mtu', 'multicast', 'allmulticast'] @@ -286,8 +300,8 @@ class SitIf(_Tunnel): default = {'type': 'sit'} required = ['local', 'remote'] - options = ['local', 'remote', 'ttl', 'tos', 'key'] - updates = ['local', 'remote', 'ttl', 'tos', + options = ['local', 'remote', 'dev', 'ttl', 'tos', 'key'] + updates = ['local', 'remote', 'dev', 'ttl', 'tos', 'mtu', 'multicast', 'allmulticast'] create = 'ip tunnel add {ifname} mode {type}' diff --git a/python/vyos/ifconfig/vrrp.py b/python/vyos/ifconfig/vrrp.py index 29b10dd9e..a872725b2 100644 --- a/python/vyos/ifconfig/vrrp.py +++ b/python/vyos/ifconfig/vrrp.py @@ -109,7 +109,7 @@ class VRRP(object): return [] disabled = [] - config = json.loads(util.readfile(cls.location['vyos'])) + config = json.loads(util.read_file(cls.location['vyos'])) # add disabled groups to the list for group in config['vrrp_groups']: diff --git a/python/vyos/remote.py b/python/vyos/remote.py index 1b4d3876e..3f46d979b 100644 --- a/python/vyos/remote.py +++ b/python/vyos/remote.py @@ -91,7 +91,7 @@ def get_remote_config(remote_file): ftp://<user>[:<passwd>]@<host>/<file> tftp://<host>/<file> """ - request = dict.fromkeys(['protocol', 'host', 'file', 'user', 'passwd']) + request = dict.fromkeys(['protocol', 'user', 'host', 'file']) protocols = ['scp', 'sftp', 'http', 'https', 'ftp', 'tftp'] or_protocols = '|'.join(protocols) @@ -108,11 +108,6 @@ def get_remote_config(remote_file): if user_match: request['user'] = user_match.groups()[0] request['host'] = user_match.groups()[1] - passwd_match = re.search(r'(.*):(.*)', request['user']) - if passwd_match: - # Deprectated in RFC 3986, but maintain for backward compatability. - request['user'] = passwd_match.groups()[0] - request['passwd'] = passwd_match.groups()[1] remote_file = '{0}://{1}{2}'.format(request['protocol'], request['host'], request['file']) @@ -137,7 +132,7 @@ def get_remote_config(remote_file): print('HTTP error: {0} {1}'.format(*val)) sys.exit(1) - if request['user'] and not request['passwd']: + if request['user']: curl_cmd = 'curl -# -u {0} {1}'.format(request['user'], remote_file) else: curl_cmd = 'curl {0} -# {1}'.format(redirect_opt, remote_file) diff --git a/python/vyos/util.py b/python/vyos/util.py index b1d95fbbf..3d4f1c42f 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -155,7 +155,8 @@ def call(command, flag='', shell=None, input=None, timeout=None, env=None, env=env, shell=shell, decode=decode, ) - print(out) + if out: + print(out) return code diff --git a/src/conf_mode/dhcpv6_server.py b/src/conf_mode/dhcpv6_server.py index 94a307826..ce98e39c3 100755 --- a/src/conf_mode/dhcpv6_server.py +++ b/src/conf_mode/dhcpv6_server.py @@ -213,6 +213,10 @@ def get_config(): # append shared network configuration to config dictionary dhcpv6['shared_network'].append(config) + # If all shared-networks are disabled, there's nothing to do. + if all(net['disabled'] for net in dhcpv6['shared_network']): + return None + return dhcpv6 def verify(dhcpv6): @@ -302,22 +306,22 @@ def verify(dhcpv6): else: subnets.append(subnet['network']) - # DHCPv6 requires at least one configured address range or one static mapping - # (FIXME: is not actually checked right now?) + # DHCPv6 requires at least one configured address range or one static mapping + # (FIXME: is not actually checked right now?) - # There must be one subnet connected to a listen interface if network is not disabled. - if not network['disabled']: - if is_subnet_connected(subnet['network']): - listen_ok = True + # There must be one subnet connected to a listen interface if network is not disabled. + if not network['disabled']: + if is_subnet_connected(subnet['network']): + listen_ok = True - # DHCPv6 subnet must not overlap. ISC DHCP also complains about overlapping - # subnets: "Warning: subnet 2001:db8::/32 overlaps subnet 2001:db8:1::/32" - net = ipaddress.ip_network(subnet['network']) - for n in subnets: - net2 = ipaddress.ip_network(n) - if (net != net2): - if net.overlaps(net2): - raise ConfigError('DHCPv6 conflicting subnet ranges: {0} overlaps {1}'.format(net, net2)) + # DHCPv6 subnet must not overlap. ISC DHCP also complains about overlapping + # subnets: "Warning: subnet 2001:db8::/32 overlaps subnet 2001:db8:1::/32" + net = ipaddress.ip_network(subnet['network']) + for n in subnets: + net2 = ipaddress.ip_network(n) + if (net != net2): + if net.overlaps(net2): + raise ConfigError('DHCPv6 conflicting subnet ranges: {0} overlaps {1}'.format(net, net2)) if not listen_ok: raise ConfigError('None of the DHCPv6 subnets are connected to a subnet6 on\n' \ @@ -346,6 +350,7 @@ def apply(dhcpv6): if os.path.exists(config_file): os.unlink(config_file) + else: call('systemctl restart isc-dhcp-server6.service') return None diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index a669580ae..f181a7b35 100755 --- a/src/conf_mode/host_name.py +++ b/src/conf_mode/host_name.py @@ -164,10 +164,17 @@ def apply(config): if process_named_running('snmpd'): call('systemctl restart snmpd.service') - # restart pdns if it is used - ret = run('/usr/bin/rec_control --socket-dir=/run/powerdns ping') - if ret == 0: - call('systemctl restart pdns-recursor.service') + # restart pdns if it is used - we check for the control dir to not raise + # an exception on system startup + # + # File "/usr/lib/python3/dist-packages/vyos/configsession.py", line 128, in __run_command + # raise ConfigSessionError(output) + # vyos.configsession.ConfigSessionError: [ system domain-name vyos.io ] + # Fatal: Unable to generate local temporary file in directory '/run/powerdns': No such file or directory + if os.path.isdir('/run/powerdns'): + ret = run('/usr/bin/rec_control --socket-dir=/run/powerdns ping') + if ret == 0: + call('systemctl restart pdns-recursor.service') return None diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py index 8eba6ea63..d5f308ed3 100755 --- a/src/conf_mode/interfaces-pseudo-ethernet.py +++ b/src/conf_mode/interfaces-pseudo-ethernet.py @@ -246,38 +246,29 @@ def generate(peth): return None def apply(peth): - - p = '' if peth['deleted']: # delete interface - p = MACVLANIf(peth['intf']) - p.remove() + MACVLANIf(peth['intf']).remove() return None - elif peth['source_interface_changed']: - # Check if MACVLAN interface already exists. Parameters like the - # underlaying source-interface device can not be changed on the fly - # and the interface needs to be recreated from the bottom. - # - # source_interface_changed also means - the interface was not present in the - # beginning and is newly created - if peth['intf'] in interfaces(): - p = MACVLANIf(peth['intf']) - p.remove() - - # MACVLAN interface needs to be created on-block instead of passing a ton - # of arguments, I just use a dict that is managed by vyos.ifconfig - conf = deepcopy(MACVLANIf.get_config()) - - # Assign MACVLAN instance configuration parameters to config dict - conf['source_interface'] = peth['source_interface'] - conf['mode'] = peth['mode'] - - # 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 - p = MACVLANIf(peth['intf'], **conf) - else: - p = MACVLANIf(peth['intf']) + # Check if MACVLAN interface already exists. Parameters like the underlaying + # source-interface device can not be changed on the fly and the interface + # needs to be recreated from the bottom. + if peth['intf'] in interfaces(): + if peth['source_interface_changed']: + MACVLANIf(peth['intf']).remove() + + # MACVLAN interface needs to be created on-block instead of passing a ton + # of arguments, I just use a dict that is managed by vyos.ifconfig + conf = deepcopy(MACVLANIf.get_config()) + + # Assign MACVLAN instance configuration parameters to config dict + conf['source_interface'] = peth['source_interface'] + conf['mode'] = peth['mode'] + + # 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 + p = MACVLANIf(peth['intf'], **conf) # update interface description used e.g. within SNMP p.set_alias(peth['description']) diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index 2ab75fcec..9c0c42414 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -255,7 +255,9 @@ default_config_data = { 'ipv6_forwarding': 1, 'ipv6_dad_transmits': 1, # internal + 'interfaces': [], 'tunnel': {}, + 'bridge': '', # the following names are exactly matching the name # for the ip command and must not be changed 'ifname': '', @@ -264,6 +266,7 @@ default_config_data = { 'mtu': '1476', 'local': '', 'remote': '', + 'dev': '', 'multicast': 'disable', 'allmulticast': 'disable', 'ttl': '255', @@ -275,7 +278,6 @@ default_config_data = { 'tclass': 'inherit', '6rd-prefix': '', '6rd-relay-prefix': '', - 'bridge': '', } # dict name -> config name, multiple values, default @@ -286,6 +288,7 @@ mapping = { 'local': ('local-ip', False, None), 'remote': ('remote-ip', False, None), 'multicast': ('multicast', False, None), + 'dev': ('source-interface', False, None), 'ttl': ('parameters ip ttl', False, None), 'tos': ('parameters ip tos', False, None), 'key': ('parameters ip key', False, None), @@ -408,6 +411,7 @@ def get_config(): # check for bridges options['bridge'] = is_bridge_member(conf, ifname) + options['interfaces'] = interfaces() for name in ct: tunnel = ct[name] @@ -483,6 +487,7 @@ def verify(conf): afi_remote = get_afi(tun_remote) tun_ismgre = iftype == 'gre' and not options['remote'] tun_is6rd = iftype == 'sit' and options['6rd-prefix'] + tun_dev = options['dev'] # incompatible options @@ -492,6 +497,9 @@ def verify(conf): if tun_local and options['dhcp-interface']: raise ConfigError(f'Must configure only one of local-ip or dhcp-interface for tunnel {iftype} {ifname}') + if tun_dev and iftype in ('gre-bridge', 'sit'): + raise ConfigError(f'source interface can not be used with {iftype} {ifname}') + # tunnel endpoint if afi_local != afi_remote: @@ -519,9 +527,14 @@ def verify(conf): # vrf check vrf = options['vrf'] - if vrf and vrf not in interfaces(): + if vrf and vrf not in options['interfaces']: raise ConfigError(f'VRF "{vrf}" does not exist') + # source-interface check + + if tun_dev and tun_dev not in options['interfaces']: + raise ConfigError(f'device "{dev}" does not exist') + # tunnel encapsulation check convert = { diff --git a/src/conf_mode/ipsec-settings.py b/src/conf_mode/ipsec-settings.py index da19dcb26..3398bcdf2 100755 --- a/src/conf_mode/ipsec-settings.py +++ b/src/conf_mode/ipsec-settings.py @@ -170,7 +170,7 @@ def generate(data): if data["ipsec_l2tp"]: remove_confs(delim_ipsec_l2tp_begin, delim_ipsec_l2tp_end, ipsec_secrets_file) # old_umask = os.umask(0o077) - # render(ipsec_secrets_file, 'ipsec/ipsec.secrets.tmpl', c, trim_blocks=True) + # render(ipsec_secrets_file, 'ipsec/ipsec.secrets.tmpl', data, trim_blocks=True) # os.umask(old_umask) ## Use this method while IPSec CLI handler won't be overwritten to python write_ipsec_secrets(data) @@ -181,12 +181,12 @@ def generate(data): if not os.path.exists(ipsec_ra_conn_dir): os.makedirs(ipsec_ra_conn_dir) - render(ipsec_ra_conn_file, 'ipsec/remote-access.tmpl', c, trim_blocks=True) + render(ipsec_ra_conn_file, 'ipsec/remote-access.tmpl', data, trim_blocks=True) os.umask(old_umask) remove_confs(delim_ipsec_l2tp_begin, delim_ipsec_l2tp_end, ipsec_conf_file) # old_umask = os.umask(0o077) - # render(ipsec_conf_file, 'ipsec/ipsec.conf.tmpl', c, trim_blocks=True) + # render(ipsec_conf_file, 'ipsec/ipsec.conf.tmpl', data, trim_blocks=True) # os.umask(old_umask) ## Use this method while IPSec CLI handler won't be overwritten to python write_ipsec_conf(data) diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py index f0dd3751a..94eb675f7 100755 --- a/src/conf_mode/service_pppoe-server.py +++ b/src/conf_mode/service_pppoe-server.py @@ -423,10 +423,10 @@ def generate(pppoe): if not os.path.exists(dirname): os.mkdir(dirname) - render(pppoe_conf, 'accel-ppp/pppoe.config.tmpl', c, trim_blocks=True) + render(pppoe_conf, 'accel-ppp/pppoe.config.tmpl', pppoe, trim_blocks=True) if pppoe['local_users']: - render(pppoe_chap_secrets, 'accel-ppp/chap-secrets.tmpl', c, trim_blocks=True) + render(pppoe_chap_secrets, 'accel-ppp/chap-secrets.tmpl', pppoe, trim_blocks=True) os.chmod(pppoe_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP) else: if os.path.exists(pppoe_chap_secrets): diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py index 417520e09..a640e2a94 100755 --- a/src/conf_mode/vpn_l2tp.py +++ b/src/conf_mode/vpn_l2tp.py @@ -348,7 +348,7 @@ def generate(l2tp): if not os.path.exists(dirname): os.mkdir(dirname) - render(l2tp_conf, 'accel-ppp/l2tp.config.tmpl', c, trim_blocks=True) + render(l2tp_conf, 'accel-ppp/l2tp.config.tmpl', l2tp, trim_blocks=True) if l2tp['auth_mode'] == 'local': render(l2tp_chap_secrets, 'accel-ppp/chap-secrets.tmpl', l2tp) diff --git a/src/op_mode/vrrp.py b/src/op_mode/vrrp.py index 923cfa4d4..e024d7f63 100755 --- a/src/op_mode/vrrp.py +++ b/src/op_mode/vrrp.py @@ -21,7 +21,6 @@ import argparse import json import tabulate -import vyos.keepalived import vyos.util from vyos.ifconfig.vrrp import VRRP |