mirror of
				https://github.com/open5gs/open5gs.git
				synced 2025-11-04 05:53:18 +00:00 
			
		
		
		
	Merge branch 'tap' of https://github.com/anarkiwi/open5gs into pull1022
This commit is contained in:
		@@ -104,6 +104,10 @@ Install Meson using Homebrew.
 | 
			
		||||
$ brew install meson
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Install libtins.
 | 
			
		||||
 | 
			
		||||
Follow the instructions at https://libtins.github.io to install libtins.
 | 
			
		||||
 | 
			
		||||
Git clone.
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
 
 | 
			
		||||
@@ -103,6 +103,10 @@ Install Meson using Homebrew.
 | 
			
		||||
$ brew install meson
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Install libtins.
 | 
			
		||||
 | 
			
		||||
Follow the instructions at https://libtins.github.io to install libtins.
 | 
			
		||||
 | 
			
		||||
Git clone.
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
 
 | 
			
		||||
@@ -121,6 +121,10 @@ $ export LIBRARY_PATH=/usr/local/lib
 | 
			
		||||
$ export C_INCLUDE_PATH=/usr/local/include
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Install libtins.
 | 
			
		||||
 | 
			
		||||
Follow the instructions at https://libtins.github.io to install libtins.
 | 
			
		||||
 | 
			
		||||
Git clone.
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
 
 | 
			
		||||
@@ -289,6 +289,8 @@ typedef struct ogs_pfcp_dev_s {
 | 
			
		||||
 | 
			
		||||
    ogs_sockaddr_t  *link_local_addr;
 | 
			
		||||
    ogs_poll_t      *poll;
 | 
			
		||||
    bool            is_tap;
 | 
			
		||||
    uint8_t         mac_addr[6];
 | 
			
		||||
} ogs_pfcp_dev_t;
 | 
			
		||||
 | 
			
		||||
typedef struct ogs_pfcp_subnet_s {
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
project('open5gs', 'c',
 | 
			
		||||
project('open5gs', 'c', 'cpp',
 | 
			
		||||
    version : '2.2.9',
 | 
			
		||||
    license : 'AGPL-3.0-or-later',
 | 
			
		||||
    meson_version : '>= 0.43.0',
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										96
									
								
								src/upf/arp-nd.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/upf/arp-nd.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 <tins/arp.h>
 | 
			
		||||
#include <tins/ethernetII.h>
 | 
			
		||||
#include <tins/hw_address.h>
 | 
			
		||||
#include <tins/icmpv6.h>
 | 
			
		||||
 | 
			
		||||
#include "arp-nd.h"
 | 
			
		||||
 | 
			
		||||
using namespace::Tins;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void _serialize_reply(uint8_t *reply_data, EthernetII &reply) {
 | 
			
		||||
    PDU::serialization_type serialized = reply.serialize();
 | 
			
		||||
    memcpy(reply_data, serialized.data(), reply.size());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool _parse_arp(EthernetII &pdu) {
 | 
			
		||||
    if (pdu.payload_type() == ETHERTYPE_ARP) {
 | 
			
		||||
        const ARP& arp = pdu.rfind_pdu<ARP>();
 | 
			
		||||
        return arp.opcode() == ARP::REQUEST && pdu.dst_addr().is_broadcast();
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool is_arp_req(uint8_t *data, uint len)
 | 
			
		||||
{
 | 
			
		||||
    EthernetII pdu(data, len);
 | 
			
		||||
    return _parse_arp(pdu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool arp_reply(uint8_t *reply_data, uint8_t *request_data, uint len, const uint8_t *mac) {
 | 
			
		||||
    EthernetII pdu(request_data, len);
 | 
			
		||||
    if (_parse_arp(pdu)) {
 | 
			
		||||
        HWAddress<ETHER_ADDR_LEN> source_mac(mac);
 | 
			
		||||
        const ARP& arp = pdu.rfind_pdu<ARP>();
 | 
			
		||||
        EthernetII reply = ARP::make_arp_reply(
 | 
			
		||||
            arp.sender_ip_addr(),
 | 
			
		||||
            arp.target_ip_addr(),
 | 
			
		||||
            arp.sender_hw_addr(),
 | 
			
		||||
            source_mac);
 | 
			
		||||
        _serialize_reply(reply_data, reply);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool _parse_nd(EthernetII &pdu) {
 | 
			
		||||
    if (pdu.payload_type() == ETHERTYPE_IPV6) {
 | 
			
		||||
        const ICMPv6& icmp6 = pdu.rfind_pdu<ICMPv6>();
 | 
			
		||||
        return icmp6.type() == ICMPv6::NEIGHBOUR_SOLICIT;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool is_nd_req(uint8_t *data, uint len)
 | 
			
		||||
{
 | 
			
		||||
    if (len < MAX_ND_SIZE) {
 | 
			
		||||
        EthernetII pdu(data, len);
 | 
			
		||||
        return _parse_nd(pdu);
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool nd_reply(uint8_t *reply_data, uint8_t *request_data, uint len, const uint8_t *mac) {
 | 
			
		||||
    EthernetII pdu(request_data, len);
 | 
			
		||||
    if (_parse_nd(pdu)) {
 | 
			
		||||
        HWAddress<ETHER_ADDR_LEN> source_mac(mac);
 | 
			
		||||
        const ICMPv6& icmp6 = pdu.rfind_pdu<ICMPv6>();
 | 
			
		||||
        EthernetII reply(pdu.src_addr(), pdu.dst_addr());
 | 
			
		||||
        ICMPv6 nd_reply(ICMPv6::NEIGHBOUR_ADVERT);
 | 
			
		||||
        nd_reply.target_link_layer_addr(source_mac);
 | 
			
		||||
        nd_reply.target_addr(icmp6.target_addr());
 | 
			
		||||
        reply /= nd_reply;
 | 
			
		||||
        _serialize_reply(reply_data, reply);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								src/upf/arp-nd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/upf/arp-nd.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 "upf-config.h"
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SYS_SOCKET_H
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NETINET_IN_H
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NET_ETHERNET_H
 | 
			
		||||
#include <net/ethernet.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define MAX_ND_SIZE 128
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void set_source_mac(uint8_t *data);
 | 
			
		||||
bool is_arp_req(uint8_t *data, uint len);
 | 
			
		||||
bool arp_reply(uint8_t *reply_data, uint8_t *request_data, uint len, const uint8_t *mac);
 | 
			
		||||
bool is_nd_req(uint8_t *data, uint len);
 | 
			
		||||
bool nd_reply(uint8_t *reply_data, uint8_t *request_data, uint len, const uint8_t *mac);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -35,6 +35,19 @@
 | 
			
		||||
#include <netinet/icmp6.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAVE_SYS_IOCTL_H
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAVE_NET_IF_DL_H
 | 
			
		||||
#include <net/if_dl.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if HAVE_IFADDRS_H
 | 
			
		||||
#include <ifaddrs.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "arp-nd.h"
 | 
			
		||||
#include "event.h"
 | 
			
		||||
#include "gtp-path.h"
 | 
			
		||||
#include "pfcp-path.h"
 | 
			
		||||
@@ -42,11 +55,21 @@
 | 
			
		||||
 | 
			
		||||
#define UPF_GTP_HANDLED     1
 | 
			
		||||
 | 
			
		||||
const uint8_t proxy_mac_addr[] = { 0x0e, 0x00, 0x00, 0x00, 0x00, 0x01 };
 | 
			
		||||
 | 
			
		||||
static ogs_pkbuf_pool_t *packet_pool = NULL;
 | 
			
		||||
 | 
			
		||||
static void upf_gtp_handle_multicast(ogs_pkbuf_t *recvbuf);
 | 
			
		||||
 | 
			
		||||
static void _gtpv1_tun_recv_cb(short when, ogs_socket_t fd, void *data)
 | 
			
		||||
static uint16_t _get_eth_type(uint8_t *data, uint len) {
 | 
			
		||||
    if (len > ETHER_HDR_LEN) {
 | 
			
		||||
        struct ether_header *hdr = (struct ether_header*)data;
 | 
			
		||||
        return htobe16(hdr->ether_type);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _gtpv1_tun_recv_common_cb(short when, ogs_socket_t fd, bool has_eth, void *data)
 | 
			
		||||
{
 | 
			
		||||
    ogs_pkbuf_t *recvbuf = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -62,6 +85,42 @@ static void _gtpv1_tun_recv_cb(short when, ogs_socket_t fd, void *data)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (has_eth) {
 | 
			
		||||
        ogs_pkbuf_t *replybuf = NULL;
 | 
			
		||||
        uint16_t eth_type = _get_eth_type(recvbuf->data, recvbuf->len);
 | 
			
		||||
 | 
			
		||||
        if (eth_type == ETHERTYPE_ARP) {
 | 
			
		||||
            if (is_arp_req(recvbuf->data, recvbuf->len)) {
 | 
			
		||||
                replybuf = ogs_pkbuf_alloc(packet_pool, OGS_MAX_PKT_LEN);
 | 
			
		||||
                ogs_assert(replybuf);
 | 
			
		||||
                ogs_pkbuf_reserve(replybuf, OGS_TUN_MAX_HEADROOM);
 | 
			
		||||
                ogs_pkbuf_put(replybuf, OGS_MAX_PKT_LEN-OGS_TUN_MAX_HEADROOM);
 | 
			
		||||
                arp_reply(replybuf->data, recvbuf->data, recvbuf->len, proxy_mac_addr);
 | 
			
		||||
                ogs_debug("[SEND] reply to ARP request");
 | 
			
		||||
            } else {
 | 
			
		||||
                goto cleanup;
 | 
			
		||||
            }
 | 
			
		||||
        } else if (eth_type == ETHERTYPE_IPV6 && is_nd_req(recvbuf->data, recvbuf->len)) {
 | 
			
		||||
            replybuf = ogs_pkbuf_alloc(packet_pool, OGS_MAX_PKT_LEN);
 | 
			
		||||
            ogs_assert(replybuf);
 | 
			
		||||
            ogs_pkbuf_reserve(replybuf, OGS_TUN_MAX_HEADROOM);
 | 
			
		||||
            ogs_pkbuf_put(replybuf, OGS_MAX_PKT_LEN-OGS_TUN_MAX_HEADROOM);
 | 
			
		||||
            nd_reply(replybuf->data, recvbuf->data, recvbuf->len, proxy_mac_addr);
 | 
			
		||||
            ogs_debug("[SEND] reply to ND solicit");
 | 
			
		||||
        }
 | 
			
		||||
        if (replybuf) {
 | 
			
		||||
            if (ogs_tun_write(fd, replybuf) != OGS_OK)
 | 
			
		||||
                ogs_warn("ogs_tun_write() for reply failed");
 | 
			
		||||
            goto cleanup;
 | 
			
		||||
        }
 | 
			
		||||
        if (eth_type != ETHERTYPE_IP && eth_type != ETHERTYPE_IPV6) {
 | 
			
		||||
            ogs_error("[DROP] Invalid eth_type [%x]]", eth_type);
 | 
			
		||||
            ogs_log_hexdump(OGS_LOG_ERROR, recvbuf->data, recvbuf->len);
 | 
			
		||||
            goto cleanup;
 | 
			
		||||
        }
 | 
			
		||||
        ogs_pkbuf_pull(recvbuf, ETHER_HDR_LEN);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sess = upf_sess_find_by_ue_ip_address(recvbuf);
 | 
			
		||||
    if (!sess)
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
@@ -127,6 +186,14 @@ cleanup:
 | 
			
		||||
    ogs_pkbuf_free(recvbuf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _gtpv1_tun_recv_cb(short when, ogs_socket_t fd, void *data) {
 | 
			
		||||
    _gtpv1_tun_recv_common_cb(when, fd, false, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _gtpv1_tun_recv_eth_cb(short when, ogs_socket_t fd, void *data) {
 | 
			
		||||
    _gtpv1_tun_recv_common_cb(when, fd, true, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
 | 
			
		||||
{
 | 
			
		||||
    int len;
 | 
			
		||||
@@ -326,10 +393,15 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
 | 
			
		||||
        ogs_assert(far);
 | 
			
		||||
 | 
			
		||||
        if (far->dst_if == OGS_PFCP_INTERFACE_CORE) {
 | 
			
		||||
            if (ip_h->ip_v == 4 && sess->ipv4)
 | 
			
		||||
            uint16_t eth_type = 0;
 | 
			
		||||
 | 
			
		||||
            if (ip_h->ip_v == 4 && sess->ipv4) {
 | 
			
		||||
                subnet = sess->ipv4->subnet;
 | 
			
		||||
            else if (ip_h->ip_v == 6 && sess->ipv6)
 | 
			
		||||
                eth_type = ETHERTYPE_IP;
 | 
			
		||||
            } else if (ip_h->ip_v == 6 && sess->ipv6) {
 | 
			
		||||
                subnet = sess->ipv6->subnet;
 | 
			
		||||
                eth_type = ETHERTYPE_IPV6;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!subnet) {
 | 
			
		||||
#if 0 /* It's redundant log message */
 | 
			
		||||
@@ -342,6 +414,19 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
 | 
			
		||||
 | 
			
		||||
            dev = subnet->dev;
 | 
			
		||||
            ogs_assert(dev);
 | 
			
		||||
 | 
			
		||||
            if (dev->is_tap) {
 | 
			
		||||
                ogs_assert(eth_type);
 | 
			
		||||
                eth_type = htobe16(eth_type);
 | 
			
		||||
                ogs_pkbuf_push(pkbuf, sizeof(eth_type));
 | 
			
		||||
                memcpy(pkbuf->data, ð_type, sizeof(eth_type));
 | 
			
		||||
                ogs_pkbuf_push(pkbuf, ETHER_ADDR_LEN);
 | 
			
		||||
                memcpy(pkbuf->data, proxy_mac_addr, ETHER_ADDR_LEN);
 | 
			
		||||
                ogs_pkbuf_push(pkbuf, ETHER_ADDR_LEN);
 | 
			
		||||
                memcpy(pkbuf->data, dev->mac_addr, ETHER_ADDR_LEN);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* TODO: if destined to another UE, hairpin back out. */
 | 
			
		||||
            if (ogs_tun_write(dev->fd, pkbuf) != OGS_OK)
 | 
			
		||||
                ogs_warn("ogs_tun_write() failed");
 | 
			
		||||
 | 
			
		||||
@@ -389,7 +474,6 @@ cleanup:
 | 
			
		||||
    ogs_pkbuf_free(pkbuf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int upf_gtp_init(void)
 | 
			
		||||
{
 | 
			
		||||
    ogs_pkbuf_config_t config;
 | 
			
		||||
@@ -407,6 +491,32 @@ void upf_gtp_final(void)
 | 
			
		||||
    ogs_pkbuf_pool_destroy(packet_pool);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _get_dev_mac_addr(char *ifname, uint8_t *mac_addr)
 | 
			
		||||
{
 | 
			
		||||
#ifdef SIOCGIFHWADDR
 | 
			
		||||
    int fd = socket(PF_INET, SOCK_DGRAM, 0);
 | 
			
		||||
    ogs_assert(fd);
 | 
			
		||||
    struct ifreq req;
 | 
			
		||||
    memset(&req, 0, sizeof(req));
 | 
			
		||||
    strncpy(req.ifr_name, ifname, IF_NAMESIZE-1);
 | 
			
		||||
    ogs_assert(ioctl(fd, SIOCGIFHWADDR, &req) == 0);
 | 
			
		||||
    memcpy(mac_addr, req.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
 | 
			
		||||
#else
 | 
			
		||||
    struct ifaddrs *ifap;
 | 
			
		||||
    ogs_assert(getifaddrs(&ifap) == 0);
 | 
			
		||||
    struct ifaddrs *p;
 | 
			
		||||
    for (p = ifap; p; p = p->ifa_next) {
 | 
			
		||||
        if (strncmp(ifname, p->ifa_name, IF_NAMESIZE-1) == 0) {
 | 
			
		||||
            struct sockaddr_dl* sdp = (struct sockaddr_dl*) p->ifa_addr;
 | 
			
		||||
            memcpy(mac_addr, sdp->sdl_data + sdp->sdl_nlen, ETHER_ADDR_LEN);
 | 
			
		||||
            freeifaddrs(ifap);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    ogs_assert(0); /* interface not found. */
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int upf_gtp_open(void)
 | 
			
		||||
{
 | 
			
		||||
    ogs_pfcp_dev_t *dev = NULL;
 | 
			
		||||
@@ -444,14 +554,22 @@ int upf_gtp_open(void)
 | 
			
		||||
 | 
			
		||||
    /* Open Tun interface */
 | 
			
		||||
    ogs_list_for_each(&ogs_pfcp_self()->dev_list, dev) {
 | 
			
		||||
        dev->fd = ogs_tun_open(dev->ifname, OGS_MAX_IFNAME_LEN, 0);
 | 
			
		||||
        dev->is_tap = strstr(dev->ifname, "tap");
 | 
			
		||||
        dev->fd = ogs_tun_open(dev->ifname, OGS_MAX_IFNAME_LEN, dev->is_tap);
 | 
			
		||||
        if (dev->fd == INVALID_SOCKET) {
 | 
			
		||||
            ogs_error("tun_open(dev:%s) failed", dev->ifname);
 | 
			
		||||
            return OGS_ERROR;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        dev->poll = ogs_pollset_add(ogs_app()->pollset,
 | 
			
		||||
                OGS_POLLIN, dev->fd, _gtpv1_tun_recv_cb, NULL);
 | 
			
		||||
        if (dev->is_tap) {
 | 
			
		||||
            _get_dev_mac_addr(dev->ifname, dev->mac_addr);
 | 
			
		||||
            dev->poll = ogs_pollset_add(ogs_app()->pollset,
 | 
			
		||||
                    OGS_POLLIN, dev->fd, _gtpv1_tun_recv_eth_cb, NULL);
 | 
			
		||||
        } else {
 | 
			
		||||
            dev->poll = ogs_pollset_add(ogs_app()->pollset,
 | 
			
		||||
                    OGS_POLLIN, dev->fd, _gtpv1_tun_recv_cb, NULL);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ogs_assert(dev->poll);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,11 +18,17 @@
 | 
			
		||||
upf_conf = configuration_data()
 | 
			
		||||
 | 
			
		||||
upf_headers = ('''
 | 
			
		||||
    ifaddrs.h
 | 
			
		||||
    net/ethernet.h
 | 
			
		||||
    net/if.h
 | 
			
		||||
    net/if_dl.h
 | 
			
		||||
    netinet/in.h
 | 
			
		||||
    netinet/ip.h
 | 
			
		||||
    netinet/ip6.h
 | 
			
		||||
    netinet/ip_icmp.h
 | 
			
		||||
    netinet/icmp6.h
 | 
			
		||||
    sys/ioctl.h
 | 
			
		||||
    sys/socket.h
 | 
			
		||||
'''.split())
 | 
			
		||||
 | 
			
		||||
foreach h : upf_headers
 | 
			
		||||
@@ -60,19 +66,30 @@ libupf_sources = files('''
 | 
			
		||||
    pfcp-path.c
 | 
			
		||||
    n4-build.c
 | 
			
		||||
    n4-handler.c
 | 
			
		||||
    arp-nd.h
 | 
			
		||||
'''.split())
 | 
			
		||||
 | 
			
		||||
tins_dep = cc.find_library('tins', required : true)
 | 
			
		||||
libarp_nd = static_library('arp_nd',
 | 
			
		||||
    sources : files('''
 | 
			
		||||
    arp-nd.cpp
 | 
			
		||||
    arp-nd.h
 | 
			
		||||
    '''.split()),
 | 
			
		||||
    dependencies : tins_dep,
 | 
			
		||||
    install : false)
 | 
			
		||||
libarp_nd_dep = declare_dependency(link_with : libarp_nd, dependencies : tins_dep)
 | 
			
		||||
 | 
			
		||||
libupf = static_library('upf',
 | 
			
		||||
    sources : libupf_sources,
 | 
			
		||||
    dependencies : [
 | 
			
		||||
        libapp_dep, libdiameter_gx_dep, libgtp_dep, libpfcp_dep, libtun_dep
 | 
			
		||||
        libapp_dep, libdiameter_gx_dep, libgtp_dep, libpfcp_dep, libtun_dep, libarp_nd_dep,
 | 
			
		||||
    ],
 | 
			
		||||
    install : false)
 | 
			
		||||
 | 
			
		||||
libupf_dep = declare_dependency(
 | 
			
		||||
    link_with : libupf,
 | 
			
		||||
    dependencies : [
 | 
			
		||||
        libapp_dep, libdiameter_gx_dep, libgtp_dep, libpfcp_dep, libtun_dep
 | 
			
		||||
        libapp_dep, libdiameter_gx_dep, libgtp_dep, libpfcp_dep, libtun_dep, libarp_nd_dep,
 | 
			
		||||
    ])
 | 
			
		||||
 | 
			
		||||
upf_sources = files('''
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user