diff --git a/docs/guide/N3IWUE/images/interfaces.png b/docs/guide/N3IWUE/images/interfaces.png
new file mode 100644
index 00000000..fba358c7
Binary files /dev/null and b/docs/guide/N3IWUE/images/interfaces.png differ
diff --git a/docs/guide/N3IWUE/images/result.png b/docs/guide/N3IWUE/images/result.png
new file mode 100644
index 00000000..1a39349a
Binary files /dev/null and b/docs/guide/N3IWUE/images/result.png differ
diff --git a/docs/guide/N3IWUE/n3iwue.md b/docs/guide/N3IWUE/n3iwue.md
new file mode 100644
index 00000000..450f4f2c
--- /dev/null
+++ b/docs/guide/N3IWUE/n3iwue.md
@@ -0,0 +1,99 @@
+# N3IWUE Design Document
+
+> [!WARNING]
+> This document doesn't include all design details about N3IWUE.
+
+
+
+## Info
+
+- GitHub Repo [https://github.com/free5gc/n3iwue](https://github.com/free5gc/n3iwue)
+- [Installation Guide](./../n3iwue-installation.md)
+- [*TS23.502 Procedures for Untrusted non-3GPP access*](https://www.tech-invite.com/3m23/toc/tinv-3gpp-23-502_zn.html)
+- [Netlink Go Library](https://github.com/vishvananda/netlink)
+
+
+
+## GRE Tunnels
+
+> [!NOTE]
+> Author: [Andy Chen (CTFang)](https://www.linkedin.com/in/tsung-fang-chen-437a71191/)
+> Date: 2024/06/12
+
+
+
+### GRE Tunnel & Spec
+
+Here is part of _TS24.502 Access 5GCN via non-3GPP access networks_ spec:
+
+> #### **8.3.2 Generic routing encapsulation (GRE)**
+>
+> If a user data packet message is transmitted over non-3GPP access between the UE and the N3IWF for untrusted non3GPP access, the user data packet message shall be encapsulated as a GRE user data packet.
+>
+> In the GRE encapsulated user data packet:
+>
+> b) the QFI field of the key field of the GRE header field is set to the QFI associated with the user data packet;
+
+The GRE key field must use the QFI value as its key.
+
+N3IWUE uses the **Netlink** Go library to create GRE Tunnel. Here is a segment of code for the new GRE Interface.
+
+```go
+greKeyField = (uint32(qfi) & 0x3F) << 24
+newGreIfaceName := greIfaceName + "-" + strconv.Itoa(int(qfi))
+
+// New GRE tunnel interface
+newGRETunnel := &netlink.Gretun{
+ LinkAttrs: netlink.LinkAttrs{
+ Name: newGreIfaceName,
+ MTU: 1438, // remain for endpoint IP header(most 40 bytes if IPv6) and ESP header (22 bytes)
+ },
+ Link: uint32(parent.Attrs().Index), // PHYS_DEV in iproute2; IFLA_GRE_LINK in linux kernel
+ Local: ueTunnelAddr,
+ Remote: n3iwfTunnelAddr,
+ IKey: greKeyField,
+ OKey: greKeyField,
+}
+```
+
+And the default rule always has **QFI = 1**.
+
+
+
+### Procedure
+
+During the N3IWUE PDU session Establishment procedure, when UE receives **PDUSessionEstablishmentAccept**, N3IWUE will try to do the following things: (refer to `n3iwue/internal/nwucp/handler/handler.go > HandleDLNASTransport()`)
+
+- Get PDU Address from NAS
+- Setup GRE Tunnels
+ - N3IWUE create per tunnel for each QFI
+- Add Route for GRE Tunnels
+ - N3IWUE adds routes for each tunnel
+ - Remote IPv4 address for each QFI retrieve from NAS message
+
+
+
+### Example Scenario
+
+- Two QoS rules
+ - QFI = 2, address = 1.1.1.1
+ - QFI = 3, address = 8.8.8.8
+
+So, the N3IWUE would create **3 GRE tunnels** and **3 routes**.
+
+![result](./images/result.png)
+
+After the ping test, use `ifconfig` to see the status for each GRE interfaces:
+
+![interfaces](./images/interfaces.png)
+
+- **ens18** is the only one interface on that computer
+- **gretun-id-2-1** for QFI = 1, receive 5 ping reply from 9.9.9.9 and send 5 ping request with some others traffics.
+- **gretun-id-2-2** for QFI = 2, send 5 ping request to 8.8.8.8 and receive 5 ping reply.
+- **gretun-id-2-3** for QFI = 3, send 5 ping request to 1.1.1.1 and receive 5 ping reply.
+
+
+
+### Related Pull Request
+
+[fix: Add multiple GRE tunnel when have multiple QFI settings #7](https://github.com/free5gc/n3iwue/pull/7)
diff --git a/docs/guide/contribute.md b/docs/guide/contribute.md
index 65e89139..c8ebac21 100644
--- a/docs/guide/contribute.md
+++ b/docs/guide/contribute.md
@@ -34,6 +34,7 @@ We maintain the design documents to help people started contributing to the free
- [CHF](./Chf/design.md)
- [PCF (Charging)](./PCF/charging.md)
- [OAuth2 on SBI](./OAuth2/OAuth2Design.md)
+- [N3IWUE](./N3IWUE/n3iwue.md)
- [Problem Details](https://github.com/free5gc/free5gc.github.io/tree/main/docs/guide/ProblemDetails)
## Recommended Articles
diff --git a/docs/guide/n3iwue-installation.md b/docs/guide/n3iwue-installation.md
index 2a0a9ddc..efdc7451 100644
--- a/docs/guide/n3iwue-installation.md
+++ b/docs/guide/n3iwue-installation.md
@@ -1,6 +1,6 @@
-# Installing N3IWUE
+# Installing N3IWUE
In this demo we will practice:
@@ -25,6 +25,7 @@ Repeat the steps of cloning `free5gc` VM from the base VM, create a new VM for t
Go to [N3IWUE GitHub Repo](https://github.com/free5gc/n3iwue).
To download N3IWUE in home directory:
+
```
cd ~
git clone https://github.com/free5gc/n3iwue.git
@@ -32,12 +33,14 @@ cd n3iwue
```
Update and upgrade the VM of N3IWUE:
+
```
sudo apt update
sudo apt upgrade
```
Install required tools:
+
```
sudo apt install make
sudo apt install libsctp-dev lksctp-tools
@@ -45,13 +48,14 @@ sudo apt install iproute2
```
Install Golang (use `1.21.6` version in this demonstrate):
+
```
wget https://dl.google.com/go/go1.21.6.linux-amd64.tar.gz
sudo tar -C /usr/local -zxvf go1.21.6.linux-amd64.tar.gz
mkdir -p ~/go/{bin,pkg,src}
echo 'export GOPATH=$HOME/go' >> ~/.bashrc
echo 'export GOROOT=/usr/local/go' >> ~/.bashrc
-echo 'export PATH=$PATH:$GOPATH/bin:$GOROOT/bin' >> ~/.bashrc
+echo 'export PATH=$PATH:$GOPATH/bin:$GOROOT/bin' >> ~/.bashrc
echo 'export GO111MODULE=auto' >> ~/.bashrc
source ~/.bashrc
@@ -60,6 +64,7 @@ go version
```
Build N3IWUE
+
```
cd ~/n3iwue
make
@@ -72,31 +77,36 @@ Open your web browser from your host machine, and enter the URL `http://192.168.
- On the login page, enter username `admin` and password `free5gc`.
- Once logged in, widen the page until you see “Subscribers” on the left-hand side column.
- Click on the `Subscribers` tab and then on the `New Subscriber` button
- - Scroll down to `Operator Code Type` and change it from "OPc" to "OP".
- - Make sure the following config between `n3iwue/config/n3ue.yaml` and `Subscriber` you create are the same:
- - PLMNID (ex. 208930000001234)
- - K
- - SQN
- - OP value (choose OP instead of OPC)
- - Scroll all the way down and click on `Submit`.
+ - Scroll down to `Operator Code Type` and change it from "OPc" to "OP".
+ - Make sure the following config between `n3iwue/config/n3ue.yaml` and `Subscriber` you create are the same:
+ - PLMNID (ex. 208930000001234)
+ - K
+ - SQN
+ - OP value (choose OP instead of OPC)
+ - Scroll all the way down and click on `Submit`.
## 4. Setting N3IWF Config
In free5gc VM, we need to edit N3IWF config file `~/free5gc/config/n3iwfcfg.yaml`
Replace IKEBindAddress from `172.16.2.100` to `192.168.56.101`, namely from:
+
```
IKEBindAddress: 172.16.2.100 # Nwu interface IP address (IKE) on this N3IWF
```
+
into:
+
```
IKEBindAddress: 192.168.56.101 # Nwu interface IP address (IKE) on this N3IWF
```
+
## 5. Setting N3IWUE
To let N3IWUE knows where is the N3IWF is, we need to edit the UE config file `~/n3iwue/config/n3ue.yaml` in N3IWUE VM
Replace these parameters:
+
```
N3IWFInformation:
IPSecIfaceAddr: 10.0.1.1 # IP address of Nwu interface (IKE) on N3IWF
@@ -105,7 +115,9 @@ N3UEInformation:
IPSecIfaceName: ens38 # Name of Nwu interface (IKE) on this N3UE
IPSecIfaceAddr: 10.0.1.4 # IP address of Nwu interface (IKE) on this N3UE
```
+
into:
+
```
N3IWFInformation:
IPSecIfaceAddr: 192.168.56.101 # IP address of Nwu interface (IKE) on N3IWF
@@ -118,6 +130,7 @@ N3UEInformation:
## 6. Testing N3IWUE with free5GC
SSH into free5gc. If you have rebooted free5gc, remember to run:
+
```
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o -j MASQUERADE
@@ -125,19 +138,28 @@ sudo iptables -t nat -A POSTROUTING -o -j MASQUERADE
sudo systemctl stop ufw
sudo systemctl disable ufw
```
+
**Tip:** Set `net.ipv4.ip_forward=1` in `/etc/sysctl.conf` to enable packet forwarding permanently
In free5gc VM:
+
```
cd ~/free5gc
./run.sh -n3iwf
```
+
In N3IWUE VM:
+
```
cd ~/n3iwue
./run.sh
```
## 7. Result
+
Success: N3IWUE can ping data network through N3IWF
-![](./images/1-13.png)
\ No newline at end of file
+![](./images/1-13.png)
+
+## Appendix
+
+- [Design Document](./N3IWUE/n3iwue.md)