diff options
| author | Christian Breunig <christian@breunig.cc> | 2024-01-13 20:12:33 +0100 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-13 20:12:33 +0100 | 
| commit | 9753fafbfed02a3b6ebe7b6ddf51783c5dcbcf62 (patch) | |
| tree | 929c8b42867462edad25b8028bac07b78c89b6fb | |
| parent | fef091bd6dc5c3cdfae47e9adb86f610a75a8a4d (diff) | |
| parent | 2d4db25386fcefd301868a4daa39d5578cbac779 (diff) | |
| download | vyos-1x-9753fafbfed02a3b6ebe7b6ddf51783c5dcbcf62.tar.gz vyos-1x-9753fafbfed02a3b6ebe7b6ddf51783c5dcbcf62.zip | |
Merge pull request #2817 from sarthurdev/kea6-options
dhcpv6: T3316: Extend scope of DHCP options, bugfixes
| -rw-r--r-- | data/templates/dhcp-server/kea-dhcp6.conf.j2 | 4 | ||||
| -rw-r--r-- | interface-definitions/include/dhcp/option-v6.xml.i | 110 | ||||
| -rw-r--r-- | interface-definitions/service_dhcpv6-server.xml.in | 144 | ||||
| -rw-r--r-- | python/vyos/kea.py | 43 | ||||
| -rw-r--r-- | python/vyos/template.py | 7 | ||||
| -rw-r--r-- | smoketest/configs/basic-vyos | 7 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_service_dhcpv6-server.py | 26 | ||||
| -rwxr-xr-x | src/conf_mode/service_dhcpv6-server.py | 44 | ||||
| -rwxr-xr-x | src/migration-scripts/dhcpv6-server/3-to-4 | 35 | ||||
| -rwxr-xr-x | src/op_mode/dhcp.py | 9 | 
10 files changed, 245 insertions, 184 deletions
| diff --git a/data/templates/dhcp-server/kea-dhcp6.conf.j2 b/data/templates/dhcp-server/kea-dhcp6.conf.j2 index 3ce4e6370..3ab21551b 100644 --- a/data/templates/dhcp-server/kea-dhcp6.conf.j2 +++ b/data/templates/dhcp-server/kea-dhcp6.conf.j2 @@ -1,7 +1,11 @@  {      "Dhcp6": {          "interfaces-config": { +{% if listen_interface is vyos_defined %} +            "interfaces": {{ listen_interface | tojson }}, +{% else %}              "interfaces": [ "*" ], +{% endif %}              "service-sockets-max-retries": 5,              "service-sockets-retry-wait-time": 5000          }, diff --git a/interface-definitions/include/dhcp/option-v6.xml.i b/interface-definitions/include/dhcp/option-v6.xml.i new file mode 100644 index 000000000..1df0c3934 --- /dev/null +++ b/interface-definitions/include/dhcp/option-v6.xml.i @@ -0,0 +1,110 @@ +<!-- include start from dhcp/option-v6.xml.i --> +<node name="option"> +  <properties> +    <help>DHCPv6 option</help> +  </properties> +  <children> +    #include <include/dhcp/captive-portal.xml.i> +    #include <include/dhcp/domain-search.xml.i> +    #include <include/name-server-ipv6.xml.i> +    <leafNode name="nis-domain"> +      <properties> +        <help>NIS domain name for client to use</help> +        <constraint> +          #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> +        </constraint> +        <constraintErrorMessage>Invalid NIS domain name</constraintErrorMessage> +      </properties> +    </leafNode> +    <leafNode name="nis-server"> +      <properties> +        <help>IPv6 address of a NIS Server</help> +        <valueHelp> +          <format>ipv6</format> +          <description>IPv6 address of NIS server</description> +        </valueHelp> +        <constraint> +          <validator name="ipv6-address"/> +        </constraint> +        <multi/> +      </properties> +    </leafNode> +    <leafNode name="nisplus-domain"> +      <properties> +        <help>NIS+ domain name for client to use</help> +        <constraint> +          #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> +        </constraint> +        <constraintErrorMessage>Invalid NIS+ domain name. May only contain letters, numbers and .-_</constraintErrorMessage> +      </properties> +    </leafNode> +    <leafNode name="nisplus-server"> +      <properties> +        <help>IPv6 address of a NIS+ Server</help> +        <valueHelp> +          <format>ipv6</format> +          <description>IPv6 address of NIS+ server</description> +        </valueHelp> +        <constraint> +          <validator name="ipv6-address"/> +        </constraint> +        <multi/> +      </properties> +    </leafNode> +    <leafNode name="sip-server"> +      <properties> +        <help>IPv6 address of SIP server</help> +        <valueHelp> +          <format>ipv6</format> +          <description>IPv6 address of SIP server</description> +        </valueHelp> +        <valueHelp> +          <format>hostname</format> +          <description>FQDN of SIP server</description> +        </valueHelp> +        <constraint> +          <validator name="ipv6-address"/> +          <validator name="fqdn"/> +        </constraint> +        <multi/> +      </properties> +    </leafNode> +    <leafNode name="sntp-server"> +      <properties> +        <help>IPv6 address of an SNTP server for client to use</help> +        <constraint> +          <validator name="ipv6-address"/> +        </constraint> +        <multi/> +      </properties> +    </leafNode> +    <node name="vendor-option"> +      <properties> +        <help>Vendor Specific Options</help> +      </properties> +      <children> +        <node name="cisco"> +          <properties> +            <help>Cisco specific parameters</help> +          </properties> +          <children> +            <leafNode name="tftp-server"> +              <properties> +                <help>TFTP server name</help> +                <valueHelp> +                  <format>ipv6</format> +                  <description>TFTP server IPv6 address</description> +                </valueHelp> +                <constraint> +                  <validator name="ipv6-address"/> +                </constraint> +                <multi/> +              </properties> +            </leafNode> +          </children> +        </node> +      </children> +    </node> +  </children> +</node> +<!-- include end --> diff --git a/interface-definitions/service_dhcpv6-server.xml.in b/interface-definitions/service_dhcpv6-server.xml.in index 6934ceeec..07cbfc85d 100644 --- a/interface-definitions/service_dhcpv6-server.xml.in +++ b/interface-definitions/service_dhcpv6-server.xml.in @@ -9,6 +9,7 @@          </properties>          <children>            #include <include/generic-disable-node.xml.i> +          #include <include/listen-interface-multi-broadcast.xml.i>            <node name="global-parameters">              <properties>                <help>Additional global parameters for DHCPv6 server</help> @@ -89,11 +90,17 @@                    </constraint>                  </properties>                  <children> -                  <node name="address-range"> +                  #include <include/dhcp/option-v6.xml.i> +                  <tagNode name="range">                      <properties>                        <help>Parameters setting ranges for assigning IPv6 addresses</help> +                      <constraint> +                        #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> +                      </constraint> +                      <constraintErrorMessage>Invalid range name, may only be alphanumeric, dot and hyphen</constraintErrorMessage>                      </properties>                      <children> +                      #include <include/dhcp/option-v6.xml.i>                        <leafNode name="prefix">                          <properties>                            <help>IPv6 prefix defining range of addresses to assign</help> @@ -104,10 +111,9 @@                            <constraint>                              <validator name="ipv6-prefix"/>                            </constraint> -                          <multi/>                          </properties>                        </leafNode> -                      <tagNode name="start"> +                      <leafNode name="start">                          <properties>                            <help>First in range of consecutive IPv6 addresses to assign</help>                            <valueHelp> @@ -118,25 +124,21 @@                              <validator name="ipv6-address"/>                            </constraint>                          </properties> -                        <children> -                          <leafNode name="stop"> -                            <properties> -                              <help>Last in range of consecutive IPv6 addresses</help> -                              <valueHelp> -                                <format>ipv6</format> -                                <description>IPv6 address</description> -                              </valueHelp> -                              <constraint> -                                <validator name="ipv6-address"/> -                              </constraint> -                            </properties> -                          </leafNode> -                        </children> -                      </tagNode> +                      </leafNode> +                      <leafNode name="stop"> +                        <properties> +                          <help>Last in range of consecutive IPv6 addresses</help> +                          <valueHelp> +                            <format>ipv6</format> +                            <description>IPv6 address</description> +                          </valueHelp> +                          <constraint> +                            <validator name="ipv6-address"/> +                          </constraint> +                        </properties> +                      </leafNode>                      </children> -                  </node> -                  #include <include/dhcp/captive-portal.xml.i> -                  #include <include/dhcp/domain-search.xml.i> +                  </tagNode>                    <node name="lease-time">                      <properties>                        <help>Parameters relating to the lease time</help> @@ -180,51 +182,6 @@                        </leafNode>                      </children>                    </node> -                  #include <include/name-server-ipv6.xml.i> -                  <leafNode name="nis-domain"> -                    <properties> -                      <help>NIS domain name for client to use</help> -                      <constraint> -                        #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> -                      </constraint> -                      <constraintErrorMessage>Invalid NIS domain name</constraintErrorMessage> -                    </properties> -                  </leafNode> -                  <leafNode name="nis-server"> -                    <properties> -                      <help>IPv6 address of a NIS Server</help> -                      <valueHelp> -                        <format>ipv6</format> -                        <description>IPv6 address of NIS server</description> -                      </valueHelp> -                      <constraint> -                        <validator name="ipv6-address"/> -                      </constraint> -                      <multi/> -                    </properties> -                  </leafNode> -                  <leafNode name="nisplus-domain"> -                    <properties> -                      <help>NIS+ domain name for client to use</help> -                      <constraint> -                        #include <include/constraint/alpha-numeric-hyphen-underscore-dot.xml.i> -                      </constraint> -                      <constraintErrorMessage>Invalid NIS+ domain name. May only contain letters, numbers and .-_</constraintErrorMessage> -                    </properties> -                  </leafNode> -                  <leafNode name="nisplus-server"> -                    <properties> -                      <help>IPv6 address of a NIS+ Server</help> -                      <valueHelp> -                        <format>ipv6</format> -                        <description>IPv6 address of NIS+ server</description> -                      </valueHelp> -                      <constraint> -                        <validator name="ipv6-address"/> -                      </constraint> -                      <multi/> -                    </properties> -                  </leafNode>                    <node name="prefix-delegation">                      <properties>                        <help>Parameters relating to IPv6 prefix delegation</help> @@ -272,33 +229,6 @@                        </tagNode>                      </children>                    </node> -                  <leafNode name="sip-server"> -                    <properties> -                      <help>IPv6 address of SIP server</help> -                      <valueHelp> -                        <format>ipv6</format> -                        <description>IPv6 address of SIP server</description> -                      </valueHelp> -                      <valueHelp> -                        <format>hostname</format> -                        <description>FQDN of SIP server</description> -                      </valueHelp> -                      <constraint> -                        <validator name="ipv6-address"/> -                        <validator name="fqdn"/> -                      </constraint> -                      <multi/> -                    </properties> -                  </leafNode> -                  <leafNode name="sntp-server"> -                    <properties> -                      <help>IPv6 address of an SNTP server for client to use</help> -                      <constraint> -                        <validator name="ipv6-address"/> -                      </constraint> -                      <multi/> -                    </properties> -                  </leafNode>                    <tagNode name="static-mapping">                      <properties>                        <help>Hostname for static mapping reservation</help> @@ -308,6 +238,7 @@                        <constraintErrorMessage>Invalid static mapping hostname</constraintErrorMessage>                      </properties>                      <children> +                      #include <include/dhcp/option-v6.xml.i>                        #include <include/generic-disable-node.xml.i>                        #include <include/interface/mac.xml.i>                        #include <include/interface/duid.xml.i> @@ -349,33 +280,6 @@                        </constraint>                      </properties>                    </leafNode> -                  <node name="vendor-option"> -                    <properties> -                      <help>Vendor Specific Options</help> -                    </properties> -                    <children> -                      <node name="cisco"> -                        <properties> -                          <help>Cisco specific parameters</help> -                        </properties> -                        <children> -                          <leafNode name="tftp-server"> -                            <properties> -                              <help>TFTP server name</help> -                              <valueHelp> -                                <format>ipv6</format> -                                <description>TFTP server IPv6 address</description> -                              </valueHelp> -                              <constraint> -                                <validator name="ipv6-address"/> -                              </constraint> -                              <multi/> -                            </properties> -                          </leafNode> -                        </children> -                      </node> -                    </children> -                  </node>                  </children>                </tagNode>              </children> diff --git a/python/vyos/kea.py b/python/vyos/kea.py index aa4fb7ae5..fb5afc2ce 100644 --- a/python/vyos/kea.py +++ b/python/vyos/kea.py @@ -175,16 +175,6 @@ def kea_parse_subnet(subnet, config):  def kea6_parse_options(config):      options = [] -    if 'common_options' in config: -        common_opt = config['common_options'] - -        for node, option_name in kea6_options.items(): -            if node not in common_opt: -                continue - -            value = ", ".join(common_opt[node]) if isinstance(common_opt[node], list) else common_opt[node] -            options.append({'name': option_name, 'data': value}) -      for node, option_name in kea6_options.items():          if node not in config:              continue @@ -218,20 +208,27 @@ def kea6_parse_options(config):  def kea6_parse_subnet(subnet, config):      out = {'subnet': subnet, 'id': int(config['subnet_id'])} -    options = kea6_parse_options(config) -    if 'address_range' in config: -        addr_range = config['address_range'] +    if 'option' in config: +        out['option-data'] = kea6_parse_options(config['option']) + +    if 'range' in config:          pools = [] +        for num, range_config in config['range'].items(): +            pool = {} -        if 'prefix' in addr_range: -            for prefix in addr_range['prefix']: -                pools.append({'pool': prefix}) +            if 'prefix' in range_config: +                pool['pool'] = range_config['prefix'] -        if 'start' in addr_range: -            for start, range_conf in addr_range['start'].items(): -                stop = range_conf['stop'] -                pools.append({'pool': f'{start} - {stop}'}) +            if 'start' in range_config: +                start = range_config['start'] +                stop = range_config['stop'] +                pool['pool'] = f'{start} - {stop}' + +            if 'option' in range_config: +                pool['option-data'] = kea6_parse_options(range_config['option']) + +            pools.append(pool)          out['pools'] = pools @@ -278,13 +275,13 @@ def kea6_parse_subnet(subnet, config):              if 'ipv6_prefix' in host_config:                  reservation['prefixes'] = [ host_config['ipv6_prefix'] ] +            if 'option' in host_config: +                reservation['option-data'] = kea6_parse_options(host_config['option']) +              reservations.append(reservation)          out['reservations'] = reservations -    if options: -        out['option-data'] = options -      return out  def kea_parse_leases(lease_path): diff --git a/python/vyos/template.py b/python/vyos/template.py index 1368f1f61..456239568 100644 --- a/python/vyos/template.py +++ b/python/vyos/template.py @@ -894,7 +894,9 @@ def kea6_shared_network_json(shared_networks):              'name': name,              'subnet6': []          } -        options = kea6_parse_options(config) + +        if 'common_options' in config: +            network['option-data'] = kea6_parse_options(config['common_options'])          if 'interface' in config:              network['interface'] = config['interface'] @@ -903,9 +905,6 @@ def kea6_shared_network_json(shared_networks):              for subnet, subnet_config in config['subnet'].items():                  network['subnet6'].append(kea6_parse_subnet(subnet, subnet_config)) -        if options: -            network['option-data'] = options -          out.append(network)      return dumps(out, indent=4) diff --git a/smoketest/configs/basic-vyos b/smoketest/configs/basic-vyos index fca4964bf..c42f14841 100644 --- a/smoketest/configs/basic-vyos +++ b/smoketest/configs/basic-vyos @@ -95,10 +95,15 @@ service {          shared-network-name LAN6 {              subnet fe88::/56 {                  address-range { -                    prefix fe88::/56 { +                    prefix fe88::/60 {                          temporary                      } +                    start fe88:0000:0000:fe:: { +                        stop fe88:0000:0000:ff:: +                    }                  } +                domain-search vyos.net +                name-server fe88::1                  prefix-delegation {                      start fe88:0000:0000:0001:: {                          prefix-length 64 diff --git a/smoketest/scripts/cli/test_service_dhcpv6-server.py b/smoketest/scripts/cli/test_service_dhcpv6-server.py index fcbfeb7be..dcce30f55 100755 --- a/smoketest/scripts/cli/test_service_dhcpv6-server.py +++ b/smoketest/scripts/cli/test_service_dhcpv6-server.py @@ -104,24 +104,25 @@ class TestServiceDHCPv6Server(VyOSUnitTestSHIM.TestCase):          self.cli_set(base_path + ['preference', preference])          self.cli_set(pool + ['subnet-id', '1'])          # we use the first subnet IP address as default gateway -        self.cli_set(pool + ['name-server', dns_1]) -        self.cli_set(pool + ['name-server', dns_2]) -        self.cli_set(pool + ['name-server', dns_2])          self.cli_set(pool + ['lease-time', 'default', lease_time])          self.cli_set(pool + ['lease-time', 'maximum', max_lease_time])          self.cli_set(pool + ['lease-time', 'minimum', min_lease_time]) -        self.cli_set(pool + ['nis-domain', domain]) -        self.cli_set(pool + ['nisplus-domain', domain]) -        self.cli_set(pool + ['sip-server', sip_server]) -        self.cli_set(pool + ['sntp-server', sntp_server]) -        self.cli_set(pool + ['address-range', 'start', range_start, 'stop', range_stop]) +        self.cli_set(pool + ['option', 'name-server', dns_1]) +        self.cli_set(pool + ['option', 'name-server', dns_2]) +        self.cli_set(pool + ['option', 'name-server', dns_2]) +        self.cli_set(pool + ['option', 'nis-domain', domain]) +        self.cli_set(pool + ['option', 'nisplus-domain', domain]) +        self.cli_set(pool + ['option', 'sip-server', sip_server]) +        self.cli_set(pool + ['option', 'sntp-server', sntp_server]) +        self.cli_set(pool + ['range', '1', 'start', range_start]) +        self.cli_set(pool + ['range', '1', 'stop', range_stop])          for server in nis_servers: -            self.cli_set(pool + ['nis-server', server]) -            self.cli_set(pool + ['nisplus-server', server]) +            self.cli_set(pool + ['option', 'nis-server', server]) +            self.cli_set(pool + ['option', 'nisplus-server', server])          for search in search_domains: -            self.cli_set(pool + ['domain-search', search]) +            self.cli_set(pool + ['option', 'domain-search', search])          client_base = 1          for client in ['client1', 'client2', 'client3']: @@ -217,7 +218,8 @@ class TestServiceDHCPv6Server(VyOSUnitTestSHIM.TestCase):          pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet]          self.cli_set(pool + ['subnet-id', '1']) -        self.cli_set(pool + ['address-range', 'start', range_start, 'stop', range_stop]) +        self.cli_set(pool + ['range', '1', 'start', range_start]) +        self.cli_set(pool + ['range', '1', 'stop', range_stop])          self.cli_set(pool + ['prefix-delegation', 'prefix', delegate_start, 'delegated-length', delegate_len])          self.cli_set(pool + ['prefix-delegation', 'prefix', delegate_start, 'prefix-length', prefix_len]) diff --git a/src/conf_mode/service_dhcpv6-server.py b/src/conf_mode/service_dhcpv6-server.py index 7cd801cdd..214531904 100755 --- a/src/conf_mode/service_dhcpv6-server.py +++ b/src/conf_mode/service_dhcpv6-server.py @@ -81,26 +81,29 @@ def verify(dhcpv6):              subnet_ids.append(subnet_config['subnet_id']) -            if 'address_range' in subnet_config: -                if 'start' in subnet_config['address_range']: -                    range6_start = [] -                    range6_stop = [] -                    for start, start_config in subnet_config['address_range']['start'].items(): -                        if 'stop' not in start_config: -                            raise ConfigError(f'address-range stop address for start "{start}" is not defined!') -                        stop = start_config['stop'] +            if 'range' in subnet_config: +                range6_start = [] +                range6_stop = [] + +                for num, range_config in subnet_config['range'].items(): +                    if 'start' in range_config: +                        start = range_config['start'] + +                        if 'stop' not in range_config: +                            raise ConfigError(f'Range stop address for start "{start}" is not defined!') +                        stop = range_config['stop']                          # Start address must be inside network                          if not ip_address(start) in ip_network(subnet): -                            raise ConfigError(f'address-range start address "{start}" is not in subnet "{subnet}"!') +                            raise ConfigError(f'Range start address "{start}" is not in subnet "{subnet}"!')                          # Stop address must be inside network                          if not ip_address(stop) in ip_network(subnet): -                             raise ConfigError(f'address-range stop address "{stop}" is not in subnet "{subnet}"!') +                             raise ConfigError(f'Range stop address "{stop}" is not in subnet "{subnet}"!')                          # Stop address must be greater or equal to start address                          if not ip_address(stop) >= ip_address(start): -                            raise ConfigError(f'address-range stop address "{stop}" must be greater then or equal ' \ +                            raise ConfigError(f'Range stop address "{stop}" must be greater then or equal ' \                                                f'to the range start address "{start}"!')                          # DHCPv6 range start address must be unique - two ranges can't @@ -108,6 +111,7 @@ def verify(dhcpv6):                          if start in range6_start:                              raise ConfigError(f'Conflicting DHCPv6 lease range: '\                                                f'Pool start address "{start}" defined multipe times!') +                          range6_start.append(start)                          # DHCPv6 range stop address must be unique - two ranges can't @@ -115,12 +119,14 @@ def verify(dhcpv6):                          if stop in range6_stop:                              raise ConfigError(f'Conflicting DHCPv6 lease range: '\                                                f'Pool stop address "{stop}" defined multipe times!') +                          range6_stop.append(stop) -                if 'prefix' in subnet_config: -                    for prefix in subnet_config['prefix']: -                        if ip_network(prefix) not in ip_network(subnet): -                            raise ConfigError(f'address-range prefix "{prefix}" is not in subnet "{subnet}""') +                    if 'prefix' in range_config: +                        prefix = range_config['prefix'] + +                        if not ip_network(prefix).subnet_of(ip_network(subnet)): +                            raise ConfigError(f'Range prefix "{prefix}" is not in subnet "{subnet}"')              # Prefix delegation sanity checks              if 'prefix_delegation' in subnet_config: @@ -151,13 +157,15 @@ def verify(dhcpv6):                              raise ConfigError(f'Either MAC address or Client identifier (DUID) is required for '                                                f'static mapping "{mapping}" within shared-network "{network}, {subnet}"!') -            if 'vendor_option' in subnet_config: -                if len(dict_search('vendor_option.cisco.tftp_server', subnet_config)) > 2: -                    raise ConfigError(f'No more then two Cisco tftp-servers should be defined for subnet "{subnet}"!') +            if 'option' in subnet_config: +                if 'vendor_option' in subnet_config['option']: +                    if len(dict_search('option.vendor_option.cisco.tftp_server', subnet_config)) > 2: +                        raise ConfigError(f'No more then two Cisco tftp-servers should be defined for subnet "{subnet}"!')              # Subnets must be unique              if subnet in subnets:                  raise ConfigError(f'DHCPv6 subnets must be unique! Subnet {subnet} defined multiple times!') +              subnets.append(subnet)          # DHCPv6 requires at least one configured address range or one static mapping diff --git a/src/migration-scripts/dhcpv6-server/3-to-4 b/src/migration-scripts/dhcpv6-server/3-to-4 index c065e3d43..4747ebd60 100755 --- a/src/migration-scripts/dhcpv6-server/3-to-4 +++ b/src/migration-scripts/dhcpv6-server/3-to-4 @@ -16,6 +16,8 @@  # T3316:  # - Add subnet IDs to existing subnets +# - Move options to option node +# - Migrate address-range to range tagNode  import sys  import re @@ -37,6 +39,10 @@ if not config.exists(base):      # Nothing to do      sys.exit(0) +option_nodes = ['captive-portal', 'domain-search', 'name-server', +                'nis-domain', 'nis-server', 'nisplus-domain', 'nisplus-server', +                'sip-server', 'sntp-server', 'vendor-option'] +  subnet_id = 1  for network in config.list_nodes(base): @@ -44,6 +50,35 @@ for network in config.list_nodes(base):          for subnet in config.list_nodes(base + [network, 'subnet']):              base_subnet = base + [network, 'subnet', subnet] +            if config.exists(base_subnet + ['address-range']): +                config.set(base_subnet + ['range']) +                config.set_tag(base_subnet + ['range']) + +                range_id = 1 + +                if config.exists(base_subnet + ['address-range', 'prefix']): +                    for prefix in config.return_values(base_subnet + ['address-range', 'prefix']): +                        config.set(base_subnet + ['range', range_id, 'prefix'], value=prefix) + +                        range_id += 1 + +                if config.exists(base_subnet + ['address-range', 'start']): +                    for start in config.list_nodes(base_subnet + ['address-range', 'start']): +                        stop = config.return_value(base_subnet + ['address-range', 'start', start, 'stop']) + +                        config.set(base_subnet + ['range', range_id, 'start'], value=start) +                        config.set(base_subnet + ['range', range_id, 'stop'], value=stop) + +                        range_id += 1 + +                config.delete(base_subnet + ['address-range']) + +            for option in option_nodes: +                if config.exists(base_subnet + [option]): +                    config.set(base_subnet + ['option']) +                    config.copy(base_subnet + [option], base_subnet + ['option', option]) +                    config.delete(base_subnet + [option]) +              config.set(base_subnet + ['subnet-id'], value=subnet_id)              subnet_id += 1 diff --git a/src/op_mode/dhcp.py b/src/op_mode/dhcp.py index 02f4d5bbb..a64acec31 100755 --- a/src/op_mode/dhcp.py +++ b/src/op_mode/dhcp.py @@ -194,14 +194,11 @@ def _get_pool_size(pool, family='inet'):      size = 0      subnets = config.list_nodes(f'{base} subnet')      for subnet in subnets: -        if family == 'inet6': -            ranges = config.list_nodes(f'{base} subnet {subnet} address-range start') -        else: -            ranges = config.list_nodes(f'{base} subnet {subnet} range') +        ranges = config.list_nodes(f'{base} subnet {subnet} range')          for range in ranges:              if family == 'inet6': -                start = config.list_nodes(f'{base} subnet {subnet} address-range start')[0] -                stop = config.value(f'{base} subnet {subnet} address-range start {start} stop') +                start = config.value(f'{base} subnet {subnet} range {range} start') +                stop = config.value(f'{base} subnet {subnet} range {range} stop')              else:                  start = config.value(f'{base} subnet {subnet} range {range} start')                  stop = config.value(f'{base} subnet {subnet} range {range} stop') | 
