diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..5a77a805 --- /dev/null +++ b/404.html @@ -0,0 +1,604 @@ + + + +
+ + + + + + + + + + + + + +Note
+Author: Jimmy Chang
+Date: 2023/7/5
This technique leverages namespace to run UERANSIM, an opensource 5G-UE and RAN(gNodeB) simulator, and connect to free5GC.
+UERANSIM follows the 3GPP specification for developing and can support multiple 5G core (5GC) including free5GC.
Why are we using namespace? Well, you can follow ULCL and free5GC compose to set up the environment with VM and docker, but there are limitations for hardware’s capability. With network namespace, you can have different and separate network instances of network
+interfaces and routing tables that operate independently.
So, what is network namespace? Network namespace makes a copy of network stack with its own routing table, firewall and devices. A named network namespace is an object at /var/run/netns/
. The file descriptor resulting from opening /var/run/netns/
refers to the specified network namespace. Holding that file descriptor open
+keeps the network namespace alive.
And how to make both namespaces communicating? A virtual Ethernet device (veth) pair provides the abstraction that can be used to create tunnels between network namespaces, and can be used to create bridge to a physical network device in another namespace. Veth pair also be used as standalone network devices.
+When the namespace freed, veth device which attatch to would be destroyed.
The environment is as follow. Suppose you have already installed as well as set up free5GC and UERANSIM properly.
+Note
+Namespace free5GC represents host network namespace. And enp0s5 is an ethernet interface connectting to external.
+Each devices as follow
+| Device | IP |
+| ------------- | ------------- |
+| veth0 | 10.200.200.1 |
+| veth1 | 10.200.200.2 |
+| br-veth0 | none |
+| br-veth1 | none |
+| enp0s5 | 10.211.55.23 |
+
+
+UE information in UERANSIM as follow. Already
+| IMSI | DNN |
+| ---------------- | ------------- |
+| 208930000000003 | internet |
+
Replace ngapIpList IP from 127.0.0.18
to 10.200.200.2
:
info:
+ version: 1.0.9
+ description: AMF initial local configuration
+
+configuration:
+ amfName: AMF # the name of this AMF
+ ngapIpList: # the IP list of N2 interfaces on this AMF
+ - 10.200.200.2 # 127.0.0.18
+ ngapPort: 38412 # the SCTP port listened by NGAP
+ sbi: # Service-based interface information
+ scheme: http # the protocol for sbi (http or https)
+ registerIPv4: 127.0.0.18 # IP used to register to NRF
+ bindingIPv4: 127.0.0.18 # IP used to bind the service
+ port: 8000 # port used to bind the service
+ tls: # the local path of TLS key
+ pem: cert/amf.pem # AMF TLS Certificate
+ key: cert/amf.key # AMF TLS Private key
+ serviceNameList: # the SBI services provided by this AMF, refer to TS 29.518
+ - namf-comm # Namf_Communication service
+ - namf-evts # Namf_EventExposure service
+ - namf-mt # Namf_MT service
+ - namf-loc # Namf_Location service
+ - namf-oam # OAM service
+ servedGuamiList: # Guami (Globally Unique AMF ID) list supported by this AMF
+ # <GUAMI> = <MCC><MNC><AMF ID>
+ - plmnId: # Public Land Mobile Network ID, <PLMN ID> = <MCC><MNC>
+ mcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)
+ mnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)
+ amfId: cafe00 # AMF identifier (3 bytes hex string, range: 000000~FFFFFF)
+ supportTaiList: # the TAI (Tracking Area Identifier) list supported by this AMF
+ - plmnId: # Public Land Mobile Network ID, <PLMN ID> = <MCC><MNC>
+ mcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)
+ mnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)
+ tac: 000001 # Tracking Area Code (3 bytes hex string, range: 000000~FFFFFF)
+ plmnSupportList: # the PLMNs (Public land mobile network) list supported by this AMF
+ - plmnId: # Public Land Mobile Network ID, <PLMN ID> = <MCC><MNC>
+ mcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)
+ mnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)
+ snssaiList: # the S-NSSAI (Single Network Slice Selection Assistance Information) list supported by this AMF
+ - sst: 1 # Slice/Service Type (uinteger, range: 0~255)
+ sd: 010203 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)
+ - sst: 1 # Slice/Service Type (uinteger, range: 0~255)
+ sd: 112233 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)
+ supportDnnList: # the DNN (Data Network Name) list supported by this AMF
+ - internet
+ nrfUri: http://127.0.0.10:8000 # a valid URI of NRF
+ security: # NAS security parameters
+ integrityOrder: # the priority of integrity algorithms
+ - NIA2
+ # - NIA0
+ cipheringOrder: # the priority of ciphering algorithms
+ - NEA0
+ # - NEA2
+ networkName: # the name of this core network
+ full: free5GC
+ short: free
+ ngapIE: # Optional NGAP IEs
+ mobilityRestrictionList: # Mobility Restriction List IE, refer to TS 38.413
+ enable: true # append this IE in related message or not
+ maskedIMEISV: # Masked IMEISV IE, refer to TS 38.413
+ enable: true # append this IE in related message or not
+ redirectionVoiceFallback: # Redirection Voice Fallback IE, refer to TS 38.413
+ enable: false # append this IE in related message or not
+ nasIE: # Optional NAS IEs
+ networkFeatureSupport5GS: # 5gs Network Feature Support IE, refer to TS 24.501
+ enable: true # append this IE in Registration accept or not
+ length: 1 # IE content length (uinteger, range: 1~3)
+ imsVoPS: 0 # IMS voice over PS session indicator (uinteger, range: 0~1)
+ emc: 0 # Emergency service support indicator for 3GPP access (uinteger, range: 0~3)
+ emf: 0 # Emergency service fallback indicator for 3GPP access (uinteger, range: 0~3)
+ iwkN26: 0 # Interworking without N26 interface indicator (uinteger, range: 0~1)
+ mpsi: 0 # MPS indicator (uinteger, range: 0~1)
+ emcN3: 0 # Emergency service support indicator for Non-3GPP access (uinteger, range: 0~1)
+ mcsi: 0 # MCS indicator (uinteger, range: 0~1)
+ t3502Value: 720 # timer value (seconds) at UE side
+ t3512Value: 3600 # timer value (seconds) at UE side
+ non3gppDeregTimerValue: 3240 # timer value (seconds) at UE side
+ # retransmission timer for paging message
+ t3513:
+ enable: true # true or false
+ expireTime: 6s # default is 6 seconds
+ maxRetryTimes: 4 # the max number of retransmission
+ # retransmission timer for NAS Deregistration Request message
+ t3522:
+ enable: true # true or false
+ expireTime: 6s # default is 6 seconds
+ maxRetryTimes: 4 # the max number of retransmission
+ # retransmission timer for NAS Registration Accept message
+ t3550:
+ enable: true # true or false
+ expireTime: 6s # default is 6 seconds
+ maxRetryTimes: 4 # the max number of retransmission
+ # retransmission timer for NAS Authentication Request/Security Mode Command message
+ t3560:
+ enable: true # true or false
+ expireTime: 6s # default is 6 seconds
+ maxRetryTimes: 4 # the max number of retransmission
+ # retransmission timer for NAS Notification message
+ t3565:
+ enable: true # true or false
+ expireTime: 6s # default is 6 seconds
+ maxRetryTimes: 4 # the max number of retransmission
+ # retransmission timer for NAS Identity Request message
+ t3570:
+ enable: true # true or false
+ expireTime: 6s # default is 6 seconds
+ maxRetryTimes: 4 # the max number of retransmission
+ locality: area1 # Name of the location where a set of AMF, SMF, PCF and UPFs are located
+ sctp: # set the sctp server setting <optinal>, once this field is set, please also add maxInputStream, maxOsStream, maxAttempts, maxInitTimeOut
+ numOstreams: 3 # the maximum out streams of each sctp connection
+ maxInstreams: 5 # the maximum in streams of each sctp connection
+ maxAttempts: 2 # the maximum attempts of each sctp connection
+ maxInitTimeout: 2 # the maximum init timeout of each sctp connection
+ defaultUECtxReq: false # the default value of UE Context Request to decide when triggering Initial Context Setup procedure
+
+logger: # log output setting
+ enable: true # true or false
+ level: info # how detailed to output, value: trace, debug, info, warn, error, fatal, panic
+ reportCaller: false # enable the caller report or not, value: true or false
+
Replace userplaneInformation / upNodes / UPF / interfaces / endpoints from 127.0.0.8
to 10.200.200.2
:
info:
+ version: 1.0.7
+ description: SMF initial local configuration
+
+configuration:
+ smfName: SMF # the name of this SMF
+ sbi: # Service-based interface information
+ scheme: http # the protocol for sbi (http or https)
+ registerIPv4: 127.0.0.2 # IP used to register to NRF
+ bindingIPv4: 127.0.0.2 # IP used to bind the service
+ port: 8000 # Port used to bind the service
+ tls: # the local path of TLS key
+ key: cert/smf.key # SMF TLS Certificate
+ pem: cert/smf.pem # SMF TLS Private key
+ serviceNameList: # the SBI services provided by this SMF, refer to TS 29.502
+ - nsmf-pdusession # Nsmf_PDUSession service
+ - nsmf-event-exposure # Nsmf_EventExposure service
+ - nsmf-oam # OAM service
+ snssaiInfos: # the S-NSSAI (Single Network Slice Selection Assistance Information) list supported by this AMF
+ - sNssai: # S-NSSAI (Single Network Slice Selection Assistance Information)
+ sst: 1 # Slice/Service Type (uinteger, range: 0~255)
+ sd: 010203 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)
+ dnnInfos: # DNN information list
+ - dnn: internet # Data Network Name
+ dns: # the IP address of DNS
+ ipv4: 8.8.8.8
+ ipv6: 2001:4860:4860::8888
+ - sNssai: # S-NSSAI (Single Network Slice Selection Assistance Information)
+ sst: 1 # Slice/Service Type (uinteger, range: 0~255)
+ sd: 112233 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)
+ dnnInfos: # DNN information list
+ - dnn: internet # Data Network Name
+ dns: # the IP address of DNS
+ ipv4: 8.8.8.8
+ ipv6: 2001:4860:4860::8888
+ plmnList: # the list of PLMN IDs that this SMF belongs to (optional, remove this key when unnecessary)
+ - mcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)
+ mnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)
+ locality: area1 # Name of the location where a set of AMF, SMF, PCF and UPFs are located
+ pfcp: # the IP address of N4 interface on this SMF (PFCP)
+ # addr config is deprecated in smf config v1.0.3, please use the following config
+ nodeID: 127.0.0.1 # the Node ID of this SMF
+ listenAddr: 127.0.0.1 # the IP/FQDN of N4 interface on this SMF (PFCP)
+ externalAddr: 127.0.0.1 # the IP/FQDN of N4 interface on this SMF (PFCP)
+ userplaneInformation: # list of userplane information
+ upNodes: # information of userplane node (AN or UPF)
+ gNB1: # the name of the node
+ type: AN # the type of the node (AN or UPF)
+ UPF: # the name of the node
+ type: UPF # the type of the node (AN or UPF)
+ nodeID: 127.0.0.8 # the Node ID of this UPF
+ addr: 127.0.0.8 # the IP/FQDN of N4 interface on this UPF (PFCP)
+ sNssaiUpfInfos: # S-NSSAI information list for this UPF
+ - sNssai: # S-NSSAI (Single Network Slice Selection Assistance Information)
+ sst: 1 # Slice/Service Type (uinteger, range: 0~255)
+ sd: 010203 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)
+ dnnUpfInfoList: # DNN information list for this S-NSSAI
+ - dnn: internet
+ pools:
+ - cidr: 10.60.0.0/16
+ staticPools:
+ - cidr: 10.60.100.0/24
+ - sNssai: # S-NSSAI (Single Network Slice Selection Assistance Information)
+ sst: 1 # Slice/Service Type (uinteger, range: 0~255)
+ sd: 112233 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)
+ dnnUpfInfoList: # DNN information list for this S-NSSAI
+ - dnn: internet
+ pools:
+ - cidr: 10.61.0.0/16
+ staticPools:
+ - cidr: 10.61.100.0/24
+ interfaces: # Interface list for this UPF
+ - interfaceType: N3 # the type of the interface (N3 or N9)
+ endpoints: # the IP address of this N3/N9 interface on this UPF
+ - 10.200.200.2 # 127.0.0.8
+ networkInstances: # Data Network Name (DNN)
+ - internet
+ links: # the topology graph of userplane, A and B represent the two nodes of each link
+ - A: gNB1
+ B: UPF
+ # retransmission timer for pdu session modification command
+ t3591:
+ enable: true # true or false
+ expireTime: 16s # default is 6 seconds
+ maxRetryTimes: 3 # the max number of retransmission
+ # retransmission timer for pdu session release command
+ t3592:
+ enable: true # true or false
+ expireTime: 16s # default is 6 seconds
+ maxRetryTimes: 3 # the max number of retransmission
+ nrfUri: http://127.0.0.10:8000 # a valid URI of NRF
+ #urrPeriod: 10 # default usage report period in seconds
+ #urrThreshold: 1000 # default usage report threshold in bytes
+
+logger: # log output setting
+ enable: true # true or false
+ level: info # how detailed to output, value: trace, debug, info, warn, error, fatal, panic
+ reportCaller: false # enable the caller report or not, value: true or false
+
Replace gtpu from 127.0.0.8
to 10.200.200.2
:
version: 1.0.3
+description: UPF initial local configuration
+
+# The listen IP and nodeID of the N4 interface on this UPF (Can't set to 0.0.0.0)
+pfcp:
+ addr: 127.0.0.8 # IP addr for listening
+ nodeID: 127.0.0.8 # External IP or FQDN can be reached
+ retransTimeout: 1s # retransmission timeout
+ maxRetrans: 3 # the max number of retransmission
+
+gtpu:
+ forwarder: gtp5g
+ # The IP list of the N3/N9 interfaces on this UPF
+ # If there are multiple connection, set addr to 0.0.0.0 or list all the addresses
+ ifList:
+ - addr: 10.200.200.2 # 127.0.0.8
+ type: N3
+ # name: upf.5gc.nctu.me
+ # ifname: gtpif
+ # mtu: 1400
+
+# The DNN list supported by UPF
+dnnList:
+ - dnn: internet # Data Network Name
+ cidr: 10.60.0.0/24 # Classless Inter-Domain Routing for assigned IPv4 pool of UE
+ # natifname: eth0
+
+logger: # log output setting
+ enable: true # true or false
+ level: info # how detailed to output, value: trace, debug, info, warn, error, fatal, panic
+ reportCaller: false # enable the caller report or not, value: true or false
+
UERANSIM/config/free5gc-gnb.yaml
+Replace ngapIp from 127.0.0.1
to 10.200.200.1
Replace gtpIp from 127.0.0.1
to 10.200.200.1
Replace amfConfigs / address from 127.0.0.1
to 10.200.200.2
mcc: '208' # Mobile Country Code value
+mnc: '93' # Mobile Network Code value (2 or 3 digits)
+
+nci: '0x000000010' # NR Cell Identity (36-bit)
+idLength: 32 # NR gNB ID length in bits [22...32]
+tac: 1 # Tracking Area Code
+
+linkIp: 127.0.0.1 # gNB's local IP address for Radio Link Simulation (Usually same with local IP)
+ngapIp: 10.200.200.1 # 127.0.0.1 # gNB's local IP address for N2 Interface (Usually same with local IP)
+gtpIp: 10.200.200.1 # 127.0.0.1 # gNB's local IP address for N3 Interface (Usually same with local IP)
+
+# List of AMF address information
+amfConfigs:
+ - address: 10.200.200.2 # 127.0.0.1
+ port: 38412
+
+# List of supported S-NSSAIs by this gNB
+slices:
+ - sst: 0x1
+ sd: 0x010203
+
+# Indicates whether or not SCTP stream number errors should be ignored.
+ignoreStreamIds: true
+
# IMSI number of the UE. IMSI = [MCC|MNC|MSISDN] (In total 15 or 16 digits)
+supi: 'imsi-208930000000003'
+# Mobile Country Code value
+mcc: '208'
+# Mobile Network Code value (2 or 3 digits)
+mnc: '93'
+
+# Permanent subscription key
+key: '8baf473f2f8fd09487cccbd7097c6862'
+# Operator code (OP or OPC) of the UE
+op: '8e27b6af0e692e750f32667a3b14605d'
+# This value specifies the OP type and it can be either 'OP' or 'OPC'
+opType: 'OP'
+# Authentication Management Field (AMF) value
+amf: '8000'
+# IMEI number of the device. It is used if no SUPI is provided
+imei: '356938035643803'
+# IMEISV number of the device. It is used if no SUPI and IMEI is provided
+imeiSv: '4370816125816151'
+
+# List of gNB IP addresses for Radio Link Simulation
+gnbSearchList:
+ - 127.0.0.1
+
+# Initial PDU sessions to be established
+sessions:
+ - type: 'IPv4'
+ apn: 'internet'
+ slice:
+ sst: 0x01
+ sd: 0x010203
+
+# List of requested S-NSSAIs by this UE
+slices:
+ - sst: 0x01
+ sd: 0x010203
+
+# Supported encryption and integrity algorithms by this UE
+integrity:
+ IA1: true
+ IA2: true
+ IA3: true
+ciphering:
+ EA1: true
+ EA2: true
+ EA3: true
+
First, create a namespace:
+Note
+Assume that you are either running as root, or it behoves you to prepend sudo
to commands as necessary.
ip netns add ueransim
+
ip link add free5gc-br type bridge
+
ip link add veth0 type veth peer name br-veth0
+ip link add veth1 type veth peer name br-veth1
+
root@free5gc:~# ip a
+1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+ inet 127.0.0.1/8 scope host lo
+ valid_lft forever preferred_lft forever
+ inet6 ::1/128 scope host
+ valid_lft forever preferred_lft forever
+2: enp0s5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
+ link/ether 00:1c:42:b1:ba:f4 brd ff:ff:ff:ff:ff:ff
+ inet 10.211.55.23/24 brd 10.211.55.255 scope global dynamic enp0s5
+ valid_lft 1714sec preferred_lft 1714sec
+ inet6 fdb2:2c26:f4e4:0:21c:42ff:feb1:baf4/64 scope global dynamic mngtmpaddr noprefixroute
+ valid_lft 2591750sec preferred_lft 604550sec
+ inet6 fe80::21c:42ff:feb1:baf4/64 scope link
+ valid_lft forever preferred_lft forever
+3: enp0s6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
+ link/ether 00:1c:42:f1:11:c6 brd ff:ff:ff:ff:ff:ff
+ inet 10.37.129.20/24 brd 10.37.129.255 scope global enp0s6
+ valid_lft forever preferred_lft forever
+ inet6 fdb2:2c26:f4e4:1:21c:42ff:fef1:11c6/64 scope global dynamic mngtmpaddr noprefixroute
+ valid_lft 2591750sec preferred_lft 604550sec
+ inet6 fe80::21c:42ff:fef1:11c6/64 scope link
+ valid_lft forever preferred_lft forever
+4: free5gc-br: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
+ link/ether 4e:f6:d7:9c:50:de brd ff:ff:ff:ff:ff:ff
+5: br-veth0@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
+ link/ether c2:31:0c:5f:45:81 brd ff:ff:ff:ff:ff:ff
+6: veth0@br-veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
+ link/ether 4a:0f:1e:80:9b:be brd ff:ff:ff:ff:ff:ff
+7: br-veth1@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
+ link/ether 56:99:b0:82:78:0d brd ff:ff:ff:ff:ff:ff
+8: veth1@br-veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
+ link/ether 12:5a:56:00:5b:be brd ff:ff:ff:ff:ff:ff
+
Next, assign interface to namespace:
+
ip link set dev veth0 netns ueransim
+
ip netns exec ueransim ip a add 10.200.200.1/24 dev veth0
+
ip netns exec ueransim ip link set lo up
+ip netns exec ueransim ip link set veth0 up
+
ip a
:root@free5gc:~# ip netns exec ueransim ip a
+1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+ inet 127.0.0.1/8 scope host lo
+ valid_lft forever preferred_lft forever
+ inet6 ::1/128 scope host
+ valid_lft forever preferred_lft forever
+6: veth0@if5: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
+ link/ether 4a:0f:1e:80:9b:be brd ff:ff:ff:ff:ff:ff link-netnsid 0
+ inet 10.200.200.1/24 scope global veth0
+ valid_lft forever preferred_lft forever
+
ip a add 10.200.200.2/24 dev veth1
+ip link set veth1 up
+
ip link set dev br-veth0 master free5gc-br
+ip link set dev br-veth1 master free5gc-br
+ip link set br-veth0 up
+ip link set br-veth1 up
+ip link set free5gc-br up
+
bridge link
to check:root@free5gc:~# bridge link
+5: br-veth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master free5gc-br state forwarding priority 32 cost 2
+7: br-veth1@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master free5gc-br state forwarding priority 32 cost 2
+
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+ inet 127.0.0.1/8 scope host lo
+ valid_lft forever preferred_lft forever
+ inet6 ::1/128 scope host
+ valid_lft forever preferred_lft forever
+2: enp0s5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
+ link/ether 00:1c:42:b1:ba:f4 brd ff:ff:ff:ff:ff:ff
+ inet 10.211.55.23/24 brd 10.211.55.255 scope global dynamic enp0s5
+ valid_lft 1000sec preferred_lft 1000sec
+ inet6 fdb2:2c26:f4e4:0:21c:42ff:feb1:baf4/64 scope global dynamic mngtmpaddr noprefixroute
+ valid_lft 2591870sec preferred_lft 604670sec
+ inet6 fe80::21c:42ff:feb1:baf4/64 scope link
+ valid_lft forever preferred_lft forever
+3: enp0s6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
+ link/ether 00:1c:42:f1:11:c6 brd ff:ff:ff:ff:ff:ff
+ inet 10.37.129.20/24 brd 10.37.129.255 scope global enp0s6
+ valid_lft forever preferred_lft forever
+ inet6 fdb2:2c26:f4e4:1:21c:42ff:fef1:11c6/64 scope global dynamic mngtmpaddr noprefixroute
+ valid_lft 2591870sec preferred_lft 604670sec
+ inet6 fe80::21c:42ff:fef1:11c6/64 scope link
+ valid_lft forever preferred_lft forever
+4: free5gc-br: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
+ link/ether 56:99:b0:82:78:0d brd ff:ff:ff:ff:ff:ff
+ inet6 fe80::5499:b0ff:fe82:780d/64 scope link
+ valid_lft forever preferred_lft forever
+5: br-veth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master free5gc-br state UP group default qlen 1000
+ link/ether c2:31:0c:5f:45:81 brd ff:ff:ff:ff:ff:ff link-netns ueransim
+ inet6 fe80::c031:cff:fe5f:4581/64 scope link
+ valid_lft forever preferred_lft forever
+7: br-veth1@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master free5gc-br state UP group default qlen 1000
+ link/ether 56:99:b0:82:78:0d brd ff:ff:ff:ff:ff:ff
+ inet6 fe80::5499:b0ff:fe82:780d/64 scope link
+ valid_lft forever preferred_lft forever
+8: veth1@br-veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
+ link/ether 12:5a:56:00:5b:be brd ff:ff:ff:ff:ff:ff
+ inet 10.200.200.2/24 scope global veth1
+ valid_lft forever preferred_lft forever
+ inet6 fe80::105a:56ff:fe00:5bbe/64 scope link
+ valid_lft forever preferred_lft forever
+
Note
+You can perform ip netns exec ueransim /bin/bash --rcfile <(echo "PS1=\"ueransim> \"")
to enter namespace and modify shell prefix.
root@free5gc:~# ip netns exec ueransim /bin/bash --rcfile <(echo "PS1=\"ueransim> \"")
+ueransim> ping -c2 10.200.200.2
+PING 10.200.200.2 (10.200.200.2) 56(84) bytes of data.
+64 bytes from 10.200.200.2: icmp_seq=1 ttl=64 time=0.089 ms
+64 bytes from 10.200.200.2: icmp_seq=2 ttl=64 time=0.226 ms
+
+--- 10.200.200.2 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1020ms
+rtt min/avg/max/mdev = 0.089/0.157/0.226/0.068 ms
+
ueransim> ip route add default via 10.200.200.2
+ueransim> netstat -rn
+Kernel IP routing table
+Destination Gateway Genmask Flags MSS Window irtt Iface
+0.0.0.0 10.200.200.2 0.0.0.0 UG 0 0 0 veth0
+10.200.200.0 0.0.0.0 255.255.255.0 U 0 0 0 veth0
+
ueransim> ping -c2 8.8.8.8
+PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
+
+--- 8.8.8.8 ping statistics ---
+2 packets transmitted, 0 received, 100% packet loss, time 1028ms
+
root@free5gc:~# iptables -t nat -A POSTROUTING -o enp0s5 -j MASQUERADE
+root@free5gc:~# sysctl -w net.ipv4.ip_forward=1
+root@free5gc:~# sudo iptables -I FORWARD 1 -j ACCEPT
+
ueransim> ping -c2 8.8.8.8
+PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
+64 bytes from 8.8.8.8: icmp_seq=1 ttl=127 time=13.9 ms
+64 bytes from 8.8.8.8: icmp_seq=2 ttl=127 time=28.0 ms
+
+--- 8.8.8.8 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1002ms
+rtt min/avg/max/mdev = 13.866/20.939/28.012/7.073 ms
+
After free5GC execute run.sh
, it's time for UERANSIM:
In terminal 1:
+
ueransim> build/nr-gnb -c config/free5gc-gnb.yaml
+UERANSIM v3.1.0
+[2023-07-05 19:58:26.368] [sctp] [info] Trying to establish SCTP connection... (10.200.200.2:38412)
+[2023-07-05 19:58:26.373] [sctp] [info] SCTP connection established (10.200.200.2:38412)
+[2023-07-05 19:58:26.374] [sctp] [debug] SCTP association setup ascId[3]
+[2023-07-05 19:58:26.375] [ngap] [debug] Sending NG Setup Request
+[2023-07-05 19:58:26.380] [ngap] [debug] NG Setup Response received
+[2023-07-05 19:58:26.380] [ngap] [info] NG Setup procedure is successful
+[2023-07-05 19:58:35.804] [mr] [info] New UE connected to gNB. Total number of UEs is now: 1
+[2023-07-05 19:58:35.806] [rrc] [debug] Sending RRC Setup for UE[3]
+[2023-07-05 19:58:35.807] [ngap] [debug] Initial NAS message received from UE 3
+[2023-07-05 19:58:35.869] [ngap] [debug] Initial Context Setup Request received
+[2023-07-05 19:58:36.108] [ngap] [info] PDU session resource is established for UE[3] count[1]
+
ueransim> sudo build/nr-ue -c config/free5gc-ue.yaml
+UERANSIM v3.1.0
+[2023-07-05 19:58:35.803] [nas] [debug] NAS layer started
+[2023-07-05 19:58:35.803] [rrc] [debug] RRC layer started
+[2023-07-05 19:58:35.804] [nas] [info] UE switches to state: MM-DEREGISTERED/PLMN-SEARCH
+[2023-07-05 19:58:35.804] [nas] [info] UE connected to gNB
+[2023-07-05 19:58:35.804] [nas] [info] UE switches to state: MM-DEREGISTERED/NORMAL-SERVICE
+[2023-07-05 19:58:35.804] [nas] [info] UE switches to state: MM-REGISTERED-INITIATED/NA
+[2023-07-05 19:58:35.805] [rrc] [debug] Sending RRC Setup Request
+[2023-07-05 19:58:35.806] [rrc] [info] RRC connection established
+[2023-07-05 19:58:35.806] [nas] [info] UE switches to state: CM-CONNECTED
+[2023-07-05 19:58:35.838] [nas] [debug] Received rand[61262F32A617D0BAD716603B1CBDA477] autn[44778026F4238000FC14B59D68855328]
+[2023-07-05 19:58:35.838] [nas] [debug] Calculated res[47759045F5ACEA59] ck[1C559301F29EF49572F5D150B3B99288] ik[D223317F752F233CE4C7AA253644D882] ak[528433D1FBE6] mac_a[FC14B59D68855328]
+[2023-07-05 19:58:35.838] [nas] [debug] Used snn[5G:mnc093.mcc208.3gppnetwork.org] sqn[16F3B3F70FC5]
+[2023-07-05 19:58:35.838] [nas] [debug] Derived kSeaf[7FC8B7FB1B141B6579B9C0FAEB9CCF1312FE9F9634868E234756DE49FD67C5F1] kAusf[FA0402A892E6046D52F4DECACA40B2A75B698FCEAD5EB320139FC69B77BD4C46] kAmf[3D4AD68E153B9642ACBECC67AD399015F7CB578F9DF4C88A35EED99C72C9B95B]
+[2023-07-05 19:58:35.843] [nas] [debug] Derived kNasEnc[1F829EB2BA238DD0226C3484E6A79D1F] kNasInt[251C0412B1BAD88A9DD0008F32D6F216]
+[2023-07-05 19:58:35.843] [nas] [debug] Selected integrity[2] ciphering[0]
+[2023-07-05 19:58:35.869] [nas] [debug] T3512 started with int[3600]
+[2023-07-05 19:58:35.869] [nas] [info] UE switches to state: MM-REGISTERED/NORMAL-SERVICE
+[2023-07-05 19:58:35.869] [nas] [info] Initial Registration is successful
+[2023-07-05 19:58:35.869] [nas] [info] Initial PDU sessions are establishing [1#]
+[2023-07-05 19:58:35.869] [nas] [debug] Sending PDU session establishment request
+[2023-07-05 19:58:36.108] [nas] [info] PDU Session establishment is successful PSI[1]
+[2023-07-05 19:58:36.113] [app] [info] Connection setup for PDU session[1] is successful, TUN interface[uesimtun0, 10.60.0.1] is up.
+
ueransim> ip a
+1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+ inet 127.0.0.1/8 scope host lo
+ valid_lft forever preferred_lft forever
+ inet6 ::1/128 scope host
+ valid_lft forever preferred_lft forever
+2: uesimtun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
+ link/none
+ inet 10.60.0.1/32 scope global uesimtun0
+ valid_lft forever preferred_lft forever
+ inet6 fe80::b5ef:5b4:e3f6:af64/64 scope link stable-privacy
+ valid_lft forever preferred_lft forever
+6: veth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
+ link/ether 4a:0f:1e:80:9b:be brd ff:ff:ff:ff:ff:ff link-netnsid 0
+ inet 10.200.200.1/24 scope global veth0
+ valid_lft forever preferred_lft forever
+ inet6 fe80::480f:1eff:fe80:9bbe/64 scope link
+ valid_lft forever preferred_lft forever
+ueransim> ping -c2 -I uesimtun0 8.8.8.8
+PING 8.8.8.8 (8.8.8.8) from 10.60.0.1 uesimtun0: 56(84) bytes of data.
+64 bytes from 8.8.8.8: icmp_seq=1 ttl=127 time=19.5 ms
+64 bytes from 8.8.8.8: icmp_seq=2 ttl=127 time=33.2 ms
+
+--- 8.8.8.8 ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1006ms
+rtt min/avg/max/mdev = 19.478/26.348/33.219/6.870 ms
+
ueransim> ping -c2 -I uesimtun0 google.com
+PING google.com (172.217.160.110) from 10.60.0.1 uesimtun0: 56(84) bytes of data.
+64 bytes from tsa03s06-in-f14.1e100.net (172.217.160.110): icmp_seq=1 ttl=127 time=17.3 ms
+64 bytes from tsa03s06-in-f14.1e100.net (172.217.160.110): icmp_seq=2 ttl=127 time=29.5 ms
+
+--- google.com ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1005ms
+rtt min/avg/max/mdev = 17.295/23.385/29.476/6.090 ms
+
Same as before, you should create another namespace for UERANSIM, called it ueransim2:
+
root@free5gc:~# ip netns ls
+ueransim2 (id: 1)
+ueransim (id: 0)
+
ip link add veth2 type veth peer name br-veth2
+ip link set dev veth2 netns ueransim2
+ip link set br-veth2 master free5gc-br
+ip link set br-veth2 up
+ip netns exec ueransim2 ip a add 10.200.200.3/24 dev veth2
+ip netns exec ueransim2 ip link set lo up
+ip netns exec ueransim2 ip link set veth2 up
+ip netns exec ueransim2 ip route add default via 10.200.200.2
+
Copy UERANSIM/config/free5gc-gnb.yaml and UERANSIM/config/free5gc-ue.yaml to free5gc-gnb2.yaml and free5gc-ue2.yaml, modify:
+free5gc-gnb2.yaml
+127.0.0.1
to 10.200.200.3
127.0.0.1
to 10.200.200.3
...
+ngapIp: 10.200.200.3 # 127.0.0.1 # gNB's local IP address for N2 Interface (Usually same with local IP)
+gtpIp: 10.200.200.3 # 127.0.0.1 # gNB's local IP address for N3 Interface (Usually same with local IP)
+
+# List of AMF address information
+amfConfigs:
+ - address: 10.200.200.2 # 127.0.0.1
+ port: 38412
+...
+
supi
change to imsi-208930000000004
...
+# IMSI number of the UE. IMSI = [MCC|MNC|MSISDN] (In total 15 or 16 digits)
+supi: 'imsi-208930000000004'
+...
+
Note
+Should register ue to webconsole first.
+The result:
+
ueransim> ip a
+1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+ inet 127.0.0.1/8 scope host lo
+ valid_lft forever preferred_lft forever
+ inet6 ::1/128 scope host
+ valid_lft forever preferred_lft forever
+6: veth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
+ link/ether 4a:0f:1e:80:9b:be brd ff:ff:ff:ff:ff:ff link-netnsid 0
+ inet 10.200.200.1/24 scope global veth0
+ valid_lft forever preferred_lft forever
+ inet6 fe80::480f:1eff:fe80:9bbe/64 scope link
+ valid_lft forever preferred_lft forever
+7: uesimtun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
+ link/none
+ inet 10.60.0.1/32 scope global uesimtun0
+ valid_lft forever preferred_lft forever
+ inet6 fe80::f6d7:dd81:fe7f:496a/64 scope link stable-privacy
+ valid_lft forever preferred_lft forever
+ueransim> ping -c2 -I uesimtun0 google.com
+PING google.com (172.217.160.110) from 10.60.0.1 uesimtun0: 56(84) bytes of data.
+64 bytes from tsa03s06-in-f14.1e100.net (172.217.160.110): icmp_seq=1 ttl=127 time=17.2 ms
+64 bytes from tsa03s06-in-f14.1e100.net (172.217.160.110): icmp_seq=2 ttl=127 time=28.5 ms
+
+--- google.com ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1003ms
+rtt min/avg/max/mdev = 17.200/22.863/28.527/5.663 ms
+
ueransim2> ip a
+1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+ inet 127.0.0.1/8 scope host lo
+ valid_lft forever preferred_lft forever
+ inet6 ::1/128 scope host
+ valid_lft forever preferred_lft forever
+5: uesimtun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
+ link/none
+ inet 10.60.0.2/32 scope global uesimtun0
+ valid_lft forever preferred_lft forever
+ inet6 fe80::16a4:523a:a86:bf83/64 scope link stable-privacy
+ valid_lft forever preferred_lft forever
+12: veth2@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
+ link/ether fa:12:bb:9c:fa:40 brd ff:ff:ff:ff:ff:ff link-netnsid 0
+ inet 10.200.200.3/24 scope global veth2
+ valid_lft forever preferred_lft forever
+ inet6 fe80::f812:bbff:fe9c:fa40/64 scope link
+ valid_lft forever preferred_lft forever
+ueransim2> ping -c2 -I uesimtun0 google.com
+PING google.com (172.217.160.110) from 10.60.0.2 uesimtun0: 56(84) bytes of data.
+64 bytes from tsa03s06-in-f14.1e100.net (172.217.160.110): icmp_seq=1 ttl=127 time=18.9 ms
+64 bytes from tsa03s06-in-f14.1e100.net (172.217.160.110): icmp_seq=2 ttl=127 time=15.8 ms
+
+--- google.com ping statistics ---
+2 packets transmitted, 2 received, 0% packet loss, time 1002ms
+rtt min/avg/max/mdev = 15.786/17.353/18.921/1.567 ms
+
Hi, my name is Jimmy Chang. The current research topic is 5G LAN with a focus on the 5G Data Plane. Any questions or errors in the article are welcome for correction. Please feel free to send an email to provide feedback.
+Regarding the theme this time, I briefly introduce OAuth. OAuth 2.0 defines four types of the authorization flow. I choose the Client Credentials Flow to explain because the authentication mechanism in NRF is closely related to the Client Credentials Flow.
+Next, I explain how to apply the concept of the Client Credentials Flow to NRF and introduce Nnrf_AccessToken Service
because Nnrf_AccessToken Service
is closely related to the Client Credentials Flow.
Finally, I make a simple experiment of the authentication mechanism in NRF and share the environment settings and methods of operation.
+I introduce OAuth before explaining the authentication mechanism in NRF. Regarding the OAuth flow, we can log in to the account through the platform before we want to access an application. After logging in, we agree that an application can limitedly obtain the information of the user on the platform. The application can be LinkedIn, YouTube, etc. The platform can be Google, Facebook, etc.
+The full English name of OAuth is Open standard Authorization. OAuth is an open standard, and it used to deal with authorization-related behaviors. OAuth 2.0 defines four types of the authorization flow. The four types of the authorization flow are:
+This article explains the entire authorization of the Client Credentials Flow only, because the authentication mechanism in NRF adopts the Client Credentials.
+++If you're interested how authorization mechanism works, please refer to this article for more details.
+
+
Figure 1. Client Credentials Flow
Referring to the Figure 1, the Client Credentials Flow is mainly composed of:
+The entire authorization of the Client Credentials Flow can be devided into 3 steps:
+In addition, the Client and the Authorization Server have their own Scope list. The Scope list records a series of the actions. The Client or the Authorization Server is permitted to do the actions for obtaining the user’s name, deleting posts, etc.
+I explain how to apply the Client Credentials Flow to NRF after talking about the Client Credentials Flow.
+The Figure 2 and the Figure 3 originate from the Figure 13.4.1.1-1 and the Figure 13.4.1.1-2 of the TS 33.501.
+
+
Figure 2. NF Service Consumer Obtaining Access Token before NF Service Access
The entire flow in Figure 2 is the same as Step 1 and Step 2 in the Figure 1. The role of the Client is played by the NF Service Consumer, and the role of the Authorization Server is played by the NRF.
+First, the NF Service Consumer registers with NRF. Then the NF Service Consumer sends the Nnrf_AccessToken_Get Request
to NRF. The Nnrf_AccessToken_Get Request
includes:
The NF Type can be AMF, SMF, etc. , and the NF Service Name can be namf-comm
, nsmf-pdusession
, etc.
NRF verifies the information provided by the NF Service Consumer after it receives the Nnrf_AccessToken_Get Request
. NRF generates an Access Token and uses the NRF private key to sign on the Access Token after the verification is successful.
Finally, NRF returns the Nnrf_AccessToken_Get Response
to the NF Service Consumer. The NF Service Consumer stores the Access Token within the validity period after it gets the Access Token. The services provided by the NF Service Producer are in the Expected NF Service Name. The NF Service Consumer don’t need to verify again when it wants to use the services provided by the NF Service Producer.
+
Figure 3. NF Service Consumer Requesting Service Access with an Access Token
The entire flow in Figure 3 is the same as Step 3 in the Figure 1. The role of the Client is played by the NF Service Consumer, and the role of the Resource Server is played by the NF Service Producer.
+First, the NF Service Consumer sends the NF Service Request
to the NF Service Producer with the Access Token. Simply put, the NF Service Consumer wants to consume the service provided by the NF Service Producer.
The NF Service Producer use the NRF public key to verify the signed on the Access Token after it receives the NF Service Request
. If the verification is successful, the NF Service Producer will send the NF Service Response
to the NF Service Consumer.
I talk about the Nnrf_AccessToken Service
after explaining how to apply the Client Credentials Flow to NRF.
+
Figure 4. Access Token Request
The Figure 4 originates from the Figure 5.4.2.2.1-1 of the TS 29.510.
+First, the NF Service Consumer sends the POST /oauth2/token
to NRF, and the data is stored in the AccessTokenReq
. The attribute name, the data type, and the formulation rule of the AccessTokenReq
are shown in the Table 1. The Table 1 originates from the Table 6.3.5.2.2-1 of the TS 29.510.
+
Table 1. Definition of Type AccessTokenReq
Definition of type AccessTokenReq
:
grant_type
: The value must be set to the client_credentials, and it is checked in the Snippet 1.nfInstanceId
: The value stores the ID of the NF Service Consumer.targetNfInstanceId
: The value stores the ID of the NF Service Producer.nfType
: The value stores the network function name of the NF Service Consumer. The network function name can be the AMF, SMF, etc. targetNfType
: The value stores the network function name of the NF Service Producer.scope
: It stores the services. The services can be the namf-comm
, nsmf-pdusession
, etc. The NF Service Consumer want to consume the services. The services are provided by the NF Service Producer.requesterPlmn
: It is mainly used in the roaming.targetPlmn
: It is mainly used in the roaming.if reqGrantType != "client_credentials" {
+ return &models.AccessTokenErr{
+ Error: "unsupported_grant_type",
+ }
+}
+
NRF sends AccessTokenRsp
to the NF Service Consumer in the Step 2a of the Figure 4. The attribute name, the data type, and the formulation rule of the AccessTokenRsp
are shown in the Table 2. The Table 2 originates from the Table 6.3.5.2.3-1 of the TS 29.510.
+
Table 2. Definition of Type AccessTokenRsp
The AccessTokenRsp
contains four attribute names. The four attribute names are:
access_token
: It stores all the attribute names and values of the AccessTokenClaims in the Table 3. The Table 3 originates form the Table 6.3.5.2.4-1 of the TS 29.510. token_type
: It must be set to the Bearer and can be seen in the Snippet 2.expires_in
: It stores information related to the expiration date.scope
: The NF Service Consumer and the NF Service Producer have their own scope list. The scope in the AccessTokenRsp
has a series of these services, and the NF Service Producer is permitted to consume these services.
+
Table 3. Definition of Type AccessTokenClaims
Definition of Type AccessTokenClaims
:
iss
: It is called issuer, and the content usually stores the ID of NRF.sub
: It is called subject, and the content stores the ID of the NF Service Consumer.aud
: It is called audience, and the content stores the ID of the NF Service Producer.scope
: The scope in the AccessTokenClaims
has a series of these services, and the NF Service Consumer is authorized by the NF Service Producer and permitted to consume these services.exp
: It stores information related to the validity period.func AccessTokenProcedure(request models.AccessTokenReq) (
+ *models.AccessTokenRsp, *models.AccessTokenErr,
+) {
+ logger.AccTokenLog.Infoln("In AccessTokenProcedure")
+
+ var expiration int32 = 1000
+ scope := request.Scope
+ tokenType := "Bearer"
+ now := int32(time.Now().Unix())
+
+ errResponse := AccessTokenScopeCheck(request)
+ if errResponse != nil {
+ return nil, errResponse
+ }
+
+ // Create AccessToken
+ nrfCtx := nrf_context.GetSelf()
+ accessTokenClaims := models.AccessTokenClaims{
+ Iss: nrfCtx.Nrf_NfInstanceID, // NF instance id of the NRF
+ Sub: request.NfInstanceId, // nfInstanceId of service consumer
+ Aud: request.TargetNfInstanceId, // nfInstanceId of service producer
+ Scope: request.Scope, // TODO: the name of the NF services for which the
+ Exp: now + expiration, // access_token is authorized for use
+ StandardClaims: jwt.StandardClaims{},
+ }
+ accessTokenClaims.IssuedAt = int64(now)
+
+ // Use NRF private key to sign AccessToken
+ token := jwt.NewWithClaims(jwt.GetSigningMethod("RS512"), accessTokenClaims)
+ accessToken, err := token.SignedString(nrfCtx.NrfPrivKey)
+ if err != nil {
+ logger.AccTokenLog.Warnln("Signed string error: ", err)
+ return nil, &models.AccessTokenErr{
+ Error: "invalid_request",
+ }
+ }
+
+ response := &models.AccessTokenRsp{
+ AccessToken: accessToken,
+ TokenType: tokenType,
+ ExpiresIn: expiration,
+ Scope: scope,
+ }
+ return response, nil
+}
+
The Snippet 2 is the AccessTokenProcedure()
function. The function is executed in NRF.
The function mainly processes:
+AccessTokenReq
sent by the NF Service Customer.AccessTokenScopeCheck()
function. The AccessTokenScopeCheck()
function checks whether the content of the attribute name in the AccessTokenReq
complies with the requirements of the TS 29.510. If not, the AccessTokenProcedure()
function immediately returns the AccessTokenErr
to the NF Service Customer.AccessTokenRsp
. The AccessTokenRsp
is sent back to the NF Service Customer. The Iss
in the AccessToken obtains its own ID in NRF. The Sub
and Aud
are obtained from the NfInstancedId
and the TargetNfInstanceId
in the AccessTokenReq
respectively. The Scope
is obtained from the scope
in the AccessTokenReq
. The expiration is set to the 1000 in the Snippet 2. Therefore, the value of the exp
is the current time + 1000.AccessTokenErr
to the NF Service Customer.AccessTokenRsp
. The value of the TokenType
is set to the Bearer by the function. The function sets the ExprieIn
and the Scope
in the Snippet 2.Finally, I make a simple experiment about the Access Token and share the environment setting and method of operation with you.
+The Table 4 is my environment setting. I provide the Table 4 for you. You can refer it.
+
+
Table 4. Environment
You remove the part of the tls
and add the content of the cert
, rootcert
and oauth
under sbi
in the nrfcfg.yaml
before implementing about the Access Token.
info:
+ version: 1.0.2
+ description: NRF initial local configuration
+
+configuration:
+ MongoDBName: free5gc # database name in MongoDB
+ MongoDBUrl: mongodb://127.0.0.1:27017 # a valid URL of the mongodb
+ sbi: # Service-based interface information
+ scheme: http # the protocol for sbi (http or https)
+ registerIPv4: 127.0.0.10 # IP used to serve NFs or register to another NRF
+ bindingIPv4: 127.0.0.10 # IP used to bind the service
+ port: 8000 # port used to bind the service
+ cert:
+ pem: cert/nrf.pem
+ key: cert/nrf.key
+ rootcert:
+ pem: cert/nrf.pem
+ key: cert/nrf.key
+ oauth: true
+ DefaultPlmnId:
+ mcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)
+ mnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)
+ serviceNameList: # the SBI services provided by this NRF, refer to TS 29.510
+ - nnrf-nfm # Nnrf_NFManagement service
+ - nnrf-disc # Nnrf_NFDiscovery service
+
+logger: # log output setting
+ enable: true # true or false
+ level: info # how detailed to output, value: trace, debug, info, warn, error, fatal, panic
+ reportCaller: false # enable the caller report or not, value: true or false
+
You find the http://127.0.0.10:8000/nnrf-nfm/v1/nf-instances/8f7891b4-b127-4f59-9ec2-b5e6aade5531
in the NRF log, and you get the 8f7891b4-b127-4f59-9ec2-b5e6aade5531
. The 8f7891b4-b127-4f59-9ec2-b5e6aade5531
is the nfInstanceID
.
2023-08-02T20:07:43.300826205Z [INFO][NRF][NFM] Handle NFRegisterRequest
+2023-08-02T20:07:43.308259291Z [INFO][NRF][NFM] urilist create
+2023-08-02T20:07:43.311674255Z [INFO][NRF][NFM] Create NF Profile
+2023-08-02T20:07:43.318192771Z [INFO][NRF][NFM] Location header: http://127.0.0.10:8000/nnrf-nfm/v1/nf-instances/8f7891b4-b127-4f59-9ec2-b5e6aade5531
+2023-08-02T20:07:43.325073275Z [INFO][NRF][GIN] | 201 | 127.0.0.1 | PUT | /nnrf-nfm/v1/nf-instances/8f7891b4-b127-4f59-9ec2-b5e6aade5531 |
+
You execute $curl -X GET {apiRoot}/nnrf-nfm/v1/nf-instances/{nfInstanceID}
, and you obtain the detail information about the nfInstanceID
. You can see the nfType
of the nfInstanceID
is NSSF, and the information about the nfInstanceID
is used when you implement the Access Token.
ubuntu@free5GC:~/free5gc/NFs/nrf$ curl -X GET http://127.0.0.10:8000/nnrf-nfm/v1/nf-instances/8f7891b4-b127-4f59-9ec2-b5e6aade5531
+{"ipv4Addresses":["127.0.0.31"],"nfInstanceId":"8f7891b4-b127-4f59-9ec2-b5e6aade5531","nfServices":[{"apiPrefix":"http://127.0.0.31:8000","ipEndPoints":[{"ipv4Address":"127.0.0.31","port":8000,"transport":"TCP"}],"nfServiceStatus":"REGISTERED","scheme":"http","serviceInstanceId":"0","serviceName":"nnssf-nsselection","versions":[{"apiFullVersion":"1.0.2","apiVersionInUri":"v1"}]},{"apiPrefix":"http://127.0.0.31:8000","ipEndPoints":[{"ipv4Address":"127.0.0.31","port":8000,"transport":"TCP"}],"nfServiceStatus":"REGISTERED","scheme":"http","serviceInstanceId":"1","serviceName":"nnssf-nssaiavailability","versions":[{"apiFullVersion":"1.0.2","apiVersionInUri":"v1"}]}],"nfStatus":"REGISTERED","nfType":"NSSF","plmnList":[{"mcc":"208","mnc":"93"}]}
+
Then you execute this command, see below.
+
$curl -X POST -H "Content-Type: application/json" -d '{"nfInstanceId": {nfInstanceID}, "grant_type": "client_credentials", "nfType": {nfType}, "targetNfType": "UDR", "scope": "nudr-dr"}' {apiRoot}/oauth2/token
+
AccessTokenRsp
.
+ubuntu@free5GC:~/free5gc/NFs/nrf$ curl -X POST -H "Content-Type: application/json" -d '{"nfInstanceId": "8f7891b4-b127-4f59-9ec2-b5e6aade5531", "grant_type": "client_credentials", "nfType": "NSSF", "targetNfType": "UDR", "scope": "nudr-dr"}' http://127.0.0.10:8000/oauth2/token
+"eyJhY2Nlc3NfdG9rZW4iOiJleUpoYkdjaU9pSlNVelV4TWlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKcGMzTWlPaUlpTENKemRXSWlPaUk0WmpjNE9URmlOQzFpTVRJM0xUUm1OVGt0T1dWak1pMWlOV1UyWVdGa1pUVTFNekVpTENKaGRXUWlPaUlpTENKelkyOXdaU0k2SW01MVpISXRaSElpTENKbGVIQWlPakUyT1RFd01EZzBPRGdzSW1saGRDSTZNVFk1TVRBd056UTRPSDAuY3VHSkkwTndfV280S2lQbS1fZEZVdnVTQWM1WVEwMmRKYk5PTUhmMV9IOHdIZ2JKWFhUam9xU1Y2OTNYSmFKemkweGIxdC1DMW14TWhVZkZjbXpNMC1Nd2oxTXZYaWhyTTktdDFRUFItSFcxQlBlN0tHMUxBV3d5MEJfcXpIalltRlR6eGhONVlyNkpURDhBbkMxaFJFeEh4WHBjV1NqbV9vZnV0NVhfUFRFRkZtaHZrbmtVbU8waWFrTmdRWElRVTc1NnlvZ29ZTlFDRnJvSmRWamJMdnpFdkJLYTVFN0hQeXc3RkRDRHpTZU5WT2t2WTlobU11eldYZ3dOVmRIT3c1c2lNbmppbTlmTVZ0RTFxS1hjWDlScXlUdXlsWjM2ZlJ1QjdVZ2hkLU15Q19xd2VJRE41ZFdYOWZqdnA3VUNZZ01mVHhSLUI2M3d5OWFjQ183eThRIiwidG9rZW5fdHlwZSI6IkJlYXJlciIsImV4cGlyZXNfaW4iOjEwMDAsInNjb3BlIjoibnVkci1kciJ9"
+
NSSF sends the AccessTokenReq
to NRF after you execute the above command. In the AccessTokenReq
, the nfInstanceId
is set to 8f7891b4-b127-4f59-9ec2-b5e6aade5531
. The grant_type
is set to the client_credentials. The nfType
is set to NSSF. The targetNfType
is set to UDR. The scope
is set to nudr-dr
. The information is shown in the NRF log. The value of the targetNfInstanceId
, requesterPlmn
, and targetPlmn
is empty because they are not set.
2023-08-02T20:18:08.127557565Z [INFO][NRF][Token] In AccessTokenProcedure
+2023-08-02T20:18:08.127586736Z [INFO][NRF][Token] Access Token Request
+2023-08-02T20:18:08.127611885Z [INFO][NRF][Token] Grant Type: client_credentials
+2023-08-02T20:18:08.127637480Z [INFO][NRF][Token] NF Instance ID: 8f7891b4-b127-4f59-9ec2-b5e6aade5531
+2023-08-02T20:18:08.127664415Z [INFO][NRF][Token] Target NF Instance ID:
+2023-08-02T20:18:08.127689792Z [INFO][NRF][Token] NF Type: NSSF
+2023-08-02T20:18:08.127712916Z [INFO][NRF][Token] Target NF Type: UDR
+2023-08-02T20:18:08.127734827Z [INFO][NRF][Token] Scope: nudr-dr
+2023-08-02T20:18:08.127758317Z [INFO][NRF][Token] Requester PLMN: <nil>
+2023-08-02T20:18:08.127781052Z [INFO][NRF][Token] Target PLMN: <nil>
+
Next, you can see the Access Token in the NRF log. The value of the Sub
is 8f7891b4-b127-4f59-9ec2-b5e6aade5531
. The Sub
represents NSSF, and NSSF belongs to the NF Service Customer. The value of the Scope
is the nudr-dr
. The value of the Exp
is 1691008488.
2023-08-02T20:18:08.134096785Z [INFO][NRF][Token] Access Token Claims
+2023-08-02T20:18:08.138100978Z [INFO][NRF][Token] Iss:
+2023-08-02T20:18:08.138185972Z [INFO][NRF][Token] Sub: 8f7891b4-b127-4f59-9ec2-b5e6aade5531
+2023-08-02T20:18:08.138228925Z [INFO][NRF][Token] Aud:
+2023-08-02T20:18:08.138264519Z [INFO][NRF][Token] Scope: nudr-dr
+2023-08-02T20:18:08.138298628Z [INFO][NRF][Token] Exp: 1691008488
+
Next, you can see the AccessTokenRsp
. You can see that the Access Token has become the long symbols. The value of the Token Type
is set to the Bearer. The value of the ExpiresIn
is set to 1000. The value of the Scope
is set to nudr-dr
.
2023-08-02T20:18:08.149587382Z [INFO][NRF][Token] Access Token Response
+2023-08-02T20:18:08.150006665Z [INFO][NRF][Token] Access Token: eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIiLCJzdWIiOiI4Zjc4OTFiNC1iMTI3LTRmNTktOWVjMi1iNWU2YWFkZTU1MzEiLCJhdWQiOiIiLCJzY29wZSI6Im51ZHItZHIiLCJleHAiOjE2OTEwMDg0ODgsImlhdCI6MTY5MTAwNzQ4OH0.cuGJI0Nw_Wo4KiPm-_dFUvuSAc5YQ02dJbNOMHf1_H8wHgbJXXTjoqSV693XJaJzi0xb1t-C1mxMhUfFcmzM0-Mwj1MvXihrM9-t1QPR-HW1BPe7KG1LAWwy0B_qzHjYmFTzxhN5Yr6JTD8AnC1hRExHxXpcWSjm_ofut5X_PTEFFmhvknkUmO0iakNgQXIQU756yogoYNQCFroJdVjbLvzEvBKa5E7HPyw7FDCDzSeNVOkvY9hmMuzWXgwNVdHOw5siMnjim9fMVtE1qKXcX9RqyTuylZ36fRuB7Ughd-MyC_qweIDN5dWX9fjvp7UCYgMfTxR-B63wy9acC_7y8Q
+2023-08-02T20:18:08.150094277Z [INFO][NRF][Token] Token Type: Bearer
+2023-08-02T20:18:08.150133189Z [INFO][NRF][Token] Expires In: 1000
+2023-08-02T20:18:08.150167371Z [INFO][NRF][Token] Scope: nudr-dr
+
Finally, you can see 200. 200 means that AUSF sends the AccessTokenReq
to NRF. NRF successfully sends to AUSF after verification.
2023-08-02T20:18:08.150302345Z [INFO][NRF][GIN] | 200 | 127.0.0.1 | POST | /oauth2/token |
+
Note
+Author: Ya-shih Tseng
+Date: 2023/7/12
This blog focuses on the role of the 5G system in 3GPP Release 16 TSN (Time-Sensitive Networking).
+Traditional Ethernet technology can only achieve "best-effort" communication and cannot meet the high reliability and low latency requirements of industrial manufacturing applications.
+Therefore, in the context of industrial automation, there is a need to upgrade the traditional "best-effort" Ethernet to provide "deterministic" services.
Time Sensitive Networking (TSN) brings determinism and real-time communication to standard Ethernet through mechanisms and protocols defined by the IEEE 802.1 standard, which is used by Audio Video Bridging (AVB) and TSN. It offers reliable message delivery, minimized jitter, and guaranteed delivery through central management, time scheduling, and other key features. The introduction of TSN technology holds great potential and benefits for real-time applications in industrial control, automation, and other fields.
+
+ ++
There are a lot of standards that TSN task group has completed or ongoing projects. Here are some base standards.
+Standard | +Title | +
---|---|
IEEE 1588 V2 | +Precision Clock Synchronization Protocol for Networked Measurement and Control Systems | +
IEEE 802.1Q-2022 | +Bridges and Bridged Networks | +
IEEE 802.1AB-2016 | +Station and Media Access Control Connectivity Discovery (specifies the Link Layer Discovery Protocol (LLDP)) | +
IEEE 802.1AS-2020 | +Timing and Synchronization for Time-Sensitive Applications | +
IEEE 802.1AX-2020 | +Link Aggregation | +
IEEE 802.1CB-2017 | +Frame Replication and Elimination for Reliability | +
IEEE 802.1CS-2020 | +Link-local Registration Protocol | +
With the increasing demands for wireless control in applications such as industrial automation, remote surgical operations, smart grid distribution automation, transportation safety, autonomous driving, and more, there is a growing need to meet the low-latency requirements of these applications while achieving management, scheduling, and traffic planning. Time synchronization becomes a critical aspect. The following will explain how the interaction between TSN and 5G systems enables time synchronization.
+To achieve time synchronization between TSN and 5G systems, TSN utilizes the time synchronization method defined in IEEE 802.1AS, which is the generalized Precision Time Protocol (gPTP). gPTP supports time synchronization for Time-aware end stations and Time-aware Bridges in Layer 2. In the 3GPP TS23.501 release 16 specification, the 5G system plays the role of a "Time-aware system" as defined in IEEE 802.1AS and is designated as a Logical bridge, connecting TSN system end stations.
+Note
+gPTP is an extended version of PTP (Precision Time Protocol) that primarily expands support for second-layer network devices.
+How can we synchronize the time of two end stations into the same time domain?
+First, the time synchronization architecture includes Master clocks and Slave clocks. The Master regularly sends sync messages to allow the Slave to obtain the Master's time. The Slave, in turn, periodically sends peer delay requests to exchange messages with the Master, obtaining the delay time between the two devices for time correction. Additionally, the resident time, which is the message propagation delay introduced by bridges, should also be taken into account. By considering all these factors, the time synchronization of both sides can be achieved within the TSN time domain.
+
+ ++
Check the link for more detail about how PTP works.
+By now, I believe you have gained an understanding of the time synchronization mechanism in TSN. Let's briefly explain how the 5G system supports TSN as a logical TSN bridge.
+The 3GPP has defined new functionalities such as NW-TT, DS-TT, and TSN-AF, as well as TSN control nodes like CUC and CNC. Please check TS 23.501 Release 16 for more details.
+
++System architecture of 5G support TSN
+
To archive the intergration, 5G system should support ingress port and egress port pair via an Ethernet Type PDU session between the corresponding UE and UPF. As mentioned above, gPTP supports layer 2 (Ethernet) only.
+In the 5G system, DS-TT (Device-side TSN translator) and NW-TT (Network-side TSN translator) serve as TSN translators. DS-TT is responsible for connecting TSN Slave endpoints with the UE, while NW-TT connects TSN Master endpoints with the UPF.
+When the sync message generated by the Master clock reaches the bridge, NW-TT captures its Ingress Timestamp and measures the delay between NW-TT and the Master clock. These timestamps are then embedded within the sync message and transmitted to the UE. Once the UE receives the sync message, DS-TT calculates the resident time by subtracting the Ingress Timestamp provided in the sync message, from the Egress Timestamp which represents the time of sync message reception. The resident time is added to the delay time mentioned in the sync message to determine the corrected time. Through the assistance of the TSN translators, the Slave endpoint receives the message and obtains information about time deviation and other relevant data for further adjustment.
+Note
+DS-TT and NW-TT enable the 5G system to function as a virtual bridge. The bridge is also called "Transparent clock" which is definded in IEEE 1588 and required in IEEE 802.1AS. You can say that Master and Slaver don't know the exist of the 5G TSN bridge, since it's logical transparent.
+"Transparent clocks are used to route timing messages within a network. Used when: Ethernet timing must pass through switches." - different type of clocks
+With TSN-AF, CNC can manage the 5G system functioning as a logical bridge and achieve the integration of the 5G TSN bridge with the TSN network in collaboration with NW-TT and DS-TT. Additionally, TSN-AF gathers information and capability lists of the 5G TSN Bridge and transmits them to CNC.
+To meet the requirements of application services and control TSN, there are two key functions utilized in the TSN system.
+CNC (Centralized Network Controller), as the central controller in the TSN system, receives the information from CUC (Centralized User Configuration) and performs scheduling and planning tasks. It calculates the optimal transmission schedule for the TSN traffic based on factors such as bandwidth requirements, latency constraints, and network conditions. Once the transmission schedule is computed and confirmed, CNC proceeds to deploy the necessary network resource configuration on the TSN switches. This ensures that the TSN network operates efficiently and effectively in delivering the required QoS (Quality of Service) for the application services.
Hi, This is Ya-shih Tseng. I am currently researching the implementation of 5G TSN (Time-Sensitive Networking) as part of my master's studies. In the future, I will introduce more information about TSN. Hope you enjoy it.
+ + + + + + +Note
+Author: 張哲睿
+Date: 2023/7/19
In this article, I will introduce UDM and its three services that will be used in the general UE registration procedure (Nudm_UECM service, Nudm_SubscriberDataManagement Service, and Nudm_UEAuthentication service) to let everyone understand UDM more clearly.
+Unified Data Management is responsible for managing information related to UE. When other NFs need to use the UE subscription information, they will obtain it from UDM through the SBI of UDM.
+This service is used by AUSF to retrieve authentication-related information and, after authentication, confirm the result.
+ ++ ++
In Authentication, AUSF uses the GET operation to retrieve authentication information for the UE. The request contains the UE’s identity (supi or suci) and the serving network name. The serving network name is used in the derivation of the anchor key, which is used by subsensual authentication. UE’s identity will be contained in the URI, and the serving network name will be contained in the request body.
+Upon reception of the Nudm_UEAuthentication_Get Request, the UDM shall de-conceal SUCI to gain SUPI if SUCI is received. At this time, UDM will query the authentication subscription data from UDR. Then, UDM shall select the authentication method based on SUPI, and if required (e.g., 5G-AKA), UDM will calculate the authentication vector and pass it to AUSF.
+logger.UeauLog.Traceln("In GenerateAuthDataProcedure")
+
+response = &models.AuthenticationInfoResult{}
+rand.Seed(time.Now().UnixNano())
+supi, err := suci.ToSupi(supiOrSuci, udm_context.Getself().SuciProfiles)
+if err != nil {
+ problemDetails = &models.ProblemDetails{
+ Status: http.StatusForbidden,
+ Cause: authenticationRejected,
+ Detail: err.Error(),
+ }
+
+ logger.UeauLog.Errorln("suciToSupi error: ", err.Error())
+ return nil, problemDetails
+}
+
+logger.UeauLog.Tracef("supi conversion => [%s]", supi)
+
+client, err := createUDMClientToUDR(supi)
+if err != nil {
+ return nil, openapi.ProblemDetailsSystemFailure(err.Error())
+}
+authSubs, res, err := client.AuthenticationDataDocumentApi.QueryAuthSubsData(context.Background(), supi, nil)
+
+//in the udm/internal/sbi/producer/generate_auth_data.go, GenerateAuthDataProcedure function.
+
From the code, we can see UDM first de-conceal SUCI (line 5), then use QueryAuthSubsData to get authSub from UDR. After that, UDM uses this information to create the authentication vector.
+Then we record the packet sent in the registration process and find the packet according to the URI specified by the specification. We can find the packet corresponding to this service.
+ +Open the response packet, and we can see the response body matches the AuthenticationInfoResult data type.
+ + ++ ++
After AUSF authenticates the UE, it will confirm the result with UDM. These details will be used in linking authentication confirmation to the Nudm_UECM_Registration procedure from AMF.
+func communicateWithUDM(ue *context.AmfUe, accessType models.AccessType) error {
+ ue.GmmLog.Debugln("communicateWithUDM")
+ amfSelf := context.GetSelf()
+
+ // UDM selection described in TS 23.501 6.3.8
+ // TODO: consider udm group id, Routing ID part of SUCI, GPSI or External Group ID (e.g., by the NEF)
+ param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{
+ Supi: optional.NewString(ue.Supi),
+ }
+ resp, err := consumer.SendSearchNFInstances(amfSelf.NrfUri, models.NfType_UDM, models.NfType_AMF, ¶m)
+ if err != nil {
+ return errors.Errorf("AMF can not select an UDM by NRF: SendSearchNFInstances failed")
+ }
+
+ var uecmUri, sdmUri string
+ for _, nfProfile := range resp.NfInstances {
+ ue.UdmId = nfProfile.NfInstanceId
+ uecmUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NUDM_UECM, models.NfServiceStatus_REGISTERED)
+ sdmUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NUDM_SDM, models.NfServiceStatus_REGISTERED)
+ if uecmUri != "" && sdmUri != "" {
+ break
+ }
+ }
+ ue.NudmUECMUri = uecmUri
+ ue.NudmSDMUri = sdmUri
+ if ue.NudmUECMUri == "" || ue.NudmSDMUri == "" {
+ return errors.Errorf("AMF can not select an UDM by NRF: SearchNFServiceUri failed")
+ }
+
+ problemDetails, err := consumer.UeCmRegistration(ue, accessType, true)
+ if problemDetails != nil {
+ return errors.Errorf(problemDetails.Cause)
+ } else if err != nil {
+ return errors.Wrap(err, "UECM_Registration Error")
+ }
+
+ // TS 23.502 4.2.2.2.1 14a-c.
+ // "After a successful response is received, the AMF subscribes to be notified
+ // using Nudm_SDM_Subscribe when the data requested is modified"
+ problemDetails, err = consumer.SDMGetAmData(ue)
+ if problemDetails != nil {
+ return errors.Errorf(problemDetails.Cause)
+ } else if err != nil {
+ return errors.Wrap(err, "SDM_Get AmData Error")
+ }
+
+ problemDetails, err = consumer.SDMGetSmfSelectData(ue)
+ if problemDetails != nil {
+ return errors.Errorf(problemDetails.Cause)
+ } else if err != nil {
+ return errors.Wrap(err, "SDM_Get SmfSelectData Error")
+ }
+
+ problemDetails, err = consumer.SDMGetUeContextInSmfData(ue)
+ if problemDetails != nil {
+ return errors.Errorf(problemDetails.Cause)
+ } else if err != nil {
+ return errors.Wrap(err, "SDM_Get UeContextInSmfData Error")
+ }
+
+ problemDetails, err = consumer.SDMSubscribe(ue)
+ if problemDetails != nil {
+ return errors.Errorf(problemDetails.Cause)
+ } else if err != nil {
+ return errors.Wrap(err, "SDM Subscribe Error")
+ }
+ ue.ContextValid = true
+ return nil
+}
+
+
+//in the amf/internal/gmm/handler.go.
+
Next, let's take a look at this function. It is called in HandleInitialRegistration, which handles UE's initial registration. UeCmRegistration will use the Nudm_UECM (UECM) service to store related UE Context Management information in UDM. In lines 40, 47, and 54, AMF uses the Nudm_SubscriberDataManagement (SDM) Service to get some subscribe data.
+In the UeCmRegistration function, AMF registers as UE's serving NF on UDM and stores related UE Context Management information in UDM. Looking at the packet, you can see that the request body contains amfInstanceId
and guami
, representing the amf identity, and ratType
, representing the radio access technology type used by UE.
// TS 29.503 5.3.2.2.2
+func RegistrationAmf3gppAccessProcedure(registerRequest models.Amf3GppAccessRegistration, ueID string) (
+ header http.Header, response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails,
+) {
+ // TODO: EPS interworking with N26 is not supported yet in this stage
+ var oldAmf3GppAccessRegContext *models.Amf3GppAccessRegistration
+ if udm_context.Getself().UdmAmf3gppRegContextExists(ueID) {
+ ue, _ := udm_context.Getself().UdmUeFindBySupi(ueID)
+ oldAmf3GppAccessRegContext = ue.Amf3GppAccessRegistration
+ }
+
+ udm_context.Getself().CreateAmf3gppRegContext(ueID, registerRequest)
+
+ clientAPI, err := createUDMClientToUDR(ueID)
+ if err != nil {
+ return nil, nil, openapi.ProblemDetailsSystemFailure(err.Error())
+ }
+
+ var createAmfContext3gppParamOpts Nudr_DataRepository.CreateAmfContext3gppParamOpts
+ optInterface := optional.NewInterface(registerRequest)
+ createAmfContext3gppParamOpts.Amf3GppAccessRegistration = optInterface
+ resp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi.CreateAmfContext3gpp(context.Background(),
+ ueID, &createAmfContext3gppParamOpts)
+ if err != nil {
+ logger.UecmLog.Errorln("CreateAmfContext3gpp error : ", err)
+ problemDetails = &models.ProblemDetails{
+ Status: int32(resp.StatusCode),
+ Cause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause,
+ Detail: err.Error(),
+ }
+ return nil, nil, problemDetails
+ }
+ defer func() {
+ if rspCloseErr := resp.Body.Close(); rspCloseErr != nil {
+ logger.UecmLog.Errorf("CreateAmfContext3gpp response body cannot close: %+v", rspCloseErr)
+ }
+ }()
+
+ // TS 23.502 4.2.2.2.2 14d: UDM initiate a Nudm_UECM_DeregistrationNotification to the old AMF
+ // corresponding to the same (e.g. 3GPP) access, if one exists
+ if oldAmf3GppAccessRegContext != nil {
+ deregistData := models.DeregistrationData{
+ DeregReason: models.DeregistrationReason_SUBSCRIPTION_WITHDRAWN,
+ AccessType: models.AccessType__3_GPP_ACCESS,
+ }
+ callback.SendOnDeregistrationNotification(ueID, oldAmf3GppAccessRegContext.DeregCallbackUri,
+ deregistData) // Deregistration Notify Triggered
+
+ return nil, nil, nil
+ } else {
+ header = make(http.Header)
+ udmUe, _ := udm_context.Getself().UdmUeFindBySupi(ueID)
+ header.Set("Location", udmUe.GetLocationURI(udm_context.LocationUriAmf3GppAccessRegistration))
+ return header, ®isterRequest, nil
+ }
+}
+
+//in the udm/internal/sbi/producer/ue_context_management.go
+
In the RegistrationAmf3gppAccessProcedure function, UDM first checks whether the context has been established for that UE; if UDM has such a context, it initiates a Nudm_UECM_DeregistrationNotification to the old AMF later. UDM used the received information to create context and stored it in UDR.
+The SDM service is used to retrieve the UE's individual subscription data relevant to the consumer's NF from the UDM. In the SDMGetAmData function, AMF gets subscription data used in registration and mobility management. In the response packet, AMF got gpsis
, subscribedUeAmbr
, and nssai
.
The GPSI (Generic Public Subscription Identifier) is used to address a 3GPP subscription in data networks outside the realms of a 3GPP system. It contains either an External ID or an MSISDN (Mobile Subscriber ISDN Number).The subscribedUeAmbr
is The Maximum Aggregated uplink and downlink MBRs (max. bit rate) to be shared across all Non-GBR (non-guaranteed Bit Rate) QoS Flows according to the subscription of the user.
In the SDMGetSmfSelectData function, AMF gets subscribed S-NSSAIs (Single Network Slice Selection Assistance Information) and Data Network Names for these S-NSSAIs. AMF will use this information to select an SMF that manages the PDU Session.
+func HandleInitialRegistration(ue *context.AmfUe, anType models.AccessType) error {
+ ue.GmmLog.Infoln("Handle InitialRegistration")
+
+ amfSelf := context.GetSelf()
+
+ // update Kgnb/Kn3iwf
+ ue.UpdateSecurityContext(anType)
+
+ // Registration with AMF re-allocation (TS 23.502 4.2.2.2.3)
+ if len(ue.SubscribedNssai) == 0 {
+ getSubscribedNssai(ue)
+ }
+
+ if err := handleRequestedNssai(ue, anType); err != nil {
+ return err
+ }
+
+//in the amf/internal/gmm/handler.go.
+
In the initialization of HandleInitialRegistration, AMF sends a request to the UDM to receive the UE's NSSAI (Network Slice Selection Assistance Information). After receiving subscribed NSSAI, AMF will compare it to UE's requested NSSAI. If there is a S-NSSAI that has not been subscribed before, AMF will request NSSF for Allowed NSSAI.
+func handleRequestedNssai(ue *context.AmfUe, anType models.AccessType) error {
+ amfSelf := context.GetSelf()
+
+ if ue.RegistrationRequest.RequestedNSSAI != nil {
+ requestedNssai, err := nasConvert.RequestedNssaiToModels(ue.RegistrationRequest.RequestedNSSAI)
+ if err != nil {
+ return fmt.Errorf("Decode failed at RequestedNSSAI[%s]", err)
+ }
+
+ needSliceSelection := false
+ for _, requestedSnssai := range requestedNssai {
+ ue.GmmLog.Infof("RequestedNssai - ServingSnssai: %+v, HomeSnssai: %+v",
+ requestedSnssai.ServingSnssai, requestedSnssai.HomeSnssai)
+ if ue.InSubscribedNssai(*requestedSnssai.ServingSnssai) {
+ allowedSnssai := models.AllowedSnssai{
+ AllowedSnssai: &models.Snssai{
+ Sst: requestedSnssai.ServingSnssai.Sst,
+ Sd: requestedSnssai.ServingSnssai.Sd,
+ },
+ MappedHomeSnssai: requestedSnssai.HomeSnssai,
+ }
+ if !ue.InAllowedNssai(*allowedSnssai.AllowedSnssai, anType) {
+ ue.AllowedNssai[anType] = append(ue.AllowedNssai[anType], allowedSnssai)
+ }
+ } else {
+ needSliceSelection = true
+ break
+ }
+ }
+
+ if needSliceSelection {
+ if ue.NssfUri == "" {
+ for {
+ err := consumer.SearchNssfNSSelectionInstance(ue, amfSelf.NrfUri, models.NfType_NSSF, models.NfType_AMF, nil)
+ if err != nil {
+ ue.GmmLog.Errorf("AMF can not select an NSSF Instance by NRF[Error: %+v]", err)
+ time.Sleep(2 * time.Second)
+ } else {
+ break
+ }
+ }
+ }
+
+ // Step 4
+ problemDetails, err := consumer.NSSelectionGetForRegistration(ue, requestedNssai)
+ if problemDetails != nil {
+ ue.GmmLog.Errorf("NSSelection Get Failed Problem[%+v]", problemDetails)
+ gmm_message.SendRegistrationReject(ue.RanUe[anType], nasMessage.Cause5GMMProtocolErrorUnspecified, "")
+ return fmt.Errorf("Handle Requested Nssai of UE failed")
+ } else if err != nil {
+ ue.GmmLog.Errorf("NSSelection Get Error[%+v]", err)
+ gmm_message.SendRegistrationReject(ue.RanUe[anType], nasMessage.Cause5GMMProtocolErrorUnspecified, "")
+ return fmt.Errorf("Handle Requested Nssai of UE failed")
+ }
+
+//in the amf/internal/gmm/handler.go.
+
if param.SliceInfoRequestForRegistration.RequestedNssai != nil &&
+ len(param.SliceInfoRequestForRegistration.RequestedNssai) != 0 {
+ // Requested NSSAI is provided
+ // Verify which S-NSSAI(s) in the Requested NSSAI are permitted based on comparing the Subscribed S-NSSAI(s)
+ if param.Tai != nil &&
+ !util.CheckSupportedNssaiInPlmn(param.SliceInfoRequestForRegistration.RequestedNssai, *param.Tai.PlmnId) {
+ // Return ProblemDetails indicating S-NSSAI is not supported
+ // TODO: Based on TS 23.501 V15.2.0, if the Requested NSSAI includes an S-NSSAI that is not valid in the
+ // Serving PLMN, the NSSF may derive the Configured NSSAI for Serving PLMN
+ *problemDetails = models.ProblemDetails{
+ Title: util.UNSUPPORTED_RESOURCE,
+ Status: http.StatusForbidden,
+ Detail: "S-NSSAI in Requested NSSAI is not supported in PLMN",
+ Cause: "SNSSAI_NOT_SUPPORTED",
+ }
+
+ status = http.StatusForbidden
+ return status
+ }
+
+ // Check if any Requested S-NSSAIs is present in Subscribed S-NSSAIs
+ checkIfRequestAllowed := false
+
+ for _, requestedSnssai := range param.SliceInfoRequestForRegistration.RequestedNssai {
+ if param.Tai != nil && !util.CheckSupportedSnssaiInTa(requestedSnssai, *param.Tai) {
+ // Requested S-NSSAI does not supported in UE's current TA
+ // Add it to Rejected NSSAI in TA
+ authorizedNetworkSliceInfo.RejectedNssaiInTa = append(
+ authorizedNetworkSliceInfo.RejectedNssaiInTa,
+ requestedSnssai)
+ continue
+ }
+
+ var mappingOfRequestedSnssai models.Snssai
+ // TODO: Compared with Restricted S-NSSAI list in configuration under roaming scenario
+ if param.HomePlmnId != nil && !util.CheckStandardSnssai(requestedSnssai) {
+ // Standard S-NSSAIs are supported to be commonly decided by all roaming partners
+ // Only non-standard S-NSSAIs are required to find mappings
+ targetMapping, found := util.FindMappingWithServingSnssai(requestedSnssai,
+ param.SliceInfoRequestForRegistration.MappingOfNssai)
+
+ if !found {
+ // No mapping of Requested S-NSSAI to HPLMN S-NSSAI is provided by UE
+ // TODO: Search for local configuration if there is no provided mapping from UE, and update UE's
+ // Configured NSSAI
+ checkInvalidRequestedNssai = true
+ authorizedNetworkSliceInfo.RejectedNssaiInPlmn = append(
+ authorizedNetworkSliceInfo.RejectedNssaiInPlmn,
+ requestedSnssai)
+ continue
+ } else {
+ // TODO: Check if mappings of S-NSSAIs are correct
+ // If not, update UE's Configured NSSAI
+ mappingOfRequestedSnssai = *targetMapping.HomeSnssai
+ }
+ } else {
+ mappingOfRequestedSnssai = requestedSnssai
+ }
+
+ hitSubscription := false
+ for _, subscribedSnssai := range param.SliceInfoRequestForRegistration.SubscribedNssai {
+ if mappingOfRequestedSnssai == *subscribedSnssai.SubscribedSnssai {
+ // Requested S-NSSAI matches one of Subscribed S-NSSAI
+ // Add it to Allowed NSSAI list
+ hitSubscription = true
+
+ var allowedSnssaiElement models.AllowedSnssai
+ allowedSnssaiElement.AllowedSnssai = new(models.Snssai)
+ *allowedSnssaiElement.AllowedSnssai = requestedSnssai
+ nsiInformationList := util.GetNsiInformationListFromConfig(requestedSnssai)
+ if nsiInformationList != nil {
+ // TODO: `NsiInformationList` should be slice in `AllowedSnssai` instead of pointer of slice
+ allowedSnssaiElement.NsiInformationList = append(
+ allowedSnssaiElement.NsiInformationList,
+ nsiInformationList...)
+ }
+ if param.HomePlmnId != nil && !util.CheckStandardSnssai(requestedSnssai) {
+ allowedSnssaiElement.MappedHomeSnssai = new(models.Snssai)
+ *allowedSnssaiElement.MappedHomeSnssai = *subscribedSnssai.SubscribedSnssai
+ }
+
+ // Default Access Type is set to 3GPP Access if no TAI is provided
+ // TODO: Depend on operator implementation, it may also return S-NSSAIs in all valid Access Type if
+ // UE's Access Type could not be identified
+ var accessType models.AccessType = models.AccessType__3_GPP_ACCESS
+ if param.Tai != nil {
+ accessType = util.GetAccessTypeFromConfig(*param.Tai)
+ }
+
+ util.AddAllowedSnssai(allowedSnssaiElement, accessType, authorizedNetworkSliceInfo)
+
+ checkIfRequestAllowed = true
+ break
+ }
+ }
+
+ if !hitSubscription {
+ // Requested S-NSSAI does not match any Subscribed S-NSSAI
+ // Add it to Rejected NSSAI in PLMN
+ checkInvalidRequestedNssai = true
+ authorizedNetworkSliceInfo.RejectedNssaiInPlmn = append(
+ authorizedNetworkSliceInfo.RejectedNssaiInPlmn,
+ requestedSnssai)
+ }
+ }
+
+ if !checkIfRequestAllowed {
+ // No S-NSSAI from Requested NSSAI is present in Subscribed S-NSSAIs
+ // Subscribed S-NSSAIs marked as default are used
+ useDefaultSubscribedSnssai(param, authorizedNetworkSliceInfo)
+ }
+} else {
+ // No Requested NSSAI is provided
+ // Subscribed S-NSSAIs marked as default are used
+ checkInvalidRequestedNssai = true
+ useDefaultSubscribedSnssai(param, authorizedNetworkSliceInfo)
+}
+
+//in the nssf/internal/sbi/producer/nsselection_for_registration.go, nsselectionForRegistration funcion.
+
If NSSF needs to select S-NSSAI, it first finds the mapping of requested NSSAI to configured NSSAI for the HPLMN and converts requested S-NSSAI to S-NSSAI in configured NSSAI for the HPLMN. Then compare these S-NSSAIs with Subscribed S-NSSAIs; if NSSF find one match, set it as AllowedSnssai
. If NSSF can't find such a mapping or no S-NSSAI in the mapping matches subscribed S-NSSAIs, it will use default subscribed S-NSSAIs.
Hello! My name is 張哲睿, and my current research topic is ATSSS (Access Traffic Steering, Switching and Splitting), I will continue to write articles related to 5G networks in the future. If you find any mistakes in my articles or have any topics you want to know about, please contact me.
+Note
+Author: Daniel Hsieh
+Date: 2023/7/26
Network slicing allows for the creation of multiple logical, isolated, and independent virtual networks that can coexist within a shared physical infrastructure. Each network slice provides dedicated and customized network resources to meet the specific requirements of different services
+The main elements of a network slice include:
Virtualized Network Functions (VNFs): Each network slice can include a set of virtualized network functions that provide specific network capabilities and services. These VNFs can include functions like routing, switching, firewalling, load balancing, or any other network service required by the slice.
+Isolation and Resource Allocation: Network slicing ensures the isolation of resources between slices, preventing interference and conflicts. It allows for the allocation of dedicated and optimized resources such as bandwidth, processing power, and storage to each slice based on its specific needs.
+Orchestration and Management: Network slice orchestration involves the creation, provisioning, and management of network slices. It involves configuring the appropriate VNFs, assigning resources, and establishing connectivity between the different components of a slice.
++ ++
Take Figure 1 as an example. The first slice is designed for mobile devices such as smartphones. Such slice requires a huge diversity of VNFs, and virtual links with high speed and low latency to support the broadband service of smartphones. In 5G network, Those slices are referred to as eMBB (enhanced mobile broadband) slices.
+The second slice is designed for autonomous driving. In such scenario, extremely low latency and high reliability are paramount to ensure the vehicles' operability, smoothness and safety. To achieve low latency, some of the NFs should be deployed close to the access node,i.e. on edge cloud. To achieve high reliability, a NF should have multiple instances on available physical resources to make the slice more fault tolerant. Such slice is referred to as URLLC (Ultra-Reliable Low-Latency Communications) slice.
+The third slice is designed for massive IoT. IoT devices are expected to not move and send very small amount of data intermittently. Due to the nature of such devices, functions that handle mobiltiy and always-on connections are not needed. Such slices are referred to as mIoT (massive IoT) slices.
+In this article, we utilize MANO network function virtualization (NFV) architecture to deploy virtual network function (VNF). It plays the role of creating, deploying, and managing VNFs. MANO consists of three main functional components: NFV Orchestrator (NFVO), Virtualized Infrastructure Manager (VIM), and Virtual Network Function Manager (VNFM).
+ ++ ++
NFVO manages the underlying resource by coordinating VIM and VNFM. It handles tasks such as receiving requests, service instantiation, scaling, termination, and monitoring.
+VNFM manages the lifecycle of VNF instances. It interacts with the VIM to instantiate, configure, monitor, and terminate VNF instances.
+VIM is responsible for managing the underlying virtualized infrastructure that hosts the VNFs. It abstracts the physical resources, such as compute, storage, and networking, and provides a unified view to the NFVO. The VIM handles tasks like resource allocation, performance monitoring, fault management, and virtualization management.
+For VIM, we use OpenStack, an open-source software that provides IaaS, to utilize the physical resources. For VNFM and NFVO, we use Tacker, a service component of OpenStack, to manage VNFs.
+OpenStack is an open-source cloud computing platform that provides a set of software tools for building and managing customized clouds. OpenStack offers a infrastructure-as-a-service (IaaS) solution, enabling organizations to create and manage virtualized resources in a cloud environment. It is designed to be modular and consists of various components that work together to deliver a comprehensive cloud computing platform. Some of the key components include:
+Nova: Nova is the computing component of OpenStack and serves as the main compute engine. It manages the creation, scheduling, and management of virtual machines (VMs) and provides APIs for controlling and interacting with the compute resources.
+Cinder: Cinder is the block storage component of OpenStack. It provides persistent storage for virtual machines. With Cinder, users can create and manage volumes that can be attached to instances, allowing for flexible and scalable storage options.
+Neutron: Neutron is the networking component of OpenStack. It provides a networking-as-a-service (NaaS) solution, allowing users to define and manage network resources. Neutron supports virtual LANs, software-defined networking (SDN), and network function virtualization (NFV), etc.
+Keystone: Keystone is the identity service component of OpenStack. It provides authentication and authorization services, enabling users to securely access and manage resources within the cloud. Keystone supports multiple authentication mechanisms, including username/password, token-based, and external identity providers.
+Horizon: Horizon is the web-based dashboard for OpenStack. It provides a user-friendly interface for managing and monitoring the cloud infrastructure. With Horizon, users can perform various tasks, such as launching instances, managing storage resources, and configuring networking options.
++ ++
OpenStack is highly flexible and customizable, allowing organizations to tailor the cloud infrastructure to their specific needs. It supports multiple hypervisors, including KVM, VMware, and Hyper-V.
+To enable NFV, we need another service component of OpenStack called Tacker. Tacker is designed to simplify the deployment and lifecycle management of VNFs and network service functions (NSFs) in a cloud infrastructure. It leverages OpenStack's existing components, such as Nova, Neutron, and Heat, to provide a comprehensive solution for network service orchestration.
+Tacker provides several key features and functionalities:
Service Templates: Tacker uses service templates to define the composition and behavior of network services. These templates describe the VNFs and NSFs involved, their interconnections, resource requirements, etc. Service templates are written using the TOSCA (Topology and Orchestration Specification for Cloud Applications) standard.
+Lifecycle Management: Tacker automates the entire lifecycle of network services, including provisioning, scaling, healing, and termination. It leverages Heat, OpenStack's orchestration service, to manage the underlying infrastructure resources required by the services and handle dynamic scaling of VNFs based on traffic demands.
+VNF Manager: Tacker includes a VNF Manager component responsible for managing the lifecycle of VNFs. It interacts with OpenStack's compute and networking services, to instantiate and manage VNF instances.
+Multi-VIM Support: Tacker supports multiple virtual infrastructure managers to accommodate different cloud platforms and environments. It can interact with OpenStack, VMware vSphere and Kubernetes and so on, enabling operators to deploy network services across heterogeneous infrastructure environments.
++ ++
In our implementation, we install OpenStack and Tacker on two different virtual machines for resource utilization reasons, but in fact, they can be installed on the same virtual machine.
+we need to install OpenStack on a virtual machine. Specific details and corresponding compatibility can be found on OpenStack official website. Using devstack scripts for installation enables operators to customize the environment based on their needs, such as extra plugins (softwares that extends the functionality of OpenStack environment) and overcommit (allows deploying NFs that require more resource than existing physical resourcce) functionality. Upon completion, a web UI enabled by Horizon can be used to access and operate on your own personalized OpenStack cloud.
+Install Tacker on another virtual machine, which requires four OpenStack service components, Keystone, Mistral, Barbican and Horizon. Once the installation is completed, we can register our OpenStack VIM on Tacker using openstack vim register
command.
Create two instances that will be used as images (one for control plane VNFs, one for UPF) for the VNFs that we will create. Then, ssh
into those instances to set up the configurations for the VNFs, such as, installing required packages (go language, mongodb, libtool, etc.) and git clone
free5GC source code. Once all the configurations are done, use OpenStack dashboard to take snapshots of these instances, which will be used as the images for VNFs.
Import all the VNF descriptors (VNFD) of the VNFs we need by using openstack vnf descriptor create
command. VNFDs should be written in accordance with TOSCA format. TOSCA format allows you to define the virtual links (a virtual network VNFs will be running in) and virtual deployment unit (operation unit of a VNF).
+ Below is an example of UPF VNFD:
+
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
+description: description
+node_types:
+ tosca.nodes.nfv.VNF11:
+ requirements:
+ - virtualLink1:
+ type: tosca.nodes.nfv.VL
+ required: true
+metadata:
+ template_name: free5GCSetup
+topology_template:
+ substitution_mappings:
+ node_type: tosca.nodes.nfv.VNF11
+ node_templates:
+ VDU1:
+ type: tosca.nodes.nfv.VDU.Tacker
+ properties:
+ name: free5gc-upf1-VNF
+ image: stage3-up
+ flavor: free5gc
+ availability_zone: nova
+ mgmt_driver: noop
+ key_name: free5gc
+ user_data_format: RAW
+ user_data: |
+ #!/bin/sh
+ cd /home/ubuntu/free5gc/src/upf/build
+ cat > config/upfcfg.yaml <<- EOM
+ info:
+ version: 1.0.0
+ description: UPF configuration
+
+ configuration:
+ # debugLevel: panic|fatal|error|warn|info|debug|trace
+ debugLevel: info
+
+ pfcp:
+ - addr: 192.168.2.111
+
+ gtpu:
+ - addr: 192.168.2.111
+ # [optional] gtpu.name
+ # - name: upf.5gc.nctu.me
+ # [optional] gtpu.ifname
+ # - ifname: gtpif
+
+ apn_list:
+ - apn: internet
+ cidr: 60.60.0.0/24
+ # [optional] apn_list[*].natifname
+ # natifname: eth0
+ EOM
+ #sudo ./bin/free5gc-upfd -f config/upfcfg.yaml
+
+ CP1:
+ type: tosca.nodes.nfv.CP.Tacker
+ properties:
+ ip_address: 192.168.2.111
+ management: true
+ requirements:
+ - virtualLink:
+ node: VL1
+ - virtualBinding:
+ node: VDU1
+ VL1:
+ type: tosca.nodes.nfv.VL
+ properties:
+ network_name: 5GC
+ vendor: Tacker
+ FIP1:
+ type: tosca.nodes.network.FloatingIP
+ properties:
+ floating_network: public
+ floating_ip_address: 172.24.4.111
+ requirements:
+ - link:
+ node: CP1
+
openstack ns descriptor create
command. The NSD should also be written in accordance with TOSCA format. Once all the VNFDs and NSD are all successfully imported, we can use openstack ns create
to deploy the network slice. The VNFs specified in the NSD will also be instantiated along with the network slice. Their instances can be viewed on OpenStack dashboard enabled by Horizon or just use openstack vnf list
to check the status of the VNFs.tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
+description: Import Common Slice VNFDs (already on-boarded)
+imports:
+ - mongo
+ - nrf
+ - amf
+ - smf
+ - udr
+ - pcf
+ - udm
+ - nssf
+ - ausf
+topology_template:
+ node_templates:
+ VNF0:
+ type: tosca.nodes.nfv.VNF0
+ VNF1:
+ type: tosca.nodes.nfv.VNF1
+ VNF2:
+ type: tosca.nodes.nfv.VNF2
+ VNF3:
+ type: tosca.nodes.nfv.VNF3
+ VNF4:
+ type: tosca.nodes.nfv.VNF4
+ VNF5:
+ type: tosca.nodes.nfv.VNF5
+ VNF6:
+ type: tosca.nodes.nfv.VNF6
+ VNF7:
+ type: tosca.nodes.nfv.VNF7
+ VNF8:
+ type: tosca.nodes.nfv.VNF8
+
ssh
into the VNF instances to make the necessary configuration for each VNF and start the free5GC VNF.There are many other ways to set up a network slice. For example, we can deploy VNFs of the same network slice on different VIMs, or we can deploy all the network slices on the same VIM, as long as it is specified in the VNFDs.
+Hi, my name is Daniel Hsieh. I am a CS major graduate student. My research field is network slicing. If there are any questions about the article, please feel free to contact.
+https://www.acecloudhosting.com/blog/openstack-the-catalyst-of-the-public-cloud-market/
+https://telcocloudbridge.com/blog/a-beginners-guide-to-nfv-management-orchestration-mano/
+https://wiki.openstack.org/wiki/Tacker
+B. Chatras, U. S. Tsang Kwong and N. Bihannic, "NFV enabling network slicing for 5G," 2017 20th Conference on Innovations in Clouds, Internet and Networks (ICIN), Paris, France, 2017, pp. 219-225, doi: 10.1109/ICIN.2017.7899415.
+In this demo, we will
+Search virtualbox download
, or visit virtualbox.org to download and install VirtualBox (currently 6.1.18) for your operation system.
+
Once installed VirtualBox, launch and see if you have something like this:
+
Search ubuntu server download
on the web and download the latest Ubuntu Server LTS, or visit ubuntu.com, choose Manual Installation Option to download the .iso
file (currently 20.04.2 LTS)
+
You should have downloaded a .iso image
file with name like ubuntu-20.04.1-live-server-amd64.iso
, probably in your download directory.
+
Launch VirtualBox and create your first Ubuntu VM using the downloaded .iso image file. We use Ubuntu Server instead of Ubuntu Desktop because we only need a basic server machine without too many unnecessary functionalities. The resulting overhead to your host machine is smaller, and the VM starts up faster too.
+Tips
+ubuntu-server
, or ubuntu-20.04
.Refer to the videos Creating VM, Setting up VM.
+Some notes about installing Ubuntu:
+Refer to videos Install Ubuntu 1, Install Ubuntu 2.
+Reboot after Ubuntu installation complete; wait a little bit for some initialization steps complete. Then log in with your username and password.
+
First try the ifconfig
command:
+
ubuntu@ubuntu:~$ ifconfig
+Command 'ifconfig' not found, but can be installed with:
+sudo apt install net-tools
+ubuntu@ubuntu:~$
+
If some messages like above show, it means ifconfig
has not been installed yet. (ifconfig
is no longer installed by defaults in newer Ubuntu, and is replaced by more versatile ip command, but we will use it here for simplicity).
Follow its suggestion and install ifconfig
:
+
ubuntu@ubuntu:~$ sudo apt install net-tools
+
Run ifconfig
again to check the network interfaces:
+
Your display may look different, but take notes about the IP address of the Host-only interface card. The example above shows 192.168.56.101
. You can SSH from your host machine into this Ubuntu VM using the IP later. (Another IP address, 10.0.2.15
is the IP address of the NAT interface card, the apps in your host machine cannot access it).
Finally check if the VM has internet access:
+
ubuntu@ubuntu:~$ ping google.com
+
Refer to the first part of the video Ping, SSH, and Upgrade.
+Launch your favorite SSH client from the host machine.
+Some operation systems (Mac, Ubuntu, some Windows) have pre-installed SSH clients. If you are using Windows, you can also download third-party SSH clients. For example, search “windows ssh download” on the web.
The benefit of using SSH is that you can easily copy and paste commands from your machine to Ubuntu VM for execution, and vice versa. You can also create multiple SSH connections with the Ubuntu VM for control and monitoring at the same time.
+Below shows some examples on a Mac host machine. Suppose the Host-only network IP is 192.168.56.101
, and tue username is ubuntu:
+
ssh 192.168.56.101 -l ubuntu
+
Tips
+If somehow SSH shows some warning messages telling you the machine has potential security risk, you may have to remove an entry in the file <your home directory>/.ssh/known_hosts
related the the IP address.
If you log in successfully, you will enter a command line interface:
+
Repeat the basic commands such as ping
, ifconfig
to see if the VM is working properly. If so, we can access the Ubuntu VM “remotely” from now on.
+
Let also update and upgrade the Ubuntu VM right now to make sure it is up-to-date with proper security updates.
+
sudo apt update
+sudo apt upgrade
+
In this demo we will exercise:
+Tips
+Refer to video Clone VM and Change IP.
+Launch VirtualBox, and make sure the Ubuntu VM (ubuntu) we created before can boot up, then:
+sudo apt update
and sudo apt upgrade
(or you can do it again)sudo shutdown -P now
, orsudo shutdown -r now
First let’s clone a new VM:
+free5gc
.After the new VM is created:
+ping
and ifconfig
again to make sure it has internet access, and also make note of the IP address of the Host-only network interface.192.168.56.101
, and the interface name is enp0s8
.The cloned free5gc VM still has host name ubuntu
(or the name you gave it in the original VM). Let’s rename the VM to free5gc
. You can do this by editing the file /etc/hostname
(using vi
or nano
):
+
sudo nano /etc/hostname
+# or
+sudo vi /etc/hostname
+
free5gc
。If you are using nano ,you can press Ctrl-O
to save the file, then Ctrl-X
to exit.
+Let’s also change the file /etc/hosts
by replacing the ubuntu inside into free5gc
:
+
sudo nano /etc/hosts
+
New content of the file /etc/hosts
looks like this:
+
127.0.0.1 localhost
+127.0.1.1 free5gc
+...
+
The changes will take effect after next reboot.
+The Host-only network interface, by default, gets its IP address through DHCP. The cloned free5gc VM seems to have trouble obtaining new IP address. We can change the host-only interface to use static IP address instead, which can save a lot of trouble later.
+Here let’s fix the static IP address as 192.168.56.101
:
+
$ cd /etc/netplan
+$ ls
+00-installer-config.yaml
+$ cat 00-installer-config.yaml
+
00-installer-config.yaml
looks like:# This is the network config written by 'subiquity'
+network:
+ ethernets:
+ enp0s3:
+ dhcp4: true
+ enp0s8:
+ dhcp4: true
+ version: 2
+
ifconfig
we know that enp0s8
is the name of the Host-only network interface. We can edit the file:sudo nano 00-installer-config.yaml
+
# This is the network config written by 'subiquity'
+network:
+ ethernets:
+ enp0s3:
+ dhcp4: true
+ enp0s8:
+ dhcp4: no
+ addresses: [192.168.56.101/24]
+ version: 2
+
sudo netplan try
+
sudo netplan apply
+
ifconfig
to see if the network setting has been changed correctly:enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
+ inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255
+ inet6 fe80::a00:27ff:fec4:254f prefixlen 64 scopeid 0x20<link>
+ ether 08:00:27:c4:25:4f txqueuelen 1000 (Ethernet)
+ RX packets 2 bytes 1180 (1.1 KB)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 18 bytes 1894 (1.8 KB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
+ inet 192.168.56.101 netmask 255.255.255.0 broadcast 192.168.56.255
+ inet6 fe80::a00:27ff:fe7e:ada6 prefixlen 64 scopeid 0x20<link>
+ ether 08:00:27:7e:ad:a6 txqueuelen 1000 (Ethernet)
+ RX packets 8420 bytes 531867 (531.8 KB)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 10887 bytes 823487 (823.4 KB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
+ inet 127.0.0.1 netmask 255.0.0.0
+ inet6 ::1 prefixlen 128 scopeid 0x10<host>
+ loop txqueuelen 1000 (Local Loopback)
+ RX packets 6621 bytes 596035 (596.0 KB)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 6621 bytes 596035 (596.0 KB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
$ route -n
+Kernel IP routing table
+Destination Gateway Genmask Flags Metric Ref Use Iface
+0.0.0.0 10.0.2.2 0.0.0.0 UG 100 0 0 enp0s3
+10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s3
+10.0.2.2 0.0.0.0 255.255.255.255 UH 100 0 0 enp0s3
+192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s8
+
For the display above, we learn that the Host-only network 192.168.56.0/24
does not have internet access by itself (even though we can access it using SSH from the host machine). Internet access is through the NAT network 10.0.2.0/24
, with the gateway being 10.0.2.2
(provided by VirtualBox).
+Now we can SSH into free5gc VM using 192.168.56.101
:
+
ssh 192.168.56.101 -l ubuntu
+
Linux Kernel Version
+5.0.0-23-generic
or 5.4.x
version of the Linux kernel. free5gc uses the gtp5g kernel module, which has been tested and compiled against that kernel versions only. If you installed Ubuntu 20.04, the version looks like 5.4.x. To determine the version of the Linux kernel you are using: $ uname -r
+ 5.4.0-65-generic
+
You will not be able to run most of the tests in Test section unless you deploy a UPF.
+Golang Version
+ go version
+
# this assumes your current version of Go is in the default location
+ sudo rm -rf /usr/local/go
+ wget https://dl.google.com/go/go1.17.8.linux-amd64.tar.gz
+ sudo tar -C /usr/local -zxvf go1.17.8.linux-amd64.tar.gz
+
wget https://dl.google.com/go/go1.17.8.linux-amd64.tar.gz
+ sudo tar -C /usr/local -zxvf go1.17.8.linux-amd64.tar.gz
+ mkdir -p ~/go/{bin,pkg,src}
+ # The following assume that your shell is bash
+ echo 'export GOPATH=$HOME/go' >> ~/.bashrc
+ echo 'export GOROOT=/usr/local/go' >> ~/.bashrc
+ echo 'export PATH=$PATH:$GOPATH/bin:$GOROOT/bin' >> ~/.bashrc
+ echo 'export GO111MODULE=auto' >> ~/.bashrc
+ source ~/.bashrc
+
golang
are available at the official golang site.Control-plane Supporting Packages
+sudo apt -y update
+sudo apt -y install mongodb wget git
+sudo systemctl start mongodb
+
WARNING: MongoDB 5.0+ requires a CPU with AVX support. Or downgrade your MongoDB to 4.4
+see https://www.mongodb.com/community/forums/t/mongodb-5-0-cpu-intel-g4650-compatibility/116610/2
+see also docker-library/mongo#485 (comment)
+User-plane Supporting Packages
+sudo apt -y update
+sudo apt -y install git gcc g++ cmake autoconf libtool pkg-config libmnl-dev libyaml-dev
+
sudo sysctl -w net.ipv4.ip_forward=1
+sudo iptables -t nat -A POSTROUTING -o <dn_interface> -j MASQUERADE
+sudo iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1400
+sudo systemctl stop ufw
+
Clone the free5GC repository
+ cd ~
+ git clone --recursive -b v3.3.0 -j `nproc` https://github.com/free5gc/free5gc.git
+ cd free5gc
+
cd ~/free5gc
+ git checkout main
+ git submodule sync
+ git submodule update --init --jobs `nproc`
+ git submodule foreach git checkout main
+ git submodule foreach git pull --jobs `nproc`
+
Compile network function services in free5gc
cd ~/free5gc
+ make amf
+
cd ~/free5gc
+ make
+
5.0.0-23-generic
or 5.4.x
. To verify your version:uname -r
+
git
and build itgit clone -b v0.8.1 https://github.com/free5gc/gtp5g.git
+cd gtp5g
+make
+sudo make install
+
Build the UPF (you may skip this step if you built all network functions above):
+to build using make:
+cd ~/free5gc
+make upf
+
run.sh
is free5gc/config/upfcfg.yaml
.sudo apt remove cmdtest
+sudo apt remove yarn
+curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
+echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
+curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
+sudo apt-get update
+sudo apt-get install -y nodejs yarn
+
Build WebConsole
+to build using make:
+cd ~/free5gc
+make webconsole
+
cd ~/free5gc/webconsole/frontend
+yarn install
+yarn build
+rm -rf ../public
+cp -R build ../public
+cd ..
+go build -o bin/webconsole server.go
+
Note: 2GB or more of OS memory is recommended. WebConsole may be failed to build if memory is less then 1GB.
+ + + + + + +Start a Wireshark capture on any core-connected interface, applying the filter 'pfcp||icmp||gtp'
.
In order to run the tests, first do this:
+cd ~/free5gc
+make upf
+chmod +x ./test.sh
+
The tests are all run from within ~/free5gc
.
a. TestRegistration
+./test.sh TestRegistration
+
b. TestGUTIRegistration
+./test.sh TestGUTIRegistration
+
c. TestServiceRequest
+./test.sh TestServiceRequest
+
d. TestXnHandover
+./test.sh TestXnHandover
+
e. TestDeregistration
+./test.sh TestDeregistration
+
f. TestPDUSessionReleaseRequest
+./test.sh TestPDUSessionReleaseRequest
+
g. TestPaging
+./test.sh TestPaging
+
h. TestN2Handover
+./test.sh TestN2Handover
+
i. TestNon3GPP
+./test.sh TestNon3GPP
+
j. TestReSynchronization
+./test.sh TestReSynchronization
+
k. TestULCL
+./test_ulcl.sh TestRequestTwoPDUSessions
+
In this demo we will practice:
+Repeat the steps of cloning free5gc
VM from the base VM, create a new VM for the UERANSIM simulator:
ueransim
, and create new MAC addresses for all network cards.ueransim
.192.168.56.102
.192.168.56.101
from the ueransim VM, and also ping 192.168.56.102
from the free5gc VM.Search “ueransim” on the web, and get the web site.
+On the web site, review what the UERANSIM open-source project is about, then browse into the installation page.
To download UERANSIM:
+
cd ~
+git clone https://github.com/aligungr/UERANSIM
+cd UERANSIM
+git checkout 3a96298
+
Update and upgrade ueransim VM first:
+
sudo apt update
+sudo apt upgrade
+
Install required tools:
+
sudo apt install make
+sudo apt install g++
+sudo apt install libsctp-dev lksctp-tools
+sudo apt install iproute2
+sudo snap install cmake --classic
+
Build UERANSIM:
+
cd ~/UERANSIM
+make
+
free5GC provides a simple web tool WebConsole to help creating and managing UE registrations to be used by various 5G network functions (NF). To build WebConsole we need Node.js and Yarn.
+First SSH into free5gc (192.168.56.101
),and remove obsolete tools that may exists:
+
sudo apt remove cmdtest
+sudo apt remove yarn
+
Then install Node.js
and Yarn
:
+
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
+echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
+sudo apt-get update
+sudo apt-get install -y nodejs yarn
+
To build WebConsole:
+
cd ~/free5gc
+make webconsole
+
First start up the WebConsole server:
+
cd ~/free5gc/webconsole
+go run server.go
+
The screen shows the port number :5000
at the end. Open your web browser from your host machine, and enter the URL http://192.168.56.101:5000
admin
and password free5gc
.Subscribers
and create a new data:Ctrl-C
on the terminal to quit WebConsole.In free5gc VM, we need to edit three files:
+~/free5gc/config/amfcfg.yaml
~/free5gc/config/smfcfg.yaml
~/free5gc/config/upfcfg.yaml
First SSH into free5gc VM, and change ~/free5gc/config/amfcfg.yaml
:
+
cd ~/free5gc
+nano config/amfcfg.yaml
+
Replace ngapIpList IP from 127.0.0.1
to 192.168.56.101
, namely from:
+
...
+ ngapIpList: # the IP list of N2 interfaces on this AMF
+ - 127.0.0.1
+
...
+ ngapIpList: # the IP list of N2 interfaces on this AMF
+ - 192.168.56.101 # 127.0.0.1
+
Next edit ~/free5gc/config/smfcfg.yaml
:
+
nano config/smfcfg.yaml
+
inside userplane_information / up_nodes / UPF / interfaces / endpoints
, change the IP from 127.0.0.8
to 192.168.56.101
, namely from:...
+ interfaces: # Interface list for this UPF
+ - interfaceType: N3 # the type of the interface (N3 or N9)
+ endpoints: # the IP address of this N3/N9 interface on this UPF
+ - 127.0.0.8
+
...
+ interfaces: # Interface list for this UPF
+ - interfaceType: N3 # the type of the interface (N3 or N9)
+ endpoints: # the IP address of this N3/N9 interface on this UPF
+ - 192.168.56.101 # 127.0.0.8
+
~/free5gc/config/upfcfg.yaml
,and chage gtpu IP from 127.0.0.8
into 192.168.56.101
, namely from:...
+ gtpu:
+ forwarder: gtp5g
+ # The IP list of the N3/N9 interfaces on this UPF
+ # If there are multiple connection, set addr to 0.0.0.0 or list all the addresses
+ ifList:
+ - addr: 127.0.0.8
+ type: N3
+
...
+ gtpu:
+ forwarder: gtp5g
+ # The IP list of the N3/N9 interfaces on this UPF
+ # If there are multiple connection, set addr to 0.0.0.0 or list all the addresses
+ ifList:
+ - addr: 192.168.56.101 # 127.0.0.8
+ type: N3
+
In the ueransim VM, there are two files related to free5GC:
+~/UERANSIM/config/free5gc-gnb.yaml
~/UERANSIM/config/free5gc-ue.yaml
The second file is for UE, which we don’t have to change if the data inside is consistent with the (default) registration data we set using WebConsole previously.
+First SSH into ueransim, and edit the file ~/UERANSIM/config/free5gc-gnb.yaml
, and change the ngapIp IP, as well as the gtpIp IP, from 127.0.0.1
to 192.168.56.102
,and also change the IP in amfConfigs into 192.168.56.101
, that is, from:
+
...
+ ngapIp: 127.0.0.1 # gNB's local IP address for N2 Interface (Usually same with local IP)
+ gtpIp: 127.0.0.1 # gNB's local IP address for N3 Interface (Usually same with local IP)
+
+ # List of AMF address information
+ amfConfigs:
+ - address: 127.0.0.1
+
...
+ ngapIp: 192.168.56.102 # 127.0.0.1 # gNB's local IP address for N2 Interface (Usually same with local IP)
+ gtpIp: 192.168.56.102 # 127.0.0.1 # gNB's local IP address for N3 Interface (Usually same with local IP)
+
+ # List of AMF address information
+ amfConfigs:
+ - address: 192.168.56.101 # 127.0.0.1
+
~/UERANSIM/config/free5gc-ue.yaml
,and see if the settings is consistent with those in free5GC (via WebConsole), for example:# IMSI number of the UE. IMSI = [MCC|MNC|MSISDN] (In total 15 or 16 digits)
+supi: 'imsi-208930000000003'
+# Mobile Country Code value
+mcc: '208'
+# Mobile Network Code value (2 or 3 digits)
+mnc: '93'
+
+# Permanent subscription key
+key: '8baf473f2f8fd09487cccbd7097c6862'
+# Operator code (OP or OPC) of the UE
+op: '8e27b6af0e692e750f32667a3b14605d'
+# This value specifies the OP type and it can be either 'OP' or 'OPC'
+opType: 'OP'
+
+...
+
+# Initial PDU sessions to be established
+sessions:
+ - type: 'IPv4'
+ apn: 'internet'
+ slice:
+ sst: 0x01
+ sd: 0x010203
+
+# List of requested S-NSSAIs by this UE
+slices:
+ - sst: 0x01
+ sd: 0x010203
+
+...
+
SSH into free5gc. If you have rebooted free5gc, remember to do:
+
sudo sysctl -w net.ipv4.ip_forward=1
+sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
+sudo systemctl stop ufw
+
In addition, execute the following command:
+
sudo iptables -I FORWARD 1 -j ACCEPT
+
Also, make sure you have make proper changes to the free5GC configuration files, then run ./run.sh
:
+
cd ~/free5gc
+./run.sh
+
At this time free5GC has been started.
+Next, prepare three additional SSH terminals from your host machine (if you know how to use tmux
, you can use just one).
In terminal 1: SSH into ueransim, make sure UERANSIM is built, and configuration files have been changed correctly, then execute nr-gnb
:
+
cd ~/UERANSIM
+build/nr-gnb -c config/free5gc-gnb.yaml
+
In terminal 2, SSH into ueransim, and execute nr-ue
with admin right:
+
cd ~/UERANSIM
+sudo build/nr-ue -c config/free5gc-ue.yaml # for multiple-UEs, use -n and -t for number and delay
+
In terminal 3, SSH into ueransim, and ping 192.168.56.101
to see free5gc is alive. Then, use ifconfig to see if the tunnel uesimtun0
has been created (by nr-ue):
+
$ ifconfig
+
+enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
+ inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255
+ inet6 fe80::a00:27ff:fe65:1472 prefixlen 64 scopeid 0x20<link>
+ ether 08:00:27:65:14:72 txqueuelen 1000 (Ethernet)
+ RX packets 80 bytes 32423 (32.4 KB)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 90 bytes 12860 (12.8 KB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
+ inet 192.168.56.102 netmask 255.255.255.0 broadcast 192.168.56.255
+ inet6 fe80::a00:27ff:fe5e:be64 prefixlen 64 scopeid 0x20<link>
+ ether 08:00:27:5e:be:64 txqueuelen 1000 (Ethernet)
+ RX packets 1515 bytes 130490 (130.4 KB)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 1010 bytes 206670 (206.6 KB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
+ inet 127.0.0.1 netmask 255.0.0.0
+ inet6 ::1 prefixlen 128 scopeid 0x10<host>
+ loop txqueuelen 1000 (Local Loopback)
+ RX packets 3445 bytes 174416 (174.4 KB)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 3445 bytes 174416 (174.4 KB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+uesimtun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
+ inet 60.60.0.1 netmask 255.255.255.255 destination 60.60.0.1
+ inet6 fe80::2034:d00:a76:84b7 prefixlen 64 scopeid 0x20<link>
+ unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC)
+ RX packets 3 bytes 252 (252.0 B)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 13 bytes 732 (732.0 B)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
Now use ping
:
+
ping -I uesimtun0 google.com
+
ping
gets replies, then free5GC is running properly. Congratulations!
+
+
+
+
+
+
+ In this demo we will use free5GC together with UERANSIM to exercise on some simple network applications:
+ping
+ tcpdump
wget
and curl
First start up free5GC and ueransim VMs. This requires one SSH terminal for free5gc, and two for ueransim.
+Open another SSH terminal and log in into ueransim:
+
ssh 192.168.56.102 -l ubuntu
+
ifconfig
to check if uesimtun0
tunnel has been created, and use ping to check if we can ping
through it:$ ping google.com
+PING google.com (172.217.27.142) 56(84) bytes of data.
+64 bytes from tsa03s02-in-f14.1e100.net (172.217.27.142): icmp_seq=1 ttl=63 time=3.98 ms
+64 bytes from tsa03s02-in-f14.1e100.net (172.217.27.142): icmp_seq=2 ttl=63 time=3.87 ms
+64 bytes from tsa03s02-in-f14.1e100.net (172.217.27.142): icmp_seq=3 ttl=63 time=4.06 ms
+^C
+--- google.com ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 2003ms
+rtt min/avg/max/mdev = 3.872/3.970/4.060/0.076 ms
+
$ ping -I uesimtun0 google.com
+PING google.com (172.217.27.142) from 60.60.0.1 uesimtun0: 56(84) bytes of data.
+64 bytes from tsa03s02-in-f14.1e100.net (172.217.27.142): icmp_seq=1 ttl=61 time=5.85 ms
+64 bytes from tsa03s02-in-f14.1e100.net (172.217.27.142): icmp_seq=2 ttl=61 time=4.87 ms
+64 bytes from tsa03s02-in-f14.1e100.net (172.217.27.142): icmp_seq=3 ttl=61 time=4.76 ms
+^C
+--- google.com ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 2004ms
+rtt min/avg/max/mdev = 4.760/5.160/5.847/0.487 ms
+
Also use route -n
to observe if current routing table shows some routing rules regarding the two network interfaces enp0s3
and enp0s8
:
+
$ route -n
+Kernel IP routing table
+Destination Gateway Genmask Flags Metric Ref Use Iface
+0.0.0.0 10.0.2.2 0.0.0.0 UG 100 0 0 enp0s3
+10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s3
+10.0.2.2 0.0.0.0 255.255.255.255 UH 100 0 0 enp0s3
+192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s8
+
The network 10.0.2.0/24
and its enp0s3
interface are related to VirtualBox NAT network card. We can bring down this interface:
+
$ sudo ifconfig enp0s3 down
+$ route -n
+Kernel IP routing table
+Destination Gateway Genmask Flags Metric Ref Use Iface
+192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s8
+
192.168.56.0/24
left. Run ping
again:$ ping 8.8.8.8
+ping: connect: Network is unreachable
+
And see that it can not ping through, but runing:
+
$ ping -I uesimtun0 8.8.8.8
+PING 8.8.8.8 (8.8.8.8) from 60.60.0.1 uesimtun0: 56(84) bytes of data.
+64 bytes from 8.8.8.8: icmp_seq=1 ttl=61 time=7.17 ms
+64 bytes from 8.8.8.8: icmp_seq=2 ttl=61 time=5.41 ms
+64 bytes from 8.8.8.8: icmp_seq=3 ttl=61 time=5.15 ms
+^C
+--- 8.8.8.8 ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 2005ms
+rtt min/avg/max/mdev = 5.150/5.907/7.165/0.895 ms
+
shows some responses, since we ask ping
to go through the free5GC core network. To make ping 8.8.8.8
in addition to ping -I uesimtun0 8.8.8.8
work, we can set the uesimtun0
interface (IP 60.60.0.1
) as the new default gateway:
+
$ sudo ip r add default dev uesimtun0
+$ route -n
+Kernel IP routing table
+Destination Gateway Genmask Flags Metric Ref Use Iface
+0.0.0.0 0.0.0.0 0.0.0.0 U 0 0 0 uesimtun0
+192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s8
+
192.168.56.0/24
network will go to uesimtun0
, and ping 8.8.8.8
works this time:$ ping 8.8.8.8
+PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
+64 bytes from 8.8.8.8: icmp_seq=1 ttl=61 time=5.02 ms
+64 bytes from 8.8.8.8: icmp_seq=2 ttl=61 time=6.31 ms
+64 bytes from 8.8.8.8: icmp_seq=3 ttl=61 time=5.41 ms
+^C
+--- 8.8.8.8 ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 2004ms
+rtt min/avg/max/mdev = 5.017/5.581/6.312/0.541 ms
+...
+
Note that normally we are using ueransim to simulate “terminal” UE device, not as a network device or proxy, therefore the above two routing rules suffice.
+Now if we still want to run:
+
$ ping google.com
+ping: google.com: Temporary failure in name resolution
+
we will get unresolved domain name. To solve this, we can modify the file /etc/resolv.conf
:
+
sudo nano /etc/resolv.conf
+
and change the nameserver IP to 8.8.8.8
:
+
nameserver 8.8.8.8
+
After the change, we can see ping
getting responses:
+
$ ping google.com
+PING google.com (216.58.200.46) 56(84) bytes of data.
+64 bytes from tsa01s08-in-f46.1e100.net (216.58.200.46): icmp_seq=1 ttl=61 time=5.19 ms
+64 bytes from tsa01s08-in-f46.1e100.net (216.58.200.46): icmp_seq=2 ttl=61 time=50.4 ms
+64 bytes from tsa01s08-in-f46.1e100.net (216.58.200.46): icmp_seq=3 ttl=61 time=5.66 ms
+^C
+--- google.com ping statistics ---
+3 packets transmitted, 3 received, 0% packet loss, time 2004ms
+rtt min/avg/max/mdev = 5.191/20.423/50.414/21.207 ms
+
We can also examine the network traffic happening underneath in the scenario above. First we open another SSH terminal into ueransim, and run the following command:
+
$ sudo tcpdump -n -i any host 60.60.0.1 or 192.168.56.101
+tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
+listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
+
then run ping 8.8.8.8
again, wait for a couple seconds, then Ctrl-C
to exit. We see the data packets actually going in and out uesimtun0
.
+
$ sudo tcpdump -n -i any host 60.60.0.1 or 192.168.56.101
+tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
+listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
+10:24:56.138729 IP 192.168.56.101.38412 > 192.168.56.102.38740: sctp (1) [HB REQ]
+10:24:56.138783 IP 192.168.56.102.38740 > 192.168.56.101.38412: sctp (1) [HB ACK]
+10:24:58.456532 IP 60.60.0.1 > 8.8.8.8: ICMP echo request, id 33, seq 1, length 64
+10:24:58.457416 IP 192.168.56.102.2152 > 192.168.56.101.2152: UDP, length 100
+10:24:58.462136 IP 192.168.56.101.2152 > 192.168.56.102.2152: UDP, length 92
+10:24:58.462324 IP 8.8.8.8 > 60.60.0.1: ICMP echo reply, id 33, seq 1, length 64
+10:24:59.458823 IP 60.60.0.1 > 8.8.8.8: ICMP echo request, id 33, seq 2, length 64
+10:24:59.459031 IP 192.168.56.102.2152 > 192.168.56.101.2152: UDP, length 100
+10:24:59.464214 IP 192.168.56.101.2152 > 192.168.56.102.2152: UDP, length 92
+10:24:59.464396 IP 8.8.8.8 > 60.60.0.1: ICMP echo reply, id 33, seq 2, length 64
+10:25:00.461293 IP 60.60.0.1 > 8.8.8.8: ICMP echo request, id 33, seq 3, length 64
+10:25:00.462178 IP 192.168.56.102.2152 > 192.168.56.101.2152: UDP, length 100
+10:25:00.474941 IP 192.168.56.101.2152 > 192.168.56.102.2152: UDP, length 92
+10:25:00.475561 IP 8.8.8.8 > 60.60.0.1: ICMP echo reply, id 33, seq 3, length 64
+10:25:01.463946 IP 60.60.0.1 > 8.8.8.8: ICMP echo request, id 33, seq 4, length 64
+10:25:01.464523 IP 192.168.56.102.2152 > 192.168.56.101.2152: UDP, length 100
+10:25:01.469297 IP 192.168.56.101.2152 > 192.168.56.102.2152: UDP, length 92
+10:25:01.470314 IP 8.8.8.8 > 60.60.0.1: ICMP echo reply, id 33, seq 4, length 64
+
Simply look for any web page for file download on the web. For example, if we choose Golang web site as an example, we may find the URL:
+
https://golang.org/dl/go1.15.8.darwin-amd64.pkg
+
wget https://golang.org/dl/go1.15.8.darwin-amd64.pkg
+
ssh bbsu@ptt.cc
)You can actually use SSH in the ueransim VM to access remote site. For example, you can SSH to a well-known terminal-based BBS site in Taiwan:
+
ssh bbsu@ppt.cc
+
You can also use Youtube as an example app. To achieve this goal, you can install a desktop VM with graphical UI, such as Ubuntu Desktop, and follow the same procedure to install and start up UERANSIM, then access Youtube through uesimtun0
and free5GC.
To reduce resource consumption on your host machine, you may install Lubuntu (at https://lubuntu.me), a more light-weight Ubuntu desktop distro instead. But since viewing free5GC YouTube Channel requires quite sime CPU consumption, you may have to set at least 2 CPUs and 2048 MB memory for the VM.
+Refer to videos Access Youtube on Lubuntu (1, 2, 3, 4 and 5).
+ + + + + + +cd webconsole
+go run server.go
+
URL: http://localhost:5000
+Username: admin
+Password: free5gc
+
Note: You can add the subscribers here too
+Please refer to free5gmano
+Please refer to free5GC/IPTV
+The below commands may be helpful for development purposes.
+ls /dev/mqueue/
rm /dev/mqueue/*
cd ./src/upf/lib/libgtp5gnl/tools
./gtp5g-tunnel list pdr
./gtp5g-tunnel list far
cd ./src/upf/lib/libgtp5gnl/tools
sudo ./gtp5g-link del {Dev-Name}
uname -r
5.0.0-23-generic
for examplesudo apt search 'linux-image-5.0.0-23-generic'
+sudo apt install 'linux-image-5.0.0-23-generic'
+sudo apt install 'linux-headers-5.0.0-23-generic'
+
sudo update-initramfs -u -k all
+sudo update-grub
+
5.0.0-23-generic
sudo reboot
+
sudo apt remove 'linux-image-5.0.0-23-generic'
+sudo apt remove 'linux-headers-5.0.0-23-generic'
+
Install packages:
+
sudo apt-get install pcscd pcsc-tools libccid python-dev swig python-setuptools python-pip libpcsclite-dev
+sudo pip install pycrypto
+
Download PySIM
+
git clone git://git.osmocom.org/pysim.git
+
Change to pyscard folder and install
+
cd <pyscard-path>
+sudo /usr/bin/python setup.py build_ext install
+
Verify your reader is ready
+sudo pcsc_scan
+
Check whether your reader can read the SIM card
+
cd <pysim-path>
+./pySim-read.py –p 0
+
Program your SIM card information
+
./pySim-prog.py -p 0 -x 208 -y 93 -t sysmoUSIM-SJS1 -i 208930000000003 --op=8e27b6af0e692e750f32667a3b14605d -k 8baf473f2f8fd09487cccbd7097c6862 -s 8988211000000088313 -a 23605945
+
You can get your SIM card from sysmocom. You also need a card reader to write your SIM card. You can get a card reader from here or use other similar devices.
+ + + + + + +There are registerIP and bindingIP design on every NF's sbi interface.
+ +This is due to some orchestration, such as Kubernets or OpenStack, has the design of service IP mapping.
+ +Use Kubernets as an example. K8S has the service type that enable users to define the service IP outside the pod. But the service IP may be different from the IP assigned inside the pod. Therefore, if we register the binding IP inside the pod to NRF, NRF cannot know which service IP outside the pod has attached. As the result, we need to separate registerIP from bindingIP in this scenario.
+If you are not sure what IP you should set, just configure it as the same IP address.
+We provide a sample config to connect to outer ran under /sample/ran_attach_config/
. The architecture is as following.
As the result, user's RAN IP must set to 192.168.0.0/24 subnet or let the routing route to this subnet.
+Notice: If user wants to use the setting, aware to set 192.168.0.1 to your host as well.
+smfcfg.yaml
uerouting.yaml
For more detail of SMF config, please refer to here.
+ + + + + + +free5gc has been tested against the following environment:
+The listed kernel version is required for the UPF element.
+Minimum Hardware
+Recommended Hardware
+This guide assumes that you will run all 5GC elements on a single machine.
+ + + + + + +If another version of free5GC was ran before, you have to delete MongoDB.
+$ mongo --eval "db.dropDatabase()" free5gc
+
+$ cd ~/free5gc/webconsole
+$ ./bin/webconsole
+
Enter
+
Username: admin
+Password: free5gc
+
There are some issues for subscriber modification.
+If you want to modify the existed subscriber, please Delete
it first and New
again for now.
This document explains the detail of SMF config.
+Also provide some examples about conversion between config file and real userplane topology
ULCL limitation:
+The branching UPF now can't connect to the Internet.
+It only serves as a Intranet in the UPF topology.
+(Please refers to the topology of example 2)
Field | +meaning | +
---|---|
scheme | +The protocol for SBI | +
registerIPv4 | +IP used to register to NRF | +
bindingIPv4 | +IP used to bind the service | +
port | +SMF bind the SBI service to this port | +
Field | +meaning | +
---|---|
addr | +The IP address of N4 interface on the SMF (PFCP) | +
Field | +meaning | +
---|---|
userplane_information | +Includes topology and information of RAN and UPFs which are controlled by this SMF | +
up_nodes | +The node in the user plane topology. Includes gNodeB, I-UPF and A-UPF | +
links | +The edge in the user plane topology | +
type | +Indicate it is RAN or specific kind of UPF | +
node_id | +The PFCP IPv4 address for UPF | +
Note:
+up_resource_ip serves as default user plane IP for the UPF.
+In this version, UPF will determine its user plane IP by itself.
+So setting up_resource_ip in SMF config won't affect real config in user plane.
To understand whole PDU session config, we must take a step forward to understand the AMF config.
+Field | +meaning | +
---|---|
NGAPIPList | +The IP list of N2 interfaces on the AMF | +
SBI | +Same meaning with SMF/SBI. | +
ERROR: [SCTP] Failed to connect given AMF N3IWF=NGAP
This error occured when N3IWF was started before AMF finishing initialization. This error usually appears when you run the TestNon3GPP in the first time.
+Rerun the test should be fine. If it still not be solved, larger the sleeping time in line 110 of test.sh
.
TestNon3GPP will modify the config/amfcfg.conf
. So, if you had killed the TestNon3GPP test before it finished, you might need to copy config/amfcfg.conf.bak
back to config/amfcfg.conf
to let other tests pass.
cp config/amfcfg.conf.bak config/amfcfg.conf
If you meet any problems about https or mogodb, it maybe couse our new version from v3.0.1 to v3.0.2 has change http to H2C verion. Try the command below.
+mongo --eval "db.NfProfile.drop()" free5gc
MQCreate() Error creating message queue: Too many open files UPF=Util
(UPF)Remove POSIX message queues
+ls /dev/mqueue/
+rm /dev/mqueue/*
+
cd lib/libgtp5gnl/tools
+sudo ./gtp5g-link del {Dev-Name}
+
UPF Cli Run Error: open Gtp5g: open link: create: file exists
sudo ip link del upfgtp
+
Run Network Function
+Check has XXFsslkey.log
+Edit >> Preference >> Protocols >> SSL (TLS)
+ +Add keylog
+ +Filter http2
+ +The similar reason as NEA0 NAS message. Althrough H2C is clear text, wirshark still considers these packets as the normal TCP packets and does not decode them by HTTP2.
+To see the details of H2C packets, do the following configuration.
+Analyze → Decode As…
+ +click Add button to add the decode rules
+ +Decode the packets from the TCP ports listened by each NF as HTTP2 packets.
+Some 5G UE and gNodeB hardware have been tested with free5GC by partners or community members:
+5G UE (Support 5G SA):
+gNodeB:
+Reports of tested hardware not listed above on Github issue or free5GC forum are welcome.
+PS: if you don't have any hardware available, we suggest to use UERANSIM to simulate.
+(Refer to Advanced environment setup section)
+ + + + + + +Here are the features on the roadmap. These items are planned to be supported in the near future:
+For people who are not familiar with virtual machines and Linux installation, here are some example demonstrations:
+For Container deployment:
+The free5GC is an open-source project for 5th generation (5G) mobile core networks. The ultimate goal of this project is to implement the 5G core network (5GC) defined in 3GPP Release 15 (R15) and beyond.
+Currently, the major contributors are from National Yang Ming Chiao Tung University (NYCU). Please refer to our roadmap for the features of each release.
+Note
+Thank you very much for your interest in free5GC. The license of free5GC follows Apache 2.0. That is, anyone can use free5GC for commercial purposes for free.
+free5GC is a nonprofit organization dedicated to developing innovative and next-generation features for open-source code of
+the 5G Core (5GC) Network under Apache 2.0 license.
+Your generous support and sponsorship will sustain our technology development and the operation of the community. Your company/organization logo will be displayed on the free5GC website and listed as the sponsorship you participate. Here are the sponsorship tiers we offer.
Your generosity is appreciated.
+Tips
+V. Jain, H.-T. Chu, S. Qi, C.-A. Lee, H.-C. Chang, C.-Y. Hsieh, K. K. Ramakrishnan, and J.-C. Chen, "L25GC: A Low Latency 5G Core Network based on High-Performance NFV Platforms," full paper, ACM SIGCOMM Conference (SIGCOMM ‘22), (Amsterdam, Netherlands), pp. 143–157, Aug. 2022.
+C.-Y. Hsieh, Y.-W. Chang, C. Chen, and J.-C. Chen, "Poster: Design and Implementation of a Generic 5G User Plane Function Development Framework," ACM International Conference on Mobile Computing and Networking (MobiCom ‘21), (New Orleans, United States), pp. 846–848, Oct. 2021. (Won second place of the ACM MobiCom 2021 Student Research Competition)
+Ralf Kundel, et al., "User plane hardware acceleration in access networks: Experiences in offloading network functions in real 5g deployments," Hawaii International Conference on System Sciences. Computer Society Press, 2022.
+Taeyun Kim, et al., "An Implementation Study of Network Data Analytic Function in 5G," IEEE International Conference on Consumer Electronics, 2022.
+Zhou Cong, et al., "CeUPF: Offloading 5G User Plane Function to Programmable Hardware Base on Co-existence Architecture," ACM International Conference on Intelligent Computing and its Emerging Applications, 2021.
+Gholamreza Ramezan, et al., "EAP-ZKP: A Zero-Knowledge Proof based Authentication Protocol to Prevent DDoS Attacks at the Edge in Beyond 5G," IEEE 4th 5G World Forum, 2021.
+Ryan Pepito and Ashutosh Dutta, "Open Source 5G Security Testbed for Edge Computing," IEEE 5G World Forum (5GWF), 2021.
+Robert MacDavid, et al., "A P4-based 5G User Plane Function," 2021.
+Joe Breen, et al., "Powder: Platform for Open Wireless Data-driven Experimental Research"," Computer Networks, 2021.
+Endri Goshi, et al,, "Investigating Inter-NF Dependencies in Cloud-Native 5G Core Network," International Conference on Network and Service Management, 2021.
+Zhi-Li Zhang, et al., "Towards aSoftware-Defined, Fine-Grained QoS Framework for 5G and Beyond Networks," ACM SIGCOMM Workshop on Network-Application Integration, 2021.
+Zujany Salazar, et al, "5Greplay: a 5G Network Traffic Fuzzer - Application to Attack Injection," International Conference on Availability, Reliability and Security, 2021.
+Yu-Herng Chai, and Fuchun Joseph Lin, "Evaluating Dedicated Slices of Different Configurations in 5G Core," Computer and Communications, 9(7), p.55-72, 2021.
+M.J. Kim, et al., "Analysis of Current 5G Open-Source Projects," Electronics and Telecommunications Trends, 36(2), p.83-92, 2021.
+Yang Hu, et al., "Fuzzing Method Based on Selection Mutation of Partition Weight Table for 5G Core Network NGAP Protocol," International Conference on Innovative Mobile and Internet Services in Ubiquitous Computing. Springer, Cham, 2021.
+Cheng-Chin Tsai, Fuchun Joseph Lin, and Hiroshige Tanaka, "Evaluation of 5G Core Slicing on User Plane Function," Communications and Network, 13(3), p.79-92, 2021.
+Wei-Cheng Chang, and Fuchun Joseph Lin, "Coordinated Management of 5G Core Slices by MANO and OSS/BSS," Computer and Communications, 9(6), p.52-72, 2021.
+Ayoub Bergaoui, et al., "Demonstration of Orchestration of 5G Core Network Functions with a Satellite Emulator," 2021.
+Seungjoon Seok, et al, "Towards Service and Networking Intelligence for Humanity: A Report on APNOMS 2020," Network and Systems Management, 29(4), p.1-11, 2021.
+Dener Kraus, "Computação de borda para indústria utilizando a rede 5G," 2021.
+Iria Míguez González, "Virtualized cellular networks with native cloud functions," Master Thesis, Telecommunications Engineering School, 2021.
+Cameron MacLeod, "Kubernetes for the Deployment of Mobile Core Networks," 2020.
+Yi-Bing Lin, Chien-Chao Tseng, and Ming-Hung Wang, "Effects of Transport Network Slicing on 5G Applications," Future Internet, 13(3), p.69, 2021.
+Alireza Hosseini Vasoukolaei, Danish Sattar, and Ashraf Matrawy, "TLS Performance Evaluation in the Control Plane of a 5G Core Network Slice," 2021.
+Rui Silva, et al., "A hybrid SDN solution for mobile networks," Computer Networks, 2021.
+Wei-Lun Lin, Chien-Hsuan Chen, and Huai-Sheng Huang, "Study on the Online Charging System in B5G Era," IEEE Asia-Pacific Network Operations and Management Symposium, 2021.
+David Lake, et al. ", "Softwarization of 5G Networks – Implications to Open Platforms and Standardizations," IEEE access 9, 2021.
+Ali Esmaeily, and Katina Kralevska, "Small-Scale 5G Testbeds for Network Slicing Deployment: A Systematic Review," Wireless Communications and Mobile Computing, 2021.
+Cheng-Ying Hsieh, et al., "Design and implementation of a generic 5G user plane function development framework," Annual International Conference on Mobile Computing and Networking, 2021.
+Yu-Herng Chai, and Fuchun Joseph Lin, "," Computer and Communications, 9(7), p.55-72, 2021.
+Ashok Kumar Murthy, Ranjani Parthasarathi, and V. Vetriselvi, "Security Testbed for Next Generation Mobile Networks," IEEE Third ISEA Conference on Security and Privacy, p.122-129, 2020.
+Tze-Jie Tan, et al., "A Reliable Intelligent Routing Mechanism in 5G Core Network (5GC)," Annual International Conference on Mobile Computing and Networking, 2020.
+Merlin Chlosta, et al., "5G SUCI-Catchers: Still catching them all?" Annual International Conference on Mobile Computing and Networking, 2020.
+Chia-Wei Liao, Fuchun Joseph Lin, and Yoichi Sato, "Evaluating NFV-enabled Network Slicing for 5G Core," IEEE Asia-Pacific Network Operations and Management Symposium, 2020.
+Žiga Berčič, et al., "Raziskava in praktični preizkus odprtokodnih mobilnih jedrnih sistemov 4G in 5G," Diss. Univerza v Ljubljani, Fakulteta za elektrotehniko, 2020.
+Christian Mailer, "Plataforma de CORE 5G em nuvem para disponibilização de funções de rede como serviço," 2020.
+Leonardo Bonati, et al., "Open, Programmable, and Virtualized 5G Networks: State-of-the-Art and the Road Ahead," Computer Networks, 2020.
+Hung-Yen Weng, Ren-Hung Hwang, and Chin-Feng Lai, "Live MPEG-DASH video streaming cache management with cognitive mobile edge computing," Ambient Intelligence and Humanized Computing p.1-18, 2020.
+Junaid Jalal, "Enabling Edge Computing In 5G Via Local Area Data Network: Implementation and Experiments," Master Thesis, University of Agder, 2019.
+The free5GC is an open-source project for 5th generation (5G) mobile core networks. The ultimate goal of this project is to implement the 5G core network (5GC) defined in 3GPP Release 15 (R15) and beyond.
Currently, the major contributors are from National Yang Ming Chiao Tung University (NYCU). Please refer to our roadmap for the features of each release.
Note
Thank you very much for your interest in free5GC. The license of free5GC follows Apache 2.0. That is, anyone can use free5GC for commercial purposes for free.
"},{"location":"#sponsors","title":"Sponsors","text":""},{"location":"#platinum","title":"Platinum","text":""},{"location":"#gold","title":"Gold","text":""},{"location":"#silver","title":"Silver","text":""},{"location":"#hardware-sponsors","title":"Hardware Sponsors","text":""},{"location":"publication/","title":"Relavent Publication","text":""},{"location":"publication/#publications-using-free5gc","title":"Publications using free5GC","text":"V. Jain, H.-T. Chu, S. Qi, C.-A. Lee, H.-C. Chang, C.-Y. Hsieh, K. K. Ramakrishnan, and J.-C. Chen, \"L25GC: A Low Latency 5G Core Network based on High-Performance NFV Platforms,\" full paper, ACM SIGCOMM Conference (SIGCOMM \u201822), (Amsterdam, Netherlands), pp. 143\u2013157, Aug. 2022.
C.-Y. Hsieh, Y.-W. Chang, C. Chen, and J.-C. Chen, \"Poster: Design and Implementation of a Generic 5G User Plane Function Development Framework,\" ACM International Conference on Mobile Computing and Networking (MobiCom \u201821), (New Orleans, United States), pp. 846\u2013848, Oct. 2021. (Won second place of the ACM MobiCom 2021 Student Research Competition)
Ralf Kundel, et al., \"User plane hardware acceleration in access networks: Experiences in offloading network functions in real 5g deployments,\" Hawaii International Conference on System Sciences. Computer Society Press, 2022.
Taeyun Kim, et al., \"An Implementation Study of Network Data Analytic Function in 5G,\" IEEE International Conference on Consumer Electronics, 2022.
Zhou Cong, et al., \"CeUPF: Offloading 5G User Plane Function to Programmable Hardware Base on Co-existence Architecture,\" ACM International Conference on Intelligent Computing and its Emerging Applications, 2021.
Gholamreza Ramezan, et al., \"EAP-ZKP: A Zero-Knowledge Proof based Authentication Protocol to Prevent DDoS Attacks at the Edge in Beyond 5G,\" IEEE 4th 5G World Forum, 2021.
Ryan Pepito and Ashutosh Dutta, \"Open Source 5G Security Testbed for Edge Computing,\" IEEE 5G World Forum (5GWF), 2021.
Robert MacDavid, et al., \"A P4-based 5G User Plane Function,\" 2021.
Joe Breen, et al., \"Powder: Platform for Open Wireless Data-driven Experimental Research\",\" Computer Networks, 2021.
Endri Goshi, et al,, \"Investigating Inter-NF Dependencies in Cloud-Native 5G Core Network,\" International Conference on Network and Service Management, 2021.
Zhi-Li Zhang, et al., \"Towards aSoftware-Defined, Fine-Grained QoS Framework for 5G and Beyond Networks,\" ACM SIGCOMM Workshop on Network-Application Integration, 2021.
Zujany Salazar, et al, \"5Greplay: a 5G Network Traffic Fuzzer - Application to Attack Injection,\" International Conference on Availability, Reliability and Security, 2021.
Yu-Herng Chai, and Fuchun Joseph Lin, \"Evaluating Dedicated Slices of Different Configurations in 5G Core,\" Computer and Communications, 9(7), p.55-72, 2021.
M.J. Kim, et al., \"Analysis of Current 5G Open-Source Projects,\" Electronics and Telecommunications Trends, 36(2), p.83-92, 2021.
Yang Hu, et al., \"Fuzzing Method Based on Selection Mutation of Partition Weight Table for 5G Core Network NGAP Protocol,\" International Conference on Innovative Mobile and Internet Services in Ubiquitous Computing. Springer, Cham, 2021.
Cheng-Chin Tsai, Fuchun Joseph Lin, and Hiroshige Tanaka, \"Evaluation of 5G Core Slicing on User Plane Function,\" Communications and Network, 13(3), p.79-92, 2021.
Wei-Cheng Chang, and Fuchun Joseph Lin, \"Coordinated Management of 5G Core Slices by MANO and OSS/BSS,\" Computer and Communications, 9(6), p.52-72, 2021.
Ayoub Bergaoui, et al., \"Demonstration of Orchestration of 5G Core Network Functions with a Satellite Emulator,\" 2021.
Seungjoon Seok, et al, \"Towards Service and Networking Intelligence for Humanity: A Report on APNOMS 2020,\" Network and Systems Management, 29(4), p.1-11, 2021.
Dener Kraus, \"Computa\u00e7\u00e3o de borda para ind\u00fastria utilizando a rede 5G,\" 2021.
Iria M\u00edguez Gonz\u00e1lez, \"Virtualized cellular networks with native cloud functions,\" Master Thesis, Telecommunications Engineering School, 2021.
Cameron MacLeod, \"Kubernetes for the Deployment of Mobile Core Networks,\" 2020.
Yi-Bing Lin, Chien-Chao Tseng, and Ming-Hung Wang, \"Effects of Transport Network Slicing on 5G Applications,\" Future Internet, 13(3), p.69, 2021.
Alireza Hosseini Vasoukolaei, Danish Sattar, and Ashraf Matrawy, \"TLS Performance Evaluation in the Control Plane of a 5G Core Network Slice,\" 2021.
Rui Silva, et al., \"A hybrid SDN solution for mobile networks,\" Computer Networks, 2021.
Wei-Lun Lin, Chien-Hsuan Chen, and Huai-Sheng Huang, \"Study on the Online Charging System in B5G Era,\" IEEE Asia-Pacific Network Operations and Management Symposium, 2021.
David Lake, et al. \", \"Softwarization of 5G Networks \u2013 Implications to Open Platforms and Standardizations,\" IEEE access 9, 2021.
Ali Esmaeily, and Katina Kralevska, \"Small-Scale 5G Testbeds for Network Slicing Deployment: A Systematic Review,\" Wireless Communications and Mobile Computing, 2021.
Cheng-Ying Hsieh, et al., \"Design and implementation of a generic 5G user plane function development framework,\" Annual International Conference on Mobile Computing and Networking, 2021.
Yu-Herng Chai, and Fuchun Joseph Lin, \",\" Computer and Communications, 9(7), p.55-72, 2021.
Ashok Kumar Murthy, Ranjani Parthasarathi, and V. Vetriselvi, \"Security Testbed for Next Generation Mobile Networks,\" IEEE Third ISEA Conference on Security and Privacy, p.122-129, 2020.
Tze-Jie Tan, et al., \"A Reliable Intelligent Routing Mechanism in 5G Core Network (5GC),\" Annual International Conference on Mobile Computing and Networking, 2020.
Merlin Chlosta, et al., \"5G SUCI-Catchers: Still catching them all?\" Annual International Conference on Mobile Computing and Networking, 2020.
Chia-Wei Liao, Fuchun Joseph Lin, and Yoichi Sato, \"Evaluating NFV-enabled Network Slicing for 5G Core,\" IEEE Asia-Pacific Network Operations and Management Symposium, 2020.
\u017diga Ber\u010di\u010d, et al., \"Raziskava in prakti\u010dni preizkus odprtokodnih mobilnih jedrnih sistemov 4G in 5G,\" Diss. Univerza v Ljubljani, Fakulteta za elektrotehniko, 2020.
Christian Mailer, \"Plataforma de CORE 5G em nuvem para disponibiliza\u00e7\u00e3o de fun\u00e7\u00f5es de rede como servi\u00e7o,\" 2020.
Leonardo Bonati, et al., \"Open, Programmable, and Virtualized 5G Networks: State-of-the-Art and the Road Ahead,\" Computer Networks, 2020.
Hung-Yen Weng, Ren-Hung Hwang, and Chin-Feng Lai, \"Live MPEG-DASH video streaming cache management with cognitive mobile edge computing,\" Ambient Intelligence and Humanized Computing p.1-18, 2020.
Junaid Jalal, \"Enabling Edge Computing In 5G Via Local Area Data Network: Implementation and Experiments,\" Master Thesis, University of Agder, 2019.
Akraino Blueprints: Integrated Cloud Native Private Wireless, The Linux Foundation, October 11, 2021
SD Core Techinar July 7 2021, Open Networking Foundation, July 13, 2021
Aarna Networks MWC 2021 Demo, Aarna Networks Channel, June 27, 2021
OpenStack Tacker Demo, Open Infrastructure Foundation, April 26, 2021
OpenNess Tungsten Fabric free5GC demo, Aarna Networks Channel, February 16, 2021
5G Core on Diamanti, Diamanti, Inc., February 3, 2021
free5GC (5G Core) Orchestration on Kubernetes with Tungsten Fabric CNI and Testing, Aarna Networks Channel, December 2, 2020
IoT LoRa (sensors and gateway in hardware), RAN in hardware (SDR) and software, and the free5GC, LABORA Research Group, July 3, 2020
UE and eNodeB in Hardware (conventional cell phone + SDR) and free5GC: a pratical approach in 5G, LABORA Research Group, July 3, 2020
OpenAirInterface and free5GC: a pratical approach in 5G networks, LABORA Research Group, June 29, 2020
Note
Author: Jimmy Chang Date: 2023/7/5
"},{"location":"blog/1-free5gc-with-namespace/#overview","title":"Overview","text":"This technique leverages namespace to run UERANSIM, an opensource 5G-UE and RAN(gNodeB) simulator, and connect to free5GC. UERANSIM follows the 3GPP specification for developing and can support multiple 5G core (5GC) including free5GC.
Why are we using namespace? Well, you can follow ULCL and free5GC compose to set up the environment with VM and docker, but there are limitations for hardware\u2019s capability. With network namespace, you can have different and separate network instances of network interfaces and routing tables that operate independently.
So, what is network namespace? Network namespace makes a copy of network stack with its own routing table, firewall and devices. A named network namespace is an object at /var/run/netns/
. The file descriptor resulting from opening /var/run/netns/
refers to the specified network namespace. Holding that file descriptor open keeps the network namespace alive.
And how to make both namespaces communicating? A virtual Ethernet device (veth) pair provides the abstraction that can be used to create tunnels between network namespaces, and can be used to create bridge to a physical network device in another namespace. Veth pair also be used as standalone network devices. When the namespace freed, veth device which attatch to would be destroyed.
The environment is as follow. Suppose you have already installed as well as set up free5GC and UERANSIM properly.
Note
Namespace free5GC represents host network namespace. And enp0s5 is an ethernet interface connectting to external.
Each devices as follow\n| Device | IP |\n| ------------- | ------------- |\n| veth0 | 10.200.200.1 |\n| veth1 | 10.200.200.2 |\n| br-veth0 | none |\n| br-veth1 | none |\n| enp0s5 | 10.211.55.23 |\n\n\nUE information in UERANSIM as follow. Already \n| IMSI | DNN |\n| ---------------- | ------------- |\n| 208930000000003 | internet |\n
"},{"location":"blog/1-free5gc-with-namespace/#configuration-file-of-free5gc-and-ueransim","title":"Configuration file of free5GC and UERANSIM","text":""},{"location":"blog/1-free5gc-with-namespace/#free5gc","title":"free5GC","text":"Replace ngapIpList IP from 127.0.0.18
to 10.200.200.2
:
info:\nversion: 1.0.9\ndescription: AMF initial local configuration\n\nconfiguration:\namfName: AMF # the name of this AMF\nngapIpList: # the IP list of N2 interfaces on this AMF\n- 10.200.200.2 # 127.0.0.18\nngapPort: 38412 # the SCTP port listened by NGAP\nsbi: # Service-based interface information\nscheme: http # the protocol for sbi (http or https)\nregisterIPv4: 127.0.0.18 # IP used to register to NRF\nbindingIPv4: 127.0.0.18 # IP used to bind the service\nport: 8000 # port used to bind the service\ntls: # the local path of TLS key\npem: cert/amf.pem # AMF TLS Certificate\nkey: cert/amf.key # AMF TLS Private key\nserviceNameList: # the SBI services provided by this AMF, refer to TS 29.518\n- namf-comm # Namf_Communication service\n- namf-evts # Namf_EventExposure service\n- namf-mt # Namf_MT service\n- namf-loc # Namf_Location service\n- namf-oam # OAM service\nservedGuamiList: # Guami (Globally Unique AMF ID) list supported by this AMF\n# <GUAMI> = <MCC><MNC><AMF ID>\n- plmnId: # Public Land Mobile Network ID, <PLMN ID> = <MCC><MNC>\nmcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)\nmnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)\namfId: cafe00 # AMF identifier (3 bytes hex string, range: 000000~FFFFFF)\nsupportTaiList: # the TAI (Tracking Area Identifier) list supported by this AMF\n- plmnId: # Public Land Mobile Network ID, <PLMN ID> = <MCC><MNC>\nmcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)\nmnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)\ntac: 000001 # Tracking Area Code (3 bytes hex string, range: 000000~FFFFFF)\nplmnSupportList: # the PLMNs (Public land mobile network) list supported by this AMF\n- plmnId: # Public Land Mobile Network ID, <PLMN ID> = <MCC><MNC>\nmcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)\nmnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)\nsnssaiList: # the S-NSSAI (Single Network Slice Selection Assistance Information) list supported by this AMF\n- sst: 1 # Slice/Service Type (uinteger, range: 0~255)\nsd: 010203 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)\n- sst: 1 # Slice/Service Type (uinteger, range: 0~255)\nsd: 112233 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)\nsupportDnnList: # the DNN (Data Network Name) list supported by this AMF\n- internet\nnrfUri: http://127.0.0.10:8000 # a valid URI of NRF\nsecurity: # NAS security parameters\nintegrityOrder: # the priority of integrity algorithms\n- NIA2\n# - NIA0\ncipheringOrder: # the priority of ciphering algorithms\n- NEA0\n# - NEA2\nnetworkName: # the name of this core network\nfull: free5GC\nshort: free\nngapIE: # Optional NGAP IEs\nmobilityRestrictionList: # Mobility Restriction List IE, refer to TS 38.413\nenable: true # append this IE in related message or not\nmaskedIMEISV: # Masked IMEISV IE, refer to TS 38.413\nenable: true # append this IE in related message or not\nredirectionVoiceFallback: # Redirection Voice Fallback IE, refer to TS 38.413\nenable: false # append this IE in related message or not\nnasIE: # Optional NAS IEs\nnetworkFeatureSupport5GS: # 5gs Network Feature Support IE, refer to TS 24.501\nenable: true # append this IE in Registration accept or not\nlength: 1 # IE content length (uinteger, range: 1~3)\nimsVoPS: 0 # IMS voice over PS session indicator (uinteger, range: 0~1)\nemc: 0 # Emergency service support indicator for 3GPP access (uinteger, range: 0~3)\nemf: 0 # Emergency service fallback indicator for 3GPP access (uinteger, range: 0~3)\niwkN26: 0 # Interworking without N26 interface indicator (uinteger, range: 0~1)\nmpsi: 0 # MPS indicator (uinteger, range: 0~1)\nemcN3: 0 # Emergency service support indicator for Non-3GPP access (uinteger, range: 0~1)\nmcsi: 0 # MCS indicator (uinteger, range: 0~1)\nt3502Value: 720 # timer value (seconds) at UE side\nt3512Value: 3600 # timer value (seconds) at UE side\nnon3gppDeregTimerValue: 3240 # timer value (seconds) at UE side\n# retransmission timer for paging message\nt3513:\nenable: true # true or false\nexpireTime: 6s # default is 6 seconds\nmaxRetryTimes: 4 # the max number of retransmission\n# retransmission timer for NAS Deregistration Request message\nt3522:\nenable: true # true or false\nexpireTime: 6s # default is 6 seconds\nmaxRetryTimes: 4 # the max number of retransmission\n# retransmission timer for NAS Registration Accept message\nt3550:\nenable: true # true or false\nexpireTime: 6s # default is 6 seconds\nmaxRetryTimes: 4 # the max number of retransmission\n# retransmission timer for NAS Authentication Request/Security Mode Command message\nt3560:\nenable: true # true or false\nexpireTime: 6s # default is 6 seconds\nmaxRetryTimes: 4 # the max number of retransmission\n# retransmission timer for NAS Notification message\nt3565:\nenable: true # true or false\nexpireTime: 6s # default is 6 seconds\nmaxRetryTimes: 4 # the max number of retransmission\n# retransmission timer for NAS Identity Request message\nt3570:\nenable: true # true or false\nexpireTime: 6s # default is 6 seconds\nmaxRetryTimes: 4 # the max number of retransmission\nlocality: area1 # Name of the location where a set of AMF, SMF, PCF and UPFs are located\nsctp: # set the sctp server setting <optinal>, once this field is set, please also add maxInputStream, maxOsStream, maxAttempts, maxInitTimeOut\nnumOstreams: 3 # the maximum out streams of each sctp connection\nmaxInstreams: 5 # the maximum in streams of each sctp connection\nmaxAttempts: 2 # the maximum attempts of each sctp connection\nmaxInitTimeout: 2 # the maximum init timeout of each sctp connection\ndefaultUECtxReq: false # the default value of UE Context Request to decide when triggering Initial Context Setup procedure\n\nlogger: # log output setting\nenable: true # true or false\nlevel: info # how detailed to output, value: trace, debug, info, warn, error, fatal, panic\nreportCaller: false # enable the caller report or not, value: true or false\n
- free5gc/config/smfcfg.yaml Replace userplaneInformation / upNodes / UPF / interfaces / endpoints from 127.0.0.8
to 10.200.200.2
:
info:\nversion: 1.0.7\ndescription: SMF initial local configuration\n\nconfiguration:\nsmfName: SMF # the name of this SMF\nsbi: # Service-based interface information\nscheme: http # the protocol for sbi (http or https)\nregisterIPv4: 127.0.0.2 # IP used to register to NRF\nbindingIPv4: 127.0.0.2 # IP used to bind the service\nport: 8000 # Port used to bind the service\ntls: # the local path of TLS key\nkey: cert/smf.key # SMF TLS Certificate\npem: cert/smf.pem # SMF TLS Private key\nserviceNameList: # the SBI services provided by this SMF, refer to TS 29.502\n- nsmf-pdusession # Nsmf_PDUSession service\n- nsmf-event-exposure # Nsmf_EventExposure service\n- nsmf-oam # OAM service\nsnssaiInfos: # the S-NSSAI (Single Network Slice Selection Assistance Information) list supported by this AMF\n- sNssai: # S-NSSAI (Single Network Slice Selection Assistance Information)\nsst: 1 # Slice/Service Type (uinteger, range: 0~255)\nsd: 010203 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)\ndnnInfos: # DNN information list\n- dnn: internet # Data Network Name\ndns: # the IP address of DNS\nipv4: 8.8.8.8\nipv6: 2001:4860:4860::8888\n- sNssai: # S-NSSAI (Single Network Slice Selection Assistance Information)\nsst: 1 # Slice/Service Type (uinteger, range: 0~255)\nsd: 112233 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)\ndnnInfos: # DNN information list\n- dnn: internet # Data Network Name\ndns: # the IP address of DNS\nipv4: 8.8.8.8\nipv6: 2001:4860:4860::8888\nplmnList: # the list of PLMN IDs that this SMF belongs to (optional, remove this key when unnecessary)\n- mcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)\nmnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)\nlocality: area1 # Name of the location where a set of AMF, SMF, PCF and UPFs are located\npfcp: # the IP address of N4 interface on this SMF (PFCP)\n# addr config is deprecated in smf config v1.0.3, please use the following config\nnodeID: 127.0.0.1 # the Node ID of this SMF\nlistenAddr: 127.0.0.1 # the IP/FQDN of N4 interface on this SMF (PFCP)\nexternalAddr: 127.0.0.1 # the IP/FQDN of N4 interface on this SMF (PFCP)\nuserplaneInformation: # list of userplane information\nupNodes: # information of userplane node (AN or UPF)\ngNB1: # the name of the node\ntype: AN # the type of the node (AN or UPF)\nUPF: # the name of the node\ntype: UPF # the type of the node (AN or UPF)\nnodeID: 127.0.0.8 # the Node ID of this UPF\naddr: 127.0.0.8 # the IP/FQDN of N4 interface on this UPF (PFCP)\nsNssaiUpfInfos: # S-NSSAI information list for this UPF\n- sNssai: # S-NSSAI (Single Network Slice Selection Assistance Information)\nsst: 1 # Slice/Service Type (uinteger, range: 0~255)\nsd: 010203 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)\ndnnUpfInfoList: # DNN information list for this S-NSSAI\n- dnn: internet\npools:\n- cidr: 10.60.0.0/16\nstaticPools:\n- cidr: 10.60.100.0/24\n- sNssai: # S-NSSAI (Single Network Slice Selection Assistance Information)\nsst: 1 # Slice/Service Type (uinteger, range: 0~255)\nsd: 112233 # Slice Differentiator (3 bytes hex string, range: 000000~FFFFFF)\ndnnUpfInfoList: # DNN information list for this S-NSSAI\n- dnn: internet\npools:\n- cidr: 10.61.0.0/16\nstaticPools:\n- cidr: 10.61.100.0/24\ninterfaces: # Interface list for this UPF\n- interfaceType: N3 # the type of the interface (N3 or N9)\nendpoints: # the IP address of this N3/N9 interface on this UPF\n- 10.200.200.2 # 127.0.0.8\nnetworkInstances: # Data Network Name (DNN)\n- internet\nlinks: # the topology graph of userplane, A and B represent the two nodes of each link\n- A: gNB1\nB: UPF\n# retransmission timer for pdu session modification command\nt3591:\nenable: true # true or false\nexpireTime: 16s # default is 6 seconds\nmaxRetryTimes: 3 # the max number of retransmission\n# retransmission timer for pdu session release command\nt3592:\nenable: true # true or false\nexpireTime: 16s # default is 6 seconds\nmaxRetryTimes: 3 # the max number of retransmission\nnrfUri: http://127.0.0.10:8000 # a valid URI of NRF\n#urrPeriod: 10 # default usage report period in seconds\n#urrThreshold: 1000 # default usage report threshold in bytes\n\nlogger: # log output setting\nenable: true # true or false\nlevel: info # how detailed to output, value: trace, debug, info, warn, error, fatal, panic\nreportCaller: false # enable the caller report or not, value: true or false\n
- free5gc/config/upfcfg.yaml Replace gtpu from 127.0.0.8
to 10.200.200.2
:
version: 1.0.3\ndescription: UPF initial local configuration\n\n# The listen IP and nodeID of the N4 interface on this UPF (Can't set to 0.0.0.0)\npfcp:\naddr: 127.0.0.8 # IP addr for listening\nnodeID: 127.0.0.8 # External IP or FQDN can be reached\nretransTimeout: 1s # retransmission timeout\nmaxRetrans: 3 # the max number of retransmission\n\ngtpu:\nforwarder: gtp5g\n# The IP list of the N3/N9 interfaces on this UPF\n# If there are multiple connection, set addr to 0.0.0.0 or list all the addresses\nifList:\n- addr: 10.200.200.2 # 127.0.0.8\ntype: N3\n# name: upf.5gc.nctu.me\n# ifname: gtpif\n# mtu: 1400\n\n# The DNN list supported by UPF\ndnnList:\n- dnn: internet # Data Network Name\ncidr: 10.60.0.0/24 # Classless Inter-Domain Routing for assigned IPv4 pool of UE\n# natifname: eth0\n\nlogger: # log output setting\nenable: true # true or false\nlevel: info # how detailed to output, value: trace, debug, info, warn, error, fatal, panic\nreportCaller: false # enable the caller report or not, value: true or false\n
"},{"location":"blog/1-free5gc-with-namespace/#ueransim","title":"UERANSIM","text":"UERANSIM/config/free5gc-gnb.yaml
Replace ngapIp from 127.0.0.1
to 10.200.200.1
Replace gtpIp from 127.0.0.1
to 10.200.200.1
Replace amfConfigs / address from 127.0.0.1
to 10.200.200.2
mcc: '208' # Mobile Country Code value\nmnc: '93' # Mobile Network Code value (2 or 3 digits)\n\nnci: '0x000000010' # NR Cell Identity (36-bit)\nidLength: 32 # NR gNB ID length in bits [22...32]\ntac: 1 # Tracking Area Code\n\nlinkIp: 127.0.0.1 # gNB's local IP address for Radio Link Simulation (Usually same with local IP)\nngapIp: 10.200.200.1 # 127.0.0.1 # gNB's local IP address for N2 Interface (Usually same with local IP)\ngtpIp: 10.200.200.1 # 127.0.0.1 # gNB's local IP address for N3 Interface (Usually same with local IP)\n\n# List of AMF address information\namfConfigs:\n- address: 10.200.200.2 # 127.0.0.1\nport: 38412\n\n# List of supported S-NSSAIs by this gNB\nslices:\n- sst: 0x1\nsd: 0x010203\n\n# Indicates whether or not SCTP stream number errors should be ignored.\nignoreStreamIds: true\n
- UERANSIM/config/free5gc-ue.yaml # IMSI number of the UE. IMSI = [MCC|MNC|MSISDN] (In total 15 or 16 digits)\nsupi: 'imsi-208930000000003'\n# Mobile Country Code value\nmcc: '208'\n# Mobile Network Code value (2 or 3 digits)\nmnc: '93'\n\n# Permanent subscription key\nkey: '8baf473f2f8fd09487cccbd7097c6862'\n# Operator code (OP or OPC) of the UE\nop: '8e27b6af0e692e750f32667a3b14605d'\n# This value specifies the OP type and it can be either 'OP' or 'OPC'\nopType: 'OP'\n# Authentication Management Field (AMF) value\namf: '8000'\n# IMEI number of the device. It is used if no SUPI is provided\nimei: '356938035643803'\n# IMEISV number of the device. It is used if no SUPI and IMEI is provided\nimeiSv: '4370816125816151'\n\n# List of gNB IP addresses for Radio Link Simulation\ngnbSearchList:\n- 127.0.0.1\n\n# Initial PDU sessions to be established\nsessions:\n- type: 'IPv4'\napn: 'internet'\nslice:\nsst: 0x01\nsd: 0x010203\n\n# List of requested S-NSSAIs by this UE\nslices:\n- sst: 0x01\nsd: 0x010203\n\n# Supported encryption and integrity algorithms by this UE\nintegrity:\nIA1: true\nIA2: true\nIA3: true\nciphering:\nEA1: true\nEA2: true\nEA3: true\n
"},{"location":"blog/1-free5gc-with-namespace/#environment-set-up-of-free5gc-and-ueransim","title":"Environment set up of free5GC and UERANSIM","text":"First, create a namespace:
Note
Assume that you are either running as root, or it behoves you to prepend sudo
to commands as necessary.
ip netns add ueransim\n
Next, add the bridge: ip link add free5gc-br type bridge\n
Add two pairs of veth: ip link add veth0 type veth peer name br-veth0\nip link add veth1 type veth peer name br-veth1\n
Now, it could be like: root@free5gc:~# ip a\n1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000\n link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n inet 127.0.0.1/8 scope host lo\n valid_lft forever preferred_lft forever\n inet6 ::1/128 scope host\n valid_lft forever preferred_lft forever\n2: enp0s5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000\n link/ether 00:1c:42:b1:ba:f4 brd ff:ff:ff:ff:ff:ff\n inet 10.211.55.23/24 brd 10.211.55.255 scope global dynamic enp0s5\n valid_lft 1714sec preferred_lft 1714sec\n inet6 fdb2:2c26:f4e4:0:21c:42ff:feb1:baf4/64 scope global dynamic mngtmpaddr noprefixroute\n valid_lft 2591750sec preferred_lft 604550sec\n inet6 fe80::21c:42ff:feb1:baf4/64 scope link\n valid_lft forever preferred_lft forever\n3: enp0s6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000\n link/ether 00:1c:42:f1:11:c6 brd ff:ff:ff:ff:ff:ff\n inet 10.37.129.20/24 brd 10.37.129.255 scope global enp0s6\n valid_lft forever preferred_lft forever\n inet6 fdb2:2c26:f4e4:1:21c:42ff:fef1:11c6/64 scope global dynamic mngtmpaddr noprefixroute\n valid_lft 2591750sec preferred_lft 604550sec\n inet6 fe80::21c:42ff:fef1:11c6/64 scope link\n valid_lft forever preferred_lft forever\n4: free5gc-br: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000\n link/ether 4e:f6:d7:9c:50:de brd ff:ff:ff:ff:ff:ff\n5: br-veth0@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000\n link/ether c2:31:0c:5f:45:81 brd ff:ff:ff:ff:ff:ff\n6: veth0@br-veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000\n link/ether 4a:0f:1e:80:9b:be brd ff:ff:ff:ff:ff:ff\n7: br-veth1@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000\n link/ether 56:99:b0:82:78:0d brd ff:ff:ff:ff:ff:ff\n8: veth1@br-veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000\n link/ether 12:5a:56:00:5b:be brd ff:ff:ff:ff:ff:ff\n
Next, assign interface to namespace:
ip link set dev veth0 netns ueransim\n
Set ip address: ip netns exec ueransim ip a add 10.200.200.1/24 dev veth0\n
Enable both interface. Don't forget lo: ip netns exec ueransim ip link set lo up\nip netns exec ueransim ip link set veth0 up\n
Check with ip a
: root@free5gc:~# ip netns exec ueransim ip a\n1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000\n link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n inet 127.0.0.1/8 scope host lo\n valid_lft forever preferred_lft forever\n inet6 ::1/128 scope host\n valid_lft forever preferred_lft forever\n6: veth0@if5: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000\n link/ether 4a:0f:1e:80:9b:be brd ff:ff:ff:ff:ff:ff link-netnsid 0\n inet 10.200.200.1/24 scope global veth0\n valid_lft forever preferred_lft forever\n
Set for veth1 as well: ip a add 10.200.200.2/24 dev veth1\nip link set veth1 up\n
Let two interfaces attatch to bridge: ip link set dev br-veth0 master free5gc-br\nip link set dev br-veth1 master free5gc-br\nip link set br-veth0 up\nip link set br-veth1 up\nip link set free5gc-br up\n
Using bridge link
to check: root@free5gc:~# bridge link\n5: br-veth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master free5gc-br state forwarding priority 32 cost 2\n7: br-veth1@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master free5gc-br state forwarding priority 32 cost 2\n
Now it looks like: 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000\n link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n inet 127.0.0.1/8 scope host lo\n valid_lft forever preferred_lft forever\n inet6 ::1/128 scope host\n valid_lft forever preferred_lft forever\n2: enp0s5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000\n link/ether 00:1c:42:b1:ba:f4 brd ff:ff:ff:ff:ff:ff\n inet 10.211.55.23/24 brd 10.211.55.255 scope global dynamic enp0s5\n valid_lft 1000sec preferred_lft 1000sec\n inet6 fdb2:2c26:f4e4:0:21c:42ff:feb1:baf4/64 scope global dynamic mngtmpaddr noprefixroute\n valid_lft 2591870sec preferred_lft 604670sec\n inet6 fe80::21c:42ff:feb1:baf4/64 scope link\n valid_lft forever preferred_lft forever\n3: enp0s6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000\n link/ether 00:1c:42:f1:11:c6 brd ff:ff:ff:ff:ff:ff\n inet 10.37.129.20/24 brd 10.37.129.255 scope global enp0s6\n valid_lft forever preferred_lft forever\n inet6 fdb2:2c26:f4e4:1:21c:42ff:fef1:11c6/64 scope global dynamic mngtmpaddr noprefixroute\n valid_lft 2591870sec preferred_lft 604670sec\n inet6 fe80::21c:42ff:fef1:11c6/64 scope link\n valid_lft forever preferred_lft forever\n4: free5gc-br: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000\n link/ether 56:99:b0:82:78:0d brd ff:ff:ff:ff:ff:ff\n inet6 fe80::5499:b0ff:fe82:780d/64 scope link\n valid_lft forever preferred_lft forever\n5: br-veth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master free5gc-br state UP group default qlen 1000\n link/ether c2:31:0c:5f:45:81 brd ff:ff:ff:ff:ff:ff link-netns ueransim\n inet6 fe80::c031:cff:fe5f:4581/64 scope link\n valid_lft forever preferred_lft forever\n7: br-veth1@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master free5gc-br state UP group default qlen 1000\n link/ether 56:99:b0:82:78:0d brd ff:ff:ff:ff:ff:ff\n inet6 fe80::5499:b0ff:fe82:780d/64 scope link\n valid_lft forever preferred_lft forever\n8: veth1@br-veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000\n link/ether 12:5a:56:00:5b:be brd ff:ff:ff:ff:ff:ff\n inet 10.200.200.2/24 scope global veth1\n valid_lft forever preferred_lft forever\n inet6 fe80::105a:56ff:fe00:5bbe/64 scope link\n valid_lft forever preferred_lft forever\n
Let's test it: Note
You can perform ip netns exec ueransim /bin/bash --rcfile <(echo \"PS1=\\\"ueransim> \\\"\")
to enter namespace and modify shell prefix.
root@free5gc:~# ip netns exec ueransim /bin/bash --rcfile <(echo \"PS1=\\\"ueransim> \\\"\")\nueransim> ping -c2 10.200.200.2\nPING 10.200.200.2 (10.200.200.2) 56(84) bytes of data.\n64 bytes from 10.200.200.2: icmp_seq=1 ttl=64 time=0.089 ms\n64 bytes from 10.200.200.2: icmp_seq=2 ttl=64 time=0.226 ms\n\n--- 10.200.200.2 ping statistics ---\n2 packets transmitted, 2 received, 0% packet loss, time 1020ms\nrtt min/avg/max/mdev = 0.089/0.157/0.226/0.068 ms\n
Insert default routing rule: ueransim> ip route add default via 10.200.200.2\nueransim> netstat -rn\nKernel IP routing table\nDestination Gateway Genmask Flags MSS Window irtt Iface\n0.0.0.0 10.200.200.2 0.0.0.0 UG 0 0 0 veth0\n10.200.200.0 0.0.0.0 255.255.255.0 U 0 0 0 veth0\n
Try to ping 8.8.8.8: ueransim> ping -c2 8.8.8.8\nPING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.\n\n--- 8.8.8.8 ping statistics ---\n2 packets transmitted, 0 received, 100% packet loss, time 1028ms\n
It is because the main host must translate the source addresses. Besides, the main host need to forward packet: root@free5gc:~# iptables -t nat -A POSTROUTING -o enp0s5 -j MASQUERADE\nroot@free5gc:~# sysctl -w net.ipv4.ip_forward=1\nroot@free5gc:~# sudo iptables -I FORWARD 1 -j ACCEPT\n
And then: ueransim> ping -c2 8.8.8.8\nPING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.\n64 bytes from 8.8.8.8: icmp_seq=1 ttl=127 time=13.9 ms\n64 bytes from 8.8.8.8: icmp_seq=2 ttl=127 time=28.0 ms\n\n--- 8.8.8.8 ping statistics ---\n2 packets transmitted, 2 received, 0% packet loss, time 1002ms\nrtt min/avg/max/mdev = 13.866/20.939/28.012/7.073 ms\n
After free5GC execute run.sh
, it's time for UERANSIM:
In terminal 1:
ueransim> build/nr-gnb -c config/free5gc-gnb.yaml\nUERANSIM v3.1.0\n[2023-07-05 19:58:26.368] [sctp] [info] Trying to establish SCTP connection... (10.200.200.2:38412)\n[2023-07-05 19:58:26.373] [sctp] [info] SCTP connection established (10.200.200.2:38412)\n[2023-07-05 19:58:26.374] [sctp] [debug] SCTP association setup ascId[3]\n[2023-07-05 19:58:26.375] [ngap] [debug] Sending NG Setup Request\n[2023-07-05 19:58:26.380] [ngap] [debug] NG Setup Response received\n[2023-07-05 19:58:26.380] [ngap] [info] NG Setup procedure is successful\n[2023-07-05 19:58:35.804] [mr] [info] New UE connected to gNB. Total number of UEs is now: 1\n[2023-07-05 19:58:35.806] [rrc] [debug] Sending RRC Setup for UE[3]\n[2023-07-05 19:58:35.807] [ngap] [debug] Initial NAS message received from UE 3\n[2023-07-05 19:58:35.869] [ngap] [debug] Initial Context Setup Request received\n[2023-07-05 19:58:36.108] [ngap] [info] PDU session resource is established for UE[3] count[1]\n
In terminal 2: ueransim> sudo build/nr-ue -c config/free5gc-ue.yaml\nUERANSIM v3.1.0\n[2023-07-05 19:58:35.803] [nas] [debug] NAS layer started\n[2023-07-05 19:58:35.803] [rrc] [debug] RRC layer started\n[2023-07-05 19:58:35.804] [nas] [info] UE switches to state: MM-DEREGISTERED/PLMN-SEARCH\n[2023-07-05 19:58:35.804] [nas] [info] UE connected to gNB\n[2023-07-05 19:58:35.804] [nas] [info] UE switches to state: MM-DEREGISTERED/NORMAL-SERVICE\n[2023-07-05 19:58:35.804] [nas] [info] UE switches to state: MM-REGISTERED-INITIATED/NA\n[2023-07-05 19:58:35.805] [rrc] [debug] Sending RRC Setup Request\n[2023-07-05 19:58:35.806] [rrc] [info] RRC connection established\n[2023-07-05 19:58:35.806] [nas] [info] UE switches to state: CM-CONNECTED\n[2023-07-05 19:58:35.838] [nas] [debug] Received rand[61262F32A617D0BAD716603B1CBDA477] autn[44778026F4238000FC14B59D68855328]\n[2023-07-05 19:58:35.838] [nas] [debug] Calculated res[47759045F5ACEA59] ck[1C559301F29EF49572F5D150B3B99288] ik[D223317F752F233CE4C7AA253644D882] ak[528433D1FBE6] mac_a[FC14B59D68855328]\n[2023-07-05 19:58:35.838] [nas] [debug] Used snn[5G:mnc093.mcc208.3gppnetwork.org] sqn[16F3B3F70FC5]\n[2023-07-05 19:58:35.838] [nas] [debug] Derived kSeaf[7FC8B7FB1B141B6579B9C0FAEB9CCF1312FE9F9634868E234756DE49FD67C5F1] kAusf[FA0402A892E6046D52F4DECACA40B2A75B698FCEAD5EB320139FC69B77BD4C46] kAmf[3D4AD68E153B9642ACBECC67AD399015F7CB578F9DF4C88A35EED99C72C9B95B]\n[2023-07-05 19:58:35.843] [nas] [debug] Derived kNasEnc[1F829EB2BA238DD0226C3484E6A79D1F] kNasInt[251C0412B1BAD88A9DD0008F32D6F216]\n[2023-07-05 19:58:35.843] [nas] [debug] Selected integrity[2] ciphering[0]\n[2023-07-05 19:58:35.869] [nas] [debug] T3512 started with int[3600]\n[2023-07-05 19:58:35.869] [nas] [info] UE switches to state: MM-REGISTERED/NORMAL-SERVICE\n[2023-07-05 19:58:35.869] [nas] [info] Initial Registration is successful\n[2023-07-05 19:58:35.869] [nas] [info] Initial PDU sessions are establishing [1#]\n[2023-07-05 19:58:35.869] [nas] [debug] Sending PDU session establishment request\n[2023-07-05 19:58:36.108] [nas] [info] PDU Session establishment is successful PSI[1]\n[2023-07-05 19:58:36.113] [app] [info] Connection setup for PDU session[1] is successful, TUN interface[uesimtun0, 10.60.0.1] is up.\n
In terminal 3: ueransim> ip a\n1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000\n link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n inet 127.0.0.1/8 scope host lo\n valid_lft forever preferred_lft forever\n inet6 ::1/128 scope host\n valid_lft forever preferred_lft forever\n2: uesimtun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500\n link/none\n inet 10.60.0.1/32 scope global uesimtun0\n valid_lft forever preferred_lft forever\n inet6 fe80::b5ef:5b4:e3f6:af64/64 scope link stable-privacy\n valid_lft forever preferred_lft forever\n6: veth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000\n link/ether 4a:0f:1e:80:9b:be brd ff:ff:ff:ff:ff:ff link-netnsid 0\n inet 10.200.200.1/24 scope global veth0\n valid_lft forever preferred_lft forever\n inet6 fe80::480f:1eff:fe80:9bbe/64 scope link\n valid_lft forever preferred_lft forever\nueransim> ping -c2 -I uesimtun0 8.8.8.8\nPING 8.8.8.8 (8.8.8.8) from 10.60.0.1 uesimtun0: 56(84) bytes of data.\n64 bytes from 8.8.8.8: icmp_seq=1 ttl=127 time=19.5 ms\n64 bytes from 8.8.8.8: icmp_seq=2 ttl=127 time=33.2 ms\n\n--- 8.8.8.8 ping statistics ---\n2 packets transmitted, 2 received, 0% packet loss, time 1006ms\nrtt min/avg/max/mdev = 19.478/26.348/33.219/6.870 ms\n
Also ping to google.com: ueransim> ping -c2 -I uesimtun0 google.com\nPING google.com (172.217.160.110) from 10.60.0.1 uesimtun0: 56(84) bytes of data.\n64 bytes from tsa03s06-in-f14.1e100.net (172.217.160.110): icmp_seq=1 ttl=127 time=17.3 ms\n64 bytes from tsa03s06-in-f14.1e100.net (172.217.160.110): icmp_seq=2 ttl=127 time=29.5 ms\n\n--- google.com ping statistics ---\n2 packets transmitted, 2 received, 0% packet loss, time 1005ms\nrtt min/avg/max/mdev = 17.295/23.385/29.476/6.090 ms\n
"},{"location":"blog/1-free5gc-with-namespace/#what-if-two-ueransims-with-two-namespaces","title":"What if two UERANSIMs with two namespaces?","text":"Same as before, you should create another namespace for UERANSIM, called it ueransim2:
root@free5gc:~# ip netns ls\nueransim2 (id: 1)\nueransim (id: 0)\n
And then: ip link add veth2 type veth peer name br-veth2\nip link set dev veth2 netns ueransim2\nip link set br-veth2 master free5gc-br\nip link set br-veth2 up\nip netns exec ueransim2 ip a add 10.200.200.3/24 dev veth2\nip netns exec ueransim2 ip link set lo up\nip netns exec ueransim2 ip link set veth2 up\nip netns exec ueransim2 ip route add default via 10.200.200.2\n
Copy UERANSIM/config/free5gc-gnb.yaml and UERANSIM/config/free5gc-ue.yaml to free5gc-gnb2.yaml and free5gc-ue2.yaml, modify:
free5gc-gnb2.yaml
127.0.0.1
to 10.200.200.3
127.0.0.1
to 10.200.200.3
...\nngapIp: 10.200.200.3 # 127.0.0.1 # gNB's local IP address for N2 Interface (Usually same with local IP)\ngtpIp: 10.200.200.3 # 127.0.0.1 # gNB's local IP address for N3 Interface (Usually same with local IP)\n\n# List of AMF address information\namfConfigs:\n- address: 10.200.200.2 # 127.0.0.1\nport: 38412\n...\n
free5gc-ue2.yaml supi
change to imsi-208930000000004
...\n# IMSI number of the UE. IMSI = [MCC|MNC|MSISDN] (In total 15 or 16 digits)\nsupi: 'imsi-208930000000004'\n...\n
Note
Should register ue to webconsole first.
The result:
ueransim> ip a\n1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000\n link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n inet 127.0.0.1/8 scope host lo\n valid_lft forever preferred_lft forever\n inet6 ::1/128 scope host\n valid_lft forever preferred_lft forever\n6: veth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000\n link/ether 4a:0f:1e:80:9b:be brd ff:ff:ff:ff:ff:ff link-netnsid 0\n inet 10.200.200.1/24 scope global veth0\n valid_lft forever preferred_lft forever\n inet6 fe80::480f:1eff:fe80:9bbe/64 scope link\n valid_lft forever preferred_lft forever\n7: uesimtun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500\n link/none\n inet 10.60.0.1/32 scope global uesimtun0\n valid_lft forever preferred_lft forever\n inet6 fe80::f6d7:dd81:fe7f:496a/64 scope link stable-privacy\n valid_lft forever preferred_lft forever\nueransim> ping -c2 -I uesimtun0 google.com\nPING google.com (172.217.160.110) from 10.60.0.1 uesimtun0: 56(84) bytes of data.\n64 bytes from tsa03s06-in-f14.1e100.net (172.217.160.110): icmp_seq=1 ttl=127 time=17.2 ms\n64 bytes from tsa03s06-in-f14.1e100.net (172.217.160.110): icmp_seq=2 ttl=127 time=28.5 ms\n\n--- google.com ping statistics ---\n2 packets transmitted, 2 received, 0% packet loss, time 1003ms\nrtt min/avg/max/mdev = 17.200/22.863/28.527/5.663 ms\n
ueransim2> ip a\n1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000\n link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n inet 127.0.0.1/8 scope host lo\n valid_lft forever preferred_lft forever\n inet6 ::1/128 scope host \n valid_lft forever preferred_lft forever\n5: uesimtun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500\n link/none \n inet 10.60.0.2/32 scope global uesimtun0\n valid_lft forever preferred_lft forever\n inet6 fe80::16a4:523a:a86:bf83/64 scope link stable-privacy \n valid_lft forever preferred_lft forever\n12: veth2@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000\n link/ether fa:12:bb:9c:fa:40 brd ff:ff:ff:ff:ff:ff link-netnsid 0\n inet 10.200.200.3/24 scope global veth2\n valid_lft forever preferred_lft forever\n inet6 fe80::f812:bbff:fe9c:fa40/64 scope link \n valid_lft forever preferred_lft forever\nueransim2> ping -c2 -I uesimtun0 google.com\nPING google.com (172.217.160.110) from 10.60.0.2 uesimtun0: 56(84) bytes of data.\n64 bytes from tsa03s06-in-f14.1e100.net (172.217.160.110): icmp_seq=1 ttl=127 time=18.9 ms\n64 bytes from tsa03s06-in-f14.1e100.net (172.217.160.110): icmp_seq=2 ttl=127 time=15.8 ms\n\n--- google.com ping statistics ---\n2 packets transmitted, 2 received, 0% packet loss, time 1002ms\nrtt min/avg/max/mdev = 15.786/17.353/18.921/1.567 ms\n
"},{"location":"blog/1-free5gc-with-namespace/#about","title":"About","text":"Hi, my name is Jimmy Chang. The current research topic is 5G LAN with a focus on the 5G Data Plane. Any questions or errors in the article are welcome for correction. Please feel free to send an email to provide feedback.
Regarding the theme this time, I briefly introduce OAuth. OAuth 2.0 defines four types of the authorization flow. I choose the Client Credentials Flow to explain because the authentication mechanism in NRF is closely related to the Client Credentials Flow.
Next, I explain how to apply the concept of the Client Credentials Flow to NRF and introduce Nnrf_AccessToken Service
because Nnrf_AccessToken Service
is closely related to the Client Credentials Flow.
Finally, I make a simple experiment of the authentication mechanism in NRF and share the environment settings and methods of operation.
"},{"location":"blog/20230802/#oauth","title":"OAuth","text":"I introduce OAuth before explaining the authentication mechanism in NRF. Regarding the OAuth flow, we can log in to the account through the platform before we want to access an application. After logging in, we agree that an application can limitedly obtain the information of the user on the platform. The application can be LinkedIn, YouTube, etc. The platform can be Google, Facebook, etc.
The full English name of OAuth is Open standard Authorization. OAuth is an open standard, and it used to deal with authorization-related behaviors. OAuth 2.0 defines four types of the authorization flow. The four types of the authorization flow are:
This article explains the entire authorization of the Client Credentials Flow only, because the authentication mechanism in NRF adopts the Client Credentials.
If you're interested how authorization mechanism works, please refer to this article for more details.
"},{"location":"blog/20230802/#client-credentials-flow","title":"Client Credentials Flow","text":"Figure 1. Client Credentials Flow
Referring to the Figure 1, the Client Credentials Flow is mainly composed of:
The entire authorization of the Client Credentials Flow can be devided into 3 steps:
In addition, the Client and the Authorization Server have their own Scope list. The Scope list records a series of the actions. The Client or the Authorization Server is permitted to do the actions for obtaining the user\u2019s name, deleting posts, etc.
I explain how to apply the Client Credentials Flow to NRF after talking about the Client Credentials Flow.
"},{"location":"blog/20230802/#client-credentials-flow-in-nrf","title":"Client Credentials Flow in NRF","text":"The Figure 2 and the Figure 3 originate from the Figure 13.4.1.1-1 and the Figure 13.4.1.1-2 of the TS 33.501.
Figure 2. NF Service Consumer Obtaining Access Token before NF Service Access
The entire flow in Figure 2 is the same as Step 1 and Step 2 in the Figure 1. The role of the Client is played by the NF Service Consumer, and the role of the Authorization Server is played by the NRF.
First, the NF Service Consumer registers with NRF. Then the NF Service Consumer sends the Nnrf_AccessToken_Get Request
to NRF. The Nnrf_AccessToken_Get Request
includes:
The NF Type can be AMF, SMF, etc. , and the NF Service Name can be namf-comm
, nsmf-pdusession
, etc.
NRF verifies the information provided by the NF Service Consumer after it receives the Nnrf_AccessToken_Get Request
. NRF generates an Access Token and uses the NRF private key to sign on the Access Token after the verification is successful.
Finally, NRF returns the Nnrf_AccessToken_Get Response
to the NF Service Consumer. The NF Service Consumer stores the Access Token within the validity period after it gets the Access Token. The services provided by the NF Service Producer are in the Expected NF Service Name. The NF Service Consumer don\u2019t need to verify again when it wants to use the services provided by the NF Service Producer.
Figure 3. NF Service Consumer Requesting Service Access with an Access Token
The entire flow in Figure 3 is the same as Step 3 in the Figure 1. The role of the Client is played by the NF Service Consumer, and the role of the Resource Server is played by the NF Service Producer.
First, the NF Service Consumer sends the NF Service Request
to the NF Service Producer with the Access Token. Simply put, the NF Service Consumer wants to consume the service provided by the NF Service Producer.
The NF Service Producer use the NRF public key to verify the signed on the Access Token after it receives the NF Service Request
. If the verification is successful, the NF Service Producer will send the NF Service Response
to the NF Service Consumer.
I talk about the Nnrf_AccessToken Service
after explaining how to apply the Client Credentials Flow to NRF.
Figure 4. Access Token Request
The Figure 4 originates from the Figure 5.4.2.2.1-1 of the TS 29.510.
First, the NF Service Consumer sends the POST /oauth2/token
to NRF, and the data is stored in the AccessTokenReq
. The attribute name, the data type, and the formulation rule of the AccessTokenReq
are shown in the Table 1. The Table 1 originates from the Table 6.3.5.2.2-1 of the TS 29.510.
Table 1. Definition of Type AccessTokenReq
Definition of type AccessTokenReq
:
grant_type
: The value must be set to the client_credentials, and it is checked in the Snippet 1.nfInstanceId
: The value stores the ID of the NF Service Consumer.targetNfInstanceId
: The value stores the ID of the NF Service Producer.nfType
: The value stores the network function name of the NF Service Consumer. The network function name can be the AMF, SMF, etc. targetNfType
: The value stores the network function name of the NF Service Producer.scope
: It stores the services. The services can be the namf-comm
, nsmf-pdusession
, etc. The NF Service Consumer want to consume the services. The services are provided by the NF Service Producer.requesterPlmn
: It is mainly used in the roaming.targetPlmn
: It is mainly used in the roaming.if reqGrantType != \"client_credentials\" {\nreturn &models.AccessTokenErr{\nError: \"unsupported_grant_type\",\n}\n}\n
Snippet 1. Grant Type Value Checking NRF sends AccessTokenRsp
to the NF Service Consumer in the Step 2a of the Figure 4. The attribute name, the data type, and the formulation rule of the AccessTokenRsp
are shown in the Table 2. The Table 2 originates from the Table 6.3.5.2.3-1 of the TS 29.510.
Table 2. Definition of Type AccessTokenRsp
The AccessTokenRsp
contains four attribute names. The four attribute names are:
access_token
: It stores all the attribute names and values of the AccessTokenClaims in the Table 3. The Table 3 originates form the Table 6.3.5.2.4-1 of the TS 29.510. token_type
: It must be set to the Bearer and can be seen in the Snippet 2.expires_in
: It stores information related to the expiration date.scope
: The NF Service Consumer and the NF Service Producer have their own scope list. The scope in the AccessTokenRsp
has a series of these services, and the NF Service Producer is permitted to consume these services.Table 3. Definition of Type AccessTokenClaims
Definition of Type AccessTokenClaims
:
iss
: It is called issuer, and the content usually stores the ID of NRF.sub
: It is called subject, and the content stores the ID of the NF Service Consumer.aud
: It is called audience, and the content stores the ID of the NF Service Producer.scope
: The scope in the AccessTokenClaims
has a series of these services, and the NF Service Consumer is authorized by the NF Service Producer and permitted to consume these services.exp
: It stores information related to the validity period.func AccessTokenProcedure(request models.AccessTokenReq) (\n*models.AccessTokenRsp, *models.AccessTokenErr,\n) {\nlogger.AccTokenLog.Infoln(\"In AccessTokenProcedure\")\n\nvar expiration int32 = 1000\nscope := request.Scope\ntokenType := \"Bearer\"\nnow := int32(time.Now().Unix())\n\nerrResponse := AccessTokenScopeCheck(request)\nif errResponse != nil {\nreturn nil, errResponse\n}\n\n// Create AccessToken\nnrfCtx := nrf_context.GetSelf()\naccessTokenClaims := models.AccessTokenClaims{\nIss: nrfCtx.Nrf_NfInstanceID, // NF instance id of the NRF\nSub: request.NfInstanceId, // nfInstanceId of service consumer\nAud: request.TargetNfInstanceId, // nfInstanceId of service producer\nScope: request.Scope, // TODO: the name of the NF services for which the\nExp: now + expiration, // access_token is authorized for use\nStandardClaims: jwt.StandardClaims{},\n}\naccessTokenClaims.IssuedAt = int64(now)\n\n// Use NRF private key to sign AccessToken\ntoken := jwt.NewWithClaims(jwt.GetSigningMethod(\"RS512\"), accessTokenClaims)\naccessToken, err := token.SignedString(nrfCtx.NrfPrivKey)\nif err != nil {\nlogger.AccTokenLog.Warnln(\"Signed string error: \", err)\nreturn nil, &models.AccessTokenErr{\nError: \"invalid_request\",\n}\n}\n\nresponse := &models.AccessTokenRsp{\nAccessToken: accessToken,\nTokenType: tokenType,\nExpiresIn: expiration,\nScope: scope,\n}\nreturn response, nil\n}\n
Snippet 2. AccessTokenProcedure Function The Snippet 2 is the AccessTokenProcedure()
function. The function is executed in NRF.
The function mainly processes:
AccessTokenReq
sent by the NF Service Customer.AccessTokenScopeCheck()
function. The AccessTokenScopeCheck()
function checks whether the content of the attribute name in the AccessTokenReq
complies with the requirements of the TS 29.510. If not, the AccessTokenProcedure()
function immediately returns the AccessTokenErr
to the NF Service Customer.AccessTokenRsp
. The AccessTokenRsp
is sent back to the NF Service Customer. The Iss
in the AccessToken obtains its own ID in NRF. The Sub
and Aud
are obtained from the NfInstancedId
and the TargetNfInstanceId
in the AccessTokenReq
respectively. The Scope
is obtained from the scope
in the AccessTokenReq
. The expiration is set to the 1000 in the Snippet 2. Therefore, the value of the exp
is the current time + 1000.AccessTokenErr
to the NF Service Customer.AccessTokenRsp
. The value of the TokenType
is set to the Bearer by the function. The function sets the ExprieIn
and the Scope
in the Snippet 2.Finally, I make a simple experiment about the Access Token and share the environment setting and method of operation with you.
"},{"location":"blog/20230802/#experiment","title":"Experiment","text":"The Table 4 is my environment setting. I provide the Table 4 for you. You can refer it.
Table 4. Environment
You remove the part of the tls
and add the content of the cert
, rootcert
and oauth
under sbi
in the nrfcfg.yaml
before implementing about the Access Token.
info:\nversion: 1.0.2\ndescription: NRF initial local configuration\n\nconfiguration:\nMongoDBName: free5gc # database name in MongoDB\nMongoDBUrl: mongodb://127.0.0.1:27017 # a valid URL of the mongodb\nsbi: # Service-based interface information\nscheme: http # the protocol for sbi (http or https)\nregisterIPv4: 127.0.0.10 # IP used to serve NFs or register to another NRF\nbindingIPv4: 127.0.0.10 # IP used to bind the service\nport: 8000 # port used to bind the service\ncert:\npem: cert/nrf.pem\nkey: cert/nrf.key\nrootcert:\npem: cert/nrf.pem\nkey: cert/nrf.key\noauth: true\nDefaultPlmnId:\nmcc: 208 # Mobile Country Code (3 digits string, digit: 0~9)\nmnc: 93 # Mobile Network Code (2 or 3 digits string, digit: 0~9)\nserviceNameList: # the SBI services provided by this NRF, refer to TS 29.510\n- nnrf-nfm # Nnrf_NFManagement service\n- nnrf-disc # Nnrf_NFDiscovery service\n\nlogger: # log output setting\nenable: true # true or false\nlevel: info # how detailed to output, value: trace, debug, info, warn, error, fatal, panic\nreportCaller: false # enable the caller report or not, value: true or false\n
nrfcfg.yaml You find the http://127.0.0.10:8000/nnrf-nfm/v1/nf-instances/8f7891b4-b127-4f59-9ec2-b5e6aade5531
in the NRF log, and you get the 8f7891b4-b127-4f59-9ec2-b5e6aade5531
. The 8f7891b4-b127-4f59-9ec2-b5e6aade5531
is the nfInstanceID
.
2023-08-02T20:07:43.300826205Z [INFO][NRF][NFM] Handle NFRegisterRequest\n2023-08-02T20:07:43.308259291Z [INFO][NRF][NFM] urilist create\n2023-08-02T20:07:43.311674255Z [INFO][NRF][NFM] Create NF Profile\n2023-08-02T20:07:43.318192771Z [INFO][NRF][NFM] Location header: http://127.0.0.10:8000/nnrf-nfm/v1/nf-instances/8f7891b4-b127-4f59-9ec2-b5e6aade5531\n2023-08-02T20:07:43.325073275Z [INFO][NRF][GIN] | 201 | 127.0.0.1 | PUT | /nnrf-nfm/v1/nf-instances/8f7891b4-b127-4f59-9ec2-b5e6aade5531 |\n
You execute $curl -X GET {apiRoot}/nnrf-nfm/v1/nf-instances/{nfInstanceID}
, and you obtain the detail information about the nfInstanceID
. You can see the nfType
of the nfInstanceID
is NSSF, and the information about the nfInstanceID
is used when you implement the Access Token.
ubuntu@free5GC:~/free5gc/NFs/nrf$ curl -X GET http://127.0.0.10:8000/nnrf-nfm/v1/nf-instances/8f7891b4-b127-4f59-9ec2-b5e6aade5531\n{\"ipv4Addresses\":[\"127.0.0.31\"],\"nfInstanceId\":\"8f7891b4-b127-4f59-9ec2-b5e6aade5531\",\"nfServices\":[{\"apiPrefix\":\"http://127.0.0.31:8000\",\"ipEndPoints\":[{\"ipv4Address\":\"127.0.0.31\",\"port\":8000,\"transport\":\"TCP\"}],\"nfServiceStatus\":\"REGISTERED\",\"scheme\":\"http\",\"serviceInstanceId\":\"0\",\"serviceName\":\"nnssf-nsselection\",\"versions\":[{\"apiFullVersion\":\"1.0.2\",\"apiVersionInUri\":\"v1\"}]},{\"apiPrefix\":\"http://127.0.0.31:8000\",\"ipEndPoints\":[{\"ipv4Address\":\"127.0.0.31\",\"port\":8000,\"transport\":\"TCP\"}],\"nfServiceStatus\":\"REGISTERED\",\"scheme\":\"http\",\"serviceInstanceId\":\"1\",\"serviceName\":\"nnssf-nssaiavailability\",\"versions\":[{\"apiFullVersion\":\"1.0.2\",\"apiVersionInUri\":\"v1\"}]}],\"nfStatus\":\"REGISTERED\",\"nfType\":\"NSSF\",\"plmnList\":[{\"mcc\":\"208\",\"mnc\":\"93\"}]}\n
Then you execute this command, see below.
$curl -X POST -H \"Content-Type: application/json\" -d '{\"nfInstanceId\": {nfInstanceID}, \"grant_type\": \"client_credentials\", \"nfType\": {nfType}, \"targetNfType\": \"UDR\", \"scope\": \"nudr-dr\"}' {apiRoot}/oauth2/token\n
You will get the long symbols. The long symbols is that the Access Token is encrypted by the private key of NRF and stored in the AccessTokenRsp
. ubuntu@free5GC:~/free5gc/NFs/nrf$ curl -X POST -H \"Content-Type: application/json\" -d '{\"nfInstanceId\": \"8f7891b4-b127-4f59-9ec2-b5e6aade5531\", \"grant_type\": \"client_credentials\", \"nfType\": \"NSSF\", \"targetNfType\": \"UDR\", \"scope\": \"nudr-dr\"}' http://127.0.0.10:8000/oauth2/token\n\"eyJhY2Nlc3NfdG9rZW4iOiJleUpoYkdjaU9pSlNVelV4TWlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKcGMzTWlPaUlpTENKemRXSWlPaUk0WmpjNE9URmlOQzFpTVRJM0xUUm1OVGt0T1dWak1pMWlOV1UyWVdGa1pUVTFNekVpTENKaGRXUWlPaUlpTENKelkyOXdaU0k2SW01MVpISXRaSElpTENKbGVIQWlPakUyT1RFd01EZzBPRGdzSW1saGRDSTZNVFk1TVRBd056UTRPSDAuY3VHSkkwTndfV280S2lQbS1fZEZVdnVTQWM1WVEwMmRKYk5PTUhmMV9IOHdIZ2JKWFhUam9xU1Y2OTNYSmFKemkweGIxdC1DMW14TWhVZkZjbXpNMC1Nd2oxTXZYaWhyTTktdDFRUFItSFcxQlBlN0tHMUxBV3d5MEJfcXpIalltRlR6eGhONVlyNkpURDhBbkMxaFJFeEh4WHBjV1NqbV9vZnV0NVhfUFRFRkZtaHZrbmtVbU8waWFrTmdRWElRVTc1NnlvZ29ZTlFDRnJvSmRWamJMdnpFdkJLYTVFN0hQeXc3RkRDRHpTZU5WT2t2WTlobU11eldYZ3dOVmRIT3c1c2lNbmppbTlmTVZ0RTFxS1hjWDlScXlUdXlsWjM2ZlJ1QjdVZ2hkLU15Q19xd2VJRE41ZFdYOWZqdnA3VUNZZ01mVHhSLUI2M3d5OWFjQ183eThRIiwidG9rZW5fdHlwZSI6IkJlYXJlciIsImV4cGlyZXNfaW4iOjEwMDAsInNjb3BlIjoibnVkci1kciJ9\"\n
NSSF sends the AccessTokenReq
to NRF after you execute the above command. In the AccessTokenReq
, the nfInstanceId
is set to 8f7891b4-b127-4f59-9ec2-b5e6aade5531
. The grant_type
is set to the client_credentials. The nfType
is set to NSSF. The targetNfType
is set to UDR. The scope
is set to nudr-dr
. The information is shown in the NRF log. The value of the targetNfInstanceId
, requesterPlmn
, and targetPlmn
is empty because they are not set.
2023-08-02T20:18:08.127557565Z [INFO][NRF][Token] In AccessTokenProcedure\n2023-08-02T20:18:08.127586736Z [INFO][NRF][Token] Access Token Request\n2023-08-02T20:18:08.127611885Z [INFO][NRF][Token] Grant Type: client_credentials\n2023-08-02T20:18:08.127637480Z [INFO][NRF][Token] NF Instance ID: 8f7891b4-b127-4f59-9ec2-b5e6aade5531\n2023-08-02T20:18:08.127664415Z [INFO][NRF][Token] Target NF Instance ID:\n2023-08-02T20:18:08.127689792Z [INFO][NRF][Token] NF Type: NSSF\n2023-08-02T20:18:08.127712916Z [INFO][NRF][Token] Target NF Type: UDR\n2023-08-02T20:18:08.127734827Z [INFO][NRF][Token] Scope: nudr-dr\n2023-08-02T20:18:08.127758317Z [INFO][NRF][Token] Requester PLMN: <nil>\n2023-08-02T20:18:08.127781052Z [INFO][NRF][Token] Target PLMN: <nil>\n
Next, you can see the Access Token in the NRF log. The value of the Sub
is 8f7891b4-b127-4f59-9ec2-b5e6aade5531
. The Sub
represents NSSF, and NSSF belongs to the NF Service Customer. The value of the Scope
is the nudr-dr
. The value of the Exp
is 1691008488.
2023-08-02T20:18:08.134096785Z [INFO][NRF][Token] Access Token Claims\n2023-08-02T20:18:08.138100978Z [INFO][NRF][Token] Iss:\n2023-08-02T20:18:08.138185972Z [INFO][NRF][Token] Sub: 8f7891b4-b127-4f59-9ec2-b5e6aade5531\n2023-08-02T20:18:08.138228925Z [INFO][NRF][Token] Aud:\n2023-08-02T20:18:08.138264519Z [INFO][NRF][Token] Scope: nudr-dr\n2023-08-02T20:18:08.138298628Z [INFO][NRF][Token] Exp: 1691008488\n
Next, you can see the AccessTokenRsp
. You can see that the Access Token has become the long symbols. The value of the Token Type
is set to the Bearer. The value of the ExpiresIn
is set to 1000. The value of the Scope
is set to nudr-dr
.
2023-08-02T20:18:08.149587382Z [INFO][NRF][Token] Access Token Response\n2023-08-02T20:18:08.150006665Z [INFO][NRF][Token] Access Token: eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIiLCJzdWIiOiI4Zjc4OTFiNC1iMTI3LTRmNTktOWVjMi1iNWU2YWFkZTU1MzEiLCJhdWQiOiIiLCJzY29wZSI6Im51ZHItZHIiLCJleHAiOjE2OTEwMDg0ODgsImlhdCI6MTY5MTAwNzQ4OH0.cuGJI0Nw_Wo4KiPm-_dFUvuSAc5YQ02dJbNOMHf1_H8wHgbJXXTjoqSV693XJaJzi0xb1t-C1mxMhUfFcmzM0-Mwj1MvXihrM9-t1QPR-HW1BPe7KG1LAWwy0B_qzHjYmFTzxhN5Yr6JTD8AnC1hRExHxXpcWSjm_ofut5X_PTEFFmhvknkUmO0iakNgQXIQU756yogoYNQCFroJdVjbLvzEvBKa5E7HPyw7FDCDzSeNVOkvY9hmMuzWXgwNVdHOw5siMnjim9fMVtE1qKXcX9RqyTuylZ36fRuB7Ughd-MyC_qweIDN5dWX9fjvp7UCYgMfTxR-B63wy9acC_7y8Q\n2023-08-02T20:18:08.150094277Z [INFO][NRF][Token] Token Type: Bearer\n2023-08-02T20:18:08.150133189Z [INFO][NRF][Token] Expires In: 1000\n2023-08-02T20:18:08.150167371Z [INFO][NRF][Token] Scope: nudr-dr\n
Finally, you can see 200. 200 means that AUSF sends the AccessTokenReq
to NRF. NRF successfully sends to AUSF after verification.
2023-08-02T20:18:08.150302345Z [INFO][NRF][GIN] | 200 | 127.0.0.1 | POST | /oauth2/token |\n
"},{"location":"blog/20230802/#reference","title":"Reference","text":"Note
Author: Ya-shih Tseng Date: 2023/7/12
This blog focuses on the role of the 5G system in 3GPP Release 16 TSN (Time-Sensitive Networking).
"},{"location":"blog/TSN/#what-is-time-sensitive-network-tsn","title":"What is Time-Sensitive Network (TSN)","text":"Traditional Ethernet technology can only achieve \"best-effort\" communication and cannot meet the high reliability and low latency requirements of industrial manufacturing applications. Therefore, in the context of industrial automation, there is a need to upgrade the traditional \"best-effort\" Ethernet to provide \"deterministic\" services.
Time Sensitive Networking (TSN) brings determinism and real-time communication to standard Ethernet through mechanisms and protocols defined by the IEEE 802.1 standard, which is used by Audio Video Bridging (AVB) and TSN. It offers reliable message delivery, minimized jitter, and guaranteed delivery through central management, time scheduling, and other key features. The introduction of TSN technology holds great potential and benefits for real-time applications in industrial control, automation, and other fields.
TSN_OSI_layer
"},{"location":"blog/TSN/#tsn-standard","title":"TSN Standard","text":"There are a lot of standards that TSN task group has completed or ongoing projects. Here are some base standards.
Standard Title IEEE 1588 V2 Precision Clock Synchronization Protocol for Networked Measurement and Control Systems IEEE 802.1Q-2022 Bridges and Bridged Networks IEEE 802.1AB-2016 Station and Media Access Control Connectivity Discovery (specifies the Link Layer Discovery Protocol (LLDP)) IEEE 802.1AS-2020 Timing and Synchronization for Time-Sensitive Applications IEEE 802.1AX-2020 Link Aggregation IEEE 802.1CB-2017 Frame Replication and Elimination for Reliability IEEE 802.1CS-2020 Link-local Registration Protocol"},{"location":"blog/TSN/#the-role-of-5g-system-in-tsn","title":"The role of 5G system in TSN","text":"With the increasing demands for wireless control in applications such as industrial automation, remote surgical operations, smart grid distribution automation, transportation safety, autonomous driving, and more, there is a growing need to meet the low-latency requirements of these applications while achieving management, scheduling, and traffic planning. Time synchronization becomes a critical aspect. The following will explain how the interaction between TSN and 5G systems enables time synchronization.
"},{"location":"blog/TSN/#time-synchronization","title":"Time Synchronization","text":"To achieve time synchronization between TSN and 5G systems, TSN utilizes the time synchronization method defined in IEEE 802.1AS, which is the generalized Precision Time Protocol (gPTP). gPTP supports time synchronization for Time-aware end stations and Time-aware Bridges in Layer 2. In the 3GPP TS23.501 release 16 specification, the 5G system plays the role of a \"Time-aware system\" as defined in IEEE 802.1AS and is designated as a Logical bridge, connecting TSN system end stations.
Note
gPTP is an extended version of PTP (Precision Time Protocol) that primarily expands support for second-layer network devices.
How can we synchronize the time of two end stations into the same time domain?
First, the time synchronization architecture includes Master clocks and Slave clocks. The Master regularly sends sync messages to allow the Slave to obtain the Master's time. The Slave, in turn, periodically sends peer delay requests to exchange messages with the Master, obtaining the delay time between the two devices for time correction. Additionally, the resident time, which is the message propagation delay introduced by bridges, should also be taken into account. By considering all these factors, the time synchronization of both sides can be achieved within the TSN time domain.
Time Synchronization process of gPTP
Check the link for more detail about how PTP works.
"},{"location":"blog/TSN/#intergration-of-tsn-and-5g","title":"Intergration of TSN and 5G","text":"By now, I believe you have gained an understanding of the time synchronization mechanism in TSN. Let's briefly explain how the 5G system supports TSN as a logical TSN bridge. The 3GPP has defined new functionalities such as NW-TT, DS-TT, and TSN-AF, as well as TSN control nodes like CUC and CNC. Please check TS 23.501 Release 16 for more details.
System architecture of 5G support TSN
"},{"location":"blog/TSN/#support-ethernet-type-pdu-session","title":"Support Ethernet type PDU session","text":"To archive the intergration, 5G system should support ingress port and egress port pair via an Ethernet Type PDU session between the corresponding UE and UPF. As mentioned above, gPTP supports layer 2 (Ethernet) only.
"},{"location":"blog/TSN/#ds-tt-and-nw-tt","title":"DS-TT and NW-TT","text":"In the 5G system, DS-TT (Device-side TSN translator) and NW-TT (Network-side TSN translator) serve as TSN translators. DS-TT is responsible for connecting TSN Slave endpoints with the UE, while NW-TT connects TSN Master endpoints with the UPF.
When the sync message generated by the Master clock reaches the bridge, NW-TT captures its Ingress Timestamp and measures the delay between NW-TT and the Master clock. These timestamps are then embedded within the sync message and transmitted to the UE. Once the UE receives the sync message, DS-TT calculates the resident time by subtracting the Ingress Timestamp provided in the sync message, from the Egress Timestamp which represents the time of sync message reception. The resident time is added to the delay time mentioned in the sync message to determine the corrected time. Through the assistance of the TSN translators, the Slave endpoint receives the message and obtains information about time deviation and other relevant data for further adjustment.
Note
DS-TT and NW-TT enable the 5G system to function as a virtual bridge. The bridge is also called \"Transparent clock\" which is definded in IEEE 1588 and required in IEEE 802.1AS. You can say that Master and Slaver don't know the exist of the 5G TSN bridge, since it's logical transparent.
\"Transparent clocks are used to route timing messages within a network. Used when: Ethernet timing must pass through switches.\" - different type of clocks
"},{"location":"blog/TSN/#tsn-af","title":"TSN-AF","text":"With TSN-AF, CNC can manage the 5G system functioning as a logical bridge and achieve the integration of the 5G TSN bridge with the TSN network in collaboration with NW-TT and DS-TT. Additionally, TSN-AF gathers information and capability lists of the 5G TSN Bridge and transmits them to CNC.
"},{"location":"blog/TSN/#tsn-control-nodes","title":"TSN control nodes","text":"To meet the requirements of application services and control TSN, there are two key functions utilized in the TSN system. CNC (Centralized Network Controller), as the central controller in the TSN system, receives the information from CUC (Centralized User Configuration) and performs scheduling and planning tasks. It calculates the optimal transmission schedule for the TSN traffic based on factors such as bandwidth requirements, latency constraints, and network conditions. Once the transmission schedule is computed and confirmed, CNC proceeds to deploy the necessary network resource configuration on the TSN switches. This ensures that the TSN network operates efficiently and effectively in delivering the required QoS (Quality of Service) for the application services.
"},{"location":"blog/TSN/#reference","title":"Reference","text":"Hi, This is Ya-shih Tseng. I am currently researching the implementation of 5G TSN (Time-Sensitive Networking) as part of my master's studies. In the future, I will introduce more information about TSN. Hope you enjoy it.
"},{"location":"blog/UDM_introduce/","title":"Network function UDM introduction","text":"Note
Author: \u5f35\u54f2\u777f Date: 2023/7/19
"},{"location":"blog/UDM_introduce/#overview","title":"Overview","text":"In this article, I will introduce UDM and its three services that will be used in the general UE registration procedure (Nudm_UECM service, Nudm_SubscriberDataManagement Service, and Nudm_UEAuthentication service) to let everyone understand UDM more clearly.
"},{"location":"blog/UDM_introduce/#udm","title":"UDM","text":"Unified Data Management is responsible for managing information related to UE. When other NFs need to use the UE subscription information, they will obtain it from UDM through the SBI of UDM.
"},{"location":"blog/UDM_introduce/#nudm_ueauthentication-service","title":"Nudm_UEAuthentication Service","text":"This service is used by AUSF to retrieve authentication-related information and, after authentication, confirm the result.
3GPP TS33.501 v15.2.0
In Authentication, AUSF uses the GET operation to retrieve authentication information for the UE. The request contains the UE\u2019s identity (supi or suci) and the serving network name. The serving network name is used in the derivation of the anchor key, which is used by subsensual authentication. UE\u2019s identity will be contained in the URI, and the serving network name will be contained in the request body.
Upon reception of the Nudm_UEAuthentication_Get Request, the UDM shall de-conceal SUCI to gain SUPI if SUCI is received. At this time, UDM will query the authentication subscription data from UDR. Then, UDM shall select the authentication method based on SUPI, and if required (e.g., 5G-AKA), UDM will calculate the authentication vector and pass it to AUSF.
logger.UeauLog.Traceln(\"In GenerateAuthDataProcedure\")\n\nresponse = &models.AuthenticationInfoResult{}\nrand.Seed(time.Now().UnixNano())\nsupi, err := suci.ToSupi(supiOrSuci, udm_context.Getself().SuciProfiles)\nif err != nil {\nproblemDetails = &models.ProblemDetails{\nStatus: http.StatusForbidden,\nCause: authenticationRejected,\nDetail: err.Error(),\n}\n\nlogger.UeauLog.Errorln(\"suciToSupi error: \", err.Error())\nreturn nil, problemDetails\n}\n\nlogger.UeauLog.Tracef(\"supi conversion => [%s]\", supi)\n\nclient, err := createUDMClientToUDR(supi)\nif err != nil {\nreturn nil, openapi.ProblemDetailsSystemFailure(err.Error())\n}\nauthSubs, res, err := client.AuthenticationDataDocumentApi.QueryAuthSubsData(context.Background(), supi, nil)\n\n//in the udm/internal/sbi/producer/generate_auth_data.go, GenerateAuthDataProcedure function.\n
From the code, we can see UDM first de-conceal SUCI (line 5), then use QueryAuthSubsData to get authSub from UDR. After that, UDM uses this information to create the authentication vector.
Then we record the packet sent in the registration process and find the packet according to the URI specified by the specification. We can find the packet corresponding to this service.
Open the response packet, and we can see the response body matches the AuthenticationInfoResult data type.
3GPP TS29.503 v15.2.1
After AUSF authenticates the UE, it will confirm the result with UDM. These details will be used in linking authentication confirmation to the Nudm_UECM_Registration procedure from AMF.
func communicateWithUDM(ue *context.AmfUe, accessType models.AccessType) error {\nue.GmmLog.Debugln(\"communicateWithUDM\")\namfSelf := context.GetSelf()\n\n// UDM selection described in TS 23.501 6.3.8\n// TODO: consider udm group id, Routing ID part of SUCI, GPSI or External Group ID (e.g., by the NEF)\nparam := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{\nSupi: optional.NewString(ue.Supi),\n}\nresp, err := consumer.SendSearchNFInstances(amfSelf.NrfUri, models.NfType_UDM, models.NfType_AMF, ¶m)\nif err != nil {\nreturn errors.Errorf(\"AMF can not select an UDM by NRF: SendSearchNFInstances failed\")\n}\n\nvar uecmUri, sdmUri string\nfor _, nfProfile := range resp.NfInstances {\nue.UdmId = nfProfile.NfInstanceId\nuecmUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NUDM_UECM, models.NfServiceStatus_REGISTERED)\nsdmUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NUDM_SDM, models.NfServiceStatus_REGISTERED)\nif uecmUri != \"\" && sdmUri != \"\" {\nbreak\n}\n}\nue.NudmUECMUri = uecmUri\nue.NudmSDMUri = sdmUri\nif ue.NudmUECMUri == \"\" || ue.NudmSDMUri == \"\" {\nreturn errors.Errorf(\"AMF can not select an UDM by NRF: SearchNFServiceUri failed\")\n}\n\nproblemDetails, err := consumer.UeCmRegistration(ue, accessType, true)\nif problemDetails != nil {\nreturn errors.Errorf(problemDetails.Cause)\n} else if err != nil {\nreturn errors.Wrap(err, \"UECM_Registration Error\")\n}\n\n// TS 23.502 4.2.2.2.1 14a-c.\n// \"After a successful response is received, the AMF subscribes to be notified\n// using Nudm_SDM_Subscribe when the data requested is modified\"\nproblemDetails, err = consumer.SDMGetAmData(ue)\nif problemDetails != nil {\nreturn errors.Errorf(problemDetails.Cause)\n} else if err != nil {\nreturn errors.Wrap(err, \"SDM_Get AmData Error\")\n}\n\nproblemDetails, err = consumer.SDMGetSmfSelectData(ue)\nif problemDetails != nil {\nreturn errors.Errorf(problemDetails.Cause)\n} else if err != nil {\nreturn errors.Wrap(err, \"SDM_Get SmfSelectData Error\")\n}\n\nproblemDetails, err = consumer.SDMGetUeContextInSmfData(ue)\nif problemDetails != nil {\nreturn errors.Errorf(problemDetails.Cause)\n} else if err != nil {\nreturn errors.Wrap(err, \"SDM_Get UeContextInSmfData Error\")\n}\n\nproblemDetails, err = consumer.SDMSubscribe(ue)\nif problemDetails != nil {\nreturn errors.Errorf(problemDetails.Cause)\n} else if err != nil {\nreturn errors.Wrap(err, \"SDM Subscribe Error\")\n}\nue.ContextValid = true\nreturn nil\n}\n\n\n//in the amf/internal/gmm/handler.go.\n
Next, let's take a look at this function. It is called in HandleInitialRegistration, which handles UE's initial registration. UeCmRegistration will use the Nudm_UECM (UECM) service to store related UE Context Management information in UDM. In lines 40, 47, and 54, AMF uses the Nudm_SubscriberDataManagement (SDM) Service to get some subscribe data.
"},{"location":"blog/UDM_introduce/#nudm_uecontextmanagement-service","title":"Nudm_UEContextManagement Service","text":"In the UeCmRegistration function, AMF registers as UE's serving NF on UDM and stores related UE Context Management information in UDM. Looking at the packet, you can see that the request body contains amfInstanceId
and guami
, representing the amf identity, and ratType
, representing the radio access technology type used by UE.
// TS 29.503 5.3.2.2.2\nfunc RegistrationAmf3gppAccessProcedure(registerRequest models.Amf3GppAccessRegistration, ueID string) (\nheader http.Header, response *models.Amf3GppAccessRegistration, problemDetails *models.ProblemDetails,\n) {\n// TODO: EPS interworking with N26 is not supported yet in this stage\nvar oldAmf3GppAccessRegContext *models.Amf3GppAccessRegistration\nif udm_context.Getself().UdmAmf3gppRegContextExists(ueID) {\nue, _ := udm_context.Getself().UdmUeFindBySupi(ueID)\noldAmf3GppAccessRegContext = ue.Amf3GppAccessRegistration\n}\n\nudm_context.Getself().CreateAmf3gppRegContext(ueID, registerRequest)\n\nclientAPI, err := createUDMClientToUDR(ueID)\nif err != nil {\nreturn nil, nil, openapi.ProblemDetailsSystemFailure(err.Error())\n}\n\nvar createAmfContext3gppParamOpts Nudr_DataRepository.CreateAmfContext3gppParamOpts\noptInterface := optional.NewInterface(registerRequest)\ncreateAmfContext3gppParamOpts.Amf3GppAccessRegistration = optInterface\nresp, err := clientAPI.AMF3GPPAccessRegistrationDocumentApi.CreateAmfContext3gpp(context.Background(),\nueID, &createAmfContext3gppParamOpts)\nif err != nil {\nlogger.UecmLog.Errorln(\"CreateAmfContext3gpp error : \", err)\nproblemDetails = &models.ProblemDetails{\nStatus: int32(resp.StatusCode),\nCause: err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails).Cause,\nDetail: err.Error(),\n}\nreturn nil, nil, problemDetails\n}\ndefer func() {\nif rspCloseErr := resp.Body.Close(); rspCloseErr != nil {\nlogger.UecmLog.Errorf(\"CreateAmfContext3gpp response body cannot close: %+v\", rspCloseErr)\n}\n}()\n\n// TS 23.502 4.2.2.2.2 14d: UDM initiate a Nudm_UECM_DeregistrationNotification to the old AMF\n// corresponding to the same (e.g. 3GPP) access, if one exists\nif oldAmf3GppAccessRegContext != nil {\nderegistData := models.DeregistrationData{\nDeregReason: models.DeregistrationReason_SUBSCRIPTION_WITHDRAWN,\nAccessType: models.AccessType__3_GPP_ACCESS,\n}\ncallback.SendOnDeregistrationNotification(ueID, oldAmf3GppAccessRegContext.DeregCallbackUri,\nderegistData) // Deregistration Notify Triggered\n\nreturn nil, nil, nil\n} else {\nheader = make(http.Header)\nudmUe, _ := udm_context.Getself().UdmUeFindBySupi(ueID)\nheader.Set(\"Location\", udmUe.GetLocationURI(udm_context.LocationUriAmf3GppAccessRegistration))\nreturn header, ®isterRequest, nil\n}\n}\n\n//in the udm/internal/sbi/producer/ue_context_management.go\n
In the RegistrationAmf3gppAccessProcedure function, UDM first checks whether the context has been established for that UE; if UDM has such a context, it initiates a Nudm_UECM_DeregistrationNotification to the old AMF later. UDM used the received information to create context and stored it in UDR.
"},{"location":"blog/UDM_introduce/#nudm_subscriberdatamanagement-sdm-service","title":"Nudm_SubscriberDataManagement (SDM) Service","text":"The SDM service is used to retrieve the UE's individual subscription data relevant to the consumer's NF from the UDM. In the SDMGetAmData function, AMF gets subscription data used in registration and mobility management. In the response packet, AMF got gpsis
, subscribedUeAmbr
, and nssai
.
The GPSI (Generic Public Subscription Identifier) is used to address a 3GPP subscription in data networks outside the realms of a 3GPP system. It contains either an External ID or an MSISDN \uff08Mobile Subscriber ISDN Number\uff09.The subscribedUeAmbr
is The Maximum Aggregated uplink and downlink MBRs (max. bit rate) to be shared across all Non-GBR (non-guaranteed Bit Rate) QoS Flows according to the subscription of the user.
In the SDMGetSmfSelectData function, AMF gets subscribed S-NSSAIs (Single Network Slice Selection Assistance Information) and Data Network Names for these S-NSSAIs. AMF will use this information to select an SMF that manages the PDU Session.
func HandleInitialRegistration(ue *context.AmfUe, anType models.AccessType) error {\nue.GmmLog.Infoln(\"Handle InitialRegistration\")\n\namfSelf := context.GetSelf()\n\n// update Kgnb/Kn3iwf\nue.UpdateSecurityContext(anType)\n\n// Registration with AMF re-allocation (TS 23.502 4.2.2.2.3)\nif len(ue.SubscribedNssai) == 0 {\ngetSubscribedNssai(ue)\n}\n\nif err := handleRequestedNssai(ue, anType); err != nil {\nreturn err\n}\n\n//in the amf/internal/gmm/handler.go.\n
In the initialization of HandleInitialRegistration, AMF sends a request to the UDM to receive the UE's NSSAI (Network Slice Selection Assistance Information). After receiving subscribed NSSAI, AMF will compare it to UE's requested NSSAI. If there is a S-NSSAI that has not been subscribed before, AMF will request NSSF for Allowed NSSAI.
func handleRequestedNssai(ue *context.AmfUe, anType models.AccessType) error {\namfSelf := context.GetSelf()\n\nif ue.RegistrationRequest.RequestedNSSAI != nil {\nrequestedNssai, err := nasConvert.RequestedNssaiToModels(ue.RegistrationRequest.RequestedNSSAI)\nif err != nil {\nreturn fmt.Errorf(\"Decode failed at RequestedNSSAI[%s]\", err)\n}\n\nneedSliceSelection := false\nfor _, requestedSnssai := range requestedNssai {\nue.GmmLog.Infof(\"RequestedNssai - ServingSnssai: %+v, HomeSnssai: %+v\",\nrequestedSnssai.ServingSnssai, requestedSnssai.HomeSnssai)\nif ue.InSubscribedNssai(*requestedSnssai.ServingSnssai) {\nallowedSnssai := models.AllowedSnssai{\nAllowedSnssai: &models.Snssai{\nSst: requestedSnssai.ServingSnssai.Sst,\nSd: requestedSnssai.ServingSnssai.Sd,\n},\nMappedHomeSnssai: requestedSnssai.HomeSnssai,\n}\nif !ue.InAllowedNssai(*allowedSnssai.AllowedSnssai, anType) {\nue.AllowedNssai[anType] = append(ue.AllowedNssai[anType], allowedSnssai)\n}\n} else {\nneedSliceSelection = true\nbreak\n}\n}\n\nif needSliceSelection {\nif ue.NssfUri == \"\" {\nfor {\nerr := consumer.SearchNssfNSSelectionInstance(ue, amfSelf.NrfUri, models.NfType_NSSF, models.NfType_AMF, nil)\nif err != nil {\nue.GmmLog.Errorf(\"AMF can not select an NSSF Instance by NRF[Error: %+v]\", err)\ntime.Sleep(2 * time.Second)\n} else {\nbreak\n}\n}\n}\n\n// Step 4\nproblemDetails, err := consumer.NSSelectionGetForRegistration(ue, requestedNssai)\nif problemDetails != nil {\nue.GmmLog.Errorf(\"NSSelection Get Failed Problem[%+v]\", problemDetails)\ngmm_message.SendRegistrationReject(ue.RanUe[anType], nasMessage.Cause5GMMProtocolErrorUnspecified, \"\")\nreturn fmt.Errorf(\"Handle Requested Nssai of UE failed\")\n} else if err != nil {\nue.GmmLog.Errorf(\"NSSelection Get Error[%+v]\", err)\ngmm_message.SendRegistrationReject(ue.RanUe[anType], nasMessage.Cause5GMMProtocolErrorUnspecified, \"\")\nreturn fmt.Errorf(\"Handle Requested Nssai of UE failed\")\n}\n\n//in the amf/internal/gmm/handler.go.\n
if param.SliceInfoRequestForRegistration.RequestedNssai != nil &&\nlen(param.SliceInfoRequestForRegistration.RequestedNssai) != 0 {\n// Requested NSSAI is provided\n// Verify which S-NSSAI(s) in the Requested NSSAI are permitted based on comparing the Subscribed S-NSSAI(s)\nif param.Tai != nil &&\n!util.CheckSupportedNssaiInPlmn(param.SliceInfoRequestForRegistration.RequestedNssai, *param.Tai.PlmnId) {\n// Return ProblemDetails indicating S-NSSAI is not supported\n// TODO: Based on TS 23.501 V15.2.0, if the Requested NSSAI includes an S-NSSAI that is not valid in the\n// Serving PLMN, the NSSF may derive the Configured NSSAI for Serving PLMN\n*problemDetails = models.ProblemDetails{\nTitle: util.UNSUPPORTED_RESOURCE,\nStatus: http.StatusForbidden,\nDetail: \"S-NSSAI in Requested NSSAI is not supported in PLMN\",\nCause: \"SNSSAI_NOT_SUPPORTED\",\n}\n\nstatus = http.StatusForbidden\nreturn status\n}\n\n// Check if any Requested S-NSSAIs is present in Subscribed S-NSSAIs\ncheckIfRequestAllowed := false\n\nfor _, requestedSnssai := range param.SliceInfoRequestForRegistration.RequestedNssai {\nif param.Tai != nil && !util.CheckSupportedSnssaiInTa(requestedSnssai, *param.Tai) {\n// Requested S-NSSAI does not supported in UE's current TA\n// Add it to Rejected NSSAI in TA\nauthorizedNetworkSliceInfo.RejectedNssaiInTa = append(\nauthorizedNetworkSliceInfo.RejectedNssaiInTa,\nrequestedSnssai)\ncontinue\n}\n\nvar mappingOfRequestedSnssai models.Snssai\n// TODO: Compared with Restricted S-NSSAI list in configuration under roaming scenario\nif param.HomePlmnId != nil && !util.CheckStandardSnssai(requestedSnssai) {\n// Standard S-NSSAIs are supported to be commonly decided by all roaming partners\n// Only non-standard S-NSSAIs are required to find mappings\ntargetMapping, found := util.FindMappingWithServingSnssai(requestedSnssai,\nparam.SliceInfoRequestForRegistration.MappingOfNssai)\n\nif !found {\n// No mapping of Requested S-NSSAI to HPLMN S-NSSAI is provided by UE\n// TODO: Search for local configuration if there is no provided mapping from UE, and update UE's\n// Configured NSSAI\ncheckInvalidRequestedNssai = true\nauthorizedNetworkSliceInfo.RejectedNssaiInPlmn = append(\nauthorizedNetworkSliceInfo.RejectedNssaiInPlmn,\nrequestedSnssai)\ncontinue\n} else {\n// TODO: Check if mappings of S-NSSAIs are correct\n// If not, update UE's Configured NSSAI\nmappingOfRequestedSnssai = *targetMapping.HomeSnssai\n}\n} else {\nmappingOfRequestedSnssai = requestedSnssai\n}\n\nhitSubscription := false\nfor _, subscribedSnssai := range param.SliceInfoRequestForRegistration.SubscribedNssai {\nif mappingOfRequestedSnssai == *subscribedSnssai.SubscribedSnssai {\n// Requested S-NSSAI matches one of Subscribed S-NSSAI\n// Add it to Allowed NSSAI list\nhitSubscription = true\n\nvar allowedSnssaiElement models.AllowedSnssai\nallowedSnssaiElement.AllowedSnssai = new(models.Snssai)\n*allowedSnssaiElement.AllowedSnssai = requestedSnssai\nnsiInformationList := util.GetNsiInformationListFromConfig(requestedSnssai)\nif nsiInformationList != nil {\n// TODO: `NsiInformationList` should be slice in `AllowedSnssai` instead of pointer of slice\nallowedSnssaiElement.NsiInformationList = append(\nallowedSnssaiElement.NsiInformationList,\nnsiInformationList...)\n}\nif param.HomePlmnId != nil && !util.CheckStandardSnssai(requestedSnssai) {\nallowedSnssaiElement.MappedHomeSnssai = new(models.Snssai)\n*allowedSnssaiElement.MappedHomeSnssai = *subscribedSnssai.SubscribedSnssai\n}\n\n// Default Access Type is set to 3GPP Access if no TAI is provided\n// TODO: Depend on operator implementation, it may also return S-NSSAIs in all valid Access Type if\n// UE's Access Type could not be identified\nvar accessType models.AccessType = models.AccessType__3_GPP_ACCESS\nif param.Tai != nil {\naccessType = util.GetAccessTypeFromConfig(*param.Tai)\n}\n\nutil.AddAllowedSnssai(allowedSnssaiElement, accessType, authorizedNetworkSliceInfo)\n\ncheckIfRequestAllowed = true\nbreak\n}\n}\n\nif !hitSubscription {\n// Requested S-NSSAI does not match any Subscribed S-NSSAI\n// Add it to Rejected NSSAI in PLMN\ncheckInvalidRequestedNssai = true\nauthorizedNetworkSliceInfo.RejectedNssaiInPlmn = append(\nauthorizedNetworkSliceInfo.RejectedNssaiInPlmn,\nrequestedSnssai)\n}\n}\n\nif !checkIfRequestAllowed {\n// No S-NSSAI from Requested NSSAI is present in Subscribed S-NSSAIs\n// Subscribed S-NSSAIs marked as default are used\nuseDefaultSubscribedSnssai(param, authorizedNetworkSliceInfo)\n}\n} else {\n// No Requested NSSAI is provided\n// Subscribed S-NSSAIs marked as default are used\ncheckInvalidRequestedNssai = true\nuseDefaultSubscribedSnssai(param, authorizedNetworkSliceInfo)\n}\n\n//in the nssf/internal/sbi/producer/nsselection_for_registration.go, nsselectionForRegistration funcion.\n
If NSSF needs to select S-NSSAI, it first finds the mapping of requested NSSAI to configured NSSAI for the HPLMN and converts requested S-NSSAI to S-NSSAI in configured NSSAI for the HPLMN. Then compare these S-NSSAIs with Subscribed S-NSSAIs; if NSSF find one match, set it as AllowedSnssai
. If NSSF can't find such a mapping or no S-NSSAI in the mapping matches subscribed S-NSSAIs, it will use default subscribed S-NSSAIs.
Hello! My name is \u5f35\u54f2\u777f, and my current research topic is ATSSS (Access Traffic Steering, Switching and Splitting), I will continue to write articles related to 5G networks in the future. If you find any mistakes in my articles or have any topics you want to know about, please contact me.
Note
Author: Daniel Hsieh Date: 2023/7/26
"},{"location":"blog/network_slice/#whats-network-slicing","title":"What's Network Slicing","text":"Network slicing allows for the creation of multiple logical, isolated, and independent virtual networks that can coexist within a shared physical infrastructure. Each network slice provides dedicated and customized network resources to meet the specific requirements of different services The main elements of a network slice include:
Virtualized Network Functions (VNFs): Each network slice can include a set of virtualized network functions that provide specific network capabilities and services. These VNFs can include functions like routing, switching, firewalling, load balancing, or any other network service required by the slice.
Isolation and Resource Allocation: Network slicing ensures the isolation of resources between slices, preventing interference and conflicts. It allows for the allocation of dedicated and optimized resources such as bandwidth, processing power, and storage to each slice based on its specific needs.
Orchestration and Management: Network slice orchestration involves the creation, provisioning, and management of network slices. It involves configuring the appropriate VNFs, assigning resources, and establishing connectivity between the different components of a slice.
NFV Enabling Network Slicing for 5G
Take Figure 1 as an example. The first slice is designed for mobile devices such as smartphones. Such slice requires a huge diversity of VNFs, and virtual links with high speed and low latency to support the broadband service of smartphones. In 5G network, Those slices are referred to as eMBB (enhanced mobile broadband) slices.
The second slice is designed for autonomous driving. In such scenario, extremely low latency and high reliability are paramount to ensure the vehicles' operability, smoothness and safety. To achieve low latency, some of the NFs should be deployed close to the access node,i.e. on edge cloud. To achieve high reliability, a NF should have multiple instances on available physical resources to make the slice more fault tolerant. Such slice is referred to as URLLC (Ultra-Reliable Low-Latency Communications) slice.
The third slice is designed for massive IoT. IoT devices are expected to not move and send very small amount of data intermittently. Due to the nature of such devices, functions that handle mobiltiy and always-on connections are not needed. Such slices are referred to as mIoT (massive IoT) slices.
"},{"location":"blog/network_slice/#mano-architecture","title":"MANO Architecture","text":"In this article, we utilize MANO network function virtualization (NFV) architecture to deploy virtual network function (VNF). It plays the role of creating, deploying, and managing VNFs. MANO consists of three main functional components: NFV Orchestrator (NFVO), Virtualized Infrastructure Manager (VIM), and Virtual Network Function Manager (VNFM).
NFV MANO Architecture
NFVO manages the underlying resource by coordinating VIM and VNFM. It handles tasks such as receiving requests, service instantiation, scaling, termination, and monitoring.
VNFM manages the lifecycle of VNF instances. It interacts with the VIM to instantiate, configure, monitor, and terminate VNF instances.
VIM is responsible for managing the underlying virtualized infrastructure that hosts the VNFs. It abstracts the physical resources, such as compute, storage, and networking, and provides a unified view to the NFVO. The VIM handles tasks like resource allocation, performance monitoring, fault management, and virtualization management.
For VIM, we use OpenStack, an open-source software that provides IaaS, to utilize the physical resources. For VNFM and NFVO, we use Tacker, a service component of OpenStack, to manage VNFs.
"},{"location":"blog/network_slice/#openstack","title":"OpenStack","text":"OpenStack is an open-source cloud computing platform that provides a set of software tools for building and managing customized clouds. OpenStack offers a infrastructure-as-a-service (IaaS) solution, enabling organizations to create and manage virtualized resources in a cloud environment. It is designed to be modular and consists of various components that work together to deliver a comprehensive cloud computing platform. Some of the key components include:
Nova: Nova is the computing component of OpenStack and serves as the main compute engine. It manages the creation, scheduling, and management of virtual machines (VMs) and provides APIs for controlling and interacting with the compute resources.
Cinder: Cinder is the block storage component of OpenStack. It provides persistent storage for virtual machines. With Cinder, users can create and manage volumes that can be attached to instances, allowing for flexible and scalable storage options.
Neutron: Neutron is the networking component of OpenStack. It provides a networking-as-a-service (NaaS) solution, allowing users to define and manage network resources. Neutron supports virtual LANs, software-defined networking (SDN), and network function virtualization (NFV), etc.
Keystone: Keystone is the identity service component of OpenStack. It provides authentication and authorization services, enabling users to securely access and manage resources within the cloud. Keystone supports multiple authentication mechanisms, including username/password, token-based, and external identity providers.
Horizon: Horizon is the web-based dashboard for OpenStack. It provides a user-friendly interface for managing and monitoring the cloud infrastructure. With Horizon, users can perform various tasks, such as launching instances, managing storage resources, and configuring networking options.
OpenStack Architecture
OpenStack is highly flexible and customizable, allowing organizations to tailor the cloud infrastructure to their specific needs. It supports multiple hypervisors, including KVM, VMware, and Hyper-V.
"},{"location":"blog/network_slice/#tacker","title":"Tacker","text":"To enable NFV, we need another service component of OpenStack called Tacker. Tacker is designed to simplify the deployment and lifecycle management of VNFs and network service functions (NSFs) in a cloud infrastructure. It leverages OpenStack's existing components, such as Nova, Neutron, and Heat, to provide a comprehensive solution for network service orchestration. Tacker provides several key features and functionalities:
Service Templates: Tacker uses service templates to define the composition and behavior of network services. These templates describe the VNFs and NSFs involved, their interconnections, resource requirements, etc. Service templates are written using the TOSCA (Topology and Orchestration Specification for Cloud Applications) standard.
Lifecycle Management: Tacker automates the entire lifecycle of network services, including provisioning, scaling, healing, and termination. It leverages Heat, OpenStack's orchestration service, to manage the underlying infrastructure resources required by the services and handle dynamic scaling of VNFs based on traffic demands.
VNF Manager: Tacker includes a VNF Manager component responsible for managing the lifecycle of VNFs. It interacts with OpenStack's compute and networking services, to instantiate and manage VNF instances.
Multi-VIM Support: Tacker supports multiple virtual infrastructure managers to accommodate different cloud platforms and environments. It can interact with OpenStack, VMware vSphere and Kubernetes and so on, enabling operators to deploy network services across heterogeneous infrastructure environments.
Tacker Architecture
"},{"location":"blog/network_slice/#deploy-a-free5gc-network-slice","title":"Deploy a free5GC Network Slice","text":"In our implementation, we install OpenStack and Tacker on two different virtual machines for resource utilization reasons, but in fact, they can be installed on the same virtual machine.
we need to install OpenStack on a virtual machine. Specific details and corresponding compatibility can be found on OpenStack official website. Using devstack scripts for installation enables operators to customize the environment based on their needs, such as extra plugins (softwares that extends the functionality of OpenStack environment) and overcommit (allows deploying NFs that require more resource than existing physical resourcce) functionality. Upon completion, a web UI enabled by Horizon can be used to access and operate on your own personalized OpenStack cloud.
Install Tacker on another virtual machine, which requires four OpenStack service components, Keystone, Mistral, Barbican and Horizon. Once the installation is completed, we can register our OpenStack VIM on Tacker using openstack vim register
command.
Create two instances that will be used as images (one for control plane VNFs, one for UPF) for the VNFs that we will create. Then, ssh
into those instances to set up the configurations for the VNFs, such as, installing required packages (go language, mongodb, libtool, etc.) and git clone
free5GC source code. Once all the configurations are done, use OpenStack dashboard to take snapshots of these instances, which will be used as the images for VNFs.
Import all the VNF descriptors (VNFD) of the VNFs we need by using openstack vnf descriptor create
command. VNFDs should be written in accordance with TOSCA format. TOSCA format allows you to define the virtual links (a virtual network VNFs will be running in) and virtual deployment unit (operation unit of a VNF). Below is an example of UPF VNFD:
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0\ndescription: description\nnode_types:\ntosca.nodes.nfv.VNF11:\nrequirements:\n- virtualLink1:\ntype: tosca.nodes.nfv.VL\nrequired: true\nmetadata:\ntemplate_name: free5GCSetup\ntopology_template:\nsubstitution_mappings:\nnode_type: tosca.nodes.nfv.VNF11\nnode_templates:\nVDU1:\ntype: tosca.nodes.nfv.VDU.Tacker\nproperties:\nname: free5gc-upf1-VNF\nimage: stage3-up\nflavor: free5gc\navailability_zone: nova\nmgmt_driver: noop\nkey_name: free5gc\nuser_data_format: RAW\nuser_data: |\n#!/bin/sh\ncd /home/ubuntu/free5gc/src/upf/build \ncat > config/upfcfg.yaml <<- EOM\ninfo:\nversion: 1.0.0\ndescription: UPF configuration\n\nconfiguration:\n# debugLevel: panic|fatal|error|warn|info|debug|trace\ndebugLevel: info\n\npfcp:\n- addr: 192.168.2.111\n\ngtpu:\n- addr: 192.168.2.111\n# [optional] gtpu.name\n# - name: upf.5gc.nctu.me\n# [optional] gtpu.ifname\n# - ifname: gtpif\n\napn_list:\n- apn: internet\ncidr: 60.60.0.0/24\n# [optional] apn_list[*].natifname\n# natifname: eth0\nEOM\n#sudo ./bin/free5gc-upfd -f config/upfcfg.yaml\n\nCP1:\ntype: tosca.nodes.nfv.CP.Tacker\nproperties:\nip_address: 192.168.2.111\nmanagement: true\nrequirements:\n- virtualLink:\nnode: VL1\n- virtualBinding:\nnode: VDU1\nVL1:\ntype: tosca.nodes.nfv.VL\nproperties:\nnetwork_name: 5GC\nvendor: Tacker\nFIP1:\ntype: tosca.nodes.network.FloatingIP\nproperties:\nfloating_network: public\nfloating_ip_address: 172.24.4.111\nrequirements:\n- link:\nnode: CP1\n
openstack ns descriptor create
command. The NSD should also be written in accordance with TOSCA format. Once all the VNFDs and NSD are all successfully imported, we can use openstack ns create
to deploy the network slice. The VNFs specified in the NSD will also be instantiated along with the network slice. Their instances can be viewed on OpenStack dashboard enabled by Horizon or just use openstack vnf list
to check the status of the VNFs. Below is an example of NSD tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0\ndescription: Import Common Slice VNFDs (already on-boarded)\nimports:\n- mongo\n- nrf\n- amf\n- smf\n- udr\n- pcf\n- udm\n- nssf\n- ausf\ntopology_template:\nnode_templates:\nVNF0:\ntype: tosca.nodes.nfv.VNF0\nVNF1:\ntype: tosca.nodes.nfv.VNF1\nVNF2:\ntype: tosca.nodes.nfv.VNF2\nVNF3:\ntype: tosca.nodes.nfv.VNF3\nVNF4:\ntype: tosca.nodes.nfv.VNF4\nVNF5:\ntype: tosca.nodes.nfv.VNF5\nVNF6:\ntype: tosca.nodes.nfv.VNF6\nVNF7:\ntype: tosca.nodes.nfv.VNF7\nVNF8:\ntype: tosca.nodes.nfv.VNF8\n
ssh
into the VNF instances to make the necessary configuration for each VNF and start the free5GC VNF.There are many other ways to set up a network slice. For example, we can deploy VNFs of the same network slice on different VIMs, or we can deploy all the network slices on the same VIM, as long as it is specified in the VNFDs.
"},{"location":"blog/network_slice/#about","title":"About","text":"Hi, my name is Daniel Hsieh. I am a CS major graduate student. My research field is network slicing. If there are any questions about the article, please feel free to contact.
https://www.acecloudhosting.com/blog/openstack-the-catalyst-of-the-public-cloud-market/
https://telcocloudbridge.com/blog/a-beginners-guide-to-nfv-management-orchestration-mano/
https://wiki.openstack.org/wiki/Tacker
B. Chatras, U. S. Tsang Kwong and N. Bihannic, \"NFV enabling network slicing for 5G,\" 2017 20th Conference on Innovations in Clouds, Internet and Networks (ICIN), Paris, France, 2017, pp. 219-225, doi: 10.1109/ICIN.2017.7899415.
Here are the features on the roadmap. These items are planned to be supported in the near future:
For people who are not familiar with virtual machines and Linux installation, here are some example demonstrations:
For Container deployment:
In this demo, we will
Search virtualbox download
, or visit virtualbox.org to download and install VirtualBox (currently 6.1.18) for your operation system.
Once installed VirtualBox, launch and see if you have something like this:
"},{"location":"guide/1-vm-en/#2-download-ubuntu-server","title":"2. Download Ubuntu Server","text":"Search ubuntu server download
on the web and download the latest Ubuntu Server LTS, or visit ubuntu.com, choose Manual Installation Option to download the .iso
file (currently 20.04.2 LTS)
You should have downloaded a .iso image
file with name like ubuntu-20.04.1-live-server-amd64.iso
, probably in your download directory.
Launch VirtualBox and create your first Ubuntu VM using the downloaded .iso image file. We use Ubuntu Server instead of Ubuntu Desktop because we only need a basic server machine without too many unnecessary functionalities. The resulting overhead to your host machine is smaller, and the VM starts up faster too.
Tips
ubuntu-server
, or ubuntu-20.04
.Refer to the videos Creating VM, Setting up VM.
"},{"location":"guide/1-vm-en/#31-start-installing-ubuntu","title":"3.1 Start Installing Ubuntu","text":"Some notes about installing Ubuntu:
Refer to videos Install Ubuntu 1, Install Ubuntu 2.
"},{"location":"guide/1-vm-en/#32-log-in-into-ubuntu","title":"3.2 Log in into Ubuntu","text":"Reboot after Ubuntu installation complete; wait a little bit for some initialization steps complete. Then log in with your username and password.
First try the ifconfig
command\uff1a
ubuntu@ubuntu:~$ ifconfig\nCommand 'ifconfig' not found, but can be installed with:\nsudo apt install net-tools\nubuntu@ubuntu:~$\n
If some messages like above show, it means ifconfig
has not been installed yet. (ifconfig
is no longer installed by defaults in newer Ubuntu, and is replaced by more versatile ip command, but we will use it here for simplicity).
Follow its suggestion and install ifconfig
:
ubuntu@ubuntu:~$ sudo apt install net-tools\n
Below shows the installation result: Run ifconfig
again to check the network interfaces:
Your display may look different, but take notes about the IP address of the Host-only interface card. The example above shows 192.168.56.101
. You can SSH from your host machine into this Ubuntu VM using the IP later. (Another IP address, 10.0.2.15
is the IP address of the NAT interface card, the apps in your host machine cannot access it).
Finally check if the VM has internet access:
ubuntu@ubuntu:~$ ping google.com\n
Refer to the first part of the video Ping, SSH, and Upgrade.
"},{"location":"guide/1-vm-en/#4-connect-to-the-ubuntu-vm-using-ssh","title":"4. Connect to the Ubuntu VM using SSH","text":"Launch your favorite SSH client from the host machine. Some operation systems (Mac, Ubuntu, some Windows) have pre-installed SSH clients. If you are using Windows, you can also download third-party SSH clients. For example, search \u201cwindows ssh download\u201d on the web.
The benefit of using SSH is that you can easily copy and paste commands from your machine to Ubuntu VM for execution, and vice versa. You can also create multiple SSH connections with the Ubuntu VM for control and monitoring at the same time.
Below shows some examples on a Mac host machine. Suppose the Host-only network IP is 192.168.56.101
, and tue username is ubuntu:
ssh 192.168.56.101 -l ubuntu\n
The first time you connect to the VM, your SSH client may show some message asking you for confirmation. Enter yes: Tips
If somehow SSH shows some warning messages telling you the machine has potential security risk, you may have to remove an entry in the file <your home directory>/.ssh/known_hosts
related the the IP address.
If you log in successfully, you will enter a command line interface:
Repeat the basic commands such as ping
, ifconfig
to see if the VM is working properly. If so, we can access the Ubuntu VM \u201cremotely\u201d from now on.
"},{"location":"guide/1-vm-en/#5-update-and-upgrade-your-ubuntu","title":"5. Update and Upgrade your Ubuntu","text":"
Let also update and upgrade the Ubuntu VM right now to make sure it is up-to-date with proper security updates.
sudo apt update\nsudo apt upgrade\n
"},{"location":"guide/2-config-vm-en/","title":"2 config vm en","text":""},{"location":"guide/2-config-vm-en/#creating-a-free5gc-vm-and-setting-up-network","title":"Creating a free5GC VM and Setting up Network","text":"In this demo we will exercise:
Tips
Refer to video Clone VM and Change IP.
"},{"location":"guide/2-config-vm-en/#1-check-up-an-existing-vm-for-cloning","title":"1. Check up an existing VM for Cloning","text":"Launch VirtualBox, and make sure the Ubuntu VM (ubuntu) we created before can boot up, then:
sudo apt update
and sudo apt upgrade
(or you can do it again)sudo shutdown -P now
, orsudo shutdown -r now
First let\u2019s clone a new VM:
free5gc
.After the new VM is created:
ping
and ifconfig
again to make sure it has internet access, and also make note of the IP address of the Host-only network interface.192.168.56.101
, and the interface name is enp0s8
.The cloned free5gc VM still has host name ubuntu
(or the name you gave it in the original VM). Let\u2019s rename the VM to free5gc
. You can do this by editing the file /etc/hostname
(using vi
or nano
):
sudo nano /etc/hostname\n# or \nsudo vi /etc/hostname\n
In the file, change ubuntu into free5gc
\u3002If you are using nano \uff0cyou can press Ctrl-O
to save the file, then Ctrl-X
to exit. Let\u2019s also change the file /etc/hosts
by replacing the ubuntu inside into free5gc
:
sudo nano /etc/hosts\n
New content of the file /etc/hosts
looks like this:
127.0.0.1 localhost\n127.0.1.1 free5gc\n...\n
The changes will take effect after next reboot.
"},{"location":"guide/2-config-vm-en/#4-setting-static-ip-address","title":"4. Setting Static IP Address","text":"The Host-only network interface, by default, gets its IP address through DHCP. The cloned free5gc VM seems to have trouble obtaining new IP address. We can change the host-only interface to use static IP address instead, which can save a lot of trouble later.
Here let\u2019s fix the static IP address as 192.168.56.101
:
$ cd /etc/netplan\n$ ls\n00-installer-config.yaml\n$ cat 00-installer-config.yaml\n
The original content of the file 00-installer-config.yaml
looks like: # This is the network config written by 'subiquity'\nnetwork:\n ethernets:\n enp0s3:\n dhcp4: true\n enp0s8:\n dhcp4: true\n version: 2\n
meaning the VM has two network interfaces. Using ifconfig
we know that enp0s8
is the name of the Host-only network interface. We can edit the file: sudo nano 00-installer-config.yaml\n
and change it into: # This is the network config written by 'subiquity'\nnetwork:\n ethernets:\n enp0s3:\n dhcp4: true\n enp0s8:\n dhcp4: no\n addresses: [192.168.56.101/24]\n version: 2\n
First check if the new content is correct: sudo netplan try\n
Press enter to exit, if successful. The apply tne new interface setting: sudo netplan apply\n
Run ifconfig
to see if the network setting has been changed correctly: enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500\n inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255\n inet6 fe80::a00:27ff:fec4:254f prefixlen 64 scopeid 0x20<link>\n ether 08:00:27:c4:25:4f txqueuelen 1000 (Ethernet)\n RX packets 2 bytes 1180 (1.1 KB)\n RX errors 0 dropped 0 overruns 0 frame 0\n TX packets 18 bytes 1894 (1.8 KB)\n TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0\n\nenp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500\n inet 192.168.56.101 netmask 255.255.255.0 broadcast 192.168.56.255\n inet6 fe80::a00:27ff:fe7e:ada6 prefixlen 64 scopeid 0x20<link>\n ether 08:00:27:7e:ad:a6 txqueuelen 1000 (Ethernet)\n RX packets 8420 bytes 531867 (531.8 KB)\n RX errors 0 dropped 0 overruns 0 frame 0\n TX packets 10887 bytes 823487 (823.4 KB)\n TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0\n\nlo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536\n inet 127.0.0.1 netmask 255.0.0.0\n inet6 ::1 prefixlen 128 scopeid 0x10<host>\n loop txqueuelen 1000 (Local Loopback)\n RX packets 6621 bytes 596035 (596.0 KB)\n RX errors 0 dropped 0 overruns 0 frame 0\n TX packets 6621 bytes 596035 (596.0 KB)\n TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0\n
We can also check the routing table, just to have a grasp of what is going on regarding the network setting: $ route -n\nKernel IP routing table\nDestination Gateway Genmask Flags Metric Ref Use Iface\n0.0.0.0 10.0.2.2 0.0.0.0 UG 100 0 0 enp0s3\n10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s3\n10.0.2.2 0.0.0.0 255.255.255.255 UH 100 0 0 enp0s3\n192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s8\n
For the display above, we learn that the Host-only network 192.168.56.0/24
does not have internet access by itself (even though we can access it using SSH from the host machine). Internet access is through the NAT network 10.0.2.0/24
, with the gateway being 10.0.2.2
(provided by VirtualBox). Now we can SSH into free5gc VM using 192.168.56.101
:
ssh 192.168.56.101 -l ubuntu\n
This is also how we interact with free5gc VM from now on."},{"location":"guide/3-install-free5gc/","title":"3 install free5gc","text":""},{"location":"guide/3-install-free5gc/#installation","title":"Installation","text":""},{"location":"guide/3-install-free5gc/#a-prerequisites","title":"A. Prerequisites","text":"Linux Kernel Version
5.0.0-23-generic
or 5.4.x
version of the Linux kernel. free5gc uses the gtp5g kernel module, which has been tested and compiled against that kernel versions only. If you installed Ubuntu 20.04, the version looks like 5.4.x. To determine the version of the Linux kernel you are using: $ uname -r\n 5.4.0-65-generic\n
You will not be able to run most of the tests in Test section unless you deploy a UPF.
Golang Version
go version\n
# this assumes your current version of Go is in the default location\nsudo rm -rf /usr/local/go\n wget https://dl.google.com/go/go1.17.8.linux-amd64.tar.gz\n sudo tar -C /usr/local -zxvf go1.17.8.linux-amd64.tar.gz\n
wget https://dl.google.com/go/go1.17.8.linux-amd64.tar.gz\n sudo tar -C /usr/local -zxvf go1.17.8.linux-amd64.tar.gz\n mkdir -p ~/go/{bin,pkg,src}\n# The following assume that your shell is bash\necho 'export GOPATH=$HOME/go' >> ~/.bashrc\n echo 'export GOROOT=/usr/local/go' >> ~/.bashrc\n echo 'export PATH=$PATH:$GOPATH/bin:$GOROOT/bin' >> ~/.bashrc\n echo 'export GO111MODULE=auto' >> ~/.bashrc\n source ~/.bashrc\n
golang
are available at the official golang site.Control-plane Supporting Packages
sudo apt -y update\nsudo apt -y install mongodb wget git\nsudo systemctl start mongodb\n
WARNING: MongoDB 5.0+ requires a CPU with AVX support. Or downgrade your MongoDB to 4.4
see https://www.mongodb.com/community/forums/t/mongodb-5-0-cpu-intel-g4650-compatibility/116610/2
see also docker-library/mongo#485 (comment)
User-plane Supporting Packages
sudo apt -y update\nsudo apt -y install git gcc g++ cmake autoconf libtool pkg-config libmnl-dev libyaml-dev\n
sudo sysctl -w net.ipv4.ip_forward=1\nsudo iptables -t nat -A POSTROUTING -o <dn_interface> -j MASQUERADE\nsudo iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1400\nsudo systemctl stop ufw\n
"},{"location":"guide/3-install-free5gc/#b-install-control-plane-elements","title":"B. Install Control Plane Elements","text":"Clone the free5GC repository
cd ~\n git clone --recursive -b v3.3.0 -j `nproc` https://github.com/free5gc/free5gc.git\n cd free5gc\n
cd ~/free5gc\n git checkout main\n git submodule sync\n git submodule update --init --jobs `nproc`\ngit submodule foreach git checkout main\n git submodule foreach git pull --jobs `nproc`\n
Compile network function services in free5gc
cd ~/free5gc\n make amf\n
cd ~/free5gc\n make\n
5.0.0-23-generic
or 5.4.x
. To verify your version:uname -r\n
git
and build itgit clone -b v0.8.1 https://github.com/free5gc/gtp5g.git\ncd gtp5g\nmake\nsudo make install\n
Build the UPF (you may skip this step if you built all network functions above):
to build using make:
cd ~/free5gc\nmake upf\n
run.sh
is free5gc/config/upfcfg.yaml
.sudo apt remove cmdtest\nsudo apt remove yarn\ncurl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -\necho \"deb https://dl.yarnpkg.com/debian/ stable main\" | sudo tee /etc/apt/sources.list.d/yarn.list\ncurl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -\nsudo apt-get update\nsudo apt-get install -y nodejs yarn\n
Build WebConsole
to build using make:
cd ~/free5gc\nmake webconsole\n
cd ~/free5gc/webconsole/frontend\nyarn install\nyarn build\nrm -rf ../public\ncp -R build ../public\ncd ..\ngo build -o bin/webconsole server.go\n
Note: 2GB or more of OS memory is recommended. WebConsole may be failed to build if memory is less then 1GB.
"},{"location":"guide/4-test-free5gc/","title":"4 test free5gc","text":""},{"location":"guide/4-test-free5gc/#test-free5gc","title":"Test free5GC","text":"Start a Wireshark capture on any core-connected interface, applying the filter 'pfcp||icmp||gtp'
.
In order to run the tests, first do this:
cd ~/free5gc\nmake upf\nchmod +x ./test.sh\n
The tests are all run from within ~/free5gc
.
a. TestRegistration
./test.sh TestRegistration\n
b. TestGUTIRegistration
./test.sh TestGUTIRegistration\n
c. TestServiceRequest
./test.sh TestServiceRequest\n
d. TestXnHandover
./test.sh TestXnHandover\n
e. TestDeregistration
./test.sh TestDeregistration\n
f. TestPDUSessionReleaseRequest
./test.sh TestPDUSessionReleaseRequest\n
g. TestPaging
./test.sh TestPaging\n
h. TestN2Handover
./test.sh TestN2Handover\n
i. TestNon3GPP
./test.sh TestNon3GPP\n
j. TestReSynchronization
./test.sh TestReSynchronization\n
k. TestULCL
./test_ulcl.sh TestRequestTwoPDUSessions\n
"},{"location":"guide/5-install-ueransim/","title":"5 install ueransim","text":""},{"location":"guide/5-install-ueransim/#installing-ueransim-a-ueran-simulator","title":"Installing UERANSIM - a UE/RAN Simulator","text":"In this demo we will practice:
Repeat the steps of cloning free5gc
VM from the base VM, create a new VM for the UERANSIM simulator:
ueransim
, and create new MAC addresses for all network cards.ueransim
.192.168.56.102
.192.168.56.101
from the ueransim VM, and also ping 192.168.56.102
from the free5gc VM.Search \u201cueransim\u201d on the web, and get the web site. On the web site, review what the UERANSIM open-source project is about, then browse into the installation page.
To download UERANSIM:
cd ~\ngit clone https://github.com/aligungr/UERANSIM\ncd UERANSIM\ngit checkout 3a96298\n
Update and upgrade ueransim VM first:
sudo apt update\nsudo apt upgrade\n
Install required tools:
sudo apt install make\nsudo apt install g++\nsudo apt install libsctp-dev lksctp-tools\nsudo apt install iproute2\nsudo snap install cmake --classic\n
Build UERANSIM:
cd ~/UERANSIM\nmake\n
"},{"location":"guide/5-install-ueransim/#3-install-free5gc-webconsole","title":"3. Install free5GC WebConsole","text":"free5GC provides a simple web tool WebConsole to help creating and managing UE registrations to be used by various 5G network functions (NF). To build WebConsole we need Node.js and Yarn.
First SSH into free5gc (192.168.56.101
)\uff0cand remove obsolete tools that may exists:
sudo apt remove cmdtest\nsudo apt remove yarn\n
Then install Node.js
and Yarn
:
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -\necho \"deb https://dl.yarnpkg.com/debian/ stable main\" | sudo tee /etc/apt/sources.list.d/yarn.list\nsudo apt-get update\nsudo apt-get install -y nodejs yarn\n
To build WebConsole:
cd ~/free5gc\nmake webconsole\n
"},{"location":"guide/5-install-ueransim/#4-use-webconsole-to-add-an-ue","title":"4. Use WebConsole to Add an UE","text":"First start up the WebConsole server:
cd ~/free5gc/webconsole\ngo run server.go\n
The screen shows the port number :5000
at the end. Open your web browser from your host machine, and enter the URL http://192.168.56.101:5000
admin
and password free5gc
.Subscribers
and create a new data:Ctrl-C
on the terminal to quit WebConsole.In free5gc VM, we need to edit three files:
~/free5gc/config/amfcfg.yaml
~/free5gc/config/smfcfg.yaml
~/free5gc/config/upfcfg.yaml
First SSH into free5gc VM, and change ~/free5gc/config/amfcfg.yaml
:
cd ~/free5gc\nnano config/amfcfg.yaml\n
Replace ngapIpList IP from 127.0.0.1
to 192.168.56.101
, namely from:
...\n ngapIpList: # the IP list of N2 interfaces on this AMF\n - 127.0.0.1\n
into: ...\n ngapIpList: # the IP list of N2 interfaces on this AMF\n - 192.168.56.101 # 127.0.0.1\n
Next edit ~/free5gc/config/smfcfg.yaml
:
nano config/smfcfg.yaml\n
and in the entry inside userplane_information / up_nodes / UPF / interfaces / endpoints
, change the IP from 127.0.0.8
to 192.168.56.101
, namely from: ...\n interfaces: # Interface list for this UPF\n - interfaceType: N3 # the type of the interface (N3 or N9)\n endpoints: # the IP address of this N3/N9 interface on this UPF\n - 127.0.0.8\n
into: ...\n interfaces: # Interface list for this UPF\n - interfaceType: N3 # the type of the interface (N3 or N9)\n endpoints: # the IP address of this N3/N9 interface on this UPF\n - 192.168.56.101 # 127.0.0.8\n
Finally, edit ~/free5gc/config/upfcfg.yaml
\uff0cand chage gtpu IP from 127.0.0.8
into 192.168.56.101
, namely from: ...\n gtpu:\n forwarder: gtp5g\n # The IP list of the N3/N9 interfaces on this UPF\n # If there are multiple connection, set addr to 0.0.0.0 or list all the addresses\n ifList:\n - addr: 127.0.0.8\n type: N3\n
into: ...\n gtpu:\n forwarder: gtp5g\n # The IP list of the N3/N9 interfaces on this UPF\n # If there are multiple connection, set addr to 0.0.0.0 or list all the addresses\n ifList:\n - addr: 192.168.56.101 # 127.0.0.8\n type: N3\n
"},{"location":"guide/5-install-ueransim/#6-setting-ueransim","title":"6. Setting UERANSIM","text":"In the ueransim VM, there are two files related to free5GC\uff1a
~/UERANSIM/config/free5gc-gnb.yaml
~/UERANSIM/config/free5gc-ue.yaml
The second file is for UE, which we don\u2019t have to change if the data inside is consistent with the (default) registration data we set using WebConsole previously.
First SSH into ueransim, and edit the file ~/UERANSIM/config/free5gc-gnb.yaml
, and change the ngapIp IP, as well as the gtpIp IP, from 127.0.0.1
to 192.168.56.102
\uff0cand also change the IP in amfConfigs into 192.168.56.101
, that is, from:
...\n ngapIp: 127.0.0.1 # gNB's local IP address for N2 Interface (Usually same with local IP)\n gtpIp: 127.0.0.1 # gNB's local IP address for N3 Interface (Usually same with local IP)\n\n # List of AMF address information\n amfConfigs:\n - address: 127.0.0.1\n
into: ...\n ngapIp: 192.168.56.102 # 127.0.0.1 # gNB's local IP address for N2 Interface (Usually same with local IP)\n gtpIp: 192.168.56.102 # 127.0.0.1 # gNB's local IP address for N3 Interface (Usually same with local IP)\n\n # List of AMF address information\n amfConfigs:\n - address: 192.168.56.101 # 127.0.0.1\n
Next we examine the file ~/UERANSIM/config/free5gc-ue.yaml
\uff0cand see if the settings is consistent with those in free5GC (via WebConsole), for example: # IMSI number of the UE. IMSI = [MCC|MNC|MSISDN] (In total 15 or 16 digits)\nsupi: 'imsi-208930000000003'\n# Mobile Country Code value\nmcc: '208'\n# Mobile Network Code value (2 or 3 digits)\nmnc: '93'\n\n# Permanent subscription key\nkey: '8baf473f2f8fd09487cccbd7097c6862'\n# Operator code (OP or OPC) of the UE\nop: '8e27b6af0e692e750f32667a3b14605d'\n# This value specifies the OP type and it can be either 'OP' or 'OPC'\nopType: 'OP'\n\n...\n\n# Initial PDU sessions to be established\nsessions:\n - type: 'IPv4'\n apn: 'internet'\n slice:\n sst: 0x01\n sd: 0x010203\n\n# List of requested S-NSSAIs by this UE\nslices:\n - sst: 0x01\n sd: 0x010203\n\n...\n
The data appear to be the same as what we set in WebConsole."},{"location":"guide/5-install-ueransim/#7-testing-ueransim-against-free5gc","title":"7. Testing UERANSIM against free5GC","text":"SSH into free5gc. If you have rebooted free5gc, remember to do:
sudo sysctl -w net.ipv4.ip_forward=1\nsudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE\nsudo systemctl stop ufw\n
In addition, execute the following command:
sudo iptables -I FORWARD 1 -j ACCEPT\n
Also, make sure you have make proper changes to the free5GC configuration files, then run ./run.sh
:
cd ~/free5gc\n./run.sh\n
At this time free5GC has been started.
Next, prepare three additional SSH terminals from your host machine (if you know how to use tmux
, you can use just one).
In terminal 1: SSH into ueransim, make sure UERANSIM is built, and configuration files have been changed correctly, then execute nr-gnb
:
cd ~/UERANSIM\nbuild/nr-gnb -c config/free5gc-gnb.yaml\n
In terminal 2, SSH into ueransim, and execute nr-ue
with admin right:
cd ~/UERANSIM\nsudo build/nr-ue -c config/free5gc-ue.yaml # for multiple-UEs, use -n and -t for number and delay\n
In terminal 3, SSH into ueransim, and ping 192.168.56.101
to see free5gc is alive. Then, use ifconfig to see if the tunnel uesimtun0
has been created (by nr-ue):
$ ifconfig\n\nenp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500\n inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255\n inet6 fe80::a00:27ff:fe65:1472 prefixlen 64 scopeid 0x20<link>\n ether 08:00:27:65:14:72 txqueuelen 1000 (Ethernet)\n RX packets 80 bytes 32423 (32.4 KB)\n RX errors 0 dropped 0 overruns 0 frame 0\n TX packets 90 bytes 12860 (12.8 KB)\n TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0\n\nenp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500\n inet 192.168.56.102 netmask 255.255.255.0 broadcast 192.168.56.255\n inet6 fe80::a00:27ff:fe5e:be64 prefixlen 64 scopeid 0x20<link>\n ether 08:00:27:5e:be:64 txqueuelen 1000 (Ethernet)\n RX packets 1515 bytes 130490 (130.4 KB)\n RX errors 0 dropped 0 overruns 0 frame 0\n TX packets 1010 bytes 206670 (206.6 KB)\n TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0\n\nlo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536\n inet 127.0.0.1 netmask 255.0.0.0\n inet6 ::1 prefixlen 128 scopeid 0x10<host>\n loop txqueuelen 1000 (Local Loopback)\n RX packets 3445 bytes 174416 (174.4 KB)\n RX errors 0 dropped 0 overruns 0 frame 0\n TX packets 3445 bytes 174416 (174.4 KB)\n TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0\n\nuesimtun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500\n inet 60.60.0.1 netmask 255.255.255.255 destination 60.60.0.1\n inet6 fe80::2034:d00:a76:84b7 prefixlen 64 scopeid 0x20<link>\n unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC)\n RX packets 3 bytes 252 (252.0 B)\n RX errors 0 dropped 0 overruns 0 frame 0\n TX packets 13 bytes 732 (732.0 B)\n TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0\n
Now use ping
:
ping -I uesimtun0 google.com\n
If ping
gets replies, then free5GC is running properly. Congratulations!"},{"location":"guide/6-simple-app/","title":"6 simple app","text":""},{"location":"guide/6-simple-app/#free5gc-simple-apps","title":"free5GC Simple Apps","text":"In this demo we will use free5GC together with UERANSIM to exercise on some simple network applications:
ping
+ tcpdump
wget
and curl
First start up free5GC and ueransim VMs. This requires one SSH terminal for free5gc, and two for ueransim.
Open another SSH terminal and log in into ueransim:
ssh 192.168.56.102 -l ubuntu\n
Use ifconfig
to check if uesimtun0
tunnel has been created, and use ping to check if we can ping
through it\uff1a $ ping google.com\nPING google.com (172.217.27.142) 56(84) bytes of data.\n64 bytes from tsa03s02-in-f14.1e100.net (172.217.27.142): icmp_seq=1 ttl=63 time=3.98 ms\n64 bytes from tsa03s02-in-f14.1e100.net (172.217.27.142): icmp_seq=2 ttl=63 time=3.87 ms\n64 bytes from tsa03s02-in-f14.1e100.net (172.217.27.142): icmp_seq=3 ttl=63 time=4.06 ms\n^C\n--- google.com ping statistics ---\n3 packets transmitted, 3 received, 0% packet loss, time 2003ms\nrtt min/avg/max/mdev = 3.872/3.970/4.060/0.076 ms\n
$ ping -I uesimtun0 google.com\nPING google.com (172.217.27.142) from 60.60.0.1 uesimtun0: 56(84) bytes of data.\n64 bytes from tsa03s02-in-f14.1e100.net (172.217.27.142): icmp_seq=1 ttl=61 time=5.85 ms\n64 bytes from tsa03s02-in-f14.1e100.net (172.217.27.142): icmp_seq=2 ttl=61 time=4.87 ms\n64 bytes from tsa03s02-in-f14.1e100.net (172.217.27.142): icmp_seq=3 ttl=61 time=4.76 ms\n^C\n--- google.com ping statistics ---\n3 packets transmitted, 3 received, 0% packet loss, time 2004ms\nrtt min/avg/max/mdev = 4.760/5.160/5.847/0.487 ms\n
Also use route -n
to observe if current routing table shows some routing rules regarding the two network interfaces enp0s3
and enp0s8
:
$ route -n\nKernel IP routing table\nDestination Gateway Genmask Flags Metric Ref Use Iface\n0.0.0.0 10.0.2.2 0.0.0.0 UG 100 0 0 enp0s3\n10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s3\n10.0.2.2 0.0.0.0 255.255.255.255 UH 100 0 0 enp0s3\n192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s8\n
The network 10.0.2.0/24
and its enp0s3
interface are related to VirtualBox NAT network card. We can bring down this interface:
$ sudo ifconfig enp0s3 down\n$ route -n\nKernel IP routing table\nDestination Gateway Genmask Flags Metric Ref Use Iface\n192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s8\n
As shown aboe we have only Host-only network 192.168.56.0/24
left. Run ping
again: $ ping 8.8.8.8\nping: connect: Network is unreachable\n
And see that it can not ping through, but runing:
$ ping -I uesimtun0 8.8.8.8\nPING 8.8.8.8 (8.8.8.8) from 60.60.0.1 uesimtun0: 56(84) bytes of data.\n64 bytes from 8.8.8.8: icmp_seq=1 ttl=61 time=7.17 ms\n64 bytes from 8.8.8.8: icmp_seq=2 ttl=61 time=5.41 ms\n64 bytes from 8.8.8.8: icmp_seq=3 ttl=61 time=5.15 ms\n^C\n--- 8.8.8.8 ping statistics ---\n3 packets transmitted, 3 received, 0% packet loss, time 2005ms\nrtt min/avg/max/mdev = 5.150/5.907/7.165/0.895 ms\n
shows some responses, since we ask ping
to go through the free5GC core network. To make ping 8.8.8.8
in addition to ping -I uesimtun0 8.8.8.8
work, we can set the uesimtun0
interface (IP 60.60.0.1
) as the new default gateway:
$ sudo ip r add default dev uesimtun0\n$ route -n\nKernel IP routing table\nDestination Gateway Genmask Flags Metric Ref Use Iface\n0.0.0.0 0.0.0.0 0.0.0.0 U 0 0 0 uesimtun0\n192.168.56.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s8\n
Now traffic not for the 192.168.56.0/24
network will go to uesimtun0
, and ping 8.8.8.8
works this time: $ ping 8.8.8.8\nPING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.\n64 bytes from 8.8.8.8: icmp_seq=1 ttl=61 time=5.02 ms\n64 bytes from 8.8.8.8: icmp_seq=2 ttl=61 time=6.31 ms\n64 bytes from 8.8.8.8: icmp_seq=3 ttl=61 time=5.41 ms\n^C\n--- 8.8.8.8 ping statistics ---\n3 packets transmitted, 3 received, 0% packet loss, time 2004ms\nrtt min/avg/max/mdev = 5.017/5.581/6.312/0.541 ms\n...\n
Note that normally we are using ueransim to simulate \u201cterminal\u201d UE device, not as a network device or proxy, therefore the above two routing rules suffice.
Now if we still want to run:
$ ping google.com\nping: google.com: Temporary failure in name resolution\n
we will get unresolved domain name. To solve this, we can modify the file /etc/resolv.conf
:
sudo nano /etc/resolv.conf\n
and change the nameserver IP to 8.8.8.8
:
nameserver 8.8.8.8\n
After the change, we can see ping
getting responses:
$ ping google.com\nPING google.com (216.58.200.46) 56(84) bytes of data.\n64 bytes from tsa01s08-in-f46.1e100.net (216.58.200.46): icmp_seq=1 ttl=61 time=5.19 ms\n64 bytes from tsa01s08-in-f46.1e100.net (216.58.200.46): icmp_seq=2 ttl=61 time=50.4 ms\n64 bytes from tsa01s08-in-f46.1e100.net (216.58.200.46): icmp_seq=3 ttl=61 time=5.66 ms\n^C\n--- google.com ping statistics ---\n3 packets transmitted, 3 received, 0% packet loss, time 2004ms\nrtt min/avg/max/mdev = 5.191/20.423/50.414/21.207 ms\n
We can also examine the network traffic happening underneath in the scenario above. First we open another SSH terminal into ueransim, and run the following command:
$ sudo tcpdump -n -i any host 60.60.0.1 or 192.168.56.101\ntcpdump: verbose output suppressed, use -v or -vv for full protocol decode\nlistening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes\n
then run ping 8.8.8.8
again, wait for a couple seconds, then Ctrl-C
to exit. We see the data packets actually going in and out uesimtun0
.
$ sudo tcpdump -n -i any host 60.60.0.1 or 192.168.56.101\ntcpdump: verbose output suppressed, use -v or -vv for full protocol decode\nlistening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes\n10:24:56.138729 IP 192.168.56.101.38412 > 192.168.56.102.38740: sctp (1) [HB REQ]\n10:24:56.138783 IP 192.168.56.102.38740 > 192.168.56.101.38412: sctp (1) [HB ACK]\n10:24:58.456532 IP 60.60.0.1 > 8.8.8.8: ICMP echo request, id 33, seq 1, length 64\n10:24:58.457416 IP 192.168.56.102.2152 > 192.168.56.101.2152: UDP, length 100\n10:24:58.462136 IP 192.168.56.101.2152 > 192.168.56.102.2152: UDP, length 92\n10:24:58.462324 IP 8.8.8.8 > 60.60.0.1: ICMP echo reply, id 33, seq 1, length 64\n10:24:59.458823 IP 60.60.0.1 > 8.8.8.8: ICMP echo request, id 33, seq 2, length 64\n10:24:59.459031 IP 192.168.56.102.2152 > 192.168.56.101.2152: UDP, length 100\n10:24:59.464214 IP 192.168.56.101.2152 > 192.168.56.102.2152: UDP, length 92\n10:24:59.464396 IP 8.8.8.8 > 60.60.0.1: ICMP echo reply, id 33, seq 2, length 64\n10:25:00.461293 IP 60.60.0.1 > 8.8.8.8: ICMP echo request, id 33, seq 3, length 64\n10:25:00.462178 IP 192.168.56.102.2152 > 192.168.56.101.2152: UDP, length 100\n10:25:00.474941 IP 192.168.56.101.2152 > 192.168.56.102.2152: UDP, length 92\n10:25:00.475561 IP 8.8.8.8 > 60.60.0.1: ICMP echo reply, id 33, seq 3, length 64\n10:25:01.463946 IP 60.60.0.1 > 8.8.8.8: ICMP echo request, id 33, seq 4, length 64\n10:25:01.464523 IP 192.168.56.102.2152 > 192.168.56.101.2152: UDP, length 100\n10:25:01.469297 IP 192.168.56.101.2152 > 192.168.56.102.2152: UDP, length 92\n10:25:01.470314 IP 8.8.8.8 > 60.60.0.1: ICMP echo reply, id 33, seq 4, length 64\n
"},{"location":"guide/6-simple-app/#wget","title":"wget","text":"Simply look for any web page for file download on the web. For example, if we choose Golang web site as an example, we may find the URL:
https://golang.org/dl/go1.15.8.darwin-amd64.pkg\n
Using the same network settings is the previous exercise, just wget https://golang.org/dl/go1.15.8.darwin-amd64.pkg\n
And see if you can download a Golang 1.15.8 install file."},{"location":"guide/6-simple-app/#ptt-ssh-bbsupttcc","title":"ptt (ssh bbsu@ptt.cc
)","text":"You can actually use SSH in the ueransim VM to access remote site. For example, you can SSH to a well-known terminal-based BBS site in Taiwan:
ssh bbsu@ppt.cc\n
"},{"location":"guide/6-simple-app/#youtube","title":"Youtube","text":"You can also use Youtube as an example app. To achieve this goal, you can install a desktop VM with graphical UI, such as Ubuntu Desktop, and follow the same procedure to install and start up UERANSIM, then access Youtube through uesimtun0
and free5GC.
To reduce resource consumption on your host machine, you may install Lubuntu (at https://lubuntu.me), a more light-weight Ubuntu desktop distro instead. But since viewing free5GC YouTube Channel requires quite sime CPU consumption, you may have to set at least 2 CPUs and 2048 MB memory for the VM.
Refer to videos Access Youtube on Lubuntu (1, 2, 3, 4 and 5).
"},{"location":"guide/Appendix/","title":"Appendix","text":""},{"location":"guide/Appendix/#appendix","title":"Appendix","text":""},{"location":"guide/Appendix/#appendix-a-oam","title":"Appendix A: OAM","text":"cd webconsole\ngo run server.go\n
URL: http://localhost:5000\nUsername: admin\nPassword: free5gc\n
Note: You can add the subscribers here too
"},{"location":"guide/Appendix/#appendix-b-orchestrator","title":"Appendix B: Orchestrator","text":"Please refer to free5gmano
"},{"location":"guide/Appendix/#appendix-c-iptv","title":"Appendix C: IPTV","text":"Please refer to free5GC/IPTV
"},{"location":"guide/Appendix/#appendix-d-system-environment-cleaning","title":"Appendix D: System Environment Cleaning","text":"The below commands may be helpful for development purposes.
ls /dev/mqueue/
rm /dev/mqueue/*
cd ./src/upf/lib/libgtp5gnl/tools
./gtp5g-tunnel list pdr
./gtp5g-tunnel list far
cd ./src/upf/lib/libgtp5gnl/tools
sudo ./gtp5g-link del {Dev-Name}
uname -r
5.0.0-23-generic
for example sudo apt search 'linux-image-5.0.0-23-generic'\nsudo apt install 'linux-image-5.0.0-23-generic'\nsudo apt install 'linux-headers-5.0.0-23-generic'\n
sudo update-initramfs -u -k all\nsudo update-grub\n
5.0.0-23-generic
sudo reboot\n
sudo apt remove 'linux-image-5.0.0-23-generic'\nsudo apt remove 'linux-headers-5.0.0-23-generic'\n
"},{"location":"guide/Appendix/#appendix-f-program-the-sim-card","title":"Appendix F: Program the SIM Card","text":"Install packages:
sudo apt-get install pcscd pcsc-tools libccid python-dev swig python-setuptools python-pip libpcsclite-dev\nsudo pip install pycrypto\n
Download PySIM
git clone git://git.osmocom.org/pysim.git\n
Change to pyscard folder and install
cd <pyscard-path>\nsudo /usr/bin/python setup.py build_ext install\n
Verify your reader is ready
sudo pcsc_scan\n
Check whether your reader can read the SIM card
cd <pysim-path>\n./pySim-read.py \u2013p 0\n
Program your SIM card information
./pySim-prog.py -p 0 -x 208 -y 93 -t sysmoUSIM-SJS1 -i 208930000000003 --op=8e27b6af0e692e750f32667a3b14605d -k 8baf473f2f8fd09487cccbd7097c6862 -s 8988211000000088313 -a 23605945\n
You can get your SIM card from sysmocom. You also need a card reader to write your SIM card. You can get a card reader from here or use other similar devices.
"},{"location":"guide/Configuration/","title":"Configuration","text":""},{"location":"guide/Configuration/#configuration","title":"Configuration","text":""},{"location":"guide/Configuration/#sbi-configuration","title":"SBI Configuration","text":"There are registerIP and bindingIP design on every NF's sbi interface.
This is due to some orchestration, such as Kubernets or OpenStack, has the design of service IP mapping.
Use Kubernets as an example. K8S has the service type that enable users to define the service IP outside the pod. But the service IP may be different from the IP assigned inside the pod. Therefore, if we register the binding IP inside the pod to NRF, NRF cannot know which service IP outside the pod has attached. As the result, we need to separate registerIP from bindingIP in this scenario.
If you are not sure what IP you should set, just configure it as the same IP address.
"},{"location":"guide/Configuration/#sample-configuration","title":"Sample configuration","text":"We provide a sample config to connect to outer ran under /sample/ran_attach_config/
. The architecture is as following.
As the result, user's RAN IP must set to 192.168.0.0/24 subnet or let the routing route to this subnet.
Notice: If user wants to use the setting, aware to set 192.168.0.1 to your host as well.
"},{"location":"guide/Configuration/#smf-configuration","title":"SMF Configuration","text":""},{"location":"guide/Configuration/#a-configure-smf-with-s-nssai","title":"A. Configure SMF with S-NSSAI","text":"smfcfg.yaml
uerouting.yaml
For more detail of SMF config, please refer to here.
"},{"location":"guide/Environment/","title":"Environment","text":""},{"location":"guide/Environment/#recommended-environment","title":"Recommended Environment","text":"free5gc has been tested against the following environment:
The listed kernel version is required for the UPF element.
Minimum Hardware
Recommended Hardware
This guide assumes that you will run all 5GC elements on a single machine.
"},{"location":"guide/New-Subscriber-via-webconsole/","title":"New Subscriber via webconsole","text":""},{"location":"guide/New-Subscriber-via-webconsole/#new-subscriber-via-webconsole","title":"New Subscriber via webconsole","text":""},{"location":"guide/New-Subscriber-via-webconsole/#1-install-webconsole","title":"1. Install webconsole","text":""},{"location":"guide/New-Subscriber-via-webconsole/#2-optionaldelete-mongodb","title":"2. (Optional)Delete MongoDB","text":"If another version of free5GC was ran before, you have to delete MongoDB.
$ mongo --eval \"db.dropDatabase()\" free5gc\n
"},{"location":"guide/New-Subscriber-via-webconsole/#3-run-webconsole-server","title":"3. Run WebConsole server","text":"$ cd ~/free5gc/webconsole\n$ ./bin/webconsole\n
"},{"location":"guide/New-Subscriber-via-webconsole/#4-use-browser-to-connect-to-webconsole","title":"4. Use browser to connect to WebConsole","text":"Enter :5000 in URL bar.
Username: admin\nPassword: free5gc\n
"},{"location":"guide/New-Subscriber-via-webconsole/#5-add-new-subscriber","title":"5. Add new subscriber","text":"There are some issues for subscriber modification. If you want to modify the existed subscriber, please Delete
it first and New
again for now.
This document explains the detail of SMF config. Also provide some examples about conversion between config file and real userplane topology
ULCL limitation: The branching UPF now can't connect to the Internet. It only serves as a Intranet in the UPF topology. (Please refers to the topology of example 2)
"},{"location":"guide/SMF-Config/#sbi","title":"SBI","text":"Field meaning scheme The protocol for SBI registerIPv4 IP used to register to NRF bindingIPv4 IP used to bind the service port SMF bind the SBI service to this port"},{"location":"guide/SMF-Config/#pfcp","title":"PFCP","text":"Field meaning addr The IP address of N4 interface on the SMF (PFCP)"},{"location":"guide/SMF-Config/#userplane-information","title":"Userplane Information","text":"Field meaning userplane_information Includes topology and information of RAN and UPFs which are controlled by this SMF up_nodes The node in the user plane topology. Includes gNodeB, I-UPF and A-UPF links The edge in the user plane topology type Indicate it is RAN or specific kind of UPF node_id The PFCP IPv4 address for UPFNote: up_resource_ip serves as default user plane IP for the UPF. In this version, UPF will determine its user plane IP by itself. So setting up_resource_ip in SMF config won't affect real config in user plane.
"},{"location":"guide/SMF-Config/#amf-config","title":"AMF Config","text":"To understand whole PDU session config, we must take a step forward to understand the AMF config.
Field meaning NGAPIPList The IP list of N2 interfaces on the AMF SBI Same meaning with SMF/SBI."},{"location":"guide/SMF-Config/#example-1","title":"Example 1","text":""},{"location":"guide/SMF-Config/#smf-config","title":"SMF Config","text":"ERROR: [SCTP] Failed to connect given AMF N3IWF=NGAP
","text":"This error occured when N3IWF was started before AMF finishing initialization. This error usually appears when you run the TestNon3GPP in the first time.
Rerun the test should be fine. If it still not be solved, larger the sleeping time in line 110 of test.sh
.
TestNon3GPP will modify the config/amfcfg.conf
. So, if you had killed the TestNon3GPP test before it finished, you might need to copy config/amfcfg.conf.bak
back to config/amfcfg.conf
to let other tests pass.
cp config/amfcfg.conf.bak config/amfcfg.conf
If you meet any problems about https or mogodb, it maybe couse our new version from v3.0.1 to v3.0.2 has change http to H2C verion. Try the command below.
mongo --eval \"db.NfProfile.drop()\" free5gc
MQCreate() Error creating message queue: Too many open files UPF=Util
(UPF)","text":"Remove POSIX message queues
ls /dev/mqueue/\nrm /dev/mqueue/*\n
"},{"location":"guide/Trouble_Shooting/#5-remove-gtp-devices-using-tools-in-libgtp5gnl-upf","title":"5. Remove gtp devices (using tools in libgtp5gnl) (UPF)","text":"cd lib/libgtp5gnl/tools\nsudo ./gtp5g-link del {Dev-Name}\n
"},{"location":"guide/Trouble_Shooting/#6-upf-cli-run-error-open-gtp5g-open-link-create-file-exists","title":"6. UPF Cli Run Error: open Gtp5g: open link: create: file exists
","text":"sudo ip link del upfgtp\n
"},{"location":"guide/Trouble_Shooting/#7-decode-http2-packet-in-wireshark","title":"7. Decode HTTP/2 packet in Wireshark","text":"Run Network Function
Check has XXFsslkey.log
Edit >> Preference >> Protocols >> SSL (TLS)
Add keylog
Filter http2
The similar reason as NEA0 NAS message. Althrough H2C is clear text, wirshark still considers these packets as the normal TCP packets and does not decode them by HTTP2.
To see the details of H2C packets, do the following configuration.
Analyze \u2192 Decode As\u2026
click Add button to add the decode rules
Decode the packets from the TCP ports listened by each NF as HTTP2 packets.
Some 5G UE and gNodeB hardware have been tested with free5GC by partners or community members:
5G UE (Support 5G SA):
gNodeB:
Reports of tested hardware not listed above on Github issue or free5GC forum are welcome.
PS: if you don't have any hardware available, we suggest to use UERANSIM to simulate.
(Refer to Advanced environment setup section)
"},{"location":"membership/","title":"Index","text":""},{"location":"membership/#sponsorship-info","title":"Sponsorship Info","text":""},{"location":"membership/#sponsorship-tiers","title":"Sponsorship Tiers","text":"free5GC is a nonprofit organization dedicated to developing innovative and next-generation features for open-source code of the 5G Core (5GC) Network under Apache 2.0 license. Your generous support and sponsorship will sustain our technology development and the operation of the community. Your company/organization logo will be displayed on the free5GC website and listed as the sponsorship you participate. Here are the sponsorship tiers we offer.
Your generosity is appreciated.
Tips
If you encounter the usage problem on free5GC, please join our official forum forum.free5gc.org and initiate a new discussion.
Otherwise, you can raise the issue on our GitHub repository for reporting the bugs/suggestions (related to vulnerability/functionality/deployment/testing), or create the pull request for contributing to our community!
Tips
If your problem can not be solved via the platforms listed above, please send an email to free5GC.org@gmail.com
directly. Thanks.
If you encounter the usage problem on free5GC, please join our official forum forum.free5gc.org and initiate a new discussion.
+Otherwise, you can raise the issue on our GitHub repository for reporting the bugs/suggestions (related to vulnerability/functionality/deployment/testing), or create the pull request for contributing to our community!
+Tips
+If your problem can not be solved via the platforms listed above, please send an email to free5GC.org@gmail.com
directly.
+Thanks.
Akraino Blueprints: Integrated Cloud Native Private Wireless, The Linux Foundation, October 11, 2021
+SD Core Techinar July 7 2021, Open Networking Foundation, July 13, 2021
+Aarna Networks MWC 2021 Demo, Aarna Networks Channel, June 27, 2021
+OpenStack Tacker Demo, Open Infrastructure Foundation, April 26, 2021
+OpenNess Tungsten Fabric free5GC demo, Aarna Networks Channel, February 16, 2021
+5G Core on Diamanti, Diamanti, Inc., February 3, 2021
+free5GC (5G Core) Orchestration on Kubernetes with Tungsten Fabric CNI and Testing, Aarna Networks Channel, December 2, 2020
+IoT LoRa (sensors and gateway in hardware), RAN in hardware (SDR) and software, and the free5GC, LABORA Research Group, July 3, 2020
+UE and eNodeB in Hardware (conventional cell phone + SDR) and free5GC: a pratical approach in 5G, LABORA Research Group, July 3, 2020
+OpenAirInterface and free5GC: a pratical approach in 5G networks, LABORA Research Group, June 29, 2020
+