- # 3. Configure the chaining of the network functions (currently only E-Line links supported)
- vnf_id2vnf_name = defaultdict(lambda: "NotExistingNode",
- reduce(lambda x, y: dict(x, **y),
- map(lambda d: {d["vnf_id"]: d["vnf_name"]},
- self.nsd["network_functions"])))
-
- vlinks = self.nsd["virtual_links"]
- fwd_links = self.nsd["forwarding_graphs"][0]["constituent_virtual_links"]
- eline_fwd_links = [l for l in vlinks if (l["id"] in fwd_links) and (l["connectivity_type"] == "E-Line")]
-
- cookie = 1 # not clear why this is needed - to check with Steven
- for link in eline_fwd_links:
- src_id, src_if_name = link["connection_points_reference"][0].split(":")
- dst_id, dst_if_name = link["connection_points_reference"][1].split(":")
-
- src_name = vnf_id2vnf_name[src_id]
- dst_name = vnf_id2vnf_name[dst_id]
-
- LOG.debug(
- "Setting up E-Line link. %s(%s:%s) -> %s(%s:%s)" % (
- src_name, src_id, src_if_name, dst_name, dst_id, dst_if_name))
-
- if (src_name in self.vnfds) and (dst_name in self.vnfds):
- network = self.vnfds[src_name].get("dc").net # there should be a cleaner way to find the DCNetwork
- src_docker_name = self.vnf_name2docker_name[src_name]
- dst_docker_name = self.vnf_name2docker_name[dst_name]
- LOG.debug(src_docker_name)
- ret = network.setChain(
- src_docker_name, dst_docker_name,
- vnf_src_interface=src_if_name, vnf_dst_interface=dst_if_name,
- bidirectional=True, cmd="add-flow", cookie=cookie)
- cookie += 1
-
- # re-configure the VNFs IP assignment and ensure that a new subnet is used for each E-Link
- src_vnfi = self._get_vnf_instance(instance_uuid, src_name)
- if src_vnfi is not None:
- self._vnf_reconfigure_network(src_vnfi, src_if_name, self.eline_subnets_src.pop(0))
- dst_vnfi = self._get_vnf_instance(instance_uuid, dst_name)
- if dst_vnfi is not None:
- self._vnf_reconfigure_network(dst_vnfi, dst_if_name, self.eline_subnets_dst.pop(0))
-
- # 4. run the emulator specific entrypoint scripts in the VNFIs of this service instance
+ if "virtual_links" in self.nsd:
+ vlinks = self.nsd["virtual_links"]
+ fwd_links = self.nsd["forwarding_graphs"][0]["constituent_virtual_links"]
+ eline_fwd_links = [l for l in vlinks if (l["id"] in fwd_links) and (l["connectivity_type"] == "E-Line")]
+ elan_fwd_links = [l for l in vlinks if (l["id"] in fwd_links) and (l["connectivity_type"] == "E-LAN")]
+
+ GK.net.deployed_elines.extend(eline_fwd_links)
+ GK.net.deployed_elans.extend(elan_fwd_links)
+
+ # 4a. deploy E-Line links
+ # cookie is used as identifier for the flowrules installed by the dummygatekeeper
+ # eg. different services get a unique cookie for their flowrules
+ cookie = 1
+ for link in eline_fwd_links:
+ src_id, src_if_name = link["connection_points_reference"][0].split(":")
+ dst_id, dst_if_name = link["connection_points_reference"][1].split(":")
+
+ # check if there is a SAP in the link
+ if src_id in self.sap_identifiers:
+ src_docker_name = "{0}_{1}".format(src_id, src_if_name)
+ src_id = src_docker_name
+ else:
+ src_docker_name = src_id
+
+ if dst_id in self.sap_identifiers:
+ dst_docker_name = "{0}_{1}".format(dst_id, dst_if_name)
+ dst_id = dst_docker_name
+ else:
+ dst_docker_name = dst_id
+
+ src_name = vnf_id2vnf_name[src_id]
+ dst_name = vnf_id2vnf_name[dst_id]
+
+ LOG.debug(
+ "Setting up E-Line link. %s(%s:%s) -> %s(%s:%s)" % (
+ src_name, src_id, src_if_name, dst_name, dst_id, dst_if_name))
+
+ if (src_name in self.vnfds) and (dst_name in self.vnfds):
+ network = self.vnfds[src_name].get("dc").net # there should be a cleaner way to find the DCNetwork
+ LOG.debug(src_docker_name)
+ ret = network.setChain(
+ src_docker_name, dst_docker_name,
+ vnf_src_interface=src_if_name, vnf_dst_interface=dst_if_name,
+ bidirectional=BIDIRECTIONAL_CHAIN, cmd="add-flow", cookie=cookie, priority=10)
+
+ # re-configure the VNFs IP assignment and ensure that a new subnet is used for each E-Link
+ src_vnfi = self._get_vnf_instance(instance_uuid, src_name)
+ if src_vnfi is not None:
+ self._vnf_reconfigure_network(src_vnfi, src_if_name, self.eline_subnets_src.pop(0))
+ dst_vnfi = self._get_vnf_instance(instance_uuid, dst_name)
+ if dst_vnfi is not None:
+ self._vnf_reconfigure_network(dst_vnfi, dst_if_name, self.eline_subnets_dst.pop(0))
+
+ # 4b. deploy E-LAN links
+ base = 10
+ for link in elan_fwd_links:
+
+ elan_vnf_list=[]
+
+ # generate lan ip address
+ ip = 1
+ for intf in link["connection_points_reference"]:
+ ip_address = generate_lan_string("10.0", base, subnet_size=24, ip=ip)
+ vnf_id, intf_name = intf.split(":")
+ if vnf_id in self.sap_identifiers:
+ src_docker_name = "{0}_{1}".format(vnf_id, intf_name)
+ vnf_id = src_docker_name
+ else:
+ src_docker_name = vnf_id
+ vnf_name = vnf_id2vnf_name[vnf_id]
+ LOG.debug(
+ "Setting up E-LAN link. %s(%s:%s) -> %s" % (
+ vnf_name, vnf_id, intf_name, ip_address))
+
+ if vnf_name in self.vnfds:
+ # re-configure the VNFs IP assignment and ensure that a new subnet is used for each E-LAN
+ # E-LAN relies on the learning switch capability of Ryu which has to be turned on in the topology
+ # (DCNetwork(controller=RemoteController, enable_learning=True)), so no explicit chaining is necessary.
+ vnfi = self._get_vnf_instance(instance_uuid, vnf_name)
+ if vnfi is not None:
+ self._vnf_reconfigure_network(vnfi, intf_name, ip_address)
+ # increase for the next ip address on this E-LAN
+ ip += 1
+
+ # add this vnf and interface to the E-LAN for tagging
+ network = self.vnfds[vnf_name].get("dc").net # there should be a cleaner way to find the DCNetwork
+ elan_vnf_list.append({'name':src_docker_name,'interface':intf_name})
+
+
+ # install the VLAN tags for this E-LAN
+ network.setLAN(elan_vnf_list)
+ # increase the base ip address for the next E-LAN
+ base += 1
+
+ # 5. run the emulator specific entrypoint scripts in the VNFIs of this service instance