EDGEPOD-399 Remove bess config files from the chart
Change-Id: Idd14d9165a6265d6e3aa24af707820fae1d0c7f6
diff --git a/omec/omec-user-plane/Chart.yaml b/omec/omec-user-plane/Chart.yaml
index 04b0b65..e54b051 100644
--- a/omec/omec-user-plane/Chart.yaml
+++ b/omec/omec-user-plane/Chart.yaml
@@ -17,4 +17,4 @@
name: omec-user-plane
icon: https://guide.opencord.org/logos/cord.svg
-version: 0.1.2
+version: 0.1.3
diff --git a/omec/omec-user-plane/files/__init__.py b/omec/omec-user-plane/files/__init__.py
deleted file mode 100644
index b3c75bf..0000000
--- a/omec/omec-user-plane/files/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env python
-# SPDX-License-Identifier: Apache-2.0
-# Copyright(c) 2019 Intel Corporation
diff --git a/omec/omec-user-plane/files/route_control.py b/omec/omec-user-plane/files/route_control.py
deleted file mode 100755
index 1d9a169..0000000
--- a/omec/omec-user-plane/files/route_control.py
+++ /dev/null
@@ -1,520 +0,0 @@
-#!/usr/bin/env python
-# SPDX-License-Identifier: Apache-2.0
-# Copyright(c) 2019 Intel Corporation
-
-import argparse
-import signal
-import sys
-import time
-
-# for retrieving neighbor info
-from pyroute2 import IPDB, IPRoute
-
-from scapy.all import *
-
-try:
- from pybess.bess import *
-except ImportError:
- print('Cannot import the API module (pybess)')
- raise
-
-MAX_RETRIES = 5
-SLEEP_S = 2
-
-
-class NeighborEntry:
- def __init__(self):
- self.neighbor_ip = None
- self.iface = None
- self.iprange = None
- self.prefix_len = None
- self.route_count = 0
- self.gate_idx = 0
- self.macstr = None
-
- def __str__(self):
- return ('{neigh: %s, iface: %s, ip-range: %s/%s}' %
- (self.neighbor_ip, self.iface, self.iprange, self.prefix_len))
-
-
-def mac2hex(mac):
- return int(mac.replace(':', ''), 16)
-
-
-def send_ping(neighbor_ip):
- send(IP(dst=neighbor_ip) / ICMP())
-
-
-def send_arp(neighbor_ip, src_mac, iface):
- pkt = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=neighbor_ip, hwsrc=src_mac)
- pkt.show()
- hexdump(pkt)
- sendp(pkt, iface=iface)
-
-
-def fetch_mac(dip):
- ip = ''
- _mac = ''
- neighbors = ipr.get_neighbours(dst=dip)
- for i in range(len(neighbors)):
- for att in neighbors[i]['attrs']:
- if 'NDA_DST' in att and dip == att[1]:
- # ('NDA_DST', dip)
- ip = att[1]
- if 'NDA_LLADDR' in att:
- # ('NDA_LLADDR', _mac)
- _mac = att[1]
- return _mac
-
-
-def link_modules(server, module, next_module, ogate=0, igate=0):
- print('Linking {} module'.format(next_module))
-
- # Pause bess first
- bess.pause_all()
- # Connect module to next_module
- for _ in range(MAX_RETRIES):
- try:
- server.connect_modules(module, next_module, ogate, igate)
- except BESS.Error as e:
- bess.resume_all()
- if e.code == errno.EBUSY:
- break
- else:
- return #raise
- except Exception as e:
- print(
- 'Error connecting module {}:{}->{}:{}: {}. Retrying in {} secs...'
- .format(module, ogate, igate, next_module, e, SLEEP_S))
- time.sleep(SLEEP_S)
- else:
- bess.resume_all()
- break
- else:
- bess.resume_all()
- print('BESS module connection ({}:{}->{}:{}) failure.'.format(
- module, ogate, igate, next_module))
- return
- #raise Exception('BESS module connection ({}:{}->{}:{}) failure.'.
- # format(module, ogate, igate, next_module))
-
-
-def link_route_module(server, gateway_mac, item):
- iprange = item.iprange
- prefix_len = item.prefix_len
- route_module = item.iface + 'Routes'
- last_module = item.iface + 'Merge'
- gateway_mac_str = '{:X}'.format(gateway_mac)
- print('Adding route entry {}/{} for {}'.format(iprange, prefix_len,
- route_module))
-
- print('Trying to retrieve neighbor entry {} from neighbor cache'.format(
- item.neighbor_ip))
- neighbor_exists = neighborcache.get(item.neighbor_ip)
-
- # How many gates does this module have?
- # If entry does not exist, then initialize it
- if not modgatecnt.get(route_module):
- modgatecnt[route_module] = 0
-
- # Compute likely index
- if neighbor_exists:
- # No need to create a new Update module
- gate_idx = neighbor_exists.gate_idx
- else:
- # Need to create a new Update module,
- # so get gate_idx from gate count
- gate_idx = modgatecnt[route_module]
-
- # Pause bess first
- bess.pause_all()
- # Pass routing entry to bessd's route module
- for _ in range(MAX_RETRIES):
- try:
- server.run_module_command(route_module, 'add',
- 'IPLookupCommandAddArg', {
- 'prefix': iprange,
- 'prefix_len': int(prefix_len),
- 'gate': gate_idx
- })
- except:
- print('Error adding route entry {}/{} in {}. Retrying in {}sec...'.
- format(iprange, prefix_len, route_module, SLEEP_S))
- time.sleep(SLEEP_S)
- else:
- bess.resume_all()
- break
- else:
- bess.resume_all()
- print('BESS route entry ({}/{}) insertion failure in module {}'.format(
- iprange, prefix_len, route_module))
- return
- #raise Exception('BESS route entry ({}/{}) insertion failure in module {}'.
- # format(iprange, prefix_len, route_module))
-
- if not neighbor_exists:
- print('Neighbor does not exist')
- # Create Update module
- update_module = route_module + 'DstMAC' + gateway_mac_str
-
- # Pause bess first
- bess.pause_all()
- for _ in range(MAX_RETRIES):
- try:
- server.create_module('Update', update_module, {
- 'fields': [{
- 'offset': 0,
- 'size': 6,
- 'value': gateway_mac
- }]
- })
- except BESS.Error as e:
- bess.resume_all()
- if e.code == errno.EEXIST:
- break
- else:
- return #raise
- except Exception as e:
- print(
- 'Error creating update module {}: {}. Retrying in {} secs...'
- .format(update_module, e, SLEEP_S))
- time.sleep(SLEEP_S)
- else:
- bess.resume_all()
- break
- else:
- bess.resume_all()
- print('BESS module {} creation failure.'.format(update_module))
- return #raise Exception('BESS module {} creation failure.'.
- # format(update_module))
-
- print('Update module created')
-
- # Connect Update module to route module
- link_modules(server, route_module, update_module, gate_idx, 0)
-
- # Connect Update module to dpdk_out module
- link_modules(server, update_module, last_module, 0, 0)
-
- # Add a new neighbor in neighbor cache
- neighborcache[item.neighbor_ip] = item
-
- # Add a record of the affliated gate id
- item.gate_idx = gate_idx
-
- # Set the mac str
- item.macstr = gateway_mac_str
-
- # Increment global gate count number
- modgatecnt[route_module] += 1
-
- neighbor_exists = item
-
- else:
- print('Neighbor already exists')
-
- # Finally increment route count
- neighborcache[item.neighbor_ip].route_count += 1
-
-
-def del_route_entry(server, item):
- iprange = item.iprange
- prefix_len = item.prefix_len
- route_module = item.iface + 'Routes'
- last_module = item.iface + 'Merge'
-
- neighbor_exists = neighborcache.get(item.neighbor_ip)
- if neighbor_exists:
- # Pause bess first
- bess.pause_all()
- # Delete routing entry from bessd's route module
- for i in range(MAX_RETRIES):
- try:
- server.run_module_command(route_module, 'delete',
- 'IPLookupCommandDeleteArg', {
- 'prefix': iprange,
- 'prefix_len': int(prefix_len)
- })
- except:
- print(
- 'Error while deleting route entry for {}. Retrying in {} sec...'
- .format(route_module, SLEEP_S))
- time.sleep(SLEEP_S)
- else:
- bess.resume_all()
- break
- else:
- bess.resume_all()
- print('Route entry deletion failure.')
- return
- #raise Exception('Route entry deletion failure.')
-
- print('Route entry {}/{} deleted from {}'.format(
- iprange, prefix_len, route_module))
-
- # Decrementing route count for the registered neighbor
- neighbor_exists.route_count -= 1
-
- # If route count is 0, then delete the whole module
- if neighbor_exists.route_count == 0:
- update_module = route_module + 'DstMAC' + neighbor_exists.macstr
- # Pause bess first
- bess.pause_all()
- for i in range(MAX_RETRIES):
- try:
- server.destroy_module(update_module)
- except:
- print('Error destroying module {}. Retrying in {}sec...'.
- format(update_module, SLEEP_S))
- time.sleep(SLEEP_S)
- else:
- bess.resume_all()
- break
- else:
- bess.resume_all()
- print('Module {} deletion failure.'.format(update_module))
- return
- #raise Exception('Module {} deletion failure.'.
- # format(update_module))
-
- print('Module {} destroyed'.format(update_module))
-
- # Delete entry from the neighbor cache
- del neighborcache[item.neighbor_ip]
- print('Deleting item from neighborcache')
- del neighbor_exists
- else:
- print('Route count for {} decremented to {}'.format(
- item.neighbor_ip, neighbor_exists.route_count))
- neighborcache[item.neighbor_ip] = neighbor_exists
- else:
- print('Neighbor {} does not exist'.format(item.neighbor_ip))
-
-
-def probe_addr(item, src_mac):
- # Store entry if entry does not exist in ARP cache
- arpcache[item.neighbor_ip] = item
- print('Adding entry {} in arp probe table'.format(item))
-
- # Probe ARP request by sending ping
- send_ping(item.neighbor_ip)
-
- # Probe ARP request
- ##send_arp(neighbor_ip, src_mac, item.iface)
-
-
-def parse_new_route(msg):
- item = NeighborEntry()
- # Fetch prefix_len
- item.prefix_len = msg['dst_len']
- # Default route
- if item.prefix_len is 0:
- item.iprange = '0.0.0.0'
-
- for att in msg['attrs']:
- if 'RTA_DST' in att:
- # Fetch IP range
- # ('RTA_DST', iprange)
- item.iprange = att[1]
- if 'RTA_GATEWAY' in att:
- # Fetch gateway MAC address
- # ('RTA_GATEWAY', neighbor_ip)
- item.neighbor_ip = att[1]
- _mac = fetch_mac(att[1])
- if not _mac:
- gateway_mac = 0
- else:
- gateway_mac = mac2hex(_mac)
- if 'RTA_OIF' in att:
- # Fetch interface name
- # ('RTA_OIF', iface)
- item.iface = ipdb.interfaces[int(att[1])].ifname
-
- if not item.iface in args.i or not item.iprange or not item.neighbor_ip:
- # Neighbor info is invalid
- del item
- return
-
- # if mac is 0, send ARP request
- if gateway_mac == 0:
- print('Adding entry {} in arp probe table'.format(item.iface))
- probe_addr(item, ipdb.interfaces[item.iface].address)
-
- else: # if gateway_mac is set
- print('Linking module {}Routes with {}Merge (Dest MAC: {})'.format(
- item.iface, item.iface, _mac))
-
- link_route_module(bess, gateway_mac, item)
-
-
-def parse_new_neighbor(msg):
- for att in msg['attrs']:
- if 'NDA_DST' in att:
- # ('NDA_DST', neighbor_ip)
- neighbor_ip = att[1]
- if 'NDA_LLADDR' in att:
- # ('NDA_LLADDR', neighbor_mac)
- gateway_mac = att[1]
-
- item = arpcache.get(neighbor_ip)
- if item:
- print('Linking module {}Routes with {}Merge (Dest MAC: {})'.format(
- item.iface, item.iface, gateway_mac))
-
- # Add route entry, and add item in the registered neighbor cache
- link_route_module(bess, mac2hex(gateway_mac), item)
-
- # Remove entry from unresolved arp cache
- del arpcache[neighbor_ip]
-
-
-def parse_del_route(msg):
- item = NeighborEntry()
- for att in msg['attrs']:
- if 'RTA_DST' in att:
- # Fetch IP range
- # ('RTA_DST', iprange)
- item.iprange = att[1]
- if 'RTA_GATEWAY' in att:
- # Fetch gateway MAC address
- # ('RTA_GATEWAY', neighbor_ip)
- item.neighbor_ip = att[1]
- if 'RTA_OIF' in att:
- # Fetch interface name
- # ('RTA_OIF', iface)
- item.iface = ipdb.interfaces[int(att[1])].ifname
-
- if not item.iface in args.i or not item.iprange or not item.neighbor_ip:
- # Neighbor info is invalid
- del item
- return
-
- # Fetch prefix_len
- item.prefix_len = msg['dst_len']
-
- del_route_entry(bess, item)
-
- # Delete item
- del item
-
-
-def netlink_event_listener(ipdb, netlink_message, action):
-
- # If you get a netlink message, parse it
- msg = netlink_message
-
- if action == 'RTM_NEWROUTE':
- parse_new_route(msg)
-
- if action == 'RTM_NEWNEIGH':
- parse_new_neighbor(msg)
-
- if action == 'RTM_DELROUTE':
- parse_del_route(msg)
-
-
-def bootstrap_routes():
- routes = ipr.get_routes()
- for i in routes:
- if i['event'] == 'RTM_NEWROUTE':
- parse_new_route(i)
-
-
-def connect_bessd():
- print('Connecting to BESS daemon...'),
- # Connect to BESS (assuming host=localhost, port=10514 (default))
- for i in range(MAX_RETRIES):
- try:
- if not bess.is_connected():
- bess.connect(grpc_url=args.ip + ':' + args.port)
- except BESS.RPCError:
- print(
- 'Error connecting to BESS daemon. Retrying in {}sec...'.format(
- SLEEP_S))
- time.sleep(SLEEP_S)
- else:
- break
- else:
- raise Exception('BESS connection failure.')
-
- print('Done.')
-
-
-def reconfigure(number, frame):
- print('Received: {} Reloading routes'.format(number))
- # clear arpcache
- for ip in list(arpcache):
- item = arpcache.get(ip)
- del item
- arpcache.clear()
- for ip in list(neighborcache):
- item = neighborcache.get(ip)
- del item
- neighborcache.clear()
- for modname in list(modgatecnt):
- item = modgatecnt.get(modname)
- del item
- modgatecnt.clear()
- bootstrap_routes()
- signal.pause()
-
-
-def cleanup(number, frame):
- ipdb.unregister_callback(event_callback)
- print('Received: {} Exiting'.format(number))
- sys.exit()
-
-
-def main():
- global arpcache, neighborcache, modgatecnt, ipdb, event_callback, bess, ipr
- # for holding unresolved ARP queries
- arpcache = {}
- # for holding list of registered neighbors
- neighborcache = {}
- # for holding gate count per route module
- modgatecnt = {}
- # for interacting with kernel
- ipdb = IPDB()
- ipr = IPRoute()
- # for bess client
- bess = BESS()
-
- # connect to bessd
- connect_bessd()
-
- # program current routes
- #bootstrap_routes()
-
- # listen for netlink events
- print('Registering netlink event listener callback...'),
- event_callback = ipdb.register_callback(netlink_event_listener)
- print('Done.')
-
- signal.signal(signal.SIGHUP, reconfigure)
- signal.signal(signal.SIGINT, cleanup)
- signal.signal(signal.SIGTERM, cleanup)
- signal.pause()
-
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser(
- description='Basic IPv4 Routing Controller')
- parser.add_argument('-i',
- type=str,
- nargs='+',
- help='interface(s) to control')
- parser.add_argument('--ip',
- type=str,
- default='localhost',
- help='BESSD address')
- parser.add_argument('--port', type=str, default='10514', help='BESSD port')
-
- # for holding command-line arguments
- global args
- args = parser.parse_args()
-
- if args.i:
- main()
- # if interface list is empty, print help menu and quit
- else:
- print(parser.print_help())
diff --git a/omec/omec-user-plane/files/spgwu.bess b/omec/omec-user-plane/files/spgwu.bess
deleted file mode 100644
index 76e546d..0000000
--- a/omec/omec-user-plane/files/spgwu.bess
+++ /dev/null
@@ -1,374 +0,0 @@
-# vim: syntax=py
-# -*- mode: python -*-
-# SPDX-License-Identifier: Apache-2.0
-# Copyright(c) 2019 Intel Corporation
-
-# for errnos
-import errno
-from conf.utils import *
-
-
-# ====================================================
-# Parameters
-# ====================================================
-
-
-conf_file = get_env('CONF_FILE', 'conf/spgwu.json')
-conf = get_json_conf(conf_file, False)
-
-# Maximum number of flows to manage ip frags for re-assembly
-max_ip_defrag_flows = None
-try:
- max_ip_defrag_flows = int(conf["max_ip_defrag_flows"])
-except ValueError:
- print('Invalid value for max_ip_defrag_flows. Not installing IPDefrag module.')
-except KeyError:
- print('max_ip_defrag_flows value not set. Not installing IPDefrag module.')
-
-# ====================================================
-# Port Helpers
-# ====================================================
-
-
-MAX_GATES = 8192
-dpdk_ports = {}
-
-
-def scan_dpdk_ports():
- idx = 0
- while True:
- try:
- intf = PMDPort(name="Port {}".format(idx), port_id=idx)
- if intf:
- # Need to declare mac so that we don't lose key during destroy_port
- mac = intf.mac_addr
- dpdk_ports[mac] = idx
- bess.destroy_port(intf.name)
- except bess.Error as e:
- if e.code == errno.ENODEV:
- break
- else:
- raise
- idx += 1
- # RTE_MAX_ETHPORTS is 32 and we need 2 for vdevs
- if idx == 30:
- break
- return True if dpdk_ports else False
-
-
-class Port:
- def __init__(self, name):
- self.name = name
- self.wid = None
- self.fpi = None
- self.fpo = None
- self.bpf = None
- self.bpfgate = 0
- self.routes_table = None
-
- def bpf_gate(self):
- if self.bpfgate < MAX_GATES - 2:
- self.bpfgate += 1
- return self.bpfgate
- else:
- raise Exception('Port {}: Out of BPF gates to allocate'.format(self.name))
-
- def detect_mode(self):
- # default case
- mode = "unselected"
-
- try:
- peer_by_interface(self.name)
- mode = "dpdk"
- except:
- mode = "linux"
- return mode
-
- def init_fastpath(self, **kwargs):
- # Initialize PMDPort and RX/TX modules
- name = self.name
- fast = PMDPort(name="{}Fast".format(name), **kwargs)
- self.fpi = __bess_module__("{}FastPI".format(name), 'PortInc', port=fast.name)
- self.fpo = __bess_module__("{}FastPO".format(name), 'PortOut', port=fast.name)
-
- # Initialize BPF to classify incoming traffic to go to kernel and/or pipeline
- self.bpf = __bess_module__("{}FastBPF".format(name), 'BPF')
- self.bpf.clear()
-
- # Reassemble IP4 fragments (if needed)
- defrag = __bess_module__("{}IP4Defrag".format(name), 'IPDefrag', num_flows=max_ip_defrag_flows, numa=0)
- # Default drop when no matches
- self.fpi -> defrag:1 -> self.bpf:0 -> Sink()
- defrag:0 -> Sink()
-
- # Initialize route module
- self.rtr = __bess_module__("{}Routes".format(name), 'IPLookup')
-
- # Default route goes to Sink
- self.rtr.add(prefix='0.0.0.0', prefix_len=0, gate=MAX_GATES-1)
- self.rtr:(MAX_GATES-1) -> Sink()
-
- # Attach fastpath to worker's root TC
- self.fpi.attach_task(wid=self.wid)
-
- def setup_port(self, idx, workers):
- # Pick the worker handling this port
- self.wid = idx % workers
-
- name = self.name
- wid = self.wid
- print('Setting up port {} on worker {}'.format(name,wid))
-
- # Detect the mode of this interface - DPDK/AF_XDP/AF_PACKET
- mode = self.detect_mode()
-
- if mode == 'linux':
- try:
- # Initialize kernel fastpath.
- # AF_XDP requires that num_rx_qs == num_tx_qs
- kwargs = {"vdev" : "net_af_xdp{},iface={},start_queue=0,queue_count={}"
- .format(idx, name, workers), "num_out_q": workers, "num_inc_q": workers}
- self.init_fastpath(**kwargs)
- except:
- print('Failed to create AF_XDP socket for {}. Creating AF_PACKET socket instead.'.format(name))
- kwargs = {"vdev" : "net_af_packet{},iface={},qpairs={}".format(idx, name, workers), "num_out_q": workers}
- self.init_fastpath(**kwargs)
-
- elif mode == 'dpdk':
- # if port list is empty, scan for dpdk_ports first
- if not dpdk_ports and scan_dpdk_ports() == False:
- print('Registered dpdk ports do not exist.')
- sys.exit()
- # Initialize DPDK fastpath
- fidx = dpdk_ports.get(mac_by_interface(name))
- if fidx is None:
- raise Exception('Registered port for {} not detected!'.format(name))
- kwargs = {"port_id" : fidx, "num_out_q": workers}
- self.init_fastpath( **kwargs)
-
- # Initialize kernel slowpath port and RX/TX modules
- try:
- peer = peer_by_interface(name)
- vdev = "net_af_packet{},iface={}".format(idx, peer)
- slow = PMDPort(name="{}Slow".format(name), vdev=vdev)
- spi = __bess_module__("{}SlowPI".format(name), 'PortInc', port=slow.name)
- spo = __bess_module__("{}SlowPO".format(name), 'PortOut', port=slow.name)
- qspo = __bess_module__("{}QSlowPO".format(name), 'Queue')
-
- # host_ip_filter: tcpdump -i foo 'dst host 198.19.0.1 or 198.18.0.1' -d
- # Should always be set to lowest priority
- HostGate = MAX_GATES - 1
- ips = ips_by_interface(name)
- host_ip_filter = {"priority": -HostGate, "filter": "dst host "
- + " or ".join(str(x) for x in ips), "gate": HostGate}
-
- self.bpf.add(filters=[host_ip_filter])
-
- # Direct control traffic from DPDK to kernel
- self.bpf:HostGate -> qspo -> spo
-
- # Direct control traffic from kernel to DPDK
- spi -> self.fpo
-
- # Direct fast path traffic to Frag module
- merge = __bess_module__("{}Merge".format(name), 'Merge')
- frag = __bess_module__("{}IP4Frag".format(name), 'IPFrag')
- merge -> frag:1 -> self.fpo
- frag:0 -> Sink()
-
- tc = 'slow{}'.format(wid)
- try:
- bess.add_tc(tc, policy='round_robin', wid=wid)
- except Exception as e:
- if e.errmsg == "Name '{}' already exists".format(tc):
- pass
- else:
- raise e
- # Limit scheduling slow path RX/TX to 1000 times/second each
- for mod in spi, qspo:
- bess.add_tc(mod.name,
- parent=tc,
- policy='rate_limit',
- resource='count',
- limit={'count': 1000})
- mod.attach_task(mod.name)
- except Exception as e:
- print('Mirror veth interface: {} misconfigured: {}'.format(name, e))
- else:
- raise Exception('Invalid mode selected.')
-
-
-# ====================================================
-# Validate
-# ====================================================
-
-
-# CIDRs
-enb_cidr = conf["enb_cidr"]
-ue_cidr = conf["ue_cidr"]
-
-cidrs = [enb_cidr, ue_cidr]
-for cidr in cidrs:
- if validate_cidr(cidr) is False:
- exit(1, 'Invalid {}'.format(cidr))
-
-# ====================================================
-# Core Setup
-# ====================================================
-
-
-# Initialize workers
-workers = 1
-try:
- workers = int(conf["workers"])
-except ValueError:
- print('Invalid workers value! Re-setting # of workers to 1.')
-
-cores = get_process_affinity()
-for wid in xrange(workers):
- bess.add_worker(wid=wid, core=int(cores[wid % len(cores)]))
-
-# ====================================================
-# Port Setup
-# ====================================================
-
-
-interfaces = ["s1u", "sgi"]
-ports = {}
-for idx, interface in enumerate(interfaces):
- port = Port(conf[interface]["ifname"])
- if port.name in ports:
- continue
- port.setup_port(idx, workers)
- ports[port.name] = port
-
-s1u_ifname = conf["s1u"]["ifname"]
-sgi_ifname = conf["sgi"]["ifname"]
-
-# ====================================================
-# Downlink Pipeline
-# ====================================================
-
-s1uRoutes = ports[s1u_ifname].rtr
-
-# Maximum number of sessions to manage
-try:
- max_sessions = int(conf["max_sessions"])
-except ValueError:
- print('Invalid max_sessions value!')
-
-# Setting filter to detect UE subnet
-sgiFastBPF = ports[sgi_ifname].bpf
-UEGate = ports[sgi_ifname].bpf_gate()
-ue_filter = {"priority": -UEGate,
- "filter": "ip dst net {}".format(ue_cidr), "gate": UEGate}
-sgiFastBPF.add(filters=[ue_filter])
-
-sgiFastBPF:UEGate \
- -> EtherTrim::GenericDecap(bytes=14) \
- -> GTPUEncap::GtpuEncap(s1u_sgw_ip=ip2long(ips_by_interface(s1u_ifname)[0]), num_subscribers=max_sessions):1 \
- -> S1UEtherAdd::GenericEncap(fields=[
- {'size': 6, 'value': {'value_int': 0x0}},
- {'size': 6, 'value': {'value_int': mac2hex(mac_by_interface(s1u_ifname))}},
- {'size': 2, 'value': {'value_int': 0x0800}}]) \
- -> OuterUDPCsum::L4Checksum() \
- -> OuterIPCsum::IPChecksum() \
- -> s1uRoutes
-
-# Drop unknown packets
-GTPUEncap:0 -> Sink()
-
-# ====================================================
-# Uplink Pipeline
-# ====================================================
-
-
-# Setting filter to detect gtpu traffic
-# src net 11.1.1.0 mask 255.255.255.0 # check eNB subnet
-# and dst host 11.1.1.1 # check S/PGWU IP
-# and udp dst port 2152 # check GTPU port
-# and (udp[28:4] & 0xffffff00) = 0x10000000 # check UE subnet
-s1uFastBPF = ports[s1u_ifname].bpf
-check_enb_subnet = "src net {} ".format(enb_cidr)
-check_spgwu_ip = " and dst host " + \
- " or ".join(str(x) for x in ips_by_interface(s1u_ifname))
-check_gtpu_port = " and udp dst port 2152"
-check_ue_subnet = " and (udp[28:4] & 0x{}) = 0x{}".format(
- cidr2mask(ue_cidr), ip2hex(cidr2block(ue_cidr)[0]))
-check_gtpu_msg_echo = " and udp[9] = 0x1"
-
-GTPUEchoGate = ports[s1u_ifname].bpf_gate()
-uplink_echo_filter = {"priority": -GTPUEchoGate, "filter": check_enb_subnet +
- check_spgwu_ip + check_gtpu_port +
- check_gtpu_msg_echo, "gate": GTPUEchoGate}
-s1uFastBPF.add(filters=[uplink_echo_filter])
-
-GTPUGate = ports[s1u_ifname].bpf_gate()
-uplink_filter = {"priority": -GTPUGate, "filter": check_enb_subnet +
- check_spgwu_ip + check_gtpu_port, "gate": GTPUGate}
-s1uFastBPF.add(filters=[uplink_filter])
-
-sgiRoutes = ports[sgi_ifname].rtr
-
-s1uFastBPF:GTPUGate \
- -> EtherDecapTrim::GenericDecap(bytes=14) -> GTPUDecap::GtpuDecap(ename="GTPUEncap"):1 \
- -> SGIEtherAdd::GenericEncap(fields=[
- {'size': 6, 'value': {'value_int': 0x0}},
- {'size': 6, 'value': {'value_int': mac2hex(mac_by_interface(sgi_ifname))}},
- {'size': 2, 'value': {'value_int': 0x0800}}]) \
- -> sgiRoutes
-
-s1uFastBPF:GTPUEchoGate \
- -> GTPUEcho::GtpuEcho(s1u_sgw_ip=ip2long(ips_by_interface(s1u_ifname)[0])):1 \
- -> EthSwap::MACSwap() \
- -> 1:OuterUDPCsum
-
-# Drop unknown packets
-GTPUEcho:0 -> Sink()
-GTPUDecap:0 -> Sink()
-
-# ====================================================
-# SIM_TEST
-# ====================================================
-
-import time
-
-def sim_start_test():
- start_teid = 0xf0000000
- start_ue_ip = 0x10000001
- start_enb_ip = 0x0b010181
- NG4T_MAX_UE_RAN = 500000
- NG4T_MAX_ENB_RAN = 80
-
- for i in range(max_sessions):
-
- # NG4T-based formula to calculate enodeB IP address against a given UE IP address
- # il_trafficgen also uses the same scheme
- # See SimuCPEnbv4Teid(...) in ngic code for more details
- ue_of_ran = i % NG4T_MAX_UE_RAN
- ran = i / NG4T_MAX_UE_RAN
- enb_of_ran = ue_of_ran % NG4T_MAX_ENB_RAN
- enb_idx = ran * NG4T_MAX_ENB_RAN + enb_of_ran
-
- GTPUEncap.add(teid=start_teid+i, eteid=i+1, ueaddr=start_ue_ip+i, enodeb_ip=start_enb_ip+enb_idx)
-
-def sim_end_test():
- start_ue_ip = 0x10000001
-
- for i in range(max_sessions):
- GTPUEncap.remove(ueaddr=start_ue_ip+i)
-
- GTPUEncap.show_records()
-
-### Uncomment the following lines to test with il_trafficgen ###
-# Start the test
-#sim_start_test()
-# Wait for 30 seconds before deleting the session info entries (optional)
-#time.sleep(30)
-#sim_end_test()
-
-# Finally send SIGHUP to route_control daemon on reload
-# TODO: behavior is unspecified if route_control.py pid is not found
-route_control_pid = getpythonpid('route_control.py')
-if route_control_pid:
- os.kill(route_control_pid, signal.SIGHUP)
diff --git a/omec/omec-user-plane/files/utils.py b/omec/omec-user-plane/files/utils.py
deleted file mode 100644
index 5b060b6..0000000
--- a/omec/omec-user-plane/files/utils.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env python
-# SPDX-License-Identifier: Apache-2.0
-# Copyright(c) 2019 Intel Corporation
-
-import os
-import signal
-import socket
-import sys
-
-import iptools
-import json
-import psutil
-from pyroute2 import IPDB
-
-
-def exit(code, msg):
- print(msg)
- sys.exit(code)
-
-
-def getpid(process_name):
- for proc in psutil.process_iter(attrs=['pid', 'name']):
- if process_name == proc.info['name']:
- return proc.info['pid']
-
-
-def getpythonpid(process_name):
- for proc in psutil.process_iter(attrs=['pid', 'cmdline']):
- if len(proc.info['cmdline']) < 2:
- continue
- if process_name in proc.info['cmdline'][1] and 'python' in proc.info['cmdline'][0]:
- return proc.info['pid']
- return
-
-def get_json_conf(path, dump):
- conf = json.loads(open(path).read())
- if dump:
- print(json.dumps(conf, indent=4, sort_keys=True))
- return conf
-
-
-def get_env(varname, default=None):
- try:
- var = os.environ[varname]
- return var
- except KeyError:
- if default is not None:
- return '{}'.format(default)
- else:
- exit(1, 'Empty env var {}'.format(varname))
-
-
-def ips_by_interface(name):
- ipdb = IPDB()
- return [ipobj[0] for ipobj in ipdb.interfaces[name]['ipaddr'].ipv4]
-
-
-def mac_by_interface(name):
- ipdb = IPDB()
- return ipdb.interfaces[name]['address']
-
-
-def mac2hex(mac):
- return int(mac.replace(':', ''), 16)
-
-
-def peer_by_interface(name):
- ipdb = IPDB()
- try:
- peer_idx = ipdb.interfaces[name]['link']
- peer_name = ipdb.interfaces[peer_idx]['ifname']
- except:
- raise Exception('veth interface {} does not exist'.format(name))
- else:
- return peer_name
-
-
-def aton(ip):
- return socket.inet_aton(ip)
-
-
-def validate_cidr(cidr):
- return iptools.ipv4.validate_cidr(cidr)
-
-
-def cidr2mask(cidr):
- _, prefix = cidr.split('/')
- return format(0xffffffff << (32 - int(prefix)), '08x')
-
-
-def cidr2block(cidr):
- return iptools.ipv4.cidr2block(cidr)
-
-
-def ip2hex(ip):
- return iptools.ipv4.ip2hex(ip)
-
-
-def ip2long(ip):
- return iptools.ipv4.ip2long(ip)
-
-
-def get_process_affinity():
- return psutil.Process().cpu_affinity()
diff --git a/omec/omec-user-plane/templates/bin/_bessd-poststart.sh.tpl b/omec/omec-user-plane/templates/bin/_bessd-poststart.sh.tpl
index 42db9b1..8c6b37a 100644
--- a/omec/omec-user-plane/templates/bin/_bessd-poststart.sh.tpl
+++ b/omec/omec-user-plane/templates/bin/_bessd-poststart.sh.tpl
@@ -16,7 +16,7 @@
set -ex
-until bessctl run spgwu; do
+until bessctl run /opt/bess/bessctl/conf/spgwu; do
sleep 2;
done;
diff --git a/omec/omec-user-plane/templates/config/_spgwu.json.tpl b/omec/omec-user-plane/templates/config/_spgwu.json.tpl
index 3fec6b1..ba36cc7 100644
--- a/omec/omec-user-plane/templates/config/_spgwu.json.tpl
+++ b/omec/omec-user-plane/templates/config/_spgwu.json.tpl
@@ -8,6 +8,5 @@
"ifname": {{ .Values.config.spgwu.sgi.device | quote }}
},
"workers": {{ .Values.config.spgwu.workers }},
- "max_sessions": {{ .Values.config.spgwu.maxSessions }},
- "max_ip_defrag_flows": {{ .Values.config.spgwu.maxIpDefragFlows }}
+ "max_sessions": {{ .Values.config.spgwu.maxSessions }}
}
diff --git a/omec/omec-user-plane/templates/configmap-spgwu.yaml b/omec/omec-user-plane/templates/configmap-spgwu.yaml
index d002175..488cf64 100644
--- a/omec/omec-user-plane/templates/configmap-spgwu.yaml
+++ b/omec/omec-user-plane/templates/configmap-spgwu.yaml
@@ -24,13 +24,5 @@
data:
spgwu.json: |
{{ tuple "config/_spgwu.json.tpl" . | include "omec-user-plane.template" | indent 4 }}
- spgwu.bess: |
-{{ .Files.Get "files/spgwu.bess" | indent 4 }}
- __init__.py: |
-{{ .Files.Get "files/__init__.py" | indent 4 }}
- route_control.py: |
-{{ .Files.Get "files/route_control.py" | indent 4 }}
- utils.py: |
-{{ .Files.Get "files/utils.py" | indent 4 }}
bessd-poststart.sh: |
{{ tuple "bin/_bessd-poststart.sh.tpl" . | include "omec-user-plane.template" | indent 4 }}
diff --git a/omec/omec-user-plane/templates/statefulset-spgwu.yaml b/omec/omec-user-plane/templates/statefulset-spgwu.yaml
index 64e123d..376b3d9 100644
--- a/omec/omec-user-plane/templates/statefulset-spgwu.yaml
+++ b/omec/omec-user-plane/templates/statefulset-spgwu.yaml
@@ -60,7 +60,7 @@
env:
- name: PYTHONUNBUFFERED
value: "1"
- command: ["/bin/conf/route_control.py"]
+ command: ["/opt/bess/bessctl/conf/route_control.py"]
args:
- -i
- {{ .Values.config.spgwu.s1u.device }}
@@ -69,9 +69,6 @@
resources:
{{ toYaml .Values.resources.routectl | indent 10 }}
{{- end }}
- volumeMounts:
- - name: scripts
- mountPath: /bin/conf
- name: bessd
image: {{ .Values.images.tags.bess | quote }}
imagePullPolicy: {{ .Values.images.pullPolicy | quote }}
@@ -87,7 +84,7 @@
lifecycle:
postStart:
exec:
- command: ["/bin/conf/bessd-poststart.sh"]
+ command: ["/etc/bess/conf/bessd-poststart.sh"]
livenessProbe:
tcpSocket:
port: 10514
@@ -110,13 +107,14 @@
intel.com/sriov_vfio_s1u_net: 1
intel.com/sriov_vfio_sgi_net: 1
{{- end }}
+ env:
+ - name: CONF_FILE
+ value: /etc/bess/conf/spgwu.json
volumeMounts:
- name: hugepages
mountPath: /dev/hugepages
- name: configs
- mountPath: /opt/bess/bessctl/conf
- - name: scripts
- mountPath: /bin/conf
+ mountPath: /etc/bess/conf
{{- if .Values.config.coreDump.enabled }}
- name: coredump
mountPath: /tmp/coredump
@@ -129,11 +127,6 @@
resources:
{{ toYaml .Values.resources.web | indent 10 }}
{{- end }}
- volumeMounts:
- - name: configs
- mountPath: /opt/bess/bessctl/conf
- - name: scripts
- mountPath: /bin/conf
- name: cpiface
image: {{ .Values.images.tags.cpiface | quote }}
imagePullPolicy: {{ .Values.images.pullPolicy | quote }}
@@ -166,10 +159,6 @@
- name: configs
configMap:
name: spgwu
- defaultMode: 420
- - name: scripts
- configMap:
- name: spgwu
defaultMode: 493
- name: hugepages
emptyDir:
diff --git a/omec/omec-user-plane/values.yaml b/omec/omec-user-plane/values.yaml
index ebed5a2..66fd9b3 100644
--- a/omec/omec-user-plane/values.yaml
+++ b/omec/omec-user-plane/values.yaml
@@ -69,7 +69,6 @@
name: "dp-staging"
workers: 1
maxSessions: 50000
- maxIpDefragFlows: 1000
# Provide the S1U and SGI networks facing device name and IP address
s1u:
device: s1u