diff --git a/ci/lib.py b/ci/lib.py
index 217cd05d72085a595714ee86a1b46d4a4008cfdb..e5551409eb23250cdd245f28c561f41e32936ef3 100644
--- a/ci/lib.py
+++ b/ci/lib.py
@@ -14,6 +14,7 @@ import openstack
 from keystoneauth1.identity import v3
 from keystoneauth1 import session
 
+#import IPython
 
 def wait_for_keypress(msg="Press Enter to continue..."):
     """ """
@@ -45,6 +46,12 @@ def executed_in_ci():
     return {i_envvar_name in os.environ for i_envvar_name in envvar_names} == {True}
 
 
+def get_ostack_project_names(project_name):
+    """ get source and destination ostack project names """
+    if '->' in project_name:
+        return project_name.split('->', 1)
+    return project_name, project_name
+
 def get_destination_network(source_network):
     """ LUT for networks """
     network_mapping = {
@@ -705,3 +712,75 @@ def migrate_rbd_image(args, server_block_device_mapping):
                   "G.17 Source OpenStack VM RBD image snapshot does not exist anymore " \
                   f"{server_block_device_mapping['source']['ceph_pool_name']}/{source_server_rbd_image}@{source_rbd_image_snapshot_name}",
                   ecode != 0, locals())
+
+
+
+def create_destination_networking(args, src_ostack_conn, dst_ostack_conn, src_project, dst_project, src_network_name):
+    """ Create matching OpenStack networking (network, subnet, router) """
+    # read source network details
+    src_network = src_ostack_conn.network.find_network(src_network_name, project_id=src_project.id)
+    # read matching subnets details
+    src_subnets = [ src_ostack_conn.network.find_subnet(i_src_subnet_id) for i_src_subnet_id in src_network.subnet_ids ]
+    # read linked routers
+    src_network_router_ports = [ i_src_router_port for i_src_router_port in src_ostack_conn.list_ports(filters={'network_id': src_network.id}) if i_src_router_port.device_owner == 'network:router_interface' ]
+    src_network_routers_subnets = [ (src_ostack_conn.network.find_router(router_port.device_id), [rp_fixed_ip['subnet_id'] for rp_fixed_ip in router_port.fixed_ips if 'subnet_id' in rp_fixed_ip])  for router_port in src_network_router_ports ]
+
+
+    # read external network
+    dst_ext_network = dst_ostack_conn.network.find_network(args.destination_ipv4_external_network)
+
+    # create network
+    dst_network_name = get_migrated_resource_name(args, src_network_name)
+    dst_network = dst_ostack_conn.network.find_network(dst_network_name,
+                                                       project_id=dst_project.id)
+    #IPython.embed()
+    if not dst_network:
+        dst_network = dst_ostack_conn.network.create_network(name=dst_network_name,
+                                                             project_id=dst_project.id,
+                                                             mtu=src_network.mtu,
+                                                             description=f"{src_network.description}, g1 migrated id:{src_network.id}",
+                                                             port_security_enabled=src_network.is_port_security_enabled)
+
+    # create subnets
+    dst_subnets = []
+    subnet_mapping = {}
+    for i_src_subnet in src_subnets:
+        i_dst_subnet_name = get_migrated_resource_name(args, i_src_subnet.name)
+        i_dst_subnet = dst_ostack_conn.network.find_subnet(get_migrated_resource_name(args, i_src_subnet.name),
+                                                           project_id=dst_project.id)
+        if not i_dst_subnet:
+            i_dst_subnet = dst_ostack_conn.network.create_subnet(network_id=dst_network.id,
+                                                                 name=i_dst_subnet_name,
+                                                                 cidr=i_src_subnet.cidr,
+                                                                 ip_version=i_src_subnet.ip_version,
+                                                                 enable_dhcp=i_src_subnet.is_dhcp_enabled,
+                                                                 project_id=dst_project.id,
+                                                                 allocation_pools=i_src_subnet.allocation_pools,
+                                                                 gateway_ip=i_src_subnet.gateway_ip,
+                                                                 host_routes=i_src_subnet.host_routes,
+                                                                 dns_nameservers=i_src_subnet.dns_nameservers,
+                                                                 description=f"{i_src_subnet.description}, g1 migrated id:{i_src_subnet.id}")
+        subnet_mapping[i_src_subnet.id] = i_dst_subnet.id
+        dst_subnets.append(i_dst_subnet)
+
+    # create router(s) and associate with subnet(s) (if needed)
+    dst_network_routers = []
+    for i_src_network_router, i_src_network_router_subnets in src_network_routers_subnets:
+
+        i_dst_network_router_name = get_migrated_resource_name(args, i_src_network_router.name)
+        i_dst_network_router = dst_ostack_conn.network.find_router(i_dst_network_router_name,
+                                                                   project_id=dst_project.id)
+        if not i_dst_network_router:
+            i_dst_network_router = dst_ostack_conn.network.create_router(name=i_dst_network_router_name,
+                                                                         description=f"{i_src_network_router.description}, g1 migrated id:{i_src_network_router.id}",
+                                                                         project_id=dst_project.id,
+                                                                         external_gateway_info={"network_id": dst_ext_network.id})
+            for i_src_network_router_subnet in i_src_network_router_subnets:
+                # TODO: Principally there may be also foreign subnets, find more general sulution
+                if i_src_network_router_subnet in subnet_mapping:
+                    dst_ostack_conn.add_router_interface(i_dst_network_router, subnet_id=subnet_mapping[i_src_network_router_subnet])
+
+        dst_network_routers.append(i_dst_network_router)
+
+    return dst_network, dst_subnets, dst_network_routers
+
diff --git a/ci/project-migrator.py b/ci/project-migrator.py
index 342e379fb1c3fbe47775565b8f363226a2ea3e35..c1cd69ad8465b3c0f98632703e45026c6ac69923 100755
--- a/ci/project-migrator.py
+++ b/ci/project-migrator.py
@@ -36,13 +36,14 @@ def main(args):
     args.logger.info("A.2 Destination OpenStack cloud connected as migrator user")
 
     # check project exists in source and destination
-    source_project = lib.get_ostack_project(source_migrator_conn, args.project_name)
+    source_project_name, destination_project_name = lib.get_ostack_project_names(args.project_name)
+    source_project = lib.get_ostack_project(source_migrator_conn, source_project_name)
     lib.log_or_assert(args, "B.1 Source OpenStack cloud project exists", source_project)
     source_project_type = lib.get_ostack_project_type(source_migrator_conn, source_project)
     lib.log_or_assert(args, f"B.2 Source OpenStack cloud project type is {source_project_type}",
                   source_project_type)
 
-    destination_project = lib.get_ostack_project(destination_migrator_conn, args.project_name)
+    destination_project = lib.get_ostack_project(destination_migrator_conn, destination_project_name)
     lib.log_or_assert(args, "B.10 Destination OpenStack cloud project exists", destination_project)
     destination_project_type = lib.get_ostack_project_type(destination_migrator_conn, destination_project)
     lib.log_or_assert(args, f"B.11 Destination OpenStack cloud project type is {destination_project_type}",
@@ -140,21 +141,22 @@ def main(args):
                          f"block_device_mapping: {i_source_server_detail.block_device_mapping}, " \
                          f"attached-volumes: {i_source_server_detail.attached_volumes}")
 
-        # network, subnet detection, TODO: better
+        # network/subnet/router detection & creation
         i_source_server_network_names = i_source_server_detail.addresses.keys()
         i_destination_server_networks = []
         for i_source_network_name in i_source_server_network_names:
             i_destination_network_name = lib.get_destination_network(i_source_network_name)
-            if not i_destination_network_name and args.destination_group_project_network_name != "":
-                # if network is not mapped use network provided from switch --destination-group-project-network-name
-                i_destination_network_name = args.destination_group_project_network_name
-            lib.log_or_assert(args,
-                              f"F.2 Source to Destination network mapping succeeeded ({i_source_network_name}->{i_destination_network_name}). " \
-                              f"Read --destination-group-project-network-name description for more details",
-                              i_destination_network_name)
 
-            i_destination_network = destination_project_conn.network.find_network(i_destination_network_name, project_id=destination_project.id)
+            if not i_destination_network_name:
+                # if network is not mapped we need to create matching one
+                i_dst_network, i_dst_subnets, i_dst_routers = lib.create_destination_networking(args,
+                                                                                                source_project_conn, destination_project_conn,
+                                                                                                source_project, destination_project,
+                                                                                                i_source_network_name)
+            i_destination_network = destination_project_conn.network.find_network(i_destination_network_name or i_dst_network.id,
+                                                                                  project_id=destination_project.id)
             lib.log_or_assert(args, f"F.3 Destination network exists ({i_destination_network})", i_destination_network)
+
             i_destination_server_networks.append(i_destination_network)
 
         # flavor detection
@@ -424,9 +426,6 @@ if __name__ == "__main__":
                     help='Destination cloud IPV4 external network.')
     AP.add_argument('--destination-entity-prefix', default='migrated-',
                     help='Destination cloud migrated cloud entity names prefix.')
-    AP.add_argument('--destination-group-project-network-name', default='group-project-network',
-                    help='Use pre-created network for group project entities (created by cloud-entities), this is preferred. ' \
-                         'Set to "" for creation new router/subnet/network this part is not yet implemented.')
 
     AP.add_argument('--project-name', default=None, required=True,
                     help='OpenStack project name (identical name in both clouds required)')