From 37911563c8039bf129063a2674e88c830576bca5 Mon Sep 17 00:00:00 2001 From: peusterm Date: Thu, 18 Oct 2018 15:03:55 +0200 Subject: [PATCH] Improved IP/E-Line management of 5GTANGO LLCM. Change-Id: I8e0c9d00e7470ef73b83d7e7d5bfde898116f632 Signed-off-by: peusterm --- pipeline_local.sh | 11 ++++++++++ src/emuvim/api/tango/llcm.py | 41 ++++++++++++++++++++++++++++-------- src/emuvim/dcemulator/net.py | 10 +++++---- 3 files changed, 49 insertions(+), 13 deletions(-) create mode 100755 pipeline_local.sh diff --git a/pipeline_local.sh b/pipeline_local.sh new file mode 100755 index 0000000..e6e4018 --- /dev/null +++ b/pipeline_local.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# helper script to be executed before committing +set -e +# trigger pep8 style check +echo "Doing flake8 style check ..." +flake8 --exclude=.eggs,devops --ignore=E501 . +echo "done." +# trigger the tests +echo "Running unit tests ..." +sudo pytest -v +echo "done." diff --git a/src/emuvim/api/tango/llcm.py b/src/emuvim/api/tango/llcm.py index 3beacce..31abe74 100755 --- a/src/emuvim/api/tango/llcm.py +++ b/src/emuvim/api/tango/llcm.py @@ -74,7 +74,7 @@ DEPLOY_SAP = False # flag to indicate if we use bidirectional forwarding rules in the # automatic chaining process -BIDIRECTIONAL_CHAIN = False +BIDIRECTIONAL_CHAIN = True # override the management interfaces in the descriptors with default # docker0 interfaces in the containers @@ -403,6 +403,9 @@ class Service(object): volumes=volumes, type=kwargs.get('type', 'docker')) + # add vnfd reference to vnfi + vnfi.vnfd = vnfd + # rename the docker0 interfaces (eth0) to the management port name # defined in the VNFD if USE_DOCKER_MGMT: @@ -655,6 +658,7 @@ class Service(object): # eg. different services get a unique cookie for their flowrules cookie = 1 for link in eline_fwd_links: + LOG.info("Found E-Line: {}".format(link)) # check if we need to deploy this link when its a management link: if USE_DOCKER_MGMT: if self.check_mgmt_interface( @@ -704,24 +708,34 @@ class Service(object): # Link between 2 VNFs else: + LOG.info("Creating E-Line: src={}, dst={}" + .format(src_id, dst_id)) # make sure we use the correct sap vnf name if src_sap_id in self.saps_int: src_id = src_sap_id if dst_sap_id in self.saps_int: dst_id = dst_sap_id - # re-configure the VNFs IP assignment and ensure that a new - # subnet is used for each E-Link + # get involved vnfis src_vnfi = self._get_vnf_instance(instance_uuid, src_id) dst_vnfi = self._get_vnf_instance(instance_uuid, dst_id) + if src_vnfi is not None and dst_vnfi is not None: + setChaining = True + # re-configure the VNFs IP assignment and ensure that a new + # subnet is used for each E-Link eline_net = ELINE_SUBNETS.pop(0) ip1 = "{0}/{1}".format(str(eline_net[1]), eline_net.prefixlen) ip2 = "{0}/{1}".format(str(eline_net[2]), eline_net.prefixlen) - self._vnf_reconfigure_network(src_vnfi, src_if_name, ip1) - self._vnf_reconfigure_network(dst_vnfi, dst_if_name, ip2) - setChaining = True + # check if VNFs have fixed IPs (address field in VNFDs) + if (self._get_vnfd_cp_from_vnfi(src_vnfi, src_if_name) + .get("address") is None): + self._vnf_reconfigure_network(src_vnfi, src_if_name, ip1) + # check if VNFs have fixed IPs (address field in VNFDs) + if (self._get_vnfd_cp_from_vnfi(dst_vnfi, dst_if_name) + .get("address") is None): + self._vnf_reconfigure_network(dst_vnfi, dst_if_name, ip2) # Set the chaining if setChaining: @@ -729,9 +743,18 @@ class Service(object): src_id, dst_id, vnf_src_interface=src_if_name, vnf_dst_interface=dst_if_name, bidirectional=BIDIRECTIONAL_CHAIN, cmd="add-flow", cookie=cookie, priority=10) - LOG.debug( - "Setting up E-Line link. (%s:%s) -> (%s:%s)" % ( - src_id, src_if_name, dst_id, dst_if_name)) + + def _get_vnfd_cp_from_vnfi(self, vnfi, ifname): + """ + Gets the connection point data structure from the VNFD + of the given VNFI using ifname. + """ + if vnfi.vnfd is None: + return {} + cps = vnfi.vnfd.get("connection_points") + for cp in cps: + if cp.get("id") == ifname: + return cp def _connect_elans(self, elan_fwd_links, instance_uuid): """ diff --git a/src/emuvim/dcemulator/net.py b/src/emuvim/dcemulator/net.py index 005e272..1f30ba7 100755 --- a/src/emuvim/dcemulator/net.py +++ b/src/emuvim/dcemulator/net.py @@ -462,7 +462,7 @@ class DCNetwork(Containernet): return "No path could be found between {0} and {1}".format( vnf_src_name, vnf_dst_name) - LOG.info("Path between {0} and {1}: {2}".format( + LOG.debug("Creating path between {0} and {1}: {2}".format( vnf_src_name, vnf_dst_name, path)) current_hop = src_sw @@ -484,7 +484,7 @@ class DCNetwork(Containernet): if next_hop == vnf_dst_name: switch_outport_nr = dst_sw_outport_nr - LOG.info("end node reached: {0}".format(vnf_dst_name)) + LOG.debug("end node reached: {0}".format(vnf_dst_name)) elif not isinstance(next_node, OVSSwitch): LOG.info("Next node: {0} is not a switch".format(next_hop)) return "Next node: {0} is not a switch".format(next_hop) @@ -666,7 +666,7 @@ class DCNetwork(Containernet): return "No path could be found between {0} and {1}".format( vnf_src_name, vnf_dst_name) - LOG.info("Path between {0} and {1}: {2}".format( + LOG.debug("Creating path between {0} and {1}: {2}".format( vnf_src_name, vnf_dst_name, path)) current_hop = src_sw @@ -706,7 +706,7 @@ class DCNetwork(Containernet): if next_hop == vnf_dst_name: switch_outport_nr = dst_sw_outport_nr - LOG.info("end node reached: {0}".format(vnf_dst_name)) + LOG.debug("end node reached: {0}".format(vnf_dst_name)) elif not isinstance(next_node, OVSSwitch): LOG.info("Next node: {0} is not a switch".format(next_hop)) return "Next node: {0} is not a switch".format(next_hop) @@ -746,6 +746,8 @@ class DCNetwork(Containernet): 'match_input': kwargs.get('match') } flow_options_str = json.dumps(flow_options, indent=1) + LOG.info("Installed flow rule: ({}:{}) -> ({}:{}) with options: {}" + .format(vnf_src_name, vnf_src_interface, vnf_dst_name, vnf_dst_interface, flow_options)) return "success: {2} between {0} and {1} with options: {3}".format( vnf_src_name, vnf_dst_name, cmd, flow_options_str) -- 2.25.1