Skip to content

Commit

Permalink
[AGW] pipelineD: configure SGi management ip address.
Browse files Browse the repository at this point in the history
Signed-off-by: Pravin B Shelar <pbshelar@fb.com>
  • Loading branch information
pshelar committed Aug 27, 2020
1 parent e28d73b commit 796dc84
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 1 deletion.
26 changes: 25 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,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)
2 changes: 2 additions & 0 deletions lte/gateway/python/magma/pipelined/main.py
Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 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 @@ -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
@@ -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
94 changes: 94 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,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()

0 comments on commit 796dc84

Please sign in to comment.