diff --git a/ci-scripts/validateN4UpfReportMessages.py b/ci-scripts/validateN4UpfReportMessages.py new file mode 100644 index 0000000000000000000000000000000000000000..ddb529e590e751d27bf71fcb89faa9b68eaee75b --- /dev/null +++ b/ci-scripts/validateN4UpfReportMessages.py @@ -0,0 +1,113 @@ +""" + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +------------------------------------------------------------------------------- + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org +""" + +import argparse +import os +import re +import sys + +class N4Statistics(): + def __init__(self): + self.nbN4Messages = 0 + self.totalDuration = 0 + self.nbPacketsTotal = 0 + self.nbPacketsDL = 0 + self.nbPacketsUL = 0 + self.totalVolume = 0 + self.dlVolume = 0 + self.ulVolume = 0 + + def printStats(self): + print(f'Received {self.nbN4Messages} N4 SESSION REPORT REQUESTS from an UPF') + print(f'- for a total duration of {self.totalDuration} seconds') + print(f'- Total Number of Packets : {self.nbPacketsTotal}') + print(f'- DL Number of Packets : {self.nbPacketsDL}') + print(f'- UL Number of Packets : {self.nbPacketsUL}') + print(f'- Total Volume : {self.totalVolume} bytes') + print(f'- DL Volume : {self.dlVolume} bytes') + print(f'- UL Volume : {self.ulVolume} bytes') + +def main() -> None: + args = _parse_args() + status = analyzeSmfLog(args.filename) + sys.exit(status) + +def _parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description='Analysis for SMF/UPF N4 Report messages') + + parser.add_argument( + '--filename', '-f', + action='store', + required=True, + help='Absolute path to the SMF file to analyze' + ) + return parser.parse_args() + +def analyzeSmfLog(logfile): + if not os.path.isfile(logfile): + print(f'{logfile} does not exist!') + return -1 + stats = N4Statistics() + with open(logfile, 'r') as smfLog: + printSection = False + packetSection = False + volumeSection = False + for line in smfLog: + if re.search('Received N4 SESSION REPORT REQUEST from an UPF', line): + printSection = True + stats.nbN4Messages += 1 + if re.search('itti_n4_session_report_response', line): + printSection = False + volumeSection = False + packetSection = False + if printSection: + res = re.search('Duration -> (?P<duration>[0-9]+)', line) + if res is not None: + stats.totalDuration += int(res.group('duration')) + res = re.search('NoP Total -> (?P<total>[0-9]+)', line) + if res is not None: + stats.nbPacketsTotal += int(res.group('total')) + packetSection = True + volumeSection = False + res = re.search('Volume Total -> (?P<total>[0-9]+)', line) + if res is not None: + stats.totalVolume += int(res.group('total')) + volumeSection = True + packetSection = False + res = re.search(' Uplink -> (?P<ul>[0-9]+)', line) + if res is not None and packetSection: + stats.nbPacketsUL += int(res.group('ul')) + if res is not None and volumeSection: + stats.ulVolume += int(res.group('ul')) + res = re.search(' Downlink -> (?P<dl>[0-9]+)', line) + if res is not None and packetSection: + stats.nbPacketsDL += int(res.group('dl')) + if res is not None and volumeSection: + stats.dlVolume += int(res.group('dl')) + smfLog.close() + stats.printStats() + if stats.nbN4Messages == 0: + return -1 + else: + return 0 + +if __name__ == '__main__': + main() diff --git a/docker-compose/docker-compose-basic-vpp-nonrf.yaml b/docker-compose/docker-compose-basic-vpp-nonrf.yaml index 63e22e343c9aec2f5d133cdbf063351336c4f150..205811567607bd96341bf6bd5bc6f3b7bbe3f056 100644 --- a/docker-compose/docker-compose-basic-vpp-nonrf.yaml +++ b/docker-compose/docker-compose-basic-vpp-nonrf.yaml @@ -213,6 +213,7 @@ services: - DNN_RANGE1=12.1.1.2 - 12.1.1.128 - DNN_RANGE0=12.2.1.2 - 12.2.1.128 - DNN_NI1=default + - ENABLE_USAGE_REPORTING=yes extra_hosts: - "gw1.vppupf.node.5gcn.mnc95.mcc208.3gppnetwork.org:192.168.70.202" depends_on: diff --git a/docker-compose/docker-compose-basic-vpp-nrf.yaml b/docker-compose/docker-compose-basic-vpp-nrf.yaml index 934e9ee28a346f6c1e7c9eaa23d5e2d73a75d5e4..9e19f7b29d36660fe30dcd150b2104b8973a1311 100644 --- a/docker-compose/docker-compose-basic-vpp-nrf.yaml +++ b/docker-compose/docker-compose-basic-vpp-nrf.yaml @@ -251,6 +251,7 @@ services: - DNN_RANGE1=12.1.1.2 - 12.1.1.128 - DNN_RANGE0=12.2.1.2 - 12.2.1.128 - DNN_NI1=default + - ENABLE_USAGE_REPORTING=yes extra_hosts: - "gw1.vppupf.node.5gcn.mnc95.mcc208.3gppnetwork.org:192.168.70.202" depends_on: diff --git a/docs/DEPLOY_SA5G_WITH_VPP_UPF.md b/docs/DEPLOY_SA5G_WITH_VPP_UPF.md index 82b6bdc45dbefe7c73c806acc40f736985a54367..8462c213aba0574e7856faa0bca6c48b04ef2e82 100644 --- a/docs/DEPLOY_SA5G_WITH_VPP_UPF.md +++ b/docs/DEPLOY_SA5G_WITH_VPP_UPF.md @@ -51,7 +51,7 @@ In previous tutorials, we were using the `oai-spgwu-tiny` implementation UPF. Th Moreover in this tutorial, we are going to integrate OAI 5G core with opensource `VPP-UPF` by [Travelping](https://www.travelping.com/). VPP-based UPF uses vector packet processing and it is has proven very good performance in the user plane. Motivation for this integration to test and validate high performance VPP-UPF in with OAI 5G core. -##### About VPP-UPG - +**About VPP-UPG** UPG implements a GTP-U user plane based on `3GPP TS 23.214` and `3GPP TS 29.244` Release `15`. It is implemented as an out-of-tree plugin for [Fdio VPP](https://github.com/FDio/vpp). The possible uses for UPG are: @@ -85,6 +85,8 @@ docker-compose-host $: chmod 777 /tmp/oai/vpp-upf-gnbsim * We will use same wrapper script for docker-compose that used for previous tutorials to set up 5gcn with `UPF-VPP`. Use help option to check how to use this wrapper script. +**Note: - To use vpp-upf on bare metal, follow [these instructions.](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-upf-vpp/-/blob/develop/docs/INSTALL_ON_HOST.md)** + All the following commands shall be executed from the `oai-cn5g-fed/docker-compose` folder. ``` console @@ -286,7 +288,7 @@ Creating gnbsim-vpp ... done <!--- For CI purposes please ignore this line ``` shell -docker-compose-host $: sleep 40 +docker-compose-host $: sleep 20 ``` --> @@ -334,6 +336,94 @@ PING 192.168.73.135 (192.168.73.135) from 12.1.1.2 : 56(84) bytes of data. rtt min/avg/max/mdev = 0.183/0.283/0.353/0.062 ms ``` +Let's analyze the N4 Traffic report from the UPF. + +``` shell +docker-compose-host $: sleep 10 +docker-compose-host $: docker logs oai-smf > /tmp/oai/vpp-upf-gnbsim/smf.log 2>&1 +docker-compose-host $: python3 ../ci-scripts/validateN4UpfReportMessages.py --filename /tmp/oai/vpp-upf-gnbsim/smf.log +Received 7 N4 SESSION REPORT REQUESTS from an UPF +- for a total duration of 70 seconds +- Total Number of Packets : 16 +- DL Number of Packets : 8 +- UL Number of Packets : 8 +- Total Volume : 1344 bytes +- DL Volume : 672 bytes +- UL Volume : 672 bytes +``` + +The SMF receives regularly N4 messages like this one: + +``` console +[2022-04-08T11:27:46.540271] [smf] [smf_n4 ] [info ] Received N4 SESSION REPORT REQUEST from an UPF +[2022-04-08T11:27:46.540357] [smf] [smf_app] [info ] SEID -> 1 +[2022-04-08T11:27:46.540378] [smf] [smf_app] [info ] UR-SEQN -> 4 +[2022-04-08T11:27:46.540384] [smf] [smf_app] [info ] Duration -> 10 +[2022-04-08T11:27:46.540389] [smf] [smf_app] [info ] NoP Total -> 2 +[2022-04-08T11:27:46.540394] [smf] [smf_app] [info ] Uplink -> 1 +[2022-04-08T11:27:46.540399] [smf] [smf_app] [info ] Downlink -> 1 +[2022-04-08T11:27:46.540404] [smf] [smf_app] [info ] Volume Total -> 168 +[2022-04-08T11:27:46.540409] [smf] [smf_app] [info ] Uplink -> 84 +[2022-04-08T11:27:46.540423] [smf] [smf_app] [info ] Downlink -> 84 +``` + +Let's create a bigger traffic: + +``` shell +docker-compose-host $: docker exec oai-ext-dn ping 12.1.1.2 -c40 -i0.1 -s500 +docker-compose-host $: sleep 10 +docker-compose-host $: docker logs oai-smf > /tmp/oai/vpp-upf-gnbsim/smf.log 2>&1 +docker-compose-host $: python3 ../ci-scripts/validateN4UpfReportMessages.py --filename /tmp/oai/vpp-upf-gnbsim/smf.log +Received 9 N4 SESSION REPORT REQUESTS from an UPF +- for a total duration of 90 seconds +- Total Number of Packets : 96 +- DL Number of Packets : 48 +- UL Number of Packets : 48 +- Total Volume : 43584 bytes +- DL Volume : 21792 bytes +- UL Volume : 21792 bytes +``` + +Now create an asymmetrical traffic with iperf3 in Downlink: + +``` shell +docker-compose-host $: docker exec -d gnbsim-vpp /bin/bash -c "nohup iperf3 -B 12.1.1.2 -s -i 1 > /tmp/iperf-server-dl.log 2>&1" +docker-compose-host $: sleep 1 +docker-compose-host $: docker exec oai-ext-dn iperf3 -c 12.1.1.2 -t 20 -i 1 +docker-compose-host $: sleep 10 +docker-compose-host $: docker logs oai-smf > /tmp/oai/vpp-upf-gnbsim/smf.log 2>&1 +docker-compose-host $: python3 ../ci-scripts/validateN4UpfReportMessages.py --filename /tmp/oai/vpp-upf-gnbsim/smf.log +Received 13 N4 SESSION REPORT REQUESTS from an UPF +- for a total duration of 130 seconds +- Total Number of Packets : 20926 +- DL Number of Packets : 13306 +- UL Number of Packets : 7620 +- Total Volume : 23912637 bytes +- DL Volume : 23436499 bytes +- UL Volume : 476138 bytes +``` + +**Don't forget to kill the iperf3 server process on `gnbsim-vpp` container.** + +``` console +docker-compose-host $: docker exec gnbsim-vpp ps aux +USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND +root 1 1.0 0.0 927132 9952 ? Ssl 11:51 0:01 /gnbsim/bin/example +root 126 0.0 0.0 18384 3064 ? Ss 11:53 0:00 /bin/bash -c nohup iperf3 -B 12.1.1.2 -s -i 1 > /tmp/iperf-server-dl.log 2>&1 +root 131 0.2 0.0 10412 2752 ? S 11:53 0:00 iperf3 -B 12.1.1.2 -s -i 1 +root 174 0.0 0.0 18516 3480 pts/0 Ss 11:54 0:00 /bin/bash +root 195 0.0 0.0 34412 2924 pts/0 R+ 11:54 0:00 ps aux + +# Here it is an example, kill the one corresponding to your run +docker-compose-host $: docker exec gnbsim-vpp kill -9 131 + +docker-compose-host $: docker exec gnbsim-vpp ps aux +USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND +root 1 1.0 0.0 927132 9952 ? Ssl 11:51 0:01 /gnbsim/bin/example +root 174 0.0 0.0 18516 3480 pts/0 Ss 11:54 0:00 /bin/bash +root 208 0.0 0.0 34412 2900 pts/0 R+ 11:54 0:00 ps aux +``` + ## 7. Recover the logs ``` shell