mac: Support Apple M1 chips

See https://open5gs.org/open5gs/docs/platform/05-macosx-apple-silicon/
This commit is contained in:
Sukchan Lee 2021-02-06 00:13:48 -05:00
parent 950c4c0a12
commit 7901a1164f
17 changed files with 622 additions and 361 deletions

View File

@ -414,11 +414,13 @@ target prot opt source destination
To enable forwarding and add the NAT rule, enter To enable forwarding and add the NAT rule, enter
```bash ```bash
### Enable IPv4 Forwarding ### Enable IPv4/IPv6 Forwarding
$ 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
### Add NAT Rule ### Add NAT Rule
$ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE $ 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
``` ```

View File

@ -444,11 +444,13 @@ target prot opt source destination
Chain POSTROUTING (policy ACCEPT) Chain POSTROUTING (policy ACCEPT)
target prot opt source destination target prot opt source destination
### Enable IPv4 Forwarding ### Enable IPv4/IPv6 Forwarding
$ 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
### Add NAT Rule ### Add NAT Rule
$ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE $ 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. **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.

View File

@ -3,14 +3,23 @@ title: Mac OS X
head_inline: "<style> .blue { color: blue; } </style>" head_inline: "<style> .blue { color: blue; } </style>"
--- ---
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} {: .blue}
### Install Xcode Command-Line Tools
---
Homebrew requires the Xcode command-line tools from Apple's Xcode.
```bash
$ xcode-select --install
```
### Installing Homebrew ### Installing Homebrew
--- ---
Install brew using the official Homebrew installation instructions.
```bash ```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 ### Getting MongoDB
@ -32,14 +41,13 @@ $ mongod --config /usr/local/etc/mongod.conf
{: .notice--info} {: .notice--info}
### Setting up TUN device (No persistent after rebooting) ### Setting up network (No persistent after rebooting)
--- ---
Install TUN/TAP driver Note that Open5GS uses built-in "utun" device driver. So, You don't have to install external TUN/TAP driver.
- You can download it from [http://tuntaposx.sourceforge.net/](http://tuntaposx.sourceforge.net/) {: .blue}
- And then, run tuntap_20150118.pkg to install TUN/TAP driver.
Configure the TUN device. Configure the loopback interface.
```bash ```bash
$ sudo ifconfig lo0 alias 127.0.0.2 netmask 255.255.255.255 $ 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 $ 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.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.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.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 Enable IP forwarding & Masquerading
```bash ```bash
$ sudo sysctl -w net.inet.ip.forwarding=1 $ 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 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 $ 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 ```bash
$ npm run dev $ npm run dev
``` ```

View File

@ -357,9 +357,10 @@ Timeout: 0
#### Is it possible to setup IP/NAT table along with Docker? #### 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. The following is the default docker IP/NAT table.
@ -435,6 +436,11 @@ And then, apply **newtables** as below.
$ sudo iptables-restore < newtables $ 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. The above operation is the same as described in the following manuals.
``` ```
### Check IP Tables ### Check IP Tables
@ -462,11 +468,13 @@ target prot opt source destination
Chain POSTROUTING (policy ACCEPT) Chain POSTROUTING (policy ACCEPT)
target prot opt source destination target prot opt source destination
### Enable IPv4 Forwarding ### Enable IPv4/IPv6 Forwarding
$ 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
### Add NAT Rule ### Add NAT Rule
$ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE $ 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 #### How to use a different DNN/APN for each SMF

View File

@ -308,11 +308,13 @@ target prot opt source destination
Chain POSTROUTING (policy ACCEPT) Chain POSTROUTING (policy ACCEPT)
target prot opt source destination target prot opt source destination
### Enable IPv4 Forwarding ### Enable IPv4/IPv6 Forwarding
$ 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
### Add NAT Rule ### Add NAT Rule
$ sudo iptables -t nat -A POSTROUTING -s 10.45.0.0/16 ! -o ogstun -j MASQUERADE $ 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. **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.

View File

@ -754,8 +754,8 @@ Below startup script can be used for setting up interfaces:
``` ```
#!/bin/bash #!/bin/bash
sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" sudo sysctl -w net.ipv4.ip_forward=1
sh -c "echo 1 > /proc/sys/net/ipv6/ip_forward" sudo sysctl -w net.ipv6.conf.all.forwarding=1
ip tuntap add name ogstun mode tun ip tuntap add name ogstun mode tun
ip addr add 192.168.100.1/24 dev ogstun ip addr add 192.168.100.1/24 dev ogstun

View File

@ -30,7 +30,8 @@ head_inline: "<style> ul { padding-bottom: 1em; } </style>"
- [Debian/Ubuntu](platform/01-debian-ubuntu) - [Debian/Ubuntu](platform/01-debian-ubuntu)
- [CentOS](platform/02-centos) - [CentOS](platform/02-centos)
- [Fedora](platform/03-fedora) - [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 - Hardware Specific Notes
- [Tested e/gNodeBs](hardware/01-genodebs) - [Tested e/gNodeBs](hardware/01-genodebs)

View File

@ -280,7 +280,6 @@ libcore_sources = files('''
ogs-socknode.c ogs-socknode.c
ogs-udp.c ogs-udp.c
ogs-tcp.c ogs-tcp.c
ogs-tun.c
ogs-queue.c ogs-queue.c
ogs-select.c ogs-select.c
ogs-poll.c ogs-poll.c
@ -304,6 +303,12 @@ if have_func_kqueue
libcore_sources += files('ogs-kqueue.c') libcore_sources += files('ogs-kqueue.c')
endif endif
if host_system == 'darwin'
libcore_sources += files('ogs-utun.c')
else
libcore_sources += files('ogs-tun.c')
endif
libcore_inc = include_directories('.') libcore_inc = include_directories('.')
libcore = library('ogscore', libcore = library('ogscore',

View File

@ -41,7 +41,10 @@
ogs_socket_t ogs_tun_open(char *ifname, int len, int is_tap) ogs_socket_t ogs_tun_open(char *ifname, int len, int is_tap)
{ {
ogs_socket_t fd = INVALID_SOCKET; ogs_socket_t fd = INVALID_SOCKET;
#if defined(__linux__)
#if !defined(__linux__)
return fd;
#else
const char *dev = "/dev/net/tun"; const char *dev = "/dev/net/tun";
int rc; int rc;
struct ifreq ifr; struct ifreq ifr;
@ -50,334 +53,71 @@ ogs_socket_t ogs_tun_open(char *ifname, int len, int is_tap)
ogs_assert(ifname); ogs_assert(ifname);
fd = open(dev, O_RDWR); fd = open(dev, O_RDWR);
if (fd < 0) if (fd < 0) {
{
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"open() failed : dev[%s]", dev); "open() failed : dev[%s]", dev);
return INVALID_SOCKET; 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)); memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = (is_tap ? (flags | IFF_TAP) : (flags | IFF_TUN)); ifr.ifr_flags = (is_tap ? (flags | IFF_TAP) : (flags | IFF_TUN));
strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1); strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
rc = ioctl(fd, TUNSETIFF, (void *)&ifr); rc = ioctl(fd, TUNSETIFF, (void *)&ifr);
if (rc < 0) if (rc < 0) {
{
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno, ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"ioctl() failed : dev[%s] flags[0x%x]", dev, flags); "ioctl() failed : dev[%s] flags[0x%x]", dev, flags);
goto cleanup; goto cleanup;
} }
#endif
return fd; return fd;
#if defined(__linux__)
cleanup: cleanup:
close(fd); close(fd);
return INVALID_SOCKET; return INVALID_SOCKET;
#endif #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 ogs_tun_set_ip(char *ifname, ogs_ipsubnet_t *gw, ogs_ipsubnet_t *sub)
{ {
int rv = OGS_OK; return OGS_OK;
}
ogs_assert(gw);
ogs_assert(sub); ogs_pkbuf_t *ogs_tun_read(ogs_socket_t fd, ogs_pkbuf_pool_t *packet_pool)
{
if (gw->family == AF_INET) ogs_pkbuf_t *recvbuf = NULL;
rv = tun_set_ipv4(ifname, gw, sub); int n;
else if (gw->family == AF_INET6)
rv = tun_set_ipv6(ifname, gw, sub); ogs_assert(fd != INVALID_SOCKET);
ogs_assert(packet_pool);
return rv;
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;
} }

View File

@ -26,9 +26,31 @@
extern "C" { extern "C" {
#endif #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); 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); 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 #ifdef __cplusplus
} }
#endif #endif

475
lib/core/ogs-utun.c Normal file
View File

@ -0,0 +1,475 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "ogs-tun.h"
#undef OGS_LOG_DOMAIN
#define OGS_LOG_DOMAIN __ogs_sock_domain
#include <net/if.h>
#include <net/route.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet6/in6_var.h>
#include <netinet6/nd6.h>
#include <net/if_utun.h>
#include <sys/kern_event.h>
#include <sys/kern_control.h>
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; i<len ; i++)
if ( (p[i/8] & (1 << (7 - (i%8)))) == 0) /* first bit unset */
break;
for (n=i+1; n < len; n++)
if ( (p[n/8] & (1 << (7 - (n%8)))) != 0)
return -1; /* mask not contiguous */
return i;
}
static int tun_set_ipv6(char *ifname,
ogs_ipsubnet_t *ipaddr, ogs_ipsubnet_t *ipsub)
{
#if 1 /* We'll just run ifconfig command in the shell */
ogs_proc_t process;
int ret = 0, out_return_code = 0;
const char *commandLine[OGS_ARG_MAX];
char devname[32];
char addr[128];
char buf[OGS_ADDRSTRLEN];
int prefixlen;
ogs_assert(ipsub);
ogs_assert(ipaddr);
#define IPV6_BITLEN (OGS_IPV6_LEN * 8)
prefixlen = contigmask((uint8_t *)ipsub->mask, 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;
}

View File

@ -17,6 +17,7 @@ if [ "$SYSTEM" = "Linux" ]; then
ip link set ogstun up ip link set ogstun up
else else
sysctl -w net.inet.ip.forwarding=1 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.2 netmask 255.255.255.255
ifconfig lo0 alias 127.0.0.3 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 ifconfig lo0 alias 127.0.0.4 netmask 255.255.255.255
@ -39,6 +40,7 @@ else
if [ "$SYSTEM" = "Darwin" ]; then if [ "$SYSTEM" = "Darwin" ]; then
if ! test -f /etc/pf.anchors/org.open5gs; 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 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 fi
pfctl -e -f /etc/pf.anchors/org.open5gs pfctl -e -f /etc/pf.anchors/org.open5gs
fi fi

View File

@ -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) static void _gtpv1_tun_recv_cb(short when, ogs_socket_t fd, void *data)
{ {
ogs_pkbuf_t *recvbuf = NULL; ogs_pkbuf_t *recvbuf = NULL;
int n;
upf_sess_t *sess = NULL; upf_sess_t *sess = NULL;
ogs_pfcp_pdr_t *pdr = NULL; ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_user_plane_report_t report; ogs_pfcp_user_plane_report_t report;
recvbuf = ogs_pkbuf_alloc(packet_pool, OGS_MAX_PKT_LEN); recvbuf = ogs_tun_read(fd, packet_pool);
ogs_assert(recvbuf); if (!recvbuf) {
ogs_pkbuf_reserve(recvbuf, OGS_GTPV1U_5GC_HEADER_LEN); ogs_warn("ogs_tun_read() failed");
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);
return; return;
} }
ogs_pkbuf_trim(recvbuf, n);
/* Find the PDR by packet filter */ /* Find the PDR by packet filter */
pdr = upf_pdr_find_by_packet(recvbuf); pdr = upf_pdr_find_by_packet(recvbuf);
if (pdr) { 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); pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_PKT_LEN);
ogs_assert(pkbuf); 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); size = ogs_recvfrom(fd, pkbuf->data, pkbuf->len, 0, &from);
if (size <= 0) { if (size <= 0) {
@ -288,10 +280,8 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
dev = subnet->dev; dev = subnet->dev;
ogs_assert(dev); ogs_assert(dev);
if (ogs_write(dev->fd, pkbuf->data, pkbuf->len) <= 0) { if (ogs_tun_write(dev->fd, pkbuf) != OGS_OK)
ogs_log_message(OGS_LOG_ERROR, ogs_warn("ogs_tun_write() failed");
ogs_socket_errno, "ogs_write() failed");
}
} else { } else {
ogs_fatal("Not implemented : FAR-DST_IF[%d]", far->dst_if); ogs_fatal("Not implemented : FAR-DST_IF[%d]", far->dst_if);
ogs_assert_if_reached(); ogs_assert_if_reached();

View File

@ -141,16 +141,11 @@ ogs_pfcp_pdr_t *upf_pdr_find_by_packet(ogs_pkbuf_t *pkt)
addr_len = OGS_IPV6_LEN; addr_len = OGS_IPV6_LEN;
sess = upf_sess_find_by_ipv6(dst_addr); sess = upf_sess_find_by_ipv6(dst_addr);
} else } else {
ogs_error("Invalid IP version = %d", ip_h->ip_v); ogs_error("Invalid packet [IP version:%d, Packet Length:%d]",
ip_h->ip_v, pkt->len);
ogs_debug("PROTO:%d SRC:%08x %08x %08x %08x", ogs_log_hexdump(OGS_LOG_ERROR, pkt->data, pkt->len);
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 (sess) { if (sess) {
ogs_pfcp_pdr_t *fallback_pdr = NULL; 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_far_t *far = NULL;
ogs_pfcp_rule_t *rule = 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) if (ip_h && sess->ipv4)
ogs_debug("PAA IPv4:%s", OGS_INET_NTOP(&sess->ipv4->addr, buf)); ogs_debug("PAA IPv4:%s", OGS_INET_NTOP(&sess->ipv4->addr, buf));
if (ip6_h && sess->ipv6) if (ip6_h && sess->ipv6)

View File

@ -292,7 +292,6 @@ static void test1_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf); ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf); ogs_pkbuf_free(recvbuf);
#if __linux__
/* Send GTP-U ICMP Packet */ /* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, bearer, TEST_PING_IPV6); rv = test_gtpu_send_ping(gtpu, bearer, TEST_PING_IPV6);
ABTS_INT_EQUAL(tc, OGS_OK, rv); 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); recvbuf = test_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf); ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf); ogs_pkbuf_free(recvbuf);
#endif
/* Send Attach Request */ /* Send Attach Request */
memset(&sess->pdn_connectivity_param, memset(&sess->pdn_connectivity_param,

View File

@ -86,7 +86,7 @@ static void child_main(void *data)
ogs_proc_t *current = NULL; ogs_proc_t *current = NULL;
FILE *out = NULL; FILE *out = NULL;
char buf[OGS_HUGE_LEN]; char buf[OGS_HUGE_LEN];
int ret = 0, out_return_code = 0;; int ret = 0, out_return_code = 0;
current = &process[process_num++]; current = &process[process_num++];
ret = ogs_proc_create(commandLine, ret = ogs_proc_create(commandLine,

View File

@ -308,7 +308,6 @@ static void test1_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf); ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf); ogs_pkbuf_free(recvbuf);
#if __linux__
/* Send GTP-U ICMP Packet */ /* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV6); rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV6);
ABTS_INT_EQUAL(tc, OGS_OK, rv); 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); recvbuf = test_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf); ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf); ogs_pkbuf_free(recvbuf);
#endif
/* Send Registration request /* Send Registration request
* - Update Registration request type * - Update Registration request type
@ -847,7 +845,6 @@ static void test2_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf); ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf); ogs_pkbuf_free(recvbuf);
#if __linux__
/* Send GTP-U ICMP Packet */ /* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV6); rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV6);
ABTS_INT_EQUAL(tc, OGS_OK, rv); 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); recvbuf = test_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf); ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf); ogs_pkbuf_free(recvbuf);
#endif
/* Send Registration request /* Send Registration request
* - Update Registration request type * - Update Registration request type