From 796dc84175e53a6774e4438b145d05399c35d83b Mon Sep 17 00:00:00 2001 From: Pravin B Shelar Date: Thu, 27 Aug 2020 15:56:29 -0700 Subject: [PATCH] [AGW] pipelineD: configure SGi management ip address. Signed-off-by: Pravin B Shelar --- .../magma/pipelined/app/uplink_bridge.py | 26 ++++- lte/gateway/python/magma/pipelined/main.py | 2 + .../pipelined/tests/pipelined_test_util.py | 24 +++++ ...est_IP_VLAN.testFlowSnapshotMatch.snapshot | 4 + .../pipelined/tests/test_uplink_bridge.py | 94 +++++++++++++++++++ 5 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 lte/gateway/python/magma/pipelined/tests/snapshots/test_uplink_bridge.UplinkBridgeWithNonNATTest_IP_VLAN.testFlowSnapshotMatch.snapshot diff --git a/lte/gateway/python/magma/pipelined/app/uplink_bridge.py b/lte/gateway/python/magma/pipelined/app/uplink_bridge.py index c0159fe71b42..cbba73aa400e 100644 --- a/lte/gateway/python/magma/pipelined/app/uplink_bridge.py +++ b/lte/gateway/python/magma/pipelined/app/uplink_bridge.py @@ -34,7 +34,7 @@ class UplinkBridgeController(MagmaController): 'UplinkBridgeConfig', ['uplink_bridge', 'uplink_eth_port_name', 'uplink_patch', 'enable_nat', 'virtual_mac', 'dhcp_port', - 'sgi_management_iface_vlan'], + 'sgi_management_iface_vlan', 'sgi_management_iface_ip_addr'], ) def __init__(self, *args, **kwargs): @@ -58,6 +58,7 @@ def _get_config(self, config_dict) -> namedtuple: virtual_mac = config_dict.get('virtual_mac', self.DEFAULT_UPLINK_MAC) sgi_management_iface_vlan = config_dict.get('sgi_management_iface_vlan', "") + sgi_management_iface_ip_addr = config_dict.get('sgi_management_iface_ip_addr', "") return self.UplinkConfig( enable_nat=enable_nat, uplink_bridge=bridge_name, @@ -66,6 +67,7 @@ def _get_config(self, config_dict) -> namedtuple: uplink_patch=uplink_patch, dhcp_port=dhcp_port, sgi_management_iface_vlan=sgi_management_iface_vlan, + sgi_management_iface_ip_addr=sgi_management_iface_ip_addr, ) def initialize_on_connect(self, datapath): @@ -77,6 +79,7 @@ def initialize_on_connect(self, datapath): self._delete_all_flows() self._add_eth_port() self._set_vlan_eth_port() + self._set_sgi_static_ip() # flows to forward traffic between patch port to eth port # 1. DHCP traffic @@ -170,3 +173,24 @@ def _del_eth_port(self): subprocess.Popen(ovs_rem_port, shell=True).wait() except subprocess.CalledProcessError as ex: self.logger.debug("ignore port del error: %s ", ex) + + def _set_sgi_static_ip(self): + if self.config.sgi_management_iface_ip_addr is None or \ + self.config.sgi_management_iface_ip_addr == "": + return + + try: + # Kill dhclient if running. + dump1 = subprocess.Popen(["pgrep", "-f", "dhclient.*" + self.config.uplink_bridge], + stdout=subprocess.PIPE) + for pid in dump1.stdout.readlines(): + subprocess.check_call(["kill", pid]) + set_ip = ["ip", + "addr", "replace", + self.config.sgi_management_iface_ip_addr, + "dev", + self.config.uplink_bridge] + subprocess.check_call(set_ip) + self.logger.debug("SGi ip address config: [%s]" % set_ip) + except subprocess.SubprocessError as e: + self.logger.warning("Error while setting SGi IP: %s", e) \ No newline at end of file diff --git a/lte/gateway/python/magma/pipelined/main.py b/lte/gateway/python/magma/pipelined/main.py index b9c06536fabe..781eb521de8f 100644 --- a/lte/gateway/python/magma/pipelined/main.py +++ b/lte/gateway/python/magma/pipelined/main.py @@ -60,6 +60,8 @@ def main(): logging.info("Nat: %s", enable_nat) vlan_tag = service.config.get('sgi_management_iface_vlan', service.mconfig.sgi_management_iface_vlan) + vlan_tag = service.config.get('sgi_management_iface_ip_addr', + service.mconfig.sgi_management_iface_ip_addr) service.config['sgi_management_iface_vlan'] = vlan_tag # Load the ryu apps diff --git a/lte/gateway/python/magma/pipelined/tests/pipelined_test_util.py b/lte/gateway/python/magma/pipelined/tests/pipelined_test_util.py index 9d635a99a3bd..1c3d2495baf1 100644 --- a/lte/gateway/python/magma/pipelined/tests/pipelined_test_util.py +++ b/lte/gateway/python/magma/pipelined/tests/pipelined_test_util.py @@ -15,6 +15,7 @@ import os import re import subprocess +import netifaces from collections import namedtuple from concurrent.futures import Future @@ -552,3 +553,26 @@ def get_ovsdb_port_tag(port_name: str) -> str: pass +def get_ovsdb_port_tag(port_name: str) -> str: + dump1 = subprocess.Popen(["ovsdb-client", "dump", "Port", "name", "tag"], + stdout=subprocess.PIPE) + for port in dump1.stdout.readlines(): + if port_name not in str(port): + continue + try: + tokens = str(port).strip().split() + port_name = tokens[0] + tag = tokens[1] + if port_name == port_name: + return str(tag).split('\\')[0] + except ValueError: + pass + + +def get_iface_ipv4(iface: str): + virt_ifaddresses = netifaces.ifaddresses(iface) + ip_addr_list = [] + for ip_rec in virt_ifaddresses[netifaces.AF_INET]: + ip_addr_list.append(ip_rec['addr']) + + return ip_addr_list \ No newline at end of file diff --git a/lte/gateway/python/magma/pipelined/tests/snapshots/test_uplink_bridge.UplinkBridgeWithNonNATTest_IP_VLAN.testFlowSnapshotMatch.snapshot b/lte/gateway/python/magma/pipelined/tests/snapshots/test_uplink_bridge.UplinkBridgeWithNonNATTest_IP_VLAN.testFlowSnapshotMatch.snapshot new file mode 100644 index 000000000000..f88f08e59680 --- /dev/null +++ b/lte/gateway/python/magma/pipelined/tests/snapshots/test_uplink_bridge.UplinkBridgeWithNonNATTest_IP_VLAN.testFlowSnapshotMatch.snapshot @@ -0,0 +1,4 @@ + priority=2000,udp,in_port=3,tp_dst=68 actions=output:1,output:2,LOCAL + priority=1000,ip,in_port=2 actions=mod_dl_src:02:bb:5e:36:06:4b,output:3 + priority=1000,ip,in_port=3,dl_dst=02:bb:5e:36:06:4b actions=output:2 + priority=100 actions=NORMAL diff --git a/lte/gateway/python/magma/pipelined/tests/test_uplink_bridge.py b/lte/gateway/python/magma/pipelined/tests/test_uplink_bridge.py index 057bd944badc..4c51e9e74dee 100644 --- a/lte/gateway/python/magma/pipelined/tests/test_uplink_bridge.py +++ b/lte/gateway/python/magma/pipelined/tests/test_uplink_bridge.py @@ -26,6 +26,7 @@ create_service_manager, assert_bridge_snapshot_match, get_ovsdb_port_tag, + get_iface_ipv4, ) @@ -274,6 +275,99 @@ def testFlowSnapshotMatch(self): self.assertEqual(get_ovsdb_port_tag(cls.UPLINK_BRIDGE), cls.VLAN_TAG) +class UplinkBridgeWithNonNATTest_IP_VLAN(unittest.TestCase): + BRIDGE = 'testing_br' + MAC_DEST = "5e:cc:cc:b1:49:4b" + BRIDGE_IP = '192.168.128.1' + + UPLINK_BRIDGE = 'ut_up_br0' + UPLINK_DHCP = 'test_dhcp0' + UPLINK_PATCH = 'test_patch_p2' + UPLINK_ETH_PORT = 'test_eth3' + VLAN_TAG='100' + SGi_IP="1.6.5.7" + + @classmethod + def setUpClass(cls): + """ + Starts the thread which launches ryu apps + + Create a testing bridge, add a port, setup the port interfaces. Then + launch the ryu apps for testing pipelined. Gets the references + to apps launched by using futures. + """ + super(UplinkBridgeWithNonNATTest_IP_VLAN, cls).setUpClass() + warnings.simplefilter('ignore') + cls.service_manager = create_service_manager([]) + + uplink_bridge_controller_reference = Future() + testing_controller_reference = Future() + test_setup = TestSetup( + apps=[PipelinedController.UplinkBridge, + PipelinedController.Testing, + PipelinedController.StartupFlows], + references={ + PipelinedController.UplinkBridge: + uplink_bridge_controller_reference, + PipelinedController.Testing: + testing_controller_reference, + PipelinedController.StartupFlows: + Future(), + }, + config={ + 'bridge_name': cls.BRIDGE, + 'bridge_ip_address': cls.BRIDGE_IP, + 'ovs_gtp_port_number': 32768, + 'clean_restart': True, + 'enable_nat': False, + 'uplink_bridge': cls.UPLINK_BRIDGE, + 'uplink_eth_port_name': cls.UPLINK_ETH_PORT, + 'virtual_mac': '02:bb:5e:36:06:4b', + 'uplink_patch': cls.UPLINK_PATCH, + 'uplink_dhcp_port': cls.UPLINK_DHCP, + 'sgi_management_iface_vlan': cls.VLAN_TAG, + 'sgi_management_iface_ip_addr': cls.SGi_IP + }, + mconfig=None, + loop=None, + service_manager=cls.service_manager, + integ_test=False, + ) + + BridgeTools.create_bridge(cls.BRIDGE, cls.BRIDGE) + # validate vlan id set + vlan = "10" + BridgeTools.create_bridge(cls.UPLINK_BRIDGE, cls.UPLINK_BRIDGE) + subprocess.Popen(["ovs-vsctl", "set", "port", cls.UPLINK_BRIDGE, + "tag=" + vlan]).wait() + assert get_ovsdb_port_tag(cls.UPLINK_BRIDGE) == vlan + + BridgeTools.create_internal_iface(cls.UPLINK_BRIDGE, + cls.UPLINK_DHCP, None) + BridgeTools.create_internal_iface(cls.UPLINK_BRIDGE, + cls.UPLINK_PATCH, None) + BridgeTools.create_internal_iface(cls.UPLINK_BRIDGE, + cls.UPLINK_ETH_PORT, None) + + cls.thread = start_ryu_app_thread(test_setup) + cls.uplink_br_controller = uplink_bridge_controller_reference.result() + + cls.testing_controller = testing_controller_reference.result() + + @classmethod + def tearDownClass(cls): + stop_ryu_app_thread(cls.thread) + BridgeTools.destroy_bridge(cls.BRIDGE) + BridgeTools.destroy_bridge(cls.UPLINK_BRIDGE) + + def testFlowSnapshotMatch(self): + cls = self.__class__ + assert_bridge_snapshot_match(self, self.UPLINK_BRIDGE, self.service_manager, + include_stats=False) + self.assertEqual(get_ovsdb_port_tag(cls.UPLINK_BRIDGE), cls.VLAN_TAG) + + self.assertIn(cls.SGi_IP, get_iface_ipv4(cls.UPLINK_BRIDGE), "ip not found") + if __name__ == "__main__": unittest.main()