diff --git a/gso/services/_ipam.py b/gso/services/_ipam.py
index 7e9ad241a91a0b86b25e8a7c75b44cb64981976b..0688dcad3be2f321f5aafc31826a0310d0ce9b8d 100644
--- a/gso/services/_ipam.py
+++ b/gso/services/_ipam.py
@@ -18,8 +18,8 @@ class V6ServiceNetwork(BaseSettings):
 
 
 class ServiceNetworks(BaseSettings):
-    v4: V4ServiceNetwork
-    v6: V6ServiceNetwork
+    v4: ipaddress.IPv4Network
+    v6: ipaddress.IPv6Network
 
 
 class V4HostAddress(BaseSettings):
@@ -27,12 +27,12 @@ class V4HostAddress(BaseSettings):
 
 
 class V6HostAddress(BaseSettings):
-     v6: ipaddress.IPv6Address
+    v6: ipaddress.IPv6Address
 
 
 class HostAddresses(BaseSettings):
-    v4: V4HostAddress
-    v6: V6HostAddress
+    v4: ipaddress.IPv4Address
+    v6: ipaddress.IPv6Address
 
 
 # TODO: remove this!
@@ -65,7 +65,7 @@ def _ip_network_version(network):
     assert ip_version in [4, 6]
     return ip_version
 
-def find_containers(network=None, ip_version=4):
+def _find_containers(network=None, ip_version=4):
     """
     If network is not None, find the container that contains specified network.
     Otherwise find all containers.
@@ -84,7 +84,7 @@ def find_containers(network=None, ip_version=4):
     assert r.status_code >= 200 and r.status_code < 300, f"HTTP error {r.status_code}: {r.reason}\n\n{r.text}"
     return r.json()
 
-def find_networks(network_container=None, network=None, ip_version=4):
+def _find_networks(network_container=None, network=None, ip_version=4):
     """
     If network_container is not None, find all networks within the specified container.
     Otherwise if network is not None, find the specified network.
@@ -110,7 +110,7 @@ def find_networks(network_container=None, network=None, ip_version=4):
     assert r.status_code >= 200 and r.status_code < 300, f"HTTP error {r.status_code}: {r.reason}\n\n{r.text}"
     return r.json()
 
-def get_network_capacity(network=None):
+def _get_network_capacity(network=None):
     """
     Get utilization of a IPv4 network in a fraction of 1000.
     """
@@ -128,6 +128,7 @@ def get_network_capacity(network=None):
         auth=HTTPBasicAuth(infoblox_params.username, infoblox_params.password),
         verify=False
     )
+    # Utilization info takes several minutes to converge. The IPAM utilization bar in the GUI as well. Why?
     assert r.status_code >= 200 and r.status_code < 300, f"HTTP error {r.status_code}: {r.reason}\n\n{r.text}"
     capacity_info = r.json()
     assert len(capacity_info) == 1, "Requested IPv4 network doesn't exist."
@@ -208,11 +209,11 @@ def allocate_service_ipv6_network(service_type) -> V6ServiceNetwork:
     assert hasattr(ipam_params, service_type) and service_type != 'INFOBLOX', "Invalid service type."
     return _allocate_network(ipam_params.INFOBLOX, getattr(ipam_params, service_type).V6, 6)
 
-def delete_network(network) -> Union[V4ServiceNetwork, V6ServiceNetwork]:
+def _delete_network(network) -> Union[V4ServiceNetwork, V6ServiceNetwork]:
     """
     Delete IPv4 or IPv6 network by CIDR.
     """
-    # TODO: should we check that there are no hosts in this network?
+    # TODO: should we check that there are no hosts in this network before deleting?
     # Deleting a network deletes the hosts in it, but not the associated DNS records.
     oss = settings.load_oss_params()
     assert oss.IPAM.INFOBLOX
@@ -220,7 +221,7 @@ def delete_network(network) -> Union[V4ServiceNetwork, V6ServiceNetwork]:
 
     ip_version = _ip_network_version(network)
 
-    network_info = find_networks(network=network, ip_version=ip_version)
+    network_info = _find_networks(network=network, ip_version=ip_version)
     assert len(network_info) == 1, "Network does not exist."
     assert '_ref' in network_info[0]
 
@@ -245,20 +246,20 @@ def _find_next_available_ip(infoblox_params, network_ref):
         auth=HTTPBasicAuth(infoblox_params.username, infoblox_params.password),
         verify=False
     )
-    # TODO: handle no more available IPs in the network
+    # TODO: propagate no more available IPs in the network
     assert r.status_code >= 200 and r.status_code < 300, f"HTTP error {r.status_code}: {r.reason}\n\n{r.text}"
     assert 'ips' in r.json()
     received_ip = r.json()['ips']
     assert len(received_ip) == 1
     return received_ip[0]
 
-def allocate_host(hostname=None, addr=None, network=None) -> Union[V4HostAddress, V6HostAddress]:
+def _allocate_host(hostname=None, addr=None, network=None) -> Union[V4HostAddress, V6HostAddress]:
     """
     If network is not None, allocate host in that network.
     Otherwise if addr is not None, allocate host with that address.
     hostname parameter must be full name including domain name.
     """
-    # TODO: should hostnames be unique (i.e. fail if hostname already exists in this domain)?
+    # TODO: should hostnames be unique (i.e. fail if hostname already exists in this domain/service)?
     assert addr or network, "You must specify either the host address or the network CIDR."
     oss = settings.load_oss_params()
     assert oss.IPAM.INFOBLOX
@@ -267,7 +268,7 @@ def allocate_host(hostname=None, addr=None, network=None) -> Union[V4HostAddress
     if network:
         ip_version = _ip_network_version(network)
         # Find the next available IP address in the network
-        network_info = find_networks(network=network, ip_version=ip_version)
+        network_info = _find_networks(network=network, ip_version=ip_version)
         assert len(network_info) == 1, "Network does not exist. Create it first."
         assert '_ref' in network_info[0]
         addr = _find_next_available_ip(infoblox_params, network_info[0]["_ref"])
@@ -339,49 +340,58 @@ def allocate_host(hostname=None, addr=None, network=None) -> Union[V4HostAddress
     else:
         return V6HostAddress(v6=addr)
 
-def allocate_service_host(hostname=None, service_type=None) -> HostAddresses:
+def allocate_service_host(hostname=None, service_type=None, service_networks: ServiceNetworks = None) -> HostAddresses:
     """
     Allocate host with both IPv4 and IPv6 address (and respective DNS records).
-    The first network with available space for this service type is used.
     The domain name is also taken from the service type and appended to specified hostname.
+    If service_networks is not provided, the first network with available space for this service type is used.
+    If service_networks is provided, that one is used.
     """
     oss = settings.load_oss_params()
     assert oss.IPAM
     ipam_params = oss.IPAM
-    assert ipam_params.INFOBLOX
-    infoblox_params = ipam_params.INFOBLOX
 
     assert hasattr(ipam_params, service_type) and service_type != 'INFOBLOX', "Invalid service type."
     ipv4_container = getattr(ipam_params, service_type).V4.container
     ipv6_container = getattr(ipam_params, service_type).V6.container
     domain_name = getattr(ipam_params, service_type).domain_name
 
-    ipv4_networks_info = find_networks(network_container=str(ipv4_container), ip_version=4)
-    assert len(ipv4_networks_info) >= 1, "No IPv4 network exists in the container for this service type."
-    first_nonfull_ipv4_network = None
-    for ipv4_network_info in ipv4_networks_info:
-        assert 'network' in ipv4_network_info
-        capacity = get_network_capacity(ipv4_network_info["network"])
-        if capacity < 1000:
-            first_nonfull_ipv4_network = ipv4_network_info["network"]
-            break
-    # Create a new network if the existing networks in the container for the service type are all full.
-    if not first_nonfull_ipv4_network:
-        first_nonfull_ipv4_network = str(allocate_service_ipv4_network(service_type=service_type).v4)
-    assert first_nonfull_ipv4_network, "No available IPv4 addresses for this service type."
-    v4_host = allocate_host(hostname=hostname+domain_name, network=first_nonfull_ipv4_network)
-
-    # ipv6 does not support capacity fetching (not even the GUI displays it).
-    # Maybe it's assumed that there is always available space?
-    ipv6_networks_info = find_networks(network_container=str(ipv6_container), ip_version=6)
-    assert len(ipv6_networks_info) >= 1, "No IPv6 network exists in the container for this service type."
-    assert 'network' in ipv6_networks_info[0]
-    # TODO: if "no available IP" error, create a new network?
-    v6_host = allocate_host(hostname=hostname+domain_name, network=ipv6_networks_info[0]['network'])
-
-    return HostAddresses(v4=v4_host,v6=v6_host)
-
-def delete_host_by_ip(addr):
+    # IPv4
+    if not service_networks:
+        ipv4_networks_info = _find_networks(network_container=str(ipv4_container), ip_version=4)
+        assert len(ipv4_networks_info) >= 1, "No IPv4 network exists in the container for this service type."
+        first_nonfull_ipv4_network = None
+        for ipv4_network_info in ipv4_networks_info:
+            assert 'network' in ipv4_network_info
+            capacity = _get_network_capacity(ipv4_network_info["network"])
+            if capacity < 1000:
+                first_nonfull_ipv4_network = ipv4_network_info["network"]
+                break
+        # Create a new network if the existing networks in the container for the service type are all full.
+        if not first_nonfull_ipv4_network:
+            first_nonfull_ipv4_network = str(allocate_service_ipv4_network(service_type=service_type).v4)
+        assert first_nonfull_ipv4_network, "No available IPv4 addresses for this service type."
+        v4_host = _allocate_host(hostname=hostname+domain_name, network=first_nonfull_ipv4_network)
+    else:
+        network = str(service_networks.v4)
+        v4_host = _allocate_host(hostname=hostname+domain_name, network=network)
+
+    # IPv6
+    if not service_networks:
+        # ipv6 does not support capacity fetching (not even the GUI displays it).
+        # Maybe it's assumed that there is always available space?
+        ipv6_networks_info = _find_networks(network_container=str(ipv6_container), ip_version=6)
+        assert len(ipv6_networks_info) >= 1, "No IPv6 network exists in the container for this service type."
+        assert 'network' in ipv6_networks_info[0]
+        # TODO: if "no available IP" error, create a new network?
+        v6_host = _allocate_host(hostname=hostname+domain_name, network=ipv6_networks_info[0]['network'])
+    else:
+        network = str(service_networks.v6)
+        v6_host = _allocate_host(hostname=hostname+domain_name, network=network)
+
+    return HostAddresses(v4=v4_host.v4,v6=v6_host.v6)
+
+def _delete_host_by_ip(addr) -> Union[V4HostAddress, V6HostAddress]:
     """
     Delete IPv4 or IPv6 host by its address.
     """
@@ -455,17 +465,17 @@ if __name__ == '__main__':
 
         if choice == '1':
             ip_version = int(input("Enter IP version (4 or 6): "))
-            containers = find_containers(ip_version=ip_version)
+            containers = _find_containers(ip_version=ip_version)
             print(json.dumps(containers, indent=2))
 
         elif choice == '2':
             ip_version = int(input("Enter IP version (4 or 6): "))
-            networks = find_networks(ip_version=ip_version)
+            networks = _find_networks(ip_version=ip_version)
             print(json.dumps(networks, indent=2))
 
         elif choice == '3':
             network = input("Enter network (in CIDR notation): ")
-            network_capacity = get_network_capacity(network=network)
+            network_capacity = _get_network_capacity(network=network)
             print(json.dumps(network_capacity, indent=2))
 
         elif choice == '4':
@@ -482,19 +492,19 @@ if __name__ == '__main__':
 
         elif choice == '5':
             network = input("Enter network to delete (in CIDR notation): ")
-            deleted_network = delete_network(network=network)
+            deleted_network = _delete_network(network=network)
             print(json.dumps(str(deleted_network), indent=2))
 
         elif choice == '6':
             hostname = input("Enter host name (full name including domain name): ")
             addr = input("Enter IP address to allocate: ")
-            alloc_ip = allocate_host(hostname=hostname, addr=addr)
+            alloc_ip = _allocate_host(hostname=hostname, addr=addr)
             print(json.dumps(str(alloc_ip), indent=2))
 
         elif choice == '7':
             hostname = input("Enter host name (full name including domain name): ")
             network = input("Enter an existing network to allocate from (in CIDR notation): ")
-            alloc_ip = allocate_host(hostname=hostname, network=network)
+            alloc_ip = _allocate_host(hostname=hostname, network=network)
             print(json.dumps(str(alloc_ip), indent=2))
 
         elif choice == '8':
@@ -505,7 +515,7 @@ if __name__ == '__main__':
 
         elif choice == '9':
             addr = input("Enter IP address of host to delete: ")
-            deleted_host = delete_host_by_ip(addr=addr)
+            deleted_host = _delete_host_by_ip(addr=addr)
             print(json.dumps(str(deleted_host), indent=2))
 
         elif choice == '10':
diff --git a/gso/services/ipam.py b/gso/services/ipam.py
index fc646e433c0532050d3e82e2466c5cd74d7449a9..723e112ed77f4546bef1b52417cf2cb3b7ae640a 100644
--- a/gso/services/ipam.py
+++ b/gso/services/ipam.py
@@ -14,8 +14,8 @@ class V6ServiceNetwork(BaseSettings):
 
 
 class ServiceNetworks(BaseSettings):
-    v4: V4ServiceNetwork
-    v6: V6ServiceNetwork
+    v4: ipaddress.IPv4Network
+    v6: ipaddress.IPv6Network
 
 
 class V4HostAddress(BaseSettings):
@@ -23,26 +23,33 @@ class V4HostAddress(BaseSettings):
 
 
 class V6HostAddress(BaseSettings):
-     v6: ipaddress.IPv6Address
+    v6: ipaddress.IPv6Address
 
 
 class HostAddresses(BaseSettings):
-    v4: V4HostAddress
-    v6: V6HostAddress
+    v4: ipaddress.IPv4Address
+    v6: ipaddress.IPv6Address
 
 
 def new_service_networks(service_type) -> ServiceNetworks:
     v4_service_network = _ipam.allocate_service_ipv4_network(service_type=service_type)
     v6_service_network = _ipam.allocate_service_ipv6_network(service_type=service_type)
     return ServiceNetworks(
-        v4=v4_service_network,
-        v6=v6_service_network)
+        v4=v4_service_network.v4,
+        v6=v6_service_network.v6)
 
 
-def new_service_host(hostname, service_type) -> HostAddresses:
-    return _ipam.allocate_service_host(hostname=hostname, service_type=service_type)
+def new_service_host(hostname, service_type, service_networks: ServiceNetworks) -> HostAddresses:
+    return _ipam.allocate_service_host(hostname=hostname, service_type=service_type, service_networks=service_networks)
 
 
 if __name__ == '__main__':
-    new_service_networks('TRUNK')
-    #new_service_host('newhost12', 'TRUNK')
\ No newline at end of file
+    hostname_A = 'newhost1'
+    hostname_B = 'newhost2'
+    lo1_service_networks = new_service_networks('LO')
+    new_service_host(hostname_A, 'LO', lo1_service_networks)
+    lo2_service_networks = new_service_networks('LO')
+    new_service_host(hostname_B, 'LO', lo2_service_networks)
+    trunk12_service_networks = new_service_networks('TRUNK')
+    new_service_host(hostname_A, 'TRUNK', trunk12_service_networks)
+    new_service_host(hostname_B, 'TRUNK', trunk12_service_networks)
\ No newline at end of file