diff --git a/docs/_docs/guide/01-quickstart.md b/docs/_docs/guide/01-quickstart.md
index 67f81a491..8b857513d 100644
--- a/docs/_docs/guide/01-quickstart.md
+++ b/docs/_docs/guide/01-quickstart.md
@@ -414,11 +414,13 @@ target prot opt source destination
To enable forwarding and add the NAT rule, enter
```bash
-### Enable IPv4 Forwarding
-$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
+### Enable IPv4/IPv6 Forwarding
+$ sudo sysctl -w net.ipv4.ip_forward=1
+$ sudo sysctl -w net.ipv6.conf.all.forwarding=1
### Add NAT Rule
$ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE
+$ sudo ip6tables -t nat -A POSTROUTING -s cafe::/64 ! -o ogstun -j MASQUERADE
```
diff --git a/docs/_docs/guide/02-building-open5gs-from-sources.md b/docs/_docs/guide/02-building-open5gs-from-sources.md
index 6a6a69215..a7722b93d 100644
--- a/docs/_docs/guide/02-building-open5gs-from-sources.md
+++ b/docs/_docs/guide/02-building-open5gs-from-sources.md
@@ -444,11 +444,13 @@ target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
-### Enable IPv4 Forwarding
-$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
+### Enable IPv4/IPv6 Forwarding
+$ sudo sysctl -w net.ipv4.ip_forward=1
+$ sudo sysctl -w net.ipv6.conf.all.forwarding=1
### Add NAT Rule
$ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE
+$ sudo ip6tables -t nat -A POSTROUTING -s cafe::/64 ! -o ogstun -j MASQUERADE
```
**Note:** The above assumes you do not have any existing rules in the filter and nat tables. If a program such as docker has already set up rules, you may need to add the Open5GS related rules differently.
diff --git a/docs/_docs/platform/05-macosx.md b/docs/_docs/platform/06-macosx-intel.md
similarity index 75%
rename from docs/_docs/platform/05-macosx.md
rename to docs/_docs/platform/06-macosx-intel.md
index eab1a7bcf..6178217f0 100644
--- a/docs/_docs/platform/05-macosx.md
+++ b/docs/_docs/platform/06-macosx-intel.md
@@ -3,14 +3,23 @@ title: Mac OS X
head_inline: ""
---
-This guide is based on **macOS Big Sur 11.0.1**.
+This guide is based on macOS Big Sur 11.2 on a Macbook Pro(Intel Chips) computer.
{: .blue}
+### Install Xcode Command-Line Tools
+---
+
+Homebrew requires the Xcode command-line tools from Apple's Xcode.
+```bash
+$ xcode-select --install
+```
+
### Installing Homebrew
---
+Install brew using the official Homebrew installation instructions.
```bash
-$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
+$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
### Getting MongoDB
@@ -32,14 +41,13 @@ $ mongod --config /usr/local/etc/mongod.conf
{: .notice--info}
-### Setting up TUN device (No persistent after rebooting)
+### Setting up network (No persistent after rebooting)
---
-Install TUN/TAP driver
-- You can download it from [http://tuntaposx.sourceforge.net/](http://tuntaposx.sourceforge.net/)
-- And then, run tuntap_20150118.pkg to install TUN/TAP driver.
+Note that Open5GS uses built-in "utun" device driver. So, You don't have to install external TUN/TAP driver.
+{: .blue}
-Configure the TUN device.
+Configure the loopback interface.
```bash
$ sudo ifconfig lo0 alias 127.0.0.2 netmask 255.255.255.255
$ sudo ifconfig lo0 alias 127.0.0.3 netmask 255.255.255.255
@@ -54,12 +62,21 @@ $ sudo ifconfig lo0 alias 127.0.0.10 netmask 255.255.255.255
$ sudo ifconfig lo0 alias 127.0.0.11 netmask 255.255.255.255
$ sudo ifconfig lo0 alias 127.0.0.12 netmask 255.255.255.255
$ sudo ifconfig lo0 alias 127.0.0.13 netmask 255.255.255.255
+$ sudo ifconfig lo0 alias 127.0.0.14 netmask 255.255.255.255
+$ sudo ifconfig lo0 alias 127.0.0.15 netmask 255.255.255.255
+$ sudo ifconfig lo0 alias 127.0.0.16 netmask 255.255.255.255
+$ sudo ifconfig lo0 alias 127.0.0.17 netmask 255.255.255.255
+$ sudo ifconfig lo0 alias 127.0.0.18 netmask 255.255.255.255
+$ sudo ifconfig lo0 alias 127.0.0.19 netmask 255.255.255.255
+$ sudo ifconfig lo0 alias 127.0.0.20 netmask 255.255.255.255
```
Enable IP forwarding & Masquerading
```bash
$ sudo sysctl -w net.inet.ip.forwarding=1
+$ sudo sysctl -w net.inet6.ip6.forwarding=1
$ sudo sh -c "echo 'nat on {en0} from 10.45.0.0/16 to any -> {en0}' > /etc/pf.anchors/org.open5gs"
+$ sudo sh -c "echo 'nat on {en0} from cafe::1/64 to any -> {en0}' > /etc/pf.anchors/org.open5gs"
$ sudo pfctl -e -f /etc/pf.anchors/org.open5gs
```
@@ -152,4 +169,3 @@ The WebUI runs as an [npm](https://www.npmjs.com/) script.
```bash
$ npm run dev
```
-
diff --git a/docs/_docs/troubleshoot/02-now-in-github-issues.md b/docs/_docs/troubleshoot/02-now-in-github-issues.md
index 924eb9d60..d891a6169 100644
--- a/docs/_docs/troubleshoot/02-now-in-github-issues.md
+++ b/docs/_docs/troubleshoot/02-now-in-github-issues.md
@@ -357,9 +357,10 @@ Timeout: 0
#### Is it possible to setup IP/NAT table along with Docker?
-Enable IP Forward.
+Enable IPv4/IPv6 Forward.
```
-$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
+$ sudo sysctl -w net.ipv4.ip_forward=1
+$ sudo sysctl -w net.ipv6.conf.all.forwarding=1
```
The following is the default docker IP/NAT table.
@@ -435,6 +436,11 @@ And then, apply **newtables** as below.
$ sudo iptables-restore < newtables
```
+Docker doesn't have IPv6 NAT rules. In this case, you just add the NAT rule as below.
+```
+$ sudo ip6tables -t nat -A POSTROUTING -s cafe::/64 ! -o ogstun -j MASQUERADE
+```
+
The above operation is the same as described in the following manuals.
```
### Check IP Tables
@@ -462,11 +468,13 @@ target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
-### Enable IPv4 Forwarding
-$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
+### Enable IPv4/IPv6 Forwarding
+$ sudo sysctl -w net.ipv4.ip_forward=1
+$ sudo sysctl -w net.ipv6.conf.all.forwarding=1
### Add NAT Rule
$ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE
+$ sudo ip6tables -t nat -A POSTROUTING -s cafe::/64 ! -o ogstun -j MASQUERADE
```
#### How to use a different DNN/APN for each SMF
diff --git a/docs/_docs/tutorial/01-your-first-lte.md b/docs/_docs/tutorial/01-your-first-lte.md
index 0ac06a30d..7bcf9ed58 100644
--- a/docs/_docs/tutorial/01-your-first-lte.md
+++ b/docs/_docs/tutorial/01-your-first-lte.md
@@ -308,11 +308,13 @@ target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
-### Enable IPv4 Forwarding
-$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
+### Enable IPv4/IPv6 Forwarding
+$ sudo sysctl -w net.ipv4.ip_forward=1
+$ sudo sysctl -w net.ipv6.conf.all.forwarding=1
### Add NAT Rule
$ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE
+$ sudo ip6tables -t nat -A POSTROUTING -s cafe::/64 ! -o ogstun -j MASQUERADE
```
**Note:** For the first time, it is a good condition if you do not have any rules in the IP/NAT tables. If a program such as docker has already set up a rule, you will need to add a rule differently.
diff --git a/docs/_docs/tutorial/02-VoLTE-setup.md b/docs/_docs/tutorial/02-VoLTE-setup.md
index 0143f46bb..32eb99ee7 100644
--- a/docs/_docs/tutorial/02-VoLTE-setup.md
+++ b/docs/_docs/tutorial/02-VoLTE-setup.md
@@ -754,8 +754,8 @@ Below startup script can be used for setting up interfaces:
```
#!/bin/bash
-sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
-sh -c "echo 1 > /proc/sys/net/ipv6/ip_forward"
+sudo sysctl -w net.ipv4.ip_forward=1
+sudo sysctl -w net.ipv6.conf.all.forwarding=1
ip tuntap add name ogstun mode tun
ip addr add 192.168.100.1/24 dev ogstun
diff --git a/docs/_pages/docs.md b/docs/_pages/docs.md
index 8f2b4ba5d..430eb6b96 100644
--- a/docs/_pages/docs.md
+++ b/docs/_pages/docs.md
@@ -30,7 +30,8 @@ head_inline: ""
- [Debian/Ubuntu](platform/01-debian-ubuntu)
- [CentOS](platform/02-centos)
- [Fedora](platform/03-fedora)
- - [MacOSX](platform/05-macosx)
+ - [MacOSX(Apple Silicon)](platform/05-macosx-apple-silicon)
+ - [MacOSX(Intel)](platform/06-macosx-intel)
- Hardware Specific Notes
- [Tested e/gNodeBs](hardware/01-genodebs)
diff --git a/lib/core/meson.build b/lib/core/meson.build
index ca8ade4e7..4b8ee465a 100644
--- a/lib/core/meson.build
+++ b/lib/core/meson.build
@@ -280,7 +280,6 @@ libcore_sources = files('''
ogs-socknode.c
ogs-udp.c
ogs-tcp.c
- ogs-tun.c
ogs-queue.c
ogs-select.c
ogs-poll.c
@@ -304,6 +303,12 @@ if have_func_kqueue
libcore_sources += files('ogs-kqueue.c')
endif
+if host_system == 'darwin'
+ libcore_sources += files('ogs-utun.c')
+else
+ libcore_sources += files('ogs-tun.c')
+endif
+
libcore_inc = include_directories('.')
libcore = library('ogscore',
diff --git a/lib/core/ogs-tun.c b/lib/core/ogs-tun.c
index 10a67238a..3e7c34e32 100644
--- a/lib/core/ogs-tun.c
+++ b/lib/core/ogs-tun.c
@@ -41,7 +41,10 @@
ogs_socket_t ogs_tun_open(char *ifname, int len, int is_tap)
{
ogs_socket_t fd = INVALID_SOCKET;
-#if defined(__linux__)
+
+#if !defined(__linux__)
+ return fd;
+#else
const char *dev = "/dev/net/tun";
int rc;
struct ifreq ifr;
@@ -50,334 +53,71 @@ ogs_socket_t ogs_tun_open(char *ifname, int len, int is_tap)
ogs_assert(ifname);
fd = open(dev, O_RDWR);
- if (fd < 0)
- {
+ if (fd < 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"open() failed : dev[%s]", dev);
return INVALID_SOCKET;
}
-#else
- char name[IFNAMSIZ];
- int tun = 0;
- ogs_assert(ifname);
-
-#define TUNTAP_ID_MAX 255
- for (tun = 0; tun < TUNTAP_ID_MAX; tun++)
- {
- ogs_snprintf(name, sizeof(name), "/dev/tun%i", tun);
- if ((fd = open(name, O_RDWR)) > 0)
- {
- ogs_snprintf(ifname, len, "tun%i", tun);
- break;
- }
- }
- if (fd < 0)
- {
- ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
- "open() failed");
- return INVALID_SOCKET;
- }
-#endif
-
-#if defined(__linux__)
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = (is_tap ? (flags | IFF_TAP) : (flags | IFF_TUN));
strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
rc = ioctl(fd, TUNSETIFF, (void *)&ifr);
- if (rc < 0)
- {
+ if (rc < 0) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"ioctl() failed : dev[%s] flags[0x%x]", dev, flags);
goto cleanup;
}
-#endif
return fd;
-#if defined(__linux__)
cleanup:
close(fd);
return INVALID_SOCKET;
#endif
}
-#define TUN_ALIGN(size, boundary) \
- (((size) + ((boundary) - 1)) & ~((boundary) - 1))
-
-static int tun_set_ipv4(char *ifname,
- ogs_ipsubnet_t *ipaddr, ogs_ipsubnet_t *ipsub)
-{
-#if !defined(__linux__) && !defined(WIN32)
- int fd;
-
- struct ifaliasreq ifa;
- struct ifreq ifr;
- struct sockaddr_in addr;
- struct sockaddr_in mask;
-
- char buf[512];
- int len;
- struct rt_msghdr *rtm;
- struct sockaddr_in dst, gw;
- struct sockaddr_in *paddr;
-
- ogs_assert(ipaddr);
- ogs_assert(ipsub);
-
- fd = socket(ipaddr->family, SOCK_DGRAM, 0);
-
- (void)memset(&ifa, '\0', sizeof ifa);
- (void)strlcpy(ifa.ifra_name, ifname, sizeof ifa.ifra_name);
-
- (void)memset(&ifr, '\0', sizeof ifr);
- (void)strlcpy(ifr.ifr_name, ifname, sizeof ifr.ifr_name);
-
-#if 0
- /* Delete previously assigned address */
- (void)ioctl(fd, SIOCDIFADDR, &ifr);
-#endif
-
- (void)memset(&addr, '\0', sizeof(addr));
- addr.sin_family = ipaddr->family;
- addr.sin_addr.s_addr = ipaddr->sub[0];
- addr.sin_len = sizeof(addr);
- (void)memcpy(&ifa.ifra_addr, &addr, sizeof(addr));
- (void)memcpy(&ifa.ifra_broadaddr, &addr, sizeof(addr));
-
- (void)memset(&mask, '\0', sizeof(mask));
- mask.sin_family = ipaddr->family;
- mask.sin_addr.s_addr = ipaddr->mask[0];
- mask.sin_len = sizeof(mask);
- (void)memcpy(&ifa.ifra_mask, &mask, sizeof(ifa.ifra_mask));
-
- if (ioctl(fd, SIOCAIFADDR, &ifa) == -1) {
- ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
- "Can't IP address : dev[%s]", ifname);
- return OGS_ERROR;
- }
-
- close(fd); /* SOCK_DGRAM */
-
- fd = socket(PF_ROUTE, SOCK_RAW, 0);
- if (fd < 0)
- {
- ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
- "Can't open PF_ROUTE");
- return OGS_ERROR;
- }
-
- (void)memset(&buf, 0, sizeof(buf));
- rtm = (struct rt_msghdr *)buf;
- rtm->rtm_type = RTM_ADD;
- rtm->rtm_version = RTM_VERSION;
- rtm->rtm_pid = getpid();
- rtm->rtm_seq = 0;
- rtm->rtm_flags = RTF_UP | RTF_GATEWAY;
- rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
- paddr = (struct sockaddr_in *)(rtm + 1);
-
- (void)memset(&dst, '\0', sizeof(dst));
- dst.sin_family = ipaddr->family;
- dst.sin_addr.s_addr = ipsub->sub[0];
- dst.sin_len = sizeof(dst);
- (void)memcpy(paddr, &dst, sizeof(dst));
- paddr = (struct sockaddr_in *)((char *)paddr +
- TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
-
- (void)memset(&gw, '\0', sizeof(gw));
- gw.sin_family = ipaddr->family;
- gw.sin_addr.s_addr = ipaddr->sub[0];
- gw.sin_len = sizeof(gw);
- (void)memcpy(paddr, &gw, sizeof(gw));
- paddr = (struct sockaddr_in *)((char *)paddr +
- TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
-
- (void)memset(&mask, '\0', sizeof(mask));
- mask.sin_family = ipaddr->family;
- mask.sin_addr.s_addr = ipsub->mask[0];
- mask.sin_len = sizeof(mask);
- (void)memcpy(paddr, &mask, sizeof(mask));
- paddr = (struct sockaddr_in *)((char *)paddr +
- TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
-
- len = (char*)paddr - buf;
- rtm->rtm_msglen = len;
- if (write(fd, buf, len) < 0)
- {
- ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
- "Can't add routing");
- return OGS_ERROR;
- }
-
- close(fd); /* PF_ROUTE, SOCK_RAW */
-
-#endif /* defined(__linux__) */
-
- return OGS_OK;
-}
-
-static int tun_set_ipv6(char *ifname,
- ogs_ipsubnet_t *ipaddr, ogs_ipsubnet_t *ipsub)
-{
-/* #if !defined(__linux__) && !defined(WIN32) */
-#if 0
- int fd;
-
- struct in6_aliasreq ifa;
- struct in6_ifreq ifr;
- struct sockaddr_in6 addr;
- struct sockaddr_in6 mask;
-
- char buf[512];
- int len;
- struct rt_msghdr *rtm;
-#if 0
- struct sockaddr_in6 dst, gw;
-#else
- struct sockaddr_in6 dst;
-#endif
- struct sockaddr_in6 *paddr;
-
- ogs_assert(ipaddr);
- ogs_assert(ipsub);
-
- fd = socket(ipaddr->family, SOCK_DGRAM, 0);
-
- (void)memset(&ifa, '\0', sizeof ifa);
- (void)strlcpy(ifa.ifra_name, ifname, sizeof ifa.ifra_name);
-
- (void)memset(&ifr, '\0', sizeof ifr);
- (void)strlcpy(ifr.ifr_name, ifname, sizeof ifr.ifr_name);
-
-#if 0
- /* Delete previously assigned address */
- (void)ioctl(fd, SIOCDIFADDR, &ifr);
-#endif
-
- (void)memset(&addr, '\0', sizeof(addr));
- addr.sin6_family = ipaddr->family;
- memcpy(addr.sin6_addr.s6_addr, ipaddr->sub, sizeof ipaddr->sub);
- addr.sin6_len = sizeof(addr);
- (void)memcpy(&ifa.ifra_addr, &addr, sizeof(addr));
- (void)memcpy(&ifa.ifra_dstaddr, &addr, sizeof(addr));
-
- (void)memset(&mask, '\0', sizeof(mask));
- mask.sin6_family = ipaddr->family;
- memcpy(mask.sin6_addr.s6_addr, ipaddr->mask, sizeof ipaddr->mask);
- mask.sin6_len = sizeof(mask);
- (void)memcpy(&ifa.ifra_prefixmask, &mask, sizeof(ifa.ifra_prefixmask));
-
- ifa.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
- ifa.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
-
- if (ioctl(fd, SIOCAIFADDR_IN6, &ifa) == -1) {
- ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
- "Can't IP address : dev[%s]", ifname);
- return OGS_ERROR;
- }
-
- close(fd); /* SOCK_DGRAM */
-
- fd = socket(PF_ROUTE, SOCK_RAW, 0);
- if (fd < 0)
- {
- ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
- "Can't open PF_ROUTE");
- return OGS_ERROR;
- }
-
- (void)memset(&buf, 0, sizeof(buf));
- rtm = (struct rt_msghdr *)buf;
- rtm->rtm_type = RTM_DELETE;
- rtm->rtm_version = RTM_VERSION;
- rtm->rtm_pid = getpid();
- rtm->rtm_seq = 0;
- rtm->rtm_addrs = RTA_DST;
- paddr = (struct sockaddr_in6 *)(rtm + 1);
-
- (void)memset(&dst, '\0', sizeof(dst));
- dst.sin6_family = ipaddr->family;
- memcpy(dst.sin6_addr.s6_addr, ipaddr->sub, sizeof ipsub->sub);
- dst.sin6_len = sizeof(dst);
- (void)memcpy(paddr, &dst, sizeof(dst));
- paddr = (struct sockaddr_in6 *)((char *)paddr +
- TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
-
- len = (char*)paddr - buf;
- rtm->rtm_msglen = len;
- if (write(fd, buf, len) < 0)
- {
- ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
- "Can't add routing");
- return OGS_ERROR;
- }
-
-#if 0
- (void)memset(&buf, 0, sizeof(buf));
- rtm = (struct rt_msghdr *)buf;
- rtm->rtm_type = RTM_ADD;
- rtm->rtm_version = RTM_VERSION;
- rtm->rtm_pid = getpid();
- rtm->rtm_seq = 0;
- rtm->rtm_flags = RTF_UP | RTF_GATEWAY;
- rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
- paddr = (struct sockaddr_in6 *)(rtm + 1);
-
- (void)memset(&dst, '\0', sizeof(dst));
- dst.sin6_family = ipaddr->family;
- memcpy(dst.sin6_addr.s6_addr, ipsub->sub, sizeof ipsub->sub);
- dst.sin6_len = sizeof(dst);
- (void)memcpy(paddr, &dst, sizeof(dst));
- paddr = (struct sockaddr_in6 *)((char *)paddr +
- TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
-
- (void)memset(&gw, '\0', sizeof(gw));
- gw.sin6_family = ipaddr->family;
- memcpy(gw.sin6_addr.s6_addr, ipaddr->sub, sizeof ipaddr->sub);
- gw.sin6_len = sizeof(gw);
- (void)memcpy(paddr, &gw, sizeof(gw));
- paddr = (struct sockaddr_in6 *)((char *)paddr +
- TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
-
- (void)memset(&mask, '\0', sizeof(mask));
- mask.sin6_family = ipaddr->family;
- memcpy(mask.sin6_addr.s6_addr, ipsub->mask, sizeof ipsub->mask);
- mask.sin6_len = sizeof(mask);
- (void)memcpy(paddr, &mask, sizeof(mask));
- paddr = (struct sockaddr_in6 *)((char *)paddr +
- TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
-
- len = (char*)paddr - buf;
- rtm->rtm_msglen = len;
- if (write(fd, buf, len) < 0)
- {
- ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
- "Can't add routing");
- return OGS_ERROR;
- }
-#endif
-
- close(fd); /* PF_ROUTE, SOCK_RAW */
-
-#endif /* defined(__linux__) */
-
- return OGS_OK;
-}
-
int ogs_tun_set_ip(char *ifname, ogs_ipsubnet_t *gw, ogs_ipsubnet_t *sub)
{
- int rv = OGS_OK;
-
- ogs_assert(gw);
- ogs_assert(sub);
-
- if (gw->family == AF_INET)
- rv = tun_set_ipv4(ifname, gw, sub);
- else if (gw->family == AF_INET6)
- rv = tun_set_ipv6(ifname, gw, sub);
-
- return rv;
+ return OGS_OK;
+}
+
+ogs_pkbuf_t *ogs_tun_read(ogs_socket_t fd, ogs_pkbuf_pool_t *packet_pool)
+{
+ ogs_pkbuf_t *recvbuf = NULL;
+ int n;
+
+ ogs_assert(fd != INVALID_SOCKET);
+ ogs_assert(packet_pool);
+
+ recvbuf = ogs_pkbuf_alloc(packet_pool, OGS_MAX_PKT_LEN);
+ ogs_assert(recvbuf);
+ ogs_pkbuf_reserve(recvbuf, OGS_TUN_MAX_HEADROOM);
+ ogs_pkbuf_put(recvbuf, OGS_MAX_PKT_LEN-OGS_TUN_MAX_HEADROOM);
+
+ n = ogs_read(fd, recvbuf->data, recvbuf->len);
+ if (n <= 0) {
+ ogs_log_message(OGS_LOG_WARN, ogs_socket_errno, "ogs_read() failed");
+ ogs_pkbuf_free(recvbuf);
+ return NULL;
+ }
+
+ ogs_pkbuf_trim(recvbuf, n);
+
+ return recvbuf;
+}
+
+int ogs_tun_write(ogs_socket_t fd, ogs_pkbuf_t *pkbuf)
+{
+ ogs_assert(fd != INVALID_SOCKET);
+ ogs_assert(pkbuf);
+
+ if (ogs_write(fd, pkbuf->data, pkbuf->len) <= 0) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "ogs_write() failed");
+ return OGS_ERROR;
+ }
+
+ return OGS_OK;
}
diff --git a/lib/core/ogs-tun.h b/lib/core/ogs-tun.h
index 4644e92e2..d0917adb2 100644
--- a/lib/core/ogs-tun.h
+++ b/lib/core/ogs-tun.h
@@ -26,9 +26,31 @@
extern "C" {
#endif
+/*
+ * OGS_TUN_MAX_HEADROOM(16bytes)
+ *
+ * Linux
+ * - ogs_tun_read(16bytes)
+ * OGS_GTPV1U_5GC_HEADER_LEN(16bytes)
+ * - ogs_tun_write(0bytes)
+ * No Need for headroom
+ *
+ * Mac OS X
+ * - ogs_tun_read(12bytes)
+ * OGS_GTPV1U_5GC_HEADER_LEN(16bytes) - Null/Loopback(4bytes)
+ * - ogs_tun_write(4bytes)
+ * Null/Loopback(4bytes)
+ *
+ * So, we'll just use 12bytes.
+ */
+#define OGS_TUN_MAX_HEADROOM 16
+
ogs_socket_t ogs_tun_open(char *ifname, int len, int is_tap);
int ogs_tun_set_ip(char *ifname, ogs_ipsubnet_t *gw, ogs_ipsubnet_t *sub);
+ogs_pkbuf_t *ogs_tun_read(ogs_socket_t fd, ogs_pkbuf_pool_t *packet_pool);
+int ogs_tun_write(ogs_socket_t fd, ogs_pkbuf_t *pkbuf);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/core/ogs-utun.c b/lib/core/ogs-utun.c
new file mode 100644
index 000000000..792d684ac
--- /dev/null
+++ b/lib/core/ogs-utun.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) 2019 by Sukchan Lee
+ *
+ * This file is part of Open5GS.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "ogs-tun.h"
+
+#undef OGS_LOG_DOMAIN
+#define OGS_LOG_DOMAIN __ogs_sock_domain
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+
+static int unit = 0;
+
+static int utun_open(char *ifname, socklen_t len)
+{
+ struct sockaddr_ctl addr;
+ struct ctl_info info;
+ int fd = -1;
+ int err = 0;
+
+ ogs_assert(ifname);
+ ogs_assert(len);
+
+ fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
+ if (fd < 0) return fd;
+
+ bzero(&info, sizeof (info));
+ strncpy(info.ctl_name, UTUN_CONTROL_NAME, MAX_KCTL_NAME);
+
+ err = ioctl(fd, CTLIOCGINFO, &info);
+ if (err != 0) goto on_error;
+
+ addr.sc_len = sizeof(addr);
+ addr.sc_family = AF_SYSTEM;
+ addr.ss_sysaddr = AF_SYS_CONTROL;
+ addr.sc_id = info.ctl_id;
+ addr.sc_unit = unit + 1;
+
+ err = connect(fd, (struct sockaddr *)&addr, sizeof (addr));
+ if (err != 0) goto on_error;
+
+ err = getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, ifname, &len);
+ if (err != 0) goto on_error;
+
+on_error:
+ if (err != 0) {
+ close(fd);
+ return err;
+ }
+
+ return fd;
+}
+
+ogs_socket_t ogs_tun_open(char *ifname, int len, int is_tap)
+{
+ ogs_socket_t fd = INVALID_SOCKET;
+
+ ogs_assert(ifname);
+
+#define TUNTAP_ID_MAX 256
+ for (unit = 0; unit < TUNTAP_ID_MAX; unit++) {
+ if ((fd = utun_open(ifname, len)) > 0) {
+ break;
+ }
+ }
+ if (fd < 0) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "open() failed");
+ return INVALID_SOCKET;
+ }
+
+ return fd;
+}
+
+#define TUN_ALIGN(size, boundary) \
+ (((size) + ((boundary) - 1)) & ~((boundary) - 1))
+
+static int tun_set_ipv4(char *ifname,
+ ogs_ipsubnet_t *ipaddr, ogs_ipsubnet_t *ipsub)
+{
+ int fd;
+
+ struct ifaliasreq ifa;
+ struct ifreq ifr;
+ struct sockaddr_in addr;
+ struct sockaddr_in mask;
+
+ char buf[512];
+ int len;
+ struct rt_msghdr *rtm;
+ struct sockaddr_in dst, gw;
+ struct sockaddr_in *paddr;
+
+ ogs_assert(ipaddr);
+ ogs_assert(ipsub);
+
+ fd = socket(ipaddr->family, SOCK_DGRAM, 0);
+
+ (void)memset(&ifa, '\0', sizeof ifa);
+ (void)strlcpy(ifa.ifra_name, ifname, sizeof ifa.ifra_name);
+
+ (void)memset(&ifr, '\0', sizeof ifr);
+ (void)strlcpy(ifr.ifr_name, ifname, sizeof ifr.ifr_name);
+
+#if 0
+ /* Delete previously assigned address */
+ (void)ioctl(fd, SIOCDIFADDR, &ifr);
+#endif
+
+ (void)memset(&addr, '\0', sizeof(addr));
+ addr.sin_family = ipaddr->family;
+ addr.sin_addr.s_addr = ipaddr->sub[0];
+ addr.sin_len = sizeof(addr);
+ (void)memcpy(&ifa.ifra_addr, &addr, sizeof(addr));
+ (void)memcpy(&ifa.ifra_broadaddr, &addr, sizeof(addr));
+
+ (void)memset(&mask, '\0', sizeof(mask));
+ mask.sin_family = ipaddr->family;
+ mask.sin_addr.s_addr = ipaddr->mask[0];
+ mask.sin_len = sizeof(mask);
+ (void)memcpy(&ifa.ifra_mask, &mask, sizeof(ifa.ifra_mask));
+
+ if (ioctl(fd, SIOCAIFADDR, &ifa) == -1) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "Can't IP address : dev[%s]", ifname);
+ return OGS_ERROR;
+ }
+
+ close(fd); /* SOCK_DGRAM */
+
+ fd = socket(PF_ROUTE, SOCK_RAW, 0);
+ if (fd < 0) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "Can't open PF_ROUTE");
+ return OGS_ERROR;
+ }
+
+ (void)memset(&buf, 0, sizeof(buf));
+ rtm = (struct rt_msghdr *)buf;
+ rtm->rtm_type = RTM_ADD;
+ rtm->rtm_version = RTM_VERSION;
+ rtm->rtm_pid = getpid();
+ rtm->rtm_seq = 0;
+ rtm->rtm_flags = RTF_UP | RTF_GATEWAY;
+ rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
+ paddr = (struct sockaddr_in *)(rtm + 1);
+
+ (void)memset(&dst, '\0', sizeof(dst));
+ dst.sin_family = ipaddr->family;
+ dst.sin_addr.s_addr = ipsub->sub[0];
+ dst.sin_len = sizeof(dst);
+ (void)memcpy(paddr, &dst, sizeof(dst));
+ paddr = (struct sockaddr_in *)((char *)paddr +
+ TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
+
+ (void)memset(&gw, '\0', sizeof(gw));
+ gw.sin_family = ipaddr->family;
+ gw.sin_addr.s_addr = ipaddr->sub[0];
+ gw.sin_len = sizeof(gw);
+ (void)memcpy(paddr, &gw, sizeof(gw));
+ paddr = (struct sockaddr_in *)((char *)paddr +
+ TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
+
+ (void)memset(&mask, '\0', sizeof(mask));
+ mask.sin_family = ipaddr->family;
+ mask.sin_addr.s_addr = ipsub->mask[0];
+ mask.sin_len = sizeof(mask);
+ (void)memcpy(paddr, &mask, sizeof(mask));
+ paddr = (struct sockaddr_in *)((char *)paddr +
+ TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
+
+ len = (char*)paddr - buf;
+ rtm->rtm_msglen = len;
+ if (write(fd, buf, len) < 0) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "Can't add routing");
+ return OGS_ERROR;
+ }
+
+ close(fd); /* PF_ROUTE, SOCK_RAW */
+
+ return OGS_OK;
+}
+
+static int contigmask(uint8_t *p, int len)
+{
+ int i, n;
+
+ for (i=0; imask, IPV6_BITLEN);
+
+ ogs_snprintf(devname, sizeof devname, "utun%d", unit);
+ ogs_snprintf(addr, sizeof addr, "%s/%d",
+ OGS_INET6_NTOP(ipaddr->sub, buf), prefixlen);
+
+ commandLine[0] = "/sbin/ifconfig";
+ commandLine[1] = devname;
+ commandLine[2] = "inet6";
+ commandLine[3] = addr;
+ commandLine[4] = "up";
+ commandLine[5] = NULL;
+
+ ret = ogs_proc_create(commandLine, 0, &process);
+ ogs_assert(ret == 0);
+
+ ret = ogs_proc_join(&process, &out_return_code);
+ ogs_assert(ret == 0);
+ ogs_assert(out_return_code == 0);
+
+ ret = ogs_proc_destroy(&process);
+ ogs_assert(ret == 0);
+
+#else /* IPv6 Setting API is not working in UTUN */
+ int fd;
+
+ struct in6_aliasreq ifa;
+ struct in6_ifreq ifr;
+ struct sockaddr_in6 addr;
+ struct sockaddr_in6 mask;
+
+ char buf[512];
+ int len;
+ struct rt_msghdr *rtm;
+ struct sockaddr_in6 dst, gw;
+ struct sockaddr_in6 *paddr;
+
+ ogs_assert(ipaddr);
+ ogs_assert(ipsub);
+
+ fd = socket(ipaddr->family, SOCK_DGRAM, 0);
+
+ (void)memset(&ifa, '\0', sizeof ifa);
+ (void)strlcpy(ifa.ifra_name, ifname, sizeof ifa.ifra_name);
+
+ (void)memset(&ifr, '\0', sizeof ifr);
+ (void)strlcpy(ifr.ifr_name, ifname, sizeof ifr.ifr_name);
+
+#if 0
+ /* Delete previously assigned address */
+ (void)ioctl(fd, SIOCDIFADDR, &ifr);
+#endif
+
+ (void)memset(&addr, '\0', sizeof(addr));
+ addr.sin6_family = ipaddr->family;
+ memcpy(addr.sin6_addr.s6_addr, ipaddr->sub, sizeof ipaddr->sub);
+ addr.sin6_len = sizeof(addr);
+ (void)memcpy(&ifa.ifra_addr, &addr, sizeof(addr));
+ (void)memcpy(&ifa.ifra_dstaddr, &addr, sizeof(addr));
+
+ (void)memset(&mask, '\0', sizeof(mask));
+ mask.sin6_family = ipaddr->family;
+ memcpy(mask.sin6_addr.s6_addr, ipaddr->mask, sizeof ipaddr->mask);
+ mask.sin6_len = sizeof(mask);
+ (void)memcpy(&ifa.ifra_prefixmask, &mask, sizeof(ifa.ifra_prefixmask));
+
+ ifa.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
+ ifa.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
+
+ if (ioctl(fd, SIOCAIFADDR_IN6, &ifa) == -1) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "Can't IP address : dev[%s]", ifname);
+ return OGS_ERROR;
+ }
+
+ close(fd); /* SOCK_DGRAM */
+
+ fd = socket(PF_ROUTE, SOCK_RAW, 0);
+ if (fd < 0) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "Can't open PF_ROUTE");
+ return OGS_ERROR;
+ }
+
+#if 0
+ (void)memset(&buf, 0, sizeof(buf));
+ rtm = (struct rt_msghdr *)buf;
+ rtm->rtm_type = RTM_DELETE;
+ rtm->rtm_version = RTM_VERSION;
+ rtm->rtm_pid = getpid();
+ rtm->rtm_seq = 0;
+ rtm->rtm_addrs = RTA_DST;
+ paddr = (struct sockaddr_in6 *)(rtm + 1);
+
+ (void)memset(&dst, '\0', sizeof(dst));
+ dst.sin6_family = ipaddr->family;
+ memcpy(dst.sin6_addr.s6_addr, ipaddr->sub, sizeof ipsub->sub);
+ dst.sin6_len = sizeof(dst);
+ (void)memcpy(paddr, &dst, sizeof(dst));
+ paddr = (struct sockaddr_in6 *)((char *)paddr +
+ TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
+
+ len = (char*)paddr - buf;
+ rtm->rtm_msglen = len;
+ if (write(fd, buf, len) < 0) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "Can't add routing");
+ return OGS_ERROR;
+ }
+#endif
+
+ /* The followings does not work in IPv6 */
+ (void)memset(&buf, 0, sizeof(buf));
+ rtm = (struct rt_msghdr *)buf;
+ rtm->rtm_type = RTM_ADD;
+ rtm->rtm_version = RTM_VERSION;
+ rtm->rtm_pid = getpid();
+ rtm->rtm_seq = 0;
+ rtm->rtm_flags = RTF_UP | RTF_GATEWAY;
+ rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
+ paddr = (struct sockaddr_in6 *)(rtm + 1);
+
+ (void)memset(&dst, '\0', sizeof(dst));
+ dst.sin6_family = ipaddr->family;
+ memcpy(dst.sin6_addr.s6_addr, ipsub->sub, sizeof ipsub->sub);
+ dst.sin6_len = sizeof(dst);
+ (void)memcpy(paddr, &dst, sizeof(dst));
+ paddr = (struct sockaddr_in6 *)((char *)paddr +
+ TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
+
+ (void)memset(&gw, '\0', sizeof(gw));
+ gw.sin6_family = ipaddr->family;
+ memcpy(gw.sin6_addr.s6_addr, ipaddr->sub, sizeof ipaddr->sub);
+ gw.sin6_len = sizeof(gw);
+ (void)memcpy(paddr, &gw, sizeof(gw));
+ paddr = (struct sockaddr_in6 *)((char *)paddr +
+ TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
+
+ (void)memset(&mask, '\0', sizeof(mask));
+ mask.sin6_family = ipaddr->family;
+ memcpy(mask.sin6_addr.s6_addr, ipsub->mask, sizeof ipsub->mask);
+ mask.sin6_len = sizeof(mask);
+ (void)memcpy(paddr, &mask, sizeof(mask));
+ paddr = (struct sockaddr_in6 *)((char *)paddr +
+ TUN_ALIGN(sizeof(*paddr), sizeof(uintptr_t)));
+
+ len = (char*)paddr - buf;
+ rtm->rtm_msglen = len;
+ if (write(fd, buf, len) < 0) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
+ "Can't add routing");
+ return OGS_ERROR;
+ }
+
+ close(fd); /* PF_ROUTE, SOCK_RAW */
+
+#endif
+
+ return OGS_OK;
+}
+
+int ogs_tun_set_ip(char *ifname, ogs_ipsubnet_t *gw, ogs_ipsubnet_t *sub)
+{
+ int rv = OGS_OK;
+
+ ogs_assert(gw);
+ ogs_assert(sub);
+
+ if (gw->family == AF_INET)
+ rv = tun_set_ipv4(ifname, gw, sub);
+ else if (gw->family == AF_INET6)
+ rv = tun_set_ipv6(ifname, gw, sub);
+
+ return rv;
+}
+
+ogs_pkbuf_t *ogs_tun_read(ogs_socket_t fd, ogs_pkbuf_pool_t *packet_pool)
+{
+ ogs_pkbuf_t *recvbuf = NULL;
+ int n;
+
+ ogs_assert(fd != INVALID_SOCKET);
+ ogs_assert(packet_pool);
+
+ recvbuf = ogs_pkbuf_alloc(packet_pool, OGS_MAX_PKT_LEN);
+ ogs_assert(recvbuf);
+ ogs_pkbuf_reserve(recvbuf, OGS_TUN_MAX_HEADROOM);
+ ogs_pkbuf_put(recvbuf, OGS_MAX_PKT_LEN-OGS_TUN_MAX_HEADROOM);
+
+ n = ogs_read(fd, recvbuf->data, recvbuf->len);
+ if (n <= 0) {
+ ogs_log_message(OGS_LOG_WARN, ogs_socket_errno, "ogs_read() failed");
+ ogs_pkbuf_free(recvbuf);
+ return NULL;
+ }
+
+ ogs_pkbuf_trim(recvbuf, n);
+
+ /* Remove Null/Loopback Header (4bytes) */
+ ogs_pkbuf_pull(recvbuf, 4);
+
+ return recvbuf;
+}
+
+int ogs_tun_write(ogs_socket_t fd, ogs_pkbuf_t *pkbuf)
+{
+ uint8_t version;
+ uint32_t family;
+
+ ogs_assert(fd != INVALID_SOCKET);
+ ogs_assert(pkbuf);
+
+ version = (*((unsigned char *)pkbuf->data) >> 4) & 0xf;
+
+ if (version == 4) {
+ family = htobe32(AF_INET);
+ } else if (version == 6) {
+ family = htobe32(AF_INET6);
+ } else {
+ ogs_error("Invalid packet [IP version:%d, Packet Length:%d]",
+ version, pkbuf->len);
+ ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
+ return OGS_ERROR;
+ }
+
+ ogs_pkbuf_push(pkbuf, sizeof(family));
+ memcpy(pkbuf->data, &family, sizeof(family));
+
+ if (ogs_write(fd, pkbuf->data, pkbuf->len) <= 0) {
+ ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, "ogs_write() failed");
+ return OGS_ERROR;
+ }
+
+ return OGS_OK;
+}
diff --git a/misc/netconf.sh b/misc/netconf.sh
index 952c2c50b..9ace2db05 100755
--- a/misc/netconf.sh
+++ b/misc/netconf.sh
@@ -17,6 +17,7 @@ if [ "$SYSTEM" = "Linux" ]; then
ip link set ogstun up
else
sysctl -w net.inet.ip.forwarding=1
+ sysctl -w net.inet6.ip6.forwarding=1
ifconfig lo0 alias 127.0.0.2 netmask 255.255.255.255
ifconfig lo0 alias 127.0.0.3 netmask 255.255.255.255
ifconfig lo0 alias 127.0.0.4 netmask 255.255.255.255
@@ -39,6 +40,7 @@ else
if [ "$SYSTEM" = "Darwin" ]; then
if ! test -f /etc/pf.anchors/org.open5gs; then
sudo sh -c "echo 'nat on {en0} from 10.45.0.0/16 to any -> {en0}' > /etc/pf.anchors/org.open5gs"
+ sudo sh -c "echo 'nat on {en0} from cafe::1/64 to any -> {en0}' > /etc/pf.anchors/org.open5gs"
fi
pfctl -e -f /etc/pf.anchors/org.open5gs
fi
diff --git a/src/upf/gtp-path.c b/src/upf/gtp-path.c
index 218cb17dd..21ab6ba75 100644
--- a/src/upf/gtp-path.c
+++ b/src/upf/gtp-path.c
@@ -52,26 +52,17 @@ static int upf_gtp_send_router_advertisement(
static void _gtpv1_tun_recv_cb(short when, ogs_socket_t fd, void *data)
{
ogs_pkbuf_t *recvbuf = NULL;
- int n;
upf_sess_t *sess = NULL;
ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_user_plane_report_t report;
- recvbuf = ogs_pkbuf_alloc(packet_pool, OGS_MAX_PKT_LEN);
- ogs_assert(recvbuf);
- ogs_pkbuf_reserve(recvbuf, OGS_GTPV1U_5GC_HEADER_LEN);
- ogs_pkbuf_put(recvbuf, OGS_MAX_PKT_LEN-OGS_GTPV1U_5GC_HEADER_LEN);
-
- n = ogs_read(fd, recvbuf->data, recvbuf->len);
- if (n <= 0) {
- ogs_log_message(OGS_LOG_WARN, ogs_socket_errno, "ogs_read() failed");
- ogs_pkbuf_free(recvbuf);
+ recvbuf = ogs_tun_read(fd, packet_pool);
+ if (!recvbuf) {
+ ogs_warn("ogs_tun_read() failed");
return;
}
- ogs_pkbuf_trim(recvbuf, n);
-
/* Find the PDR by packet filter */
pdr = upf_pdr_find_by_packet(recvbuf);
if (pdr) {
@@ -119,7 +110,8 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_PKT_LEN);
ogs_assert(pkbuf);
- ogs_pkbuf_put(pkbuf, OGS_MAX_PKT_LEN);
+ ogs_pkbuf_reserve(pkbuf, OGS_TUN_MAX_HEADROOM);
+ ogs_pkbuf_put(pkbuf, OGS_MAX_PKT_LEN-OGS_TUN_MAX_HEADROOM);
size = ogs_recvfrom(fd, pkbuf->data, pkbuf->len, 0, &from);
if (size <= 0) {
@@ -288,10 +280,8 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
dev = subnet->dev;
ogs_assert(dev);
- if (ogs_write(dev->fd, pkbuf->data, pkbuf->len) <= 0) {
- ogs_log_message(OGS_LOG_ERROR,
- ogs_socket_errno, "ogs_write() failed");
- }
+ if (ogs_tun_write(dev->fd, pkbuf) != OGS_OK)
+ ogs_warn("ogs_tun_write() failed");
} else {
ogs_fatal("Not implemented : FAR-DST_IF[%d]", far->dst_if);
ogs_assert_if_reached();
diff --git a/src/upf/rule-match.c b/src/upf/rule-match.c
index b8945c209..54127bdea 100644
--- a/src/upf/rule-match.c
+++ b/src/upf/rule-match.c
@@ -141,16 +141,11 @@ ogs_pfcp_pdr_t *upf_pdr_find_by_packet(ogs_pkbuf_t *pkt)
addr_len = OGS_IPV6_LEN;
sess = upf_sess_find_by_ipv6(dst_addr);
- } else
- ogs_error("Invalid IP version = %d", ip_h->ip_v);
-
- ogs_debug("PROTO:%d SRC:%08x %08x %08x %08x",
- proto, be32toh(src_addr[0]), be32toh(src_addr[1]),
- be32toh(src_addr[2]), be32toh(src_addr[3]));
- ogs_debug("HLEN:%d DST:%08x %08x %08x %08x",
- ip_hlen, be32toh(dst_addr[0]), be32toh(dst_addr[1]),
- be32toh(dst_addr[2]), be32toh(dst_addr[3]));
-
+ } else {
+ ogs_error("Invalid packet [IP version:%d, Packet Length:%d]",
+ ip_h->ip_v, pkt->len);
+ ogs_log_hexdump(OGS_LOG_ERROR, pkt->data, pkt->len);
+ }
if (sess) {
ogs_pfcp_pdr_t *fallback_pdr = NULL;
@@ -158,6 +153,13 @@ ogs_pfcp_pdr_t *upf_pdr_find_by_packet(ogs_pkbuf_t *pkt)
ogs_pfcp_far_t *far = NULL;
ogs_pfcp_rule_t *rule = NULL;
+ ogs_debug("PROTO:%d SRC:%08x %08x %08x %08x",
+ proto, be32toh(src_addr[0]), be32toh(src_addr[1]),
+ be32toh(src_addr[2]), be32toh(src_addr[3]));
+ ogs_debug("HLEN:%d DST:%08x %08x %08x %08x",
+ ip_hlen, be32toh(dst_addr[0]), be32toh(dst_addr[1]),
+ be32toh(dst_addr[2]), be32toh(dst_addr[3]));
+
if (ip_h && sess->ipv4)
ogs_debug("PAA IPv4:%s", OGS_INET_NTOP(&sess->ipv4->addr, buf));
if (ip6_h && sess->ipv6)
diff --git a/tests/attach/guti-test.c b/tests/attach/guti-test.c
index 3352be632..faa7eece4 100644
--- a/tests/attach/guti-test.c
+++ b/tests/attach/guti-test.c
@@ -292,7 +292,6 @@ static void test1_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
-#if __linux__
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, bearer, TEST_PING_IPV6);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@@ -301,7 +300,6 @@ static void test1_func(abts_case *tc, void *data)
recvbuf = test_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
-#endif
/* Send Attach Request */
memset(&sess->pdn_connectivity_param,
diff --git a/tests/common/application.c b/tests/common/application.c
index 0e90c6b40..1bf1a0528 100644
--- a/tests/common/application.c
+++ b/tests/common/application.c
@@ -86,7 +86,7 @@ static void child_main(void *data)
ogs_proc_t *current = NULL;
FILE *out = NULL;
char buf[OGS_HUGE_LEN];
- int ret = 0, out_return_code = 0;;
+ int ret = 0, out_return_code = 0;
current = &process[process_num++];
ret = ogs_proc_create(commandLine,
diff --git a/tests/registration/guti-test.c b/tests/registration/guti-test.c
index 127217698..9388f93b7 100644
--- a/tests/registration/guti-test.c
+++ b/tests/registration/guti-test.c
@@ -308,7 +308,6 @@ static void test1_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
-#if __linux__
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV6);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@@ -317,7 +316,6 @@ static void test1_func(abts_case *tc, void *data)
recvbuf = test_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
-#endif
/* Send Registration request
* - Update Registration request type
@@ -847,7 +845,6 @@ static void test2_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
-#if __linux__
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV6);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@@ -856,7 +853,6 @@ static void test2_func(abts_case *tc, void *data)
recvbuf = test_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
-#endif
/* Send Registration request
* - Update Registration request type