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

Added NTF to new pipeline #106

Merged
merged 1 commit into from
Jul 31, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions conf/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def __init__(self, fname):
self.s1u_ifname = None
self.sgi_ifname = None
self.interfaces = dict()
self.enable_ntf = False

def parse(self, ifaces):
# Maximum number of flows to manage ip4 frags for re-assembly
Expand Down Expand Up @@ -112,3 +113,9 @@ def parse(self, ifaces):
self.s1u_ifname = "s1u"
self.sgi_ifname = "sgi"
print('Can\'t parse interface name(s)! Setting it to default values ({}, {})'.format("s1u", "sgi"))

# Network Token Function
try:
self.enable_ntf = bool(self.conf['enable_ntf'])
except KeyError:
print('Network Token Function disabled')
76 changes: 76 additions & 0 deletions conf/sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,82 @@ def gen_ue_packet(size, src_mac, dst_mac, src_ip, dst_ip, inner_src_ip, inner_ds
return bytes(pkt)


def gen_ue_ntf_packet(size, src_mac, dst_mac, src_ip, dst_ip, inner_src_ip, inner_dst_ip, teid):
eth = Ether(src=src_mac, dst=dst_mac)
ip = IP(src=src_ip, dst=dst_ip)
udp = UDP(sport=2152, dport=2152)
inet_p = IP(src=inner_src_ip, dst=inner_dst_ip) / \
UDP(sport=10001, dport=10002)

# Since scapy doesn't have a helper for STUN, the following blob contains
# this STUN packet:
#
# Session Traversal Utilities for NAT
# Message Type: 0x0001 (Binding Request)
# .... ...0 ...0 .... = Message Class: 0x00 Request (0)
# ..00 000. 000. 0001 = Message Method: 0x0001 Binding (0x001)
# ..0. .... .... .... = Message Method Assignment: IETF Review (0x0)
# Message Length: 296
# Message Cookie: 2112a442
# Message Transaction ID: 3566674b4274783565347871
# Attributes
# Unknown
# Attribute Type: Unknown (0x8030)
# Attribute Length: 206
# Value: 0000b00f65794a68624763694f694a6b615849694c434a6c...
# Padding: 2
# USERNAME: dkvc21eeecviv3:cPtQ
# Attribute Type: USERNAME (0x0006)
# Attribute Length: 19
# Username: dkvc21eeecviv3:cPtQ
# Padding: 1
# Unknown
# Attribute Type: Unknown (0xc057)
# Attribute Length: 4
# Value: 0003000a
# ICE-CONTROLLED
# Attribute Type: ICE-CONTROLLED (0x8029)
# Attribute Length: 8
# Tie breaker: 6dd28d3d5768520a
# PRIORITY
# Attribute Type: PRIORITY (0x0024)
# Attribute Length: 4
# Priority: 1853693695
# MESSAGE-INTEGRITY
# Attribute Type: MESSAGE-INTEGRITY (0x0008)
# Attribute Length: 20
# HMAC-SHA1: 8c6403d231f11d99b0564a2c5e3e421e9b194c8b
# FINGERPRINT
# Attribute Type: FINGERPRINT (0x8028)
# Attribute Length: 4
# CRC-32: 0x29e46f38

payload = \
b"\x00\x01\x01\x28\x21\x12\xa4\x42\x35\x66\x67\x4b\x42\x74\x78\x35" \
b"\x65\x34\x78\x71\x80\x30\x00\xce\x00\x00\xb0\x0f\x65\x79\x4a\x68" \
b"\x62\x47\x63\x69\x4f\x69\x4a\x6b\x61\x58\x49\x69\x4c\x43\x4a\x6c" \
b"\x62\x6d\x4d\x69\x4f\x69\x4a\x42\x4d\x54\x49\x34\x51\x30\x4a\x44" \
b"\x4c\x55\x68\x54\x4d\x6a\x55\x32\x49\x6e\x30\x2e\x2e\x74\x4f\x2d" \
b"\x68\x78\x70\x56\x51\x6a\x56\x69\x50\x4e\x70\x75\x45\x4c\x46\x71" \
b"\x72\x50\x77\x2e\x77\x4c\x77\x4c\x6c\x30\x50\x75\x4d\x53\x36\x6f" \
b"\x4d\x6d\x41\x48\x50\x76\x6c\x5a\x71\x74\x64\x4e\x59\x30\x78\x6b" \
b"\x62\x4f\x6e\x49\x69\x30\x4f\x43\x7a\x30\x69\x4f\x76\x4a\x6f\x4c" \
b"\x62\x76\x69\x4f\x2d\x57\x42\x67\x59\x62\x56\x52\x57\x6b\x71\x75" \
b"\x6d\x76\x53\x33\x63\x61\x6d\x76\x66\x45\x66\x53\x54\x6d\x54\x72" \
b"\x6b\x79\x4d\x5a\x57\x4f\x69\x38\x78\x6a\x4a\x44\x30\x4b\x53\x76" \
b"\x55\x4c\x43\x4f\x33\x58\x54\x74\x43\x4a\x53\x6d\x6c\x2d\x45\x2e" \
b"\x74\x39\x2d\x52\x70\x45\x34\x6a\x31\x78\x4c\x44\x56\x2d\x61\x34" \
b"\x6f\x48\x6a\x6d\x74\x67\x00\x00\x00\x06\x00\x13\x64\x6b\x76\x63" \
b"\x32\x31\x65\x65\x65\x63\x76\x69\x76\x33\x3a\x63\x50\x74\x51\x00" \
b"\xc0\x57\x00\x04\x00\x03\x00\x0a\x80\x29\x00\x08\x6d\xd2\x8d\x3d" \
b"\x57\x68\x52\x0a\x00\x24\x00\x04\x6e\x7d\x1e\xff\x00\x08\x00\x14" \
b"\x8c\x64\x03\xd2\x31\xf1\x1d\x99\xb0\x56\x4a\x2c\x5e\x3e\x42\x1e" \
b"\x9b\x19\x4c\x8b\x80\x28\x00\x04\x29\xe4\x6f\x38"

pkt = eth/ip/udp/GTP_U_Header(teid=teid)/inet_p/payload
return bytes(pkt)


def get_ue_sequpdate_args(max_session, start_ue_ip, start_teid):
kwargs = {"fields": [
{'offset': 46, 'size': 4, 'min': start_teid,
Expand Down
43 changes: 40 additions & 3 deletions conf/up4.bess
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ if parser.mode == 'sim':
parser.sim_start_enb_ip, s1u_ip[0],
parser.sim_start_ue_ip, '172.16.100.1',
parser.sim_start_teid)]
if parser.enable_ntf:
# Every 30th packet will be a STUN packet. With 5000 flows, this
# results in about 1000 flows with network tokens, and every 3rd packet
# is a STUN packet with a token. This is not a good representation of
# a real world test, but it is enough to verify that NTF can match
# tokens and pass traffic through with mode="sim".
ue_packets = ue_packets * 29
ue_packets.append(
sim.gen_ue_ntf_packet(parser.sim_pkt_size, macstr_d, macstr_u,
parser.sim_start_enb_ip, s1u_ip[0],
parser.sim_start_ue_ip, '172.16.100.1',
parser.sim_start_teid))
packet_generator = {'s1u': ue_packets, 'sgi': inet_packets}
seq_kwargs = {'s1u': sim.get_ue_sequpdate_args(parser.sim_total_flows, parser.sim_start_ue_ip, parser.sim_start_teid),
'sgi': sim.get_inet_sequpdate_args(parser.sim_total_flows, parser.sim_start_ue_ip)}
Expand Down Expand Up @@ -106,6 +118,23 @@ for idx, iface in enumerate(interfaces):
ports[p.name] = p


# ====================================================
# Network Token Functions Setup
# ====================================================

ntf = None
if parser.enable_ntf:
try:
ntf = NTF()
# TODO: Populate these tables by talking to the NTE
ntf.table_create(dpid=1, max_entries=5)
ntf.entry_create(dpid=1, entry_id=1, dscp=1, token={
'app_id': 0xB00F,
'encryption_key': '{"alg":"A128CBC-HS256","k":"Qr_XwDGctna3SlR88rEJYt6Zm100SASYeJWSJihDnsA","key_ops":["encrypt","decrypt"],"kty":"oct"}'
})
except NameError:
pass

# ====================================================
# Shared Pipeline (DL + UL)
# ====================================================
Expand Down Expand Up @@ -134,8 +163,15 @@ linkMerge::Merge() \
{'attr_name':'fseid', 'num_bytes':4}, \
{'attr_name':'ctr_id', 'num_bytes':4}, \
{'attr_name':'far_id', 'num_bytes':4}]):noGTPUDecap \
-> preQoSCounter::Counter(name_id='ctr_id', check_exist=True, total=parser.max_sessions) \
-> farLookup::ExactMatch(fields=[{'attr_name':'far_id', 'num_bytes':4}, \
-> preQoSCounter::Counter(name_id='ctr_id', check_exist=True, total=parser.max_sessions)

# Insert NTF module, if enabled
_in = preQoSCounter
if ntf:
_in -> ntf
_in = ntf

_in -> farLookup::ExactMatch(fields=[{'attr_name':'far_id', 'num_bytes':4}, \
{'attr_name':'fseid', 'num_bytes':4}], \
values=[{'attr_name':'action', 'num_bytes':1}, \
{'attr_name':'tunnel_out_type', 'num_bytes':1}, \
Expand All @@ -148,7 +184,8 @@ linkMerge::Merge() \

# Add logical pipeline when gtpudecap is needed
pdrLookup:GTPUDecap \
-> etherTrimDecap::GenericDecap(bytes=14) -> gtpuDecap::GtpuDecap() \
-> etherTrimDecap::GenericDecap(bytes=14) \
-> gtpuDecap::GtpuDecap() \
-> sgiEtherAdd::GenericEncap(fields=[
{'size': 6, 'value': {'value_int': 0x0}},
{'size': 6, 'value': {'value_int': 0x0}},
Expand Down
18 changes: 9 additions & 9 deletions conf/upf.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

"": "Use the sim block to enable simulation using either Source module or via il_trafficgen",
"sim": {
"start_ue_ip": "16.0.0.1",
"start_enb_ip": "11.1.1.129",
"start_teid": "0xf0000000",
"pkt_size": 128,
"total_flows": 5000
"start_ue_ip": "16.0.0.1",
"start_enb_ip": "11.1.1.129",
"start_teid": "0xf0000000",
"pkt_size": 128,
"total_flows": 5000
},

"": "max IP frag table entries (for IPv4 reassembly). Update the line below to `\"max_ip_defrag_flows\": 1000` to enable",
Expand All @@ -33,7 +33,7 @@
"": "UE IP Natting. Update the line below to `\"ip_masquerade\": \"<ip> [or <ip>]\"` to enable",
"sgi": {
"ifname": "ens803f3",
"": "ip_masquerade: 18.0.0.1 or 18.0.0.2 or 18.0.0.3"
"": "ip_masquerade: 18.0.0.1 or 18.0.0.2 or 18.0.0.3"
},

"": "Number of worker threads. Default: use 1 thread to run both (uplink/downlink) pipelines",
Expand All @@ -44,8 +44,8 @@

"": "Control plane controller settings",
"cpiface": {
"nb_dst_ip": "172.17.0.1",
"" : "nb_dst_ip: CPHostname",
"hostname": "ngic-skx2"
"nb_dst_ip": "172.17.0.1",
"" : "nb_dst_ip: CPHostname",
"hostname": "ngic-skx2"
}
}