From 482aaf1cee85487c14a183770d23ceda4611d1c6 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sat, 18 Sep 2021 21:27:47 +0200 Subject: dhcp-server: T1968: allow multiple static-routes to be configured vyos@vyos# show service dhcp-server shared-network-name LAN { subnet 10.0.0.0/24 { default-router 10.0.0.1 dns-server 194.145.150.1 lease 88 range 0 { start 10.0.0.100 stop 10.0.0.200 } static-route 192.168.10.0/24 { next-hop 10.0.0.2 } static-route 192.168.20.0/24 { router 10.0.0.2 } } } (cherry picked from commit a4440bd589db645eb99f343a8163e188a700774c) --- data/templates/dhcp-server/dhcpd.conf.tmpl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'data/templates/dhcp-server') diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl index ff2e31998..58be7984d 100644 --- a/data/templates/dhcp-server/dhcpd.conf.tmpl +++ b/data/templates/dhcp-server/dhcpd.conf.tmpl @@ -114,9 +114,13 @@ shared-network {{ network | replace('_','-') }} { {% if subnet_config.default_router and subnet_config.default_router is not none %} {% set static_default_route = ', ' + '0.0.0.0/0' | isc_static_route(subnet_config.default_router) %} {% endif %} -{% if subnet_config.static_route.router is defined and subnet_config.static_route.router is not none and subnet_config.static_route.destination_subnet is defined and subnet_config.static_route.destination_subnet is not none %} - option rfc3442-static-route {{ subnet_config.static_route.destination_subnet | isc_static_route(subnet_config.static_route.router) }}{{ static_default_route }}; - option windows-static-route {{ subnet_config.static_route.destination_subnet | isc_static_route(subnet_config.static_route.router) }}; +{% if subnet_config.static_route is defined and subnet_config.static_route is not none %} +{% set rfc3442_routes = [] %} +{% for route, route_options in subnet_config.static_route.items() %} +{% set rfc3442_routes = rfc3442_routes.append(route | isc_static_route(route_options.next_hop)) %} +{% endfor %} + option rfc3442-static-route {{ rfc3442_routes | join(', ') }}{{ static_default_route }}; + option windows-static-route {{ rfc3442_routes | join(', ') }}; {% endif %} {% endif %} {% if subnet_config.ip_forwarding is defined %} -- cgit v1.2.3 From abad387fcaf700a32f8fc85183d617fcfbb0b8f4 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sat, 18 Sep 2021 21:48:53 +0200 Subject: dhcp-server: T3838: rename dns-server to name-server node IPv4 DHCP uses "dns-server" to specify one or more name-servers for a given pool. In order to use the same CLI syntax this should be renamed to name-server, which is already the case for DHCPv6. (cherry picked from commit e2f9f4f4e8b2e961a58d935d09798ddb4e1e0460) --- data/templates/dhcp-server/dhcpd.conf.tmpl | 4 +-- interface-definitions/dhcp-server.xml.in | 14 +------- interface-definitions/dhcpv6-server.xml.in | 42 ++-------------------- interface-definitions/dns-forwarding.xml.in | 19 +--------- .../include/accel-ppp/name-server.xml.i | 20 ----------- .../include/name-server-ipv4-ipv6.xml.i | 20 +++++++++++ .../include/name-server-ipv4.xml.i | 15 ++++++++ .../include/name-server-ipv6.xml.i | 15 ++++++++ interface-definitions/interfaces-openvpn.xml.in | 18 +--------- interface-definitions/service_ipoe-server.xml.in | 2 +- interface-definitions/service_pppoe-server.xml.in | 2 +- interface-definitions/service_router-advert.xml.in | 14 +------- interface-definitions/vpn_l2tp.xml.in | 2 +- interface-definitions/vpn_openconnect.xml.in | 2 +- interface-definitions/vpn_pptp.xml.in | 14 +------- interface-definitions/vpn_sstp.xml.in | 2 +- smoketest/scripts/cli/test_service_dhcp-server.py | 16 ++++----- src/migration-scripts/dhcp-server/5-to-6 | 7 ++++ 18 files changed, 80 insertions(+), 148 deletions(-) delete mode 100644 interface-definitions/include/accel-ppp/name-server.xml.i create mode 100644 interface-definitions/include/name-server-ipv4-ipv6.xml.i create mode 100644 interface-definitions/include/name-server-ipv4.xml.i create mode 100644 interface-definitions/include/name-server-ipv6.xml.i (limited to 'data/templates/dhcp-server') diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl index 58be7984d..f64192acf 100644 --- a/data/templates/dhcp-server/dhcpd.conf.tmpl +++ b/data/templates/dhcp-server/dhcpd.conf.tmpl @@ -88,8 +88,8 @@ shared-network {{ network | replace('_','-') }} { {% if network_config.subnet is defined and network_config.subnet is not none %} {% for subnet, subnet_config in network_config.subnet.items() %} subnet {{ subnet | address_from_cidr }} netmask {{ subnet | netmask_from_cidr }} { -{% if subnet_config.dns_server is defined and subnet_config.dns_server is not none %} - option domain-name-servers {{ subnet_config.dns_server | join(', ') }}; +{% if subnet_config.name_server is defined and subnet_config.name_server is not none %} + option domain-name-servers {{ subnet_config.name_server | join(', ') }}; {% endif %} {% if subnet_config.domain_search is defined and subnet_config.domain_search is not none %} option domain-search "{{ subnet_config.domain_search | join('", "') }}"; diff --git a/interface-definitions/dhcp-server.xml.in b/interface-definitions/dhcp-server.xml.in index c0f72dd86..3a1eee60e 100644 --- a/interface-definitions/dhcp-server.xml.in +++ b/interface-definitions/dhcp-server.xml.in @@ -117,19 +117,7 @@ - - - DNS server IPv4 address - - ipv4 - DNS server IPv4 address - - - - - - - + #include Client Domain Name diff --git a/interface-definitions/dhcpv6-server.xml.in b/interface-definitions/dhcpv6-server.xml.in index 95b1e5602..58181872b 100644 --- a/interface-definitions/dhcpv6-server.xml.in +++ b/interface-definitions/dhcpv6-server.xml.in @@ -14,19 +14,7 @@ Additional global parameters for DHCPv6 server - - - IPv6 address of a Recursive DNS Server - - ipv6 - IPv6 address of DNS name server - - - - - - - + #include @@ -70,19 +58,7 @@ #include - - - IPv6 address of a Recursive DNS Server - - ipv6 - IPv6 address of DNS name server - - - - - - - + #include @@ -194,19 +170,7 @@ - - - IPv6 address of a Recursive DNS Server - - ipv6 - IPv6 address of DNS name server - - - - - - - + #include NIS domain name for client to use diff --git a/interface-definitions/dns-forwarding.xml.in b/interface-definitions/dns-forwarding.xml.in index 9edd18a66..5d6e25a27 100644 --- a/interface-definitions/dns-forwarding.xml.in +++ b/interface-definitions/dns-forwarding.xml.in @@ -142,24 +142,7 @@ 3600 - - - Domain Name Servers (DNS) addresses [OPTIONAL] - - ipv4 - Domain Name Server (DNS) IPv4 address - - - ipv6 - Domain Name Server (DNS) IPv6 address - - - - - - - - + #include Local addresses from which to send DNS queries diff --git a/interface-definitions/include/accel-ppp/name-server.xml.i b/interface-definitions/include/accel-ppp/name-server.xml.i deleted file mode 100644 index e744b384f..000000000 --- a/interface-definitions/include/accel-ppp/name-server.xml.i +++ /dev/null @@ -1,20 +0,0 @@ - - - - Domain Name Server (DNS) propagated to client - - ipv4 - Domain Name Server (DNS) IPv4 address - - - ipv6 - Domain Name Server (DNS) IPv6 address - - - - - - - - - diff --git a/interface-definitions/include/name-server-ipv4-ipv6.xml.i b/interface-definitions/include/name-server-ipv4-ipv6.xml.i new file mode 100644 index 000000000..14973234b --- /dev/null +++ b/interface-definitions/include/name-server-ipv4-ipv6.xml.i @@ -0,0 +1,20 @@ + + + + Domain Name Servers (DNS) addresses + + ipv4 + Domain Name Server (DNS) IPv4 address + + + ipv6 + Domain Name Server (DNS) IPv6 address + + + + + + + + + diff --git a/interface-definitions/include/name-server-ipv4.xml.i b/interface-definitions/include/name-server-ipv4.xml.i new file mode 100644 index 000000000..0cf884e03 --- /dev/null +++ b/interface-definitions/include/name-server-ipv4.xml.i @@ -0,0 +1,15 @@ + + + + Domain Name Servers (DNS) addresses + + ipv4 + Domain Name Server (DNS) IPv4 address + + + + + + + + diff --git a/interface-definitions/include/name-server-ipv6.xml.i b/interface-definitions/include/name-server-ipv6.xml.i new file mode 100644 index 000000000..d4517c4c6 --- /dev/null +++ b/interface-definitions/include/name-server-ipv6.xml.i @@ -0,0 +1,15 @@ + + + + Domain Name Servers (DNS) addresses + + ipv6 + Domain Name Server (DNS) IPv6 address + + + + + + + + diff --git a/interface-definitions/interfaces-openvpn.xml.in b/interface-definitions/interfaces-openvpn.xml.in index 40f8fe65c..51e81390c 100644 --- a/interface-definitions/interfaces-openvpn.xml.in +++ b/interface-definitions/interfaces-openvpn.xml.in @@ -554,23 +554,7 @@ - - - Domain Name Server (DNS) - - ipv4 - DNS server IPv4 address - - - ipv6 - DNS server IPv6 address - - - - - - - + #include Route to be pushed to all clients diff --git a/interface-definitions/service_ipoe-server.xml.in b/interface-definitions/service_ipoe-server.xml.in index 7c575ba77..b19acab56 100644 --- a/interface-definitions/service_ipoe-server.xml.in +++ b/interface-definitions/service_ipoe-server.xml.in @@ -111,7 +111,7 @@ - #include + #include #include diff --git a/interface-definitions/service_pppoe-server.xml.in b/interface-definitions/service_pppoe-server.xml.in index 955c104f7..712e6549e 100644 --- a/interface-definitions/service_pppoe-server.xml.in +++ b/interface-definitions/service_pppoe-server.xml.in @@ -59,7 +59,7 @@ #include - #include + #include interface(s) to listen on diff --git a/interface-definitions/service_router-advert.xml.in b/interface-definitions/service_router-advert.xml.in index e18b27f1b..0f4009f5c 100644 --- a/interface-definitions/service_router-advert.xml.in +++ b/interface-definitions/service_router-advert.xml.in @@ -135,19 +135,7 @@ - - - IPv6 address of recursive DNS server - - ipv6 - IPv6 address of DNS name server - - - - - - - + #include Hosts use the administered (stateful) protocol for autoconfiguration of other (non-address) information diff --git a/interface-definitions/vpn_l2tp.xml.in b/interface-definitions/vpn_l2tp.xml.in index 787298284..8bcede159 100644 --- a/interface-definitions/vpn_l2tp.xml.in +++ b/interface-definitions/vpn_l2tp.xml.in @@ -22,7 +22,7 @@ #include - #include + #include L2TP Network Server (LNS) diff --git a/interface-definitions/vpn_openconnect.xml.in b/interface-definitions/vpn_openconnect.xml.in index b345b560e..f35b1ebbd 100644 --- a/interface-definitions/vpn_openconnect.xml.in +++ b/interface-definitions/vpn_openconnect.xml.in @@ -190,7 +190,7 @@ - #include + #include diff --git a/interface-definitions/vpn_pptp.xml.in b/interface-definitions/vpn_pptp.xml.in index 91c8cd76f..9b84a00c1 100644 --- a/interface-definitions/vpn_pptp.xml.in +++ b/interface-definitions/vpn_pptp.xml.in @@ -21,19 +21,7 @@ - - - Domain Name Server (DNS) propagated to client - - ipv4 - Domain Name Server (DNS) IPv4 address - - - - - - - + #include #include diff --git a/interface-definitions/vpn_sstp.xml.in b/interface-definitions/vpn_sstp.xml.in index 840e237cc..5406ede41 100644 --- a/interface-definitions/vpn_sstp.xml.in +++ b/interface-definitions/vpn_sstp.xml.in @@ -27,7 +27,7 @@ #include #include - #include + #include Client IP pools and gateway setting diff --git a/smoketest/scripts/cli/test_service_dhcp-server.py b/smoketest/scripts/cli/test_service_dhcp-server.py index 40977bb04..37e016778 100755 --- a/smoketest/scripts/cli/test_service_dhcp-server.py +++ b/smoketest/scripts/cli/test_service_dhcp-server.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-2021 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 @@ -59,8 +59,8 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase): pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet] # we use the first subnet IP address as default gateway self.cli_set(pool + ['default-router', router]) - self.cli_set(pool + ['dns-server', dns_1]) - self.cli_set(pool + ['dns-server', dns_2]) + self.cli_set(pool + ['name-server', dns_1]) + self.cli_set(pool + ['name-server', dns_2]) self.cli_set(pool + ['domain-name', domain_name]) # check validate() - No DHCP address range or active static-mapping set @@ -108,8 +108,8 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase): pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet] # we use the first subnet IP address as default gateway self.cli_set(pool + ['default-router', router]) - self.cli_set(pool + ['dns-server', dns_1]) - self.cli_set(pool + ['dns-server', dns_2]) + self.cli_set(pool + ['name-server', dns_1]) + self.cli_set(pool + ['name-server', dns_2]) self.cli_set(pool + ['domain-name', domain_name]) self.cli_set(pool + ['ip-forwarding']) self.cli_set(pool + ['smtp-server', smtp_server]) @@ -201,8 +201,8 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase): pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet] # we use the first subnet IP address as default gateway self.cli_set(pool + ['default-router', router]) - self.cli_set(pool + ['dns-server', dns_1]) - self.cli_set(pool + ['dns-server', dns_2]) + self.cli_set(pool + ['name-server', dns_1]) + self.cli_set(pool + ['name-server', dns_2]) self.cli_set(pool + ['domain-name', domain_name]) # check validate() - No DHCP address range or active static-mapping set @@ -261,7 +261,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase): pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet] # we use the first subnet IP address as default gateway self.cli_set(pool + ['default-router', router]) - self.cli_set(pool + ['dns-server', dns_1]) + self.cli_set(pool + ['name-server', dns_1]) self.cli_set(pool + ['domain-name', domain_name]) self.cli_set(pool + ['lease', lease_time]) diff --git a/src/migration-scripts/dhcp-server/5-to-6 b/src/migration-scripts/dhcp-server/5-to-6 index 4cd2ec07a..7f447ac17 100755 --- a/src/migration-scripts/dhcp-server/5-to-6 +++ b/src/migration-scripts/dhcp-server/5-to-6 @@ -14,6 +14,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +# T1968: allow multiple static-routes to be configured +# T3838: rename dns-server -> name-server import sys from vyos.configtree import ConfigTree @@ -45,6 +47,7 @@ for network in config.list_nodes(base): for subnet in config.list_nodes(base_network + ['subnet']): base_subnet = base_network + ['subnet', subnet] + # T1968: allow multiple static-routes to be configured if config.exists(base_subnet + ['static-route']): prefix = config.return_value(base_subnet + ['static-route', 'destination-subnet']) router = config.return_value(base_subnet + ['static-route', 'router']) @@ -53,6 +56,10 @@ for network in config.list_nodes(base): config.set(base_subnet + ['static-route', prefix, 'next-hop'], value=router) config.set_tag(base_subnet + ['static-route']) + # T3838: rename dns-server -> name-server + if config.exists(base_subnet + ['dns-server']): + config.rename(base_subnet + ['dns-server'], 'name-server') + try: with open(file_name, 'w') as f: f.write(config.to_string()) -- cgit v1.2.3 From 81dbce734c207a0fce836bf2a5d283910509f4ff Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 19 Sep 2021 10:51:15 +0200 Subject: dhcp-server: T3672: only one failover peer is supported (cherry picked from commit a8ccf72c222caad8cd7aaca9bca773be39e87f5c) --- data/templates/dhcp-server/dhcpd.conf.tmpl | 37 ++++------- interface-definitions/dhcp-server.xml.in | 98 ++++++++++++++---------------- src/conf_mode/dhcp_server.py | 36 +++++------ src/migration-scripts/dhcp-server/5-to-6 | 25 ++++++-- 4 files changed, 97 insertions(+), 99 deletions(-) (limited to 'data/templates/dhcp-server') diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl index f64192acf..23917b303 100644 --- a/data/templates/dhcp-server/dhcpd.conf.tmpl +++ b/data/templates/dhcp-server/dhcpd.conf.tmpl @@ -35,32 +35,25 @@ option wpad-url code 252 = text; {% endfor %} {% endif %} -{% if shared_network_name is defined and shared_network_name is not none %} -{% for network, network_config in shared_network_name.items() if network_config.disable is not defined %} -{% if network_config.subnet is defined and network_config.subnet is not none %} -{% for subnet, subnet_config in network_config.subnet.items() %} -{% if subnet_config.failover is defined and subnet_config.failover is defined and subnet_config.failover.name is defined and subnet_config.failover.name is not none %} -# Failover configuration for {{ subnet }} -failover peer "{{ subnet_config.failover.name }}" { -{% if subnet_config.failover.status == 'primary' %} +{% if failover is defined and failover is not none %} +{% set dhcp_failover_name = 'VyOS-DHCP-failover-peer' %} +# DHCP failover configuration +failover peer "{{ dhcp_failover_name }}" { +{% if failover.status == 'primary' %} primary; mclt 1800; split 128; -{% elif subnet_config.failover.status == 'secondary' %} +{% elif failover.status == 'secondary' %} secondary; -{% endif %} - address {{ subnet_config.failover.local_address }}; +{% endif %} + address {{ failover.source_address }}; port 520; - peer address {{ subnet_config.failover.peer_address }}; + peer address {{ failover.remote }}; peer port 520; max-response-delay 30; max-unacked-updates 10; load balance max seconds 3; } -{% endif %} -{% endfor %} -{% endif %} -{% endfor %} {% endif %} {% if listen_address is defined and listen_address is not none %} @@ -182,23 +175,17 @@ shared-network {{ network | replace('_','-') }} { } {% endfor %} {% endif %} -{% if subnet_config.failover is defined and subnet_config.failover.name is defined and subnet_config.failover.name is not none %} pool { - failover peer "{{ subnet_config.failover.name }}"; +{% if subnet_config.enable_failover is defined %} + failover peer "{{ dhcp_failover_name }}"; deny dynamic bootp clients; +{% endif %} {% if subnet_config.range is defined and subnet_config.range is not none %} {% for range, range_options in subnet_config.range.items() %} range {{ range_options.start }} {{ range_options.stop }}; {% endfor %} {% endif %} } -{% else %} -{% if subnet_config.range is defined and subnet_config.range is not none %} -{% for range, range_options in subnet_config.range.items() %} - range {{ range_options.start }} {{ range_options.stop }}; -{% endfor %} -{% endif %} -{% endif %} } {% endfor %} {% endif %} diff --git a/interface-definitions/dhcp-server.xml.in b/interface-definitions/dhcp-server.xml.in index 3a1eee60e..10384947a 100644 --- a/interface-definitions/dhcp-server.xml.in +++ b/interface-definitions/dhcp-server.xml.in @@ -16,6 +16,46 @@ + + + DHCP failover configuration + + + #include + + + IPv4 remote address used for connectio + + ipv4 + IPv4 address of failover peer + + + + + + + + + Failover hierarchy + + primary secondary + + + primary + Configure this server to be the primary node + + + secondary + Configure this server to be the secondary node + + + ^(primary|secondary)$ + + Invalid DHCP failover peer status + + + + Additional global parameters for DHCP server. You must @@ -128,6 +168,12 @@ #include + + + Enable DHCP failover support for this subnet + + + IP address to exclude from DHCP lease range @@ -141,58 +187,6 @@ - - - DHCP failover parameters - - - - - IP address for failover peer to connect [REQUIRED] - - ipv4 - IPv4 address to exclude from lease range - - - - - - - - - DHCP failover peer name [REQUIRED] - - [-_a-zA-Z0-9.]+ - - Invalid failover peer name. May only contain letters, numbers and .-_ - - - - - IP address of failover peer [REQUIRED] - - ipv4 - IPv4 address of failover peer - - - - - - - - - DHCP failover peer status (primary|secondary) [REQUIRED] - - primary secondary - - - ^(primary|secondary)$ - - Invalid DHCP failover peer status - - - - Enable IP forwarding on client diff --git a/src/conf_mode/dhcp_server.py b/src/conf_mode/dhcp_server.py index 8d6cef8b7..5b3809017 100755 --- a/src/conf_mode/dhcp_server.py +++ b/src/conf_mode/dhcp_server.py @@ -148,9 +148,9 @@ def verify(dhcp): 'At least one DHCP shared network must be configured.') # Inspect shared-network/subnet - failover_names = [] listen_ok = False subnets = [] + failover_ok = False # A shared-network requires a subnet definition for network, network_config in dhcp['shared_network_name'].items(): @@ -159,11 +159,19 @@ def verify(dhcp): 'lease subnet must be configured.') for subnet, subnet_config in network_config['subnet'].items(): + # All delivered static routes require a next-hop to be set if 'static_route' in subnet_config: for route, route_option in subnet_config['static_route'].items(): if 'next_hop' not in route_option: raise ConfigError(f'DHCP static-route "{route}" requires router to be defined!') + # DHCP failover needs at least one subnet that uses it + if 'enable_failover' in subnet_config: + if 'failover' not in dhcp: + raise ConfigError(f'Can not enable failover for "{subnet}" in "{network}".\n' \ + 'Failover is not configured globally!') + failover_ok = True + # Check if DHCP address range is inside configured subnet declaration if 'range' in subnet_config: networks = [] @@ -192,23 +200,6 @@ def verify(dhcp): tmp = IPRange(range_config['start'], range_config['stop']) networks.append(tmp) - if 'failover' in subnet_config: - for key in ['local_address', 'peer_address', 'name', 'status']: - if key not in subnet_config['failover']: - raise ConfigError(f'Missing DHCP failover parameter "{key}"!') - - # Failover names must be uniquie - if subnet_config['failover']['name'] in failover_names: - name = subnet_config['failover']['name'] - raise ConfigError(f'DHCP failover names must be unique:\n' \ - f'{name} has already been configured!') - failover_names.append(subnet_config['failover']['name']) - - # Failover requires start/stop ranges for pool - if 'range' not in subnet_config: - raise ConfigError(f'DHCP failover requires at least one start-stop range to be configured\n'\ - f'within shared-network "{network}, {subnet}" for using failover!') - # Exclude addresses must be in bound if 'exclude' in subnet_config: for exclude in subnet_config['exclude']: @@ -252,6 +243,15 @@ def verify(dhcp): if net.overlaps(net2): raise ConfigError('Conflicting subnet ranges: "{net}" overlaps "{net2}"!') + if 'failover' in dhcp: + if not failover_ok: + raise ConfigError('DHCP failover must be enabled for at least one subnet!') + + for key in ['source_address', 'remote', 'status']: + if key not in dhcp['failover']: + tmp = key.replace('_', '-') + raise ConfigError(f'DHCP failover requires "{tmp}" to be specified!') + for address in (dict_search('listen_address', dhcp) or []): if is_addr_assigned(address): listen_ok = True diff --git a/src/migration-scripts/dhcp-server/5-to-6 b/src/migration-scripts/dhcp-server/5-to-6 index 7f447ac17..39bbb9f50 100755 --- a/src/migration-scripts/dhcp-server/5-to-6 +++ b/src/migration-scripts/dhcp-server/5-to-6 @@ -29,16 +29,16 @@ file_name = sys.argv[1] with open(file_name, 'r') as f: config_file = f.read() -base = ['service', 'dhcp-server', 'shared-network-name'] +base = ['service', 'dhcp-server'] config = ConfigTree(config_file) -if not config.exists(base): +if not config.exists(base + ['shared-network-name']): # Nothing to do exit(0) # Run this for every instance if 'shared-network-name' -for network in config.list_nodes(base): - base_network = base + [network] +for network in config.list_nodes(base + ['shared-network-name']): + base_network = base + ['shared-network-name', network] if not config.exists(base_network + ['subnet']): continue @@ -60,6 +60,23 @@ for network in config.list_nodes(base): if config.exists(base_subnet + ['dns-server']): config.rename(base_subnet + ['dns-server'], 'name-server') + + # T3672: ISC DHCP server only supports one failover peer + if config.exists(base_subnet + ['failover']): + # There can only be one failover configuration, if none is present + # we add the first one + if not config.exists(base + ['failover']): + local = config.return_value(base_subnet + ['failover', 'local-address']) + remote = config.return_value(base_subnet + ['failover', 'peer-address']) + status = config.return_value(base_subnet + ['failover', 'status']) + + config.set(base + ['failover', 'remote'], value=remote) + config.set(base + ['failover', 'source-address'], value=local) + config.set(base + ['failover', 'status'], value=status) + + config.delete(base_subnet + ['failover']) + config.set(base_subnet + ['enable-failover']) + try: with open(file_name, 'w') as f: f.write(config.to_string()) -- cgit v1.2.3 From a672c7c012b85cd2950403400900453aa318613b Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 19 Sep 2021 11:32:04 +0200 Subject: dhcp-server: T3672: re-add missing "name" CLI option This option is mandatory and must be user configurable as it needs to match on both sides. (cherry picked from commit 2985035bcb2f3732e15a41e3c2ee6c6c93a6836e) --- data/templates/dhcp-server/dhcpd.conf.tmpl | 5 ++--- interface-definitions/dhcp-server.xml.in | 9 +++++++++ src/conf_mode/dhcp_server.py | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'data/templates/dhcp-server') diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl index 23917b303..9aeaafcc2 100644 --- a/data/templates/dhcp-server/dhcpd.conf.tmpl +++ b/data/templates/dhcp-server/dhcpd.conf.tmpl @@ -36,9 +36,8 @@ option wpad-url code 252 = text; {% endif %} {% if failover is defined and failover is not none %} -{% set dhcp_failover_name = 'VyOS-DHCP-failover-peer' %} # DHCP failover configuration -failover peer "{{ dhcp_failover_name }}" { +failover peer "{{ failover.name }}" { {% if failover.status == 'primary' %} primary; mclt 1800; @@ -177,7 +176,7 @@ shared-network {{ network | replace('_','-') }} { {% endif %} pool { {% if subnet_config.enable_failover is defined %} - failover peer "{{ dhcp_failover_name }}"; + failover peer "{{ failover.name }}"; deny dynamic bootp clients; {% endif %} {% if subnet_config.range is defined and subnet_config.range is not none %} diff --git a/interface-definitions/dhcp-server.xml.in b/interface-definitions/dhcp-server.xml.in index 10384947a..598be74b4 100644 --- a/interface-definitions/dhcp-server.xml.in +++ b/interface-definitions/dhcp-server.xml.in @@ -34,6 +34,15 @@ + + + Peer name used to identify connection + + [-_a-zA-Z0-9.]+ + + Invalid failover peer name. May only contain letters, numbers and .-_ + + Failover hierarchy diff --git a/src/conf_mode/dhcp_server.py b/src/conf_mode/dhcp_server.py index 5b3809017..28f2a4ca5 100755 --- a/src/conf_mode/dhcp_server.py +++ b/src/conf_mode/dhcp_server.py @@ -247,7 +247,7 @@ def verify(dhcp): if not failover_ok: raise ConfigError('DHCP failover must be enabled for at least one subnet!') - for key in ['source_address', 'remote', 'status']: + for key in ['name', 'remote', 'source_address', 'status']: if key not in dhcp['failover']: tmp = key.replace('_', '-') raise ConfigError(f'DHCP failover requires "{tmp}" to be specified!') -- cgit v1.2.3 From a00f3bfd0ff580625f63f024bdce9ed55100d63d Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 19 Sep 2021 11:14:43 +0200 Subject: dhcp-server: T3841: add option to perform ICMP check before address assignment (cherry picked from commit 83ea0cb273e29db22062cc133b6eabd4ba2761c7) --- data/templates/dhcp-server/dhcpd.conf.tmpl | 6 ++++++ interface-definitions/dhcp-server.xml.in | 2 ++ interface-definitions/include/dhcp-ping-check.xml.i | 8 ++++++++ 3 files changed, 16 insertions(+) create mode 100644 interface-definitions/include/dhcp-ping-check.xml.i (limited to 'data/templates/dhcp-server') diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl index 9aeaafcc2..11482c1ec 100644 --- a/data/templates/dhcp-server/dhcpd.conf.tmpl +++ b/data/templates/dhcp-server/dhcpd.conf.tmpl @@ -70,6 +70,9 @@ shared-network {{ network | replace('_','-') }} { {% if network_config.authoritative is defined %} authoritative; {% endif %} +{% if network_config.ping_check is defined %} + ping-check true; +{% endif %} {% if network_config.shared_network_parameters is defined and network_config.shared_network_parameters is not none %} # The following {{ network_config.shared_network_parameters | length }} line(s) # were added as shared-network-parameters in the CLI and have not been validated @@ -157,6 +160,9 @@ shared-network {{ network | replace('_','-') }} { default-lease-time {{ subnet_config.lease }}; max-lease-time {{ subnet_config.lease }}; {% endif %} +{% if network_config.ping_check is not defined and subnet_config.ping_check is defined %} + ping-check true; +{% endif %} {% if subnet_config.static_mapping is defined and subnet_config.static_mapping is not none %} {% for host, host_config in subnet_config.static_mapping.items() if host_config.disable is not defined %} host {{ host | replace('_','-') if host_decl_name is defined else network | replace('_','-') + '_' + host | replace('_','-') }} { diff --git a/interface-definitions/dhcp-server.xml.in b/interface-definitions/dhcp-server.xml.in index 598be74b4..e1d224121 100644 --- a/interface-definitions/dhcp-server.xml.in +++ b/interface-definitions/dhcp-server.xml.in @@ -107,6 +107,7 @@ Shared-network-name description + #include #include @@ -229,6 +230,7 @@ + #include IP address of POP3 server diff --git a/interface-definitions/include/dhcp-ping-check.xml.i b/interface-definitions/include/dhcp-ping-check.xml.i new file mode 100644 index 000000000..0b2a1214a --- /dev/null +++ b/interface-definitions/include/dhcp-ping-check.xml.i @@ -0,0 +1,8 @@ + + + + Sends ICMP Echo request to the address being assigned + + + + -- cgit v1.2.3 From 8f3fe8cc5db13e2fa5ef6f0a962546087a6fa6d8 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 19 Sep 2021 11:58:19 +0200 Subject: dhcp-server: T3672: bugfix Jinja2 template The DHCP servers pool {} option can only be used when there follows a range statement. This is invalid for a network with only "static" leases. (cherry picked from commit 6c2c089c26f1652644c9ded7d5cfd8a0497f148e) --- data/templates/dhcp-server/dhcpd.conf.tmpl | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'data/templates/dhcp-server') diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl index 11482c1ec..7173986a4 100644 --- a/data/templates/dhcp-server/dhcpd.conf.tmpl +++ b/data/templates/dhcp-server/dhcpd.conf.tmpl @@ -180,7 +180,10 @@ shared-network {{ network | replace('_','-') }} { } {% endfor %} {% endif %} +{% if subnet_config.range is defined and subnet_config.range is not none %} +{# pool configuration can only be used if there follows a range option #} pool { +{% endif %} {% if subnet_config.enable_failover is defined %} failover peer "{{ failover.name }}"; deny dynamic bootp clients; @@ -190,7 +193,10 @@ shared-network {{ network | replace('_','-') }} { range {{ range_options.start }} {{ range_options.stop }}; {% endfor %} {% endif %} +{% if subnet_config.range is defined and subnet_config.range is not none %} +{# pool configuration can only be used if there follows a range option #} } +{% endif %} } {% endfor %} {% endif %} -- cgit v1.2.3 From b72fff14c4061e26657835d72e0944229a196940 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sat, 18 Sep 2021 22:09:05 +0200 Subject: dhcp-server: T3839: support name-servers and domain config per shared-network DHCP servers "shared-network" level only makes sense if one can specify configuration items that can be inherited by individual subnets. This is now possible for name-servers and the domain-name. set service dhcp-server shared-network-name LAN domain-name 'vyos.net' set service dhcp-server shared-network-name LAN name-server '192.0.2.1' (cherry picked from commit d411a40a3598c55fae7abd8bc5f1876007aa704b) --- data/templates/dhcp-server/dhcpd.conf.tmpl | 6 ++++++ interface-definitions/dhcp-server.xml.in | 12 +++--------- interface-definitions/include/dhcp-domain-name.xml.i | 11 +++++++++++ 3 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 interface-definitions/include/dhcp-domain-name.xml.i (limited to 'data/templates/dhcp-server') diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl index 7173986a4..a2d5cb242 100644 --- a/data/templates/dhcp-server/dhcpd.conf.tmpl +++ b/data/templates/dhcp-server/dhcpd.conf.tmpl @@ -70,6 +70,12 @@ shared-network {{ network | replace('_','-') }} { {% if network_config.authoritative is defined %} authoritative; {% endif %} +{% if network_config.name_server is defined and network_config.name_server is not none %} + option domain-name-servers {{ network_config.name_server | join(', ') }}; +{% endif %} +{% if network_config.domain_name is defined and network_config.domain_name is not none %} + option domain-name "{{ network_config.domain_name }}"; +{% endif %} {% if network_config.ping_check is defined %} ping-check true; {% endif %} diff --git a/interface-definitions/dhcp-server.xml.in b/interface-definitions/dhcp-server.xml.in index 502a07c05..3a2c05698 100644 --- a/interface-definitions/dhcp-server.xml.in +++ b/interface-definitions/dhcp-server.xml.in @@ -103,6 +103,8 @@ #include + #include + #include #include #include @@ -164,15 +166,7 @@ #include - - - Client Domain Name - - - - Invalid domain name (RFC 1123 section 2).\nMay only contain letters, numbers and .-_ - - + #include #include diff --git a/interface-definitions/include/dhcp-domain-name.xml.i b/interface-definitions/include/dhcp-domain-name.xml.i new file mode 100644 index 000000000..eb95596da --- /dev/null +++ b/interface-definitions/include/dhcp-domain-name.xml.i @@ -0,0 +1,11 @@ + + + + Client Domain Name + + + + Invalid domain name (RFC 1123 section 2).\nMay only contain letters, numbers and .-_ + + + -- cgit v1.2.3 From 404b4c7b7b4f3063bc2bb608a32833d6cf23d834 Mon Sep 17 00:00:00 2001 From: DmitriyEshenko Date: Tue, 23 Feb 2021 17:38:05 +0000 Subject: dhcp-server: T2927: Add empty args if does not possible to determine variables (cherry picked from commit 2f8b33a26e63e5b9ac4e697b9312f2238d6241f3) --- data/templates/dhcp-server/dhcpd.conf.tmpl | 18 +++++++++--------- src/system/on-dhcp-event.sh | 25 ++++++++++++------------- 2 files changed, 21 insertions(+), 22 deletions(-) (limited to 'data/templates/dhcp-server') diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl index a2d5cb242..d774b4827 100644 --- a/data/templates/dhcp-server/dhcpd.conf.tmpl +++ b/data/templates/dhcp-server/dhcpd.conf.tmpl @@ -8,16 +8,12 @@ on release { set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name); set ClientIp = binary-to-ascii(10, 8, ".",leased-address); - set ClientMac = binary-to-ascii(16, 8, ":",substring(hardware, 1, 6)); - set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!"); - execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", ClientName, ClientIp, ClientMac, ClientDomain); + execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", "", ClientIp, "", ""); } on expiry { set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name); set ClientIp = binary-to-ascii(10, 8, ".",leased-address); - set ClientMac = binary-to-ascii(16, 8, ":",substring(hardware, 1, 6)); - set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!"); - execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", ClientName, ClientIp, ClientMac, ClientDomain); + execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", "", ClientIp, "", ""); } {% endif %} @@ -209,11 +205,15 @@ shared-network {{ network | replace('_','-') }} { on commit { set shared-networkname = "{{ network | replace('_','-') }}"; {% if hostfile_update is defined %} - set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name); set ClientIp = binary-to-ascii(10, 8, ".", leased-address); set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6)); - set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!"); - execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "commit", ClientName, ClientIp, ClientMac, ClientDomain); + set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name, "empty_hostname"); + if not (ClientName = "empty_hostname") { + set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!"); + execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "commit", ClientName, ClientIp, ClientMac, ClientDomain); + } else { + log(concat("Hostname is not defined for client with IP: ", ClientIP, " MAC: ", ClientMac)); + } {% endif %} } } diff --git a/src/system/on-dhcp-event.sh b/src/system/on-dhcp-event.sh index a062dc810..49e53d7e1 100755 --- a/src/system/on-dhcp-event.sh +++ b/src/system/on-dhcp-event.sh @@ -21,21 +21,20 @@ client_mac=$4 domain=$5 hostsd_client="/usr/bin/vyos-hostsd-client" -if [ -z "$client_name" ]; then - logger -s -t on-dhcp-event "Client name was empty, using MAC \"$client_mac\" instead" - client_name=$(echo "client-"$client_mac | tr : -) -fi - -if [ "$domain" == "..YYZ!" ]; then - client_fqdn_name=$client_name - client_search_expr=$client_name -else - client_fqdn_name=$client_name.$domain - client_search_expr="$client_name\\.$domain" -fi - case "$action" in commit) # add mapping for new lease + if [ -z "$client_name" ]; then + logger -s -t on-dhcp-event "Client name was empty, using MAC \"$client_mac\" instead" + client_name=$(echo "client-"$client_mac | tr : -) + fi + + if [ "$domain" == "..YYZ!" ]; then + client_fqdn_name=$client_name + client_search_expr=$client_name + else + client_fqdn_name=$client_name.$domain + client_search_expr="$client_name\\.$domain" + fi $hostsd_client --add-hosts "$client_fqdn_name,$client_ip" --tag "dhcp-server-$client_ip" --apply exit 0 ;; -- cgit v1.2.3 From 10a71d6d0534810c314010adc22ae7265334647c Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 21 Sep 2021 20:01:21 +0200 Subject: dhcp-server: T3839: support domain-search and ntp-server config per shared-network (cherry picked from commit 689d1824d251ea9fbd81bf0c941dbd36e33ef420) --- data/templates/dhcp-server/dhcpd.conf.tmpl | 12 +++++++++--- interface-definitions/dhcp-server.xml.in | 21 ++++++--------------- interface-definitions/include/dhcp/ntp-server.xml.i | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 interface-definitions/include/dhcp/ntp-server.xml.i (limited to 'data/templates/dhcp-server') diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl index d774b4827..003c585dd 100644 --- a/data/templates/dhcp-server/dhcpd.conf.tmpl +++ b/data/templates/dhcp-server/dhcpd.conf.tmpl @@ -72,6 +72,12 @@ shared-network {{ network | replace('_','-') }} { {% if network_config.domain_name is defined and network_config.domain_name is not none %} option domain-name "{{ network_config.domain_name }}"; {% endif %} +{% if network_config.domain_search is defined and network_config.domain_search is not none %} + option domain-search "{{ network_config.domain_search | join('", "') }}"; +{% endif %} +{% if network_config.ntp_server is defined and network_config.ntp_server is not none %} + option ntp-servers {{ network_config.ntp_server | join(', ') }}; +{% endif %} {% if network_config.ping_check is defined %} ping-check true; {% endif %} @@ -88,6 +94,9 @@ shared-network {{ network | replace('_','-') }} { {% if subnet_config.name_server is defined and subnet_config.name_server is not none %} option domain-name-servers {{ subnet_config.name_server | join(', ') }}; {% endif %} +{% if subnet_config.domain_name is defined and subnet_config.domain_name is not none %} + option domain-name "{{ subnet_config.domain_name }}"; +{% endif %} {% if subnet_config.domain_search is defined and subnet_config.domain_search is not none %} option domain-search "{{ subnet_config.domain_search | join('", "') }}"; {% endif %} @@ -129,9 +138,6 @@ shared-network {{ network | replace('_','-') }} { {% if subnet_config.server_identifier is defined and subnet_config.server_identifier is not none %} option dhcp-server-identifier {{ subnet_config.server_identifier }}; {% endif %} -{% if subnet_config.domain_name is defined and subnet_config.domain_name is not none %} - option domain-name "{{ subnet_config.domain_name }}"; -{% endif %} {% if subnet_config.subnet_parameters is defined and subnet_config.subnet_parameters is not none %} # The following {{ subnet_config.subnet_parameters | length }} line(s) were added as # subnet-parameters in the CLI and have not been validated!!! diff --git a/interface-definitions/dhcp-server.xml.in b/interface-definitions/dhcp-server.xml.in index 2707ce96d..47bdc4db1 100644 --- a/interface-definitions/dhcp-server.xml.in +++ b/interface-definitions/dhcp-server.xml.in @@ -103,10 +103,12 @@ #include + #include + #include #include - #include #include #include + #include Additional shared-network parameters for DHCP server. @@ -165,9 +167,10 @@ - #include #include #include + #include + #include Enable DHCP failover support for this subnet @@ -207,19 +210,7 @@ 86400 - - - IP address of NTP server - - ipv4 - NTP server IPv4 address - - - - - - - + #include #include diff --git a/interface-definitions/include/dhcp/ntp-server.xml.i b/interface-definitions/include/dhcp/ntp-server.xml.i new file mode 100644 index 000000000..32d8207e5 --- /dev/null +++ b/interface-definitions/include/dhcp/ntp-server.xml.i @@ -0,0 +1,15 @@ + + + + IP address of NTP server + + ipv4 + NTP server IPv4 address + + + + + + + + -- cgit v1.2.3 From 51bdfc7e04b96dfe0cb59756c83ab176efb27993 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Thu, 30 Sep 2021 20:28:31 +0200 Subject: dhcp-server: T2230: add subnet description into rendered config (cherry picked from commit 2974628487abb9127922bf695331fd706a1d0e51) --- data/templates/dhcp-server/dhcpd.conf.tmpl | 3 +++ 1 file changed, 3 insertions(+) (limited to 'data/templates/dhcp-server') diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl index 003c585dd..233e2cc53 100644 --- a/data/templates/dhcp-server/dhcpd.conf.tmpl +++ b/data/templates/dhcp-server/dhcpd.conf.tmpl @@ -90,6 +90,9 @@ shared-network {{ network | replace('_','-') }} { {% endif %} {% if network_config.subnet is defined and network_config.subnet is not none %} {% for subnet, subnet_config in network_config.subnet.items() %} +{% if subnet_config.description is defined and subnet_config.description is not none %} + # {{ subnet_config.description }} +{% endif %} subnet {{ subnet | address_from_cidr }} netmask {{ subnet | netmask_from_cidr }} { {% if subnet_config.name_server is defined and subnet_config.name_server is not none %} option domain-name-servers {{ subnet_config.name_server | join(', ') }}; -- cgit v1.2.3