Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AGW] pipelineD: configure SGi management ip address. #2510

Merged
merged 1 commit into from Aug 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 33 additions & 1 deletion lte/gateway/python/magma/pipelined/app/uplink_bridge.py
Expand Up @@ -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):
Expand All @@ -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,
Expand All @@ -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):
Expand All @@ -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
Expand Down Expand Up @@ -170,3 +173,32 @@ 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):
self.logger.debug("self.config.sgi_management_iface_ip_addr %s",
self.config.sgi_management_iface_ip_addr)
if self.config.sgi_management_iface_ip_addr is None or \
self.config.sgi_management_iface_ip_addr == "":
return

try:
# Kill dhclient if running.
pgrep_out = subprocess.Popen(["pgrep", "-f",
"dhclient.*" + self.config.uplink_bridge],
stdout=subprocess.PIPE)
for pid in pgrep_out.stdout.readlines():
subprocess.check_call(["kill", pid.strip()])

flush_ip = ["ip", "addr", "flush",
"dev" , self.config.uplink_bridge]
subprocess.check_call(flush_ip)

set_ip_cmd = ["ip",
"addr", "add",
self.config.sgi_management_iface_ip_addr,
"dev",
self.config.uplink_bridge]
subprocess.check_call(set_ip_cmd)
self.logger.debug("SGi ip address config: [%s]", set_ip_cmd)
except subprocess.SubprocessError as e:
self.logger.warning("Error while setting SGi IP: %s", e)
4 changes: 4 additions & 0 deletions lte/gateway/python/magma/pipelined/main.py
Expand Up @@ -62,6 +62,10 @@ def main():
service.mconfig.sgi_management_iface_vlan)
service.config['sgi_management_iface_vlan'] = vlan_tag

sgi_ip = service.config.get('sgi_management_iface_ip_addr',
service.mconfig.sgi_management_iface_ip_addr)
service.config['sgi_management_iface_ip_addr'] = sgi_ip

# Load the ryu apps
service_manager = ServiceManager(service)
service_manager.load()
Expand Down
15 changes: 10 additions & 5 deletions lte/gateway/python/magma/pipelined/tests/pipelined_test_util.py
Expand Up @@ -15,6 +15,7 @@
import os
import re
import subprocess
import netifaces

from collections import namedtuple
from concurrent.futures import Future
Expand Down Expand Up @@ -543,12 +544,16 @@ def get_ovsdb_port_tag(port_name: str) -> str:
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]
tokens = str(port.decode("utf-8")).strip('\"').split()
return tokens[1]
except ValueError:
pass


def get_iface_ipv4(iface: str) -> List[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
@@ -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
101 changes: 101 additions & 0 deletions lte/gateway/python/magma/pipelined/tests/test_uplink_bridge.py
Expand Up @@ -26,6 +26,7 @@
create_service_manager,
assert_bridge_snapshot_match,
get_ovsdb_port_tag,
get_iface_ipv4,
)


Expand Down Expand Up @@ -274,6 +275,106 @@ 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

set_ip_cmd = ["ip",
"addr", "replace",
"2.33.44.6",
"dev",
cls.UPLINK_BRIDGE]
subprocess.check_call(set_ip_cmd)

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()