def test_relay_in_subnet(dhcp_version): relay_addr_1 = "10.0.0.1" if dhcp_version == 'v4' else '10:0:0::1' relay_addr_2 = "10.0.0.2" if dhcp_version == 'v4' else '10:0:0::2' exp_addr_1 = '192.168.50.1' if dhcp_version == 'v4' else '2001:db8:1::1' exp_addr_2 = '192.168.50.2' if dhcp_version == 'v4' else '2001:db8:1::2' exp_addr_3 = '192.168.50.3' if dhcp_version == 'v4' else '2001:db8:1::3' cfg = setup_server_for_config_backend_cmds() # create a subnet with specific IP address for relay agent subnet_cfg, _ = cfg.add_subnet(relay={"ip-addresses": [relay_addr_1]}) # client 1 behind relay agent 1 should get a lease get_address(mac_addr='00:00:00:00:00:01', relay_addr=relay_addr_1, exp_addr=exp_addr_1) # client 2 behing unknown relay agent 2 should NOT get any lease get_rejected(mac_addr='00:00:00:00:00:02', relay_addr=relay_addr_2) # add another relay agent 2 subnet_cfg.update(relay={"ip-addresses": [relay_addr_1, relay_addr_2]}) # client 2 now should get a lease get_address(mac_addr='00:00:00:00:00:02', relay_addr=relay_addr_2, exp_addr=exp_addr_2) # another client 3 behind relay agent 1 still should be able to get a lease get_address(mac_addr='00:00:00:00:00:03', relay_addr=relay_addr_1, exp_addr=exp_addr_3)
def test_interface_id_in_subnet(): cfg = setup_server_for_config_backend_cmds() # relay_addr='7::1' always set to avoid matching thie relay agent # to defined subnet # create a subnet with specific relay agent interface-id subnet_cfg, _ = cfg.add_subnet(interface_id='vlan-a') # client 1 behind interface-id 'vlan-a' should get a lease get_address(mac_addr='00:00:00:00:00:01', interface_id='vlan-a', relay_addr='7::1') # client 2 behind interface-id 'vlan-b' should NOT get any lease get_rejected(mac_addr='00:00:00:00:00:02', interface_id='vlan-b', relay_addr='7::1') # change interface-id in subnet from 'vlan-a' to 'vlan-b' subnet_cfg.update(interface_id='vlan-b') # client 3 now should get a lease over interface-id 'vlan-b' get_address(mac_addr='00:00:00:00:00:03', interface_id='vlan-b', relay_addr='7::1') # but client 4 now behind interface-id 'vlan-a' should NOT get any lease get_rejected(mac_addr='00:00:00:00:00:04', interface_id='vlan-a', relay_addr='7::1')
def test_class_in_subnet(dhcp_version): # prepare initial config with 1 class 'modem' for 1 client with specificed MAC address init_cfg = {'client-classes': [{'name': 'modem'}]} if dhcp_version == 'v4': init_cfg['client-classes'][0]['test'] = "hexstring(pkt4.mac, ':') == '00:00:00:00:00:01'" else: init_cfg['client-classes'][0]['test'] = "hexstring(option[1].hex, ':') == '00:03:00:01:00:00:00:00:00:01'" cfg = setup_server_for_config_backend_cmds(**init_cfg) # add 1 subnet that permits only client from 'modem' class subnet_cfg, _ = cfg.add_subnet(client_class='modem') # client from 'modem' class with specific MAC address should get lease get_address(mac_addr="00:00:00:00:00:01", exp_addr='192.168.50.1' if dhcp_version == 'v4' else '2001:db8:1::1') # client with another MAC address should be rejected get_rejected(mac_addr='00:00:00:00:00:02') # change class name in subnet and now the first client should not be given a lease # as class names do not match subnet_cfg.update(client_class='not-modem') get_rejected(mac_addr='00:00:00:00:00:01') # change class name in subnet to '' ie. reset it, ie. make the subnet open to any client # and now unclassified should get a lease subnet_cfg.update(client_class='') get_address(mac_addr="00:00:00:00:00:03", exp_addr='192.168.50.2' if dhcp_version == 'v4' else '2001:db8:1::2')
def test_server_tag_kea_without_tag(): # create first configuration, kea has no assigned tag, so it should get config just from "all" cfg = setup_server_for_config_backend_cmds(server_tag="") _set_server_tag("abc") cfg.add_subnet(server_tags=["abc"], subnet="2001:db8:1::/64", id=1, pools=[{'pool': "2001:db8:1::1-2001:db8:1::100"}]) get_rejected() xyz = _get_server_config() # check that we don't have anything configured except default value assert len(xyz["arguments"]["Dhcp6"]["subnet6"]) == 0 assert len(xyz["arguments"]["Dhcp6"]["shared-networks"]) == 0 assert xyz["arguments"]["Dhcp6"]["valid-lifetime"] == 7200 assert len(xyz["arguments"]["Dhcp6"]["option-data"]) == 0 # set network, subnet, option and parameter for "all" cfg.add_network(server_tags=["all"], name="flor1") cfg.add_subnet(server_tags=["all"], shared_network_name="flor1", subnet="2001:db8:2::/64", id=2, pools=[{'pool': "2001:db8:2::1-2001:db8:2::100"}]) cfg.set_global_parameter(server_tags=["all"], valid_lifetime=7700) cfg.add_option(server_tags=["all"], code=22, csv_format=True, data="2001::1", name="sip-server-addr", space="dhcp6") xyz = _get_server_config() assert len(xyz["arguments"]["Dhcp6"]["subnet6"]) == 0 assert len(xyz["arguments"]["Dhcp6"]["shared-networks"]) == 1 assert len(xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"]) == 1 assert xyz["arguments"]["Dhcp6"]["valid-lifetime"] == 7700 assert len(xyz["arguments"]["Dhcp6"]["option-data"]) == 1 get_address(mac_addr='00:00:00:00:00:06', exp_ia_na_iaaddr_validlft=7700, req_opts=[22], exp_option={"code": 22, "data": "2001::1"})
def test_class_in_network(dhcp_version): # prepare initial config with 3 class: modem, user, other # each class is assigned to 1 client with specificed MAC address if dhcp_version == 'v4': init_cfg = {'client-classes': [{ 'name': 'modem', 'test': "hexstring(pkt4.mac, ':') == '00:00:00:00:00:01'" }, { 'name': 'user', 'test': "hexstring(pkt4.mac, ':') == '00:00:00:00:00:02'" }, { 'name': 'other', 'test': "hexstring(pkt4.mac, ':') == '00:00:00:00:00:03'" }]} else: init_cfg = {'client-classes': [{ 'name': 'modem', 'test': "hexstring(option[1].hex, ':') == '00:03:00:01:00:00:00:00:00:01'" }, { 'name': 'user', 'test': "hexstring(option[1].hex, ':') == '00:03:00:01:00:00:00:00:00:02'" }, { 'name': 'other', 'test': "hexstring(option[1].hex, ':') == '00:03:00:01:00:00:00:00:00:03'" }]} cfg = setup_server_for_config_backend_cmds(**init_cfg) # add 2 subnets # subnet 1 is for a modem class cfg.add_subnet(client_class='modem') # subnet 2 is assigned to shared netwrok which is assigned to user class network_cfg, _ = cfg.add_network(name='user-nets', client_class='user') pool = '2.2.2.1-2.2.2.10' if dhcp_version == 'v4' else '2:2:2::1-2:2:2::10' cfg.add_subnet(shared_network_name='user-nets', subnet='2.2.2.0/24' if dhcp_version == 'v4' else '2:2:2::/64', pools=[{'pool': pool}]) # client 1 from 'modem' class should get lease from subnet 1 get_address(mac_addr="00:00:00:00:00:01", exp_addr='192.168.50.1' if dhcp_version == 'v4' else '2001:db8:1::1') # client 2 from 'user' class should get lease from subnet 2 get_address(mac_addr="00:00:00:00:00:02", exp_addr='2.2.2.1' if dhcp_version == 'v4' else '2:2:2::1') # client 3 from 'other' class should be rejected get_rejected(mac_addr='00:00:00:00:00:03') # change class name in network to 'other' and now client 3 should be given a lease network_cfg.update(client_class='other') get_address(mac_addr="00:00:00:00:00:03", exp_addr='2.2.2.2' if dhcp_version == 'v4' else '2:2:2::2') # change class name in network to '' ie. reset it, ie. make the network open to any client # and now unclassified client 4 should be given a lease from subnet 2 network_cfg.update(client_class='') get_address(mac_addr="00:00:00:00:00:04", exp_addr='2.2.2.3' if dhcp_version == 'v4' else '2:2:2::3')
def test_server_tag_network(): cfg = setup_server_for_config_backend_cmds(server_tag="abc") _set_server_tag("xyz") _set_server_tag("abc") cfg.add_network(server_tags=["abc"], name="flor1") cfg.add_subnet(shared_network_name="flor1", server_tags=["abc"], subnet="2001:db8:1::/64", id=1, pools=[{'pool': "2001:db8:1::1-2001:db8:1::1"}]) xyz = _get_server_config() assert len(xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"]) == 1 assert xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"][0]["subnet"] == "2001:db8:1::/64" get_address(mac_addr='00:00:00:00:00:03', exp_addr='2001:db8:1::1') cfg.add_network(server_tags=["xyz"], name="flor2") cfg.add_subnet(shared_network_name="flor2", server_tags=["xyz"], subnet="2001:db8:2::/64", id=2, pools=[{'pool': "2001:db8:2::5-2001:db8:2::5"}]) # we still want just one network with one subnet xyz = _get_server_config() assert len(xyz["arguments"]["Dhcp6"]["shared-networks"]) == 1 assert len(xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"]) == 1 assert xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"][0]["subnet"] == "2001:db8:1::/64" get_rejected(mac_addr='00:00:00:00:00:10') srv_control.start_srv('DHCP', 'stopped') setup_server_for_config_backend_cmds(server_tag="xyz") get_address(mac_addr='00:00:00:00:00:04', exp_addr='2001:db8:2::5') # we still want just one network with one subnet but different subnet, from xyz xyz = _get_server_config() assert len(xyz["arguments"]["Dhcp6"]["shared-networks"]) == 1 assert len(xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"]) == 1 assert xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"][0]["subnet"] == "2001:db8:2::/64" cfg.add_subnet(shared_network_name="flor2", server_tags=["all"], subnet="2001:db8:3::/64", id=3, pools=[{'pool': "2001:db8:3::5-2001:db8:3::5"}]) # model was incomplete on previous step so I can't use del_subnet method because it's again # forcing checking cmd = dict(command="remote-subnet6-del-by-prefix", arguments={"remote": {"type": "mysql"}, "subnets": [{"subnet": "2001:db8:2::/64"}]}) srv_msg.send_ctrl_cmd(cmd, exp_result=0) xyz = _get_server_config(reload_kea=True) assert len(xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"]) == 1 assert xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"][0]["subnet"] == "2001:db8:3::/64" # this time we expect address from "all" get_address(mac_addr='00:00:00:00:00:05', exp_addr='2001:db8:3::5')
def test_subnet_and_valid_lifetime(dhcp_version): # change valid-lifetime on different levels (global and subnet) # and check if behavior is as expected ie leases after lifetime # are available for other clients cfg = setup_server_for_config_backend_cmds() # define one, default subnet with 1 IP address cfg.add_subnet(pool="192.168.50.2/32" if dhcp_version == 'v4' else '2001:db8:1::2/128') # check getting address from this subnet by client 1 get_address(mac_addr='00:00:00:00:00:01', exp_addr='192.168.50.2' if dhcp_version == 'v4' else '2001:db8:1::2') # after 2 seconds check if another client 2 can get address - as default lifetime is big # it should fail because there is no more IP addresses (there is only 1 taken) time.sleep(2) get_rejected(mac_addr='00:00:00:00:00:02') # change lease lifetime on global level to be small ie. 1sec # and 1) extend address pool by 1 IP for new client 3 as previous IP address is taken for long time # and 2) check getting address by this new client 3 cfg.set_global_parameter(valid_lifetime=1) cfg.update_subnet(pool="192.168.50.2/31" if dhcp_version == 'v4' else '2001:db8:1::2/127') get_address(mac_addr='00:00:00:00:00:03', exp_lease_time=1, exp_addr='192.168.50.3' if dhcp_version == 'v4' else '2001:db8:1::3') # as lease time is 1 sec after 2secs this just taken IP address should # be available for other clients ie. client 4 time.sleep(2) get_address(mac_addr='00:00:00:00:00:04', exp_addr='192.168.50.3' if dhcp_version == 'v4' else '2001:db8:1::3') # wait for lease expiration for next test steps time.sleep(2) # change lease lifetime on subnet level to be big ie. 1000sec # and check getting address by client 5 cfg.update_subnet(valid_lifetime=1000) get_address(mac_addr='00:00:00:00:00:05', exp_lease_time=1000, exp_addr='192.168.50.3' if dhcp_version == 'v4' else '2001:db8:1::3') # after 2 seconds check if another client 6 can get address - as new lifetime is big # it should fail because there is no more IP addresses (there is only 2 taken) time.sleep(2) get_rejected(mac_addr='00:00:00:00:00:06') # change lease lifetime on subnet level to be small ie. 1sec # and check getting address by client 7 but first extent pool by one address # as previous IP addresses are taken for long time cfg.update_subnet(valid_lifetime=1, pool="192.168.50.2-192.168.50.4" if dhcp_version == 'v4' else '2001:db8:1::2-2001:db8:1::4') get_address(mac_addr='00:00:00:00:00:07', exp_lease_time=1, exp_addr='192.168.50.4' if dhcp_version == 'v4' else '2001:db8:1::4') # as lease time is 1 sec after 2secs this just taken IP address should # be available for other clients ie. client 8 time.sleep(2) get_address(mac_addr='00:00:00:00:00:08', exp_addr='192.168.50.4' if dhcp_version == 'v4' else '2001:db8:1::4')
def test_server_tag_kea_without_tag(): # create first configuration, kea has no assigned tag, so it should get config just from "all" cfg = setup_server_for_config_backend_cmds(server_tag="") _set_server_tag("abc") cfg.add_subnet(server_tags=["abc"], subnet="192.168.52.0/24", id=1, pools=[{ 'pool': "192.168.52.1-192.168.52.100" }]) get_rejected() xyz = _get_server_config() # check that we don't have anything configured except default value assert len(xyz["arguments"]["Dhcp4"]["subnet4"]) == 0 assert len(xyz["arguments"]["Dhcp4"]["shared-networks"]) == 0 assert xyz["arguments"]["Dhcp4"]["boot-file-name"] == "" assert len(xyz["arguments"]["Dhcp4"]["option-data"]) == 0 # set network, subnet, option and parameter for "all" cfg.add_network(server_tags=["all"], name="flor1") cfg.add_subnet(server_tags=["all"], shared_network_name="flor1", subnet="192.168.50.0/24", id=2, pools=[{ 'pool': "192.168.50.1-192.168.50.100" }]) cfg.set_global_parameter(server_tags=["all"], valid_lifetime=7700) cfg.set_global_parameter(server_tags=["all"], boot_file_name="/dev/null_all") cfg.add_option(server_tags=["all"], code=3, csv_format=True, data="10.0.0.1", name="routers", space="dhcp4") xyz = _get_server_config() assert len(xyz["arguments"]["Dhcp4"]["subnet4"]) == 0 assert len(xyz["arguments"]["Dhcp4"]["shared-networks"]) == 1 assert len(xyz["arguments"]["Dhcp4"]["shared-networks"][0]["subnet4"]) == 1 assert xyz["arguments"]["Dhcp4"]["boot-file-name"] == "/dev/null_all" assert len(xyz["arguments"]["Dhcp4"]["option-data"]) == 1 get_address(mac_addr='00:00:00:00:00:06', exp_boot_file_name="/dev/null_all", req_opts=[3], exp_option={ "code": 3, "data": "10.0.0.1" })
def test_relay_in_network(dhcp_version): relay_addr_1 = "10.0.0.1" if dhcp_version == 'v4' else '10:0:0::1' relay_addr_2 = "10.0.0.2" if dhcp_version == 'v4' else '10:0:0::2' relay_addr_3 = "10.0.0.3" if dhcp_version == 'v4' else '10:0:0::3' exp_addr_1 = '192.168.50.1' if dhcp_version == 'v4' else '2001:db8:1::1' exp_addr_2 = '192.168.50.2' if dhcp_version == 'v4' else '2001:db8:1::2' exp_addr_3 = '192.168.50.3' if dhcp_version == 'v4' else '2001:db8:1::3' exp_addr_4 = '192.168.50.4' if dhcp_version == 'v4' else '2001:db8:1::4' cfg = setup_server_for_config_backend_cmds() # create a network with specific IP address for relay agent network_cfg, _ = cfg.add_network(relay={"ip-addresses": [relay_addr_1]}) subnet_cfg, _ = cfg.add_subnet(network=network_cfg) # client 1 behind relay agent 1 should get a lease get_address(mac_addr='00:00:00:00:00:01', relay_addr=relay_addr_1, exp_addr=exp_addr_1) # client 2 behing unknown relay agent 2 should NOT get any lease get_rejected(mac_addr='00:00:00:00:00:02', relay_addr=relay_addr_2) # add another relay agent 2 network_cfg.update(relay={"ip-addresses": [relay_addr_1, relay_addr_2]}) # client 2 now should get a lease get_address(mac_addr='00:00:00:00:00:02', relay_addr=relay_addr_2, exp_addr=exp_addr_2) # another client 3 behind relay agent 1 still should be able to get a lease get_address(mac_addr='00:00:00:00:00:03', relay_addr=relay_addr_1, exp_addr=exp_addr_3) # and now override relay on subnet level to relay agent 3 subnet_cfg.update(relay={"ip-addresses": [relay_addr_3]}) # client 4 now should get a lease get_address(mac_addr='00:00:00:00:00:04', relay_addr=relay_addr_3, exp_addr=exp_addr_4) # another client 5 behind relay agent 1 now should NOT be able to get any lease get_rejected(mac_addr='00:00:00:00:00:03', relay_addr=relay_addr_1)
def test_interface_id_in_subnet(): cfg = setup_server_for_config_backend_cmds() # create a subnet with specific relay agent interface-id subnet_cfg, _ = cfg.add_subnet(interface_id='vlan-a') # client 1 behind interface-id 'vlan-a' should get a lease get_address(mac_addr='00:00:00:00:00:01', interface_id='vlan-a') # client 2 behind interface-id 'vlan-b' should NOT get any lease get_rejected(mac_addr='00:00:00:00:00:02', interface_id='vlan-b') # change interface-id in subnet from 'vlan-a' to 'vlan-b' subnet_cfg.update(interface_id='vlan-b') # client 3 now should get a lease over interface-id 'vlan-b' get_address(mac_addr='00:00:00:00:00:03', interface_id='vlan-b') # but client 4 now behind interface-id 'vlan-a' should NOT get any lease get_rejected(mac_addr='00:00:00:00:00:04', interface_id='vlan-a')
def test_interface_id_in_network(): cfg = setup_server_for_config_backend_cmds() # relay_addr='7::1' always set to avoid matching thie relay agent # to defined subnet # create a network with specific relay agent interface-id network_cfg, _ = cfg.add_network(interface_id='vlan-a') subnet_cfg, _ = cfg.add_subnet(network=network_cfg, interface='') # client 1 behind interface-id 'vlan-a' should get a lease get_address(mac_addr='00:00:00:00:00:01', interface_id='vlan-a', relay_addr='7::1') # client 2 behind interface-id 'vlan-b' should NOT get any lease get_rejected(mac_addr='00:00:00:00:00:02', interface_id='vlan-b', relay_addr='7::1') # change interface-id in network from 'vlan-a' to 'vlan-b' network_cfg.update(interface_id='vlan-b') # client 3 now should get a lease over interface-id 'vlan-b' get_address(mac_addr='00:00:00:00:00:03', interface_id='vlan-b', relay_addr='7::1') # but client 4 now behind interface-id 'vlan-a' should NOT get any lease get_rejected(mac_addr='00:00:00:00:00:04', interface_id='vlan-a', relay_addr='7::1') # set interface-id in subnet from 'vlan-c' ie. override the one in network subnet_cfg.update(interface_id='vlan-c') # client 5 now should get a lease over interface-id 'vlan-c' get_address(mac_addr='00:00:00:00:00:05', interface_id='vlan-b', relay_addr='7::1') # but client 6 now behind interface-id 'vlan-b' (that is set in network) # should NOT get any lease get_rejected(mac_addr='00:00:00:00:00:06', interface_id='vlan-b', relay_addr='7::1')
def test_interface_id_in_network(): cfg = setup_server_for_config_backend_cmds() # create a network with specific relay agent interface-id network_cfg, _ = cfg.add_network(interface_id='vlan-a') subnet_cfg, _ = cfg.add_subnet(network=network_cfg) # client 1 behind interface-id 'vlan-a' should get a lease get_address(mac_addr='00:00:00:00:00:01', interface_id='vlan-a') # client 2 behind interface-id 'vlan-b' should NOT get any lease get_rejected(mac_addr='00:00:00:00:00:02', interface_id='vlan-b') # change interface-id in network from 'vlan-a' to 'vlan-b' network_cfg.update(interface_id='vlan-b') # client 3 now should get a lease over interface-id 'vlan-b' get_address(mac_addr='00:00:00:00:00:03', interface_id='vlan-b') # but client 4 now behind interface-id 'vlan-a' should NOT get any lease get_rejected(mac_addr='00:00:00:00:00:04', interface_id='vlan-a') # set interface-id in subnet from 'vlan-c' ie. override the one in network subnet_cfg.update(interface_id='vlan-c') # client 5 now should get a lease over interface-id 'vlan-c' get_address(mac_addr='00:00:00:00:00:05', interface_id='vlan-b') # but client 6 now behind interface-id 'vlan-b' (that is set in network) # should NOT get any lease get_rejected(mac_addr='00:00:00:00:00:06', interface_id='vlan-b')
def test_auto_reload_100seconds(dhcp_version): # prepare initial config with fetch wait time set to 100 seconds cfg = setup_server_for_config_backend_cmds(config_control={"config-fetch-wait-time": 100}, force_reload=False) dhcp_key = 'Dhcp%s' % dhcp_version[1] subnet_key = 'subnet%s' % dhcp_version[1] # check config that there is no subnets and fetch time is 100 new_cfg = get_config() assert len(new_cfg[dhcp_key][subnet_key]) == 0 assert new_cfg[dhcp_key]['config-control']['config-fetch-wait-time'] == 100 # add subnet and wait 2 seconds that config is NOT reloaded automatically as it is done every 100 seconds cfg.add_subnet() time.sleep(2) # now check if there is NO subnets in config new_cfg = get_config() assert len(new_cfg[dhcp_key][subnet_key]) == 0 # there is NO subnet so getting address should fail get_rejected()
def test_auto_reload_100seconds(dhcp_version): # prepare initial config with fetch wait time set to 100 seconds cfg = setup_server_for_config_backend_cmds( config_control={"config-fetch-wait-time": 100}, force_reload=False) dhcp_key = 'Dhcp%s' % dhcp_version[1] subnet_key = 'subnet%s' % dhcp_version[1] # check config that there is no subnets and fetch time is 100 new_cfg = get_config() assert len(new_cfg[dhcp_key][subnet_key]) == 0 assert new_cfg[dhcp_key]['config-control']['config-fetch-wait-time'] == 100 # add subnet and wait 2 seconds that config is NOT reloaded automatically as it is done every 100 seconds cfg.add_subnet() time.sleep(2) # now check if there is NO subnets in config new_cfg = get_config() assert len(new_cfg[dhcp_key][subnet_key]) == 0 # there is NO subnet so getting address should fail get_rejected()
def test_decline_and_probation_period(initial_decline_probation_period, dhcp_version): # Set initial value of decline-probation-period in config file and then change it # using cb-cmds. Observe if the setting is honored in case of sending DECLINE messages. # Different initial settings for decline-probation-period: default (=24h), 1 second and 1000 seconds. cfg = setup_server_for_config_backend_cmds(decline_probation_period=initial_decline_probation_period) # Prepare subnet with only 1 IP address in a pool. This way when the second DISCOVER is send # no response should be expected from server. cfg.add_subnet(pool='192.168.50.1/32' if dhcp_version == 'v4' else '2001:db8:1::1/128') # Get address and decline it. if dhcp_version == 'v4': addr = get_address4(exp_yiaddr='192.168.50.1') send_decline4(addr) else: get_address6(exp_ia_na_iaaddr_addr='2001:db8:1::1') send_decline6() # Wait a moment. time.sleep(2) # If initial decline-probation-period was 1 second then it should # be possible to acquire the same IP again, ie. after 1 second it should have been # returned to pool from probation space. if initial_decline_probation_period == 1: get_address(exp_addr='192.168.50.1' if dhcp_version == 'v4' else '2001:db8:1::1') else: # If initial value was other than 1 second then server should still keep # the IP in probation and no response should be sent by server. get_rejected() # Delete subnet. This will delete IP in probation. Ie. start from scratch. cfg.del_subnet() # Change decline-probation-period from initial to 1000 seconds. cfg.set_global_parameter(decline_probation_period=1000) # Create new subnet with different pool but still with 1 IP address. cfg.add_subnet(pool='192.168.50.2/32' if dhcp_version == 'v4' else '2001:db8:1::2/128') # Now after decline and sleeping 2 seconds the declined address still should # be in probation and server should not send any response for discover. if dhcp_version == 'v4': addr = get_address4(exp_yiaddr='192.168.50.2') send_decline4(addr) else: get_address6(exp_ia_na_iaaddr_addr='2001:db8:1::2') send_decline6() time.sleep(2) get_rejected() # Start from scratch again. New pool with 1 IP address. # Probation period is changed now to 1 second. cfg.del_subnet() cfg.set_global_parameter(decline_probation_period=1) cfg.add_subnet(pool='192.168.50.3/32' if dhcp_version == 'v4' else '2001:db8:1::3/128') # This time after decline and sleeping the address should be available # for the following request. if dhcp_version == 'v4': addr1 = get_address4(exp_yiaddr='192.168.50.3') send_decline4(addr1) time.sleep(2) addr2 = get_address4() assert addr2 == addr1 else: get_address6(exp_ia_na_iaaddr_addr='2001:db8:1::3') send_decline6() time.sleep(2) get_address6(exp_ia_na_iaaddr_addr='2001:db8:1::3')
def test_shared_networks_and_valid_lifetime(dhcp_version): # change valid-lifetime on different levels (global, shared network and subnet) # and check if behavior is as expected ie leases after lifetime # are not available for rebinding cfg = setup_server_for_config_backend_cmds() # define a shared network with one subnet network_cfg, _ = cfg.add_network() subnet_cfg, _ = cfg.add_subnet(network=network_cfg, pool="192.168.50.2/32" if dhcp_version == 'v4' else '2001:db8:1::2/128') # check getting address from this subnet by client 1 get_address( mac_addr='00:00:00:00:00:01', exp_addr='192.168.50.2' if dhcp_version == 'v4' else '2001:db8:1::2') # after 2 seconds check if another client 2 can get address - as default lifetime is big # it should fail because there is no more IP addresses (there is only 1 that is taken) time.sleep(2) get_rejected(mac_addr='00:00:00:00:00:02') # change lease lifetime on global level to be small ie. 1sec # and 1) extend address pool by 1 IP for new client 3 as previous IP address is taken for long time # and 2) check getting address by this new client 3 cfg.set_global_parameter(valid_lifetime=1) subnet_cfg.update(pool="192.168.50.2/31" if dhcp_version == 'v4' else '2001:db8:1::2/127') get_address( mac_addr='00:00:00:00:00:03', exp_lease_time=1, exp_addr='192.168.50.3' if dhcp_version == 'v4' else '2001:db8:1::3') # as lease time is 1 sec after 2secs this just taken IP address should # be available for other clients ie. client 4 time.sleep(2) get_address( mac_addr='00:00:00:00:00:04', exp_addr='192.168.50.3' if dhcp_version == 'v4' else '2001:db8:1::3') # wait for lease expiration for next test steps time.sleep(2) # change lease lifetime on network level to be big ie. 1000sec # and check getting address by client 5 network_cfg.update(valid_lifetime=1000) get_address( mac_addr='00:00:00:00:00:05', exp_lease_time=1000, exp_addr='192.168.50.3' if dhcp_version == 'v4' else '2001:db8:1::3') # after 2 seconds check if another client 6 can get address - as new lifetime is big # it should fail because there is no more IP addresses (there are only 2 that are taken) time.sleep(2) get_rejected(mac_addr='00:00:00:00:00:06') # change lease lifetime on network level to be small ie. 1sec # and check getting address by client 7 but first extent pool by one address # as previous IP addresses are taken for long time network_cfg.update(valid_lifetime=1) subnet_cfg.update(pool="192.168.50.2-192.168.50.4" if dhcp_version == 'v4' else '2001:db8:1::2-2001:db8:1::4') get_address( mac_addr='00:00:00:00:00:07', exp_lease_time=1, exp_addr='192.168.50.4' if dhcp_version == 'v4' else '2001:db8:1::4') # as lease time is 1 sec after 2secs this just taken IP address should # be available for other clients ie. client 8 time.sleep(2) get_address( mac_addr='00:00:00:00:00:08', exp_addr='192.168.50.4' if dhcp_version == 'v4' else '2001:db8:1::4') # wait for lease expiration for next test steps time.sleep(2) # change lease lifetime on subnet level to be big ie. 1000sec # and check getting address by client 9 subnet_cfg.update(valid_lifetime=1000) get_address( mac_addr='00:00:00:00:00:09', exp_lease_time=1000, exp_addr='192.168.50.4' if dhcp_version == 'v4' else '2001:db8:1::4') # after 2 seconds check if another client 10 can get address - as new lifetime is big # it should fail because there is no more IP addresses (there are only 4 that are taken) time.sleep(2) get_rejected(mac_addr='00:00:00:00:00:10') # change lease lifetime on subnet level to be small ie. 1sec # and check getting address by client 11 but first extent pool by one address # as previous IP addresses are taken for long time subnet_cfg.update(valid_lifetime=1, pool="192.168.50.2-192.168.50.5" if dhcp_version == 'v4' else '2001:db8:1::2-2001:db8:1::5') get_address( mac_addr='00:00:00:00:00:11', exp_lease_time=1, exp_addr='192.168.50.5' if dhcp_version == 'v4' else '2001:db8:1::5') # as lease time is 1 sec after 2secs this just taken IP address should # be available for other clients ie. client 12 time.sleep(2) get_address( mac_addr='00:00:00:00:00:12', exp_addr='192.168.50.5' if dhcp_version == 'v4' else '2001:db8:1::5')
def test_decline_and_probation_period(initial_decline_probation_period, dhcp_version): # Set initial value of decline-probation-period in config file and then change it # using cb-cmds. Observe if the setting is honored in case of sending DECLINE messages. # Different initial settings for decline-probation-period: default (=24h), 1 second and 1000 seconds. cfg = setup_server_for_config_backend_cmds( decline_probation_period=initial_decline_probation_period) # Prepare subnet with only 1 IP address in a pool. This way when the second DISCOVER is send # no response should be expected from server. cfg.add_subnet(pool='192.168.50.1/32' if dhcp_version == 'v4' else '2001:db8:1::1/128') # Get address and decline it. if dhcp_version == 'v4': addr = get_address4(exp_yiaddr='192.168.50.1') send_decline4(addr) else: get_address6(exp_ia_na_iaaddr_addr='2001:db8:1::1') send_decline6() # Wait a moment. time.sleep(2) # If initial decline-probation-period was 1 second then it should # be possible to acquire the same IP again, ie. after 1 second it should have been # returned to pool from probation space. if initial_decline_probation_period == 1: get_address(exp_addr='192.168.50.1' if dhcp_version == 'v4' else '2001:db8:1::1') else: # If initial value was other than 1 second then server should still keep # the IP in probation and no response should be sent by server. get_rejected() # Delete subnet. This will delete IP in probation. Ie. start from scratch. cfg.del_subnet() # Change decline-probation-period from initial to 1000 seconds. cfg.set_global_parameter(decline_probation_period=1000) # Create new subnet with different pool but still with 1 IP address. cfg.add_subnet(pool='192.168.50.2/32' if dhcp_version == 'v4' else '2001:db8:1::2/128') # Now after decline and sleeping 2 seconds the declined address still should # be in probation and server should not send any response for discover. if dhcp_version == 'v4': addr = get_address4(exp_yiaddr='192.168.50.2') send_decline4(addr) else: get_address6(exp_ia_na_iaaddr_addr='2001:db8:1::2') send_decline6() time.sleep(2) get_rejected() # Start from scratch again. New pool with 1 IP address. # Probation period is changed now to 1 second. cfg.del_subnet() cfg.set_global_parameter(decline_probation_period=1) cfg.add_subnet(pool='192.168.50.3/32' if dhcp_version == 'v4' else '2001:db8:1::3/128') # This time after decline and sleeping the address should be available # for the following request. if dhcp_version == 'v4': addr1 = get_address4(exp_yiaddr='192.168.50.3') send_decline4(addr1) time.sleep(2) addr2 = get_address4() assert addr2 == addr1 else: get_address6(exp_ia_na_iaaddr_addr='2001:db8:1::3') send_decline6() time.sleep(2) get_address6(exp_ia_na_iaaddr_addr='2001:db8:1::3')
def test_server_tag_subnet(): # create first configuration cfg_xyz = setup_server_for_config_backend_cmds(server_tag="xyz") _set_server_tag("xyz") _set_server_tag("abc") get_rejected() # add configuration for abc, don't check reconfigure result cfg_xyz.add_subnet(server_tags=["abc"], subnet="2001:db8:1::/64", id=1, pools=[{ 'pool': "2001:db8:1::1/128" }]) get_rejected() # unassigned is not supported yet # cfg_xyz.add_subnet(server_tags=["unassigned"], subnet="2001:db8:1::/64", id=3, # pools=[{'pool': "2001:db8:1::10-2001:db8:1::10"}]) # # get_rejected() # add configuration for xyz cfg_xyz.add_subnet(server_tags=["xyz"], subnet="2001:db8:2::/64", id=2, pools=[{ 'pool': "2001:db8:2::50/128" }]) get_address(mac_addr='00:00:00:00:00:01', exp_addr='2001:db8:2::50') xyz = _get_server_config() # check if it's configured with just one subnet assert len(xyz["arguments"]["Dhcp6"]["subnet6"]) == 1 # and this subnet is as expected assert xyz["arguments"]["Dhcp6"]["subnet6"][0]["id"] == 2 assert xyz["arguments"]["Dhcp6"]["subnet6"][0][ "subnet"] == "2001:db8:2::/64" srv_control.start_srv('DHCP', 'stopped') # create second configuration setup_server_for_config_backend_cmds(server_tag="abc") get_address(mac_addr='00:00:00:00:00:02', exp_addr='2001:db8:1::1') abc = _get_server_config() # check if it's configured with just one subnet assert len(abc["arguments"]["Dhcp6"]["subnet6"]) == 1 # and this subnet is as expected assert abc["arguments"]["Dhcp6"]["subnet6"][0]["id"] == 1 assert abc["arguments"]["Dhcp6"]["subnet6"][0][ "subnet"] == "2001:db8:1::/64" srv_control.start_srv('DHCP', 'stopped') # create third subnet that will use "all" tag cfg_qwe = setup_server_for_config_backend_cmds(server_tag="qwe") get_rejected() cfg_qwe.add_subnet(server_tags=["all"], subnet="2001:db8:3::/64", id=3, pools=[{ 'pool': "2001:db8:3::20-2001:db8:3::21" }]) abc = _get_server_config() # check if it's configured with just one subnet assert len(abc["arguments"]["Dhcp6"]["subnet6"]) == 1 # and this subnet is as expected assert abc["arguments"]["Dhcp6"]["subnet6"][0]["id"] == 3 assert abc["arguments"]["Dhcp6"]["subnet6"][0][ "subnet"] == "2001:db8:3::/64" get_address(mac_addr='00:00:00:00:00:03', exp_addr='2001:db8:3::20') srv_control.start_srv('DHCP', 'stopped') setup_server_for_config_backend_cmds(server_tag="abc") abc = _get_server_config() # two subnets without classification on the same interface doesn't make sense so we will just check config # check if it's configured with just two subnets, all and abc configured at the beginning of a test assert len(abc["arguments"]["Dhcp6"]["subnet6"]) == 2 # and this subnet is as expected assert abc["arguments"]["Dhcp6"]["subnet6"][0]["id"] == 1 assert abc["arguments"]["Dhcp6"]["subnet6"][1]["id"] == 3 assert abc["arguments"]["Dhcp6"]["subnet6"][0][ "subnet"] == "2001:db8:1::/64" assert abc["arguments"]["Dhcp6"]["subnet6"][1][ "subnet"] == "2001:db8:3::/64"