forked from acouzens/open5gs
Tun IPv4 is done
This commit is contained in:
parent
3fc397c9f2
commit
6cd9e965a1
|
@ -198,8 +198,8 @@ CORE_DECLARE(int) core_sctp_recvmsg(sock_id id, void *msg, size_t len,
|
|||
*/
|
||||
CORE_DECLARE(status_t) tun_open(sock_id *new,
|
||||
char *ifname, int is_tap);
|
||||
CORE_DECLARE(status_t) tun_set_ipv4(sock_id id,
|
||||
c_uint32_t ip_addr, c_uint8_t bits);
|
||||
CORE_DECLARE(status_t) tun_set_ip(sock_id id,
|
||||
const char *ipstr, const char *mask_or_numbits);
|
||||
|
||||
/*
|
||||
* Send/Recv
|
||||
|
|
|
@ -79,7 +79,7 @@ cleanup:
|
|||
#endif
|
||||
}
|
||||
|
||||
status_t tun_set_ipv4(sock_id id, c_uint32_t ip_addr, c_uint8_t bits)
|
||||
static status_t tun_set_ipv4(sock_id id, c_uint32_t ip_addr, c_uint8_t bits)
|
||||
{
|
||||
#if LINUX != 1
|
||||
sock_t *sock = NULL;
|
||||
|
@ -187,3 +187,28 @@ status_t tun_set_ipv4(sock_id id, c_uint32_t ip_addr, c_uint8_t bits)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
status_t tun_set_ip(sock_id id, const char *ipstr, const char *mask_or_numbits)
|
||||
{
|
||||
ipsubnet_t ipsub;
|
||||
status_t rv;
|
||||
|
||||
d_assert(id, return CORE_ERROR,);
|
||||
d_assert(ipstr, return CORE_ERROR,);
|
||||
d_assert(mask_or_numbits, return CORE_ERROR,);
|
||||
|
||||
rv = core_ipsubnet(&ipsub, ipstr, NULL);
|
||||
d_assert(rv == CORE_OK, return CORE_ERROR,);
|
||||
|
||||
if (ipsub.family == AF_INET)
|
||||
{
|
||||
rv = tun_set_ipv4(id, ipsub.sub[0], atoi(mask_or_numbits));
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("Not support : %d\n", ipsub.family);
|
||||
rv = CORE_OK;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -176,12 +176,6 @@ static status_t pgw_context_validation()
|
|||
context_self()->config.path);
|
||||
return CORE_ERROR;
|
||||
}
|
||||
if (self.num_of_ue_network == 0)
|
||||
{
|
||||
d_error("No pgw.pdn.addr in '%s'",
|
||||
context_self()->config.path);
|
||||
return CORE_ERROR;
|
||||
}
|
||||
if (self.dns.primary == 0)
|
||||
{
|
||||
d_error("No pgw.dns in '%s'",
|
||||
|
@ -593,116 +587,6 @@ status_t pgw_context_parse_config()
|
|||
} while(yaml_iter_type(&ue_pool_array) ==
|
||||
YAML_SEQUENCE_NODE);
|
||||
}
|
||||
else if (!strcmp(pgw_key, "ue_network"))
|
||||
{
|
||||
yaml_iter_t ue_network_array, ue_network_iter;
|
||||
yaml_iter_recurse(&pgw_iter, &ue_network_array);
|
||||
do
|
||||
{
|
||||
c_uint32_t addr = 0;
|
||||
c_uint8_t bits = 0;
|
||||
const char *dev = NULL;
|
||||
const char *apn = NULL;
|
||||
|
||||
d_assert(self.num_of_ue_network <=
|
||||
MAX_NUM_OF_UE_NETWORK, return CORE_ERROR,);
|
||||
if (yaml_iter_type(&ue_network_array) ==
|
||||
YAML_MAPPING_NODE)
|
||||
{
|
||||
memcpy(&ue_network_iter, &ue_network_array,
|
||||
sizeof(yaml_iter_t));
|
||||
}
|
||||
else if (yaml_iter_type(&ue_network_array) ==
|
||||
YAML_SEQUENCE_NODE)
|
||||
{
|
||||
if (!yaml_iter_next(&ue_network_array))
|
||||
break;
|
||||
yaml_iter_recurse(&ue_network_array,
|
||||
&ue_network_iter);
|
||||
}
|
||||
else if (yaml_iter_type(&ue_network_array) ==
|
||||
YAML_SCALAR_NODE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
d_assert(0, return CORE_ERROR,);
|
||||
|
||||
while(yaml_iter_next(&ue_network_iter))
|
||||
{
|
||||
const char *ue_network_key =
|
||||
yaml_iter_key(&ue_network_iter);
|
||||
d_assert(ue_network_key,
|
||||
return CORE_ERROR,);
|
||||
if (!strcmp(ue_network_key, "addr"))
|
||||
{
|
||||
yaml_iter_t addr_iter;
|
||||
yaml_iter_recurse(&ue_network_iter, &addr_iter);
|
||||
d_assert(yaml_iter_type(&addr_iter) !=
|
||||
YAML_MAPPING_NODE, return CORE_ERROR,);
|
||||
|
||||
do
|
||||
{
|
||||
char *v = NULL;
|
||||
|
||||
#if 0
|
||||
d_assert(ue_network->num_of_addr <=
|
||||
MAX_NUM_OF_PDN_ADDR,
|
||||
return CORE_ERROR,);
|
||||
#endif
|
||||
|
||||
if (yaml_iter_type(&addr_iter) ==
|
||||
YAML_SEQUENCE_NODE)
|
||||
{
|
||||
if (!yaml_iter_next(&addr_iter))
|
||||
break;
|
||||
}
|
||||
|
||||
v = (char *)yaml_iter_value(&addr_iter);
|
||||
if (v)
|
||||
{
|
||||
char *str = strsep(&v, "/");
|
||||
if (str)
|
||||
{
|
||||
addr = inet_addr(str);
|
||||
bits = atoi(v);
|
||||
}
|
||||
}
|
||||
} while(
|
||||
yaml_iter_type(&addr_iter) ==
|
||||
YAML_SEQUENCE_NODE);
|
||||
}
|
||||
else if (!strcmp(ue_network_key, "dev"))
|
||||
{
|
||||
dev = yaml_iter_value(&ue_network_iter);
|
||||
}
|
||||
else if (!strcmp(ue_network_key, "apn"))
|
||||
{
|
||||
apn = yaml_iter_value(&ue_network_iter);
|
||||
d_warn("Not implemented apn=%s", apn);
|
||||
}
|
||||
else
|
||||
d_warn("unknown key `%s`", ue_network_key);
|
||||
}
|
||||
|
||||
if (addr && bits)
|
||||
{
|
||||
self.ue_network[self.num_of_ue_network].ipv4.addr =
|
||||
addr;
|
||||
self.ue_network[self.num_of_ue_network].ipv4.bits =
|
||||
bits;
|
||||
self.ue_network[self.num_of_ue_network].if_name =
|
||||
dev;
|
||||
self.num_of_ue_network++;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("Ignore ue_network : addr(0x%x), bits(%d)",
|
||||
addr, bits);
|
||||
}
|
||||
} while(yaml_iter_type(&ue_network_array) ==
|
||||
YAML_SEQUENCE_NODE);
|
||||
}
|
||||
else if (!strcmp(pgw_key, "dns"))
|
||||
{
|
||||
int count = 0;
|
||||
|
@ -1444,86 +1328,6 @@ pgw_pf_t* pgw_pf_next(pgw_pf_t *pf)
|
|||
return list_next(pf);
|
||||
}
|
||||
|
||||
status_t pgw_ip_pool_generate()
|
||||
{
|
||||
int i, j;
|
||||
int pool_index = 0;
|
||||
|
||||
for (i = 0; i < self.num_of_ue_network; i++)
|
||||
{
|
||||
c_uint32_t mask =
|
||||
htonl(0xffffffff << (32 - self.ue_network[i].ipv4.bits));
|
||||
c_uint32_t prefix = self.ue_network[i].ipv4.addr & mask;
|
||||
|
||||
#if 1 /* Update IP assign rule from bradon's comment */
|
||||
c_uint32_t broadcast = prefix + ~mask;
|
||||
|
||||
for (j = 1; j < (0xffffffff >> self.ue_network[i].ipv4.bits) &&
|
||||
pool_index < MAX_POOL_OF_SESS; j++)
|
||||
{
|
||||
pgw_ip_pool_t *ip_pool = &pgw_ip_pool_pool.pool[pool_index];
|
||||
ip_pool->ue_addr = prefix + htonl(j);
|
||||
|
||||
/* Exclude Network Address */
|
||||
if (ip_pool->ue_addr == prefix) continue;
|
||||
|
||||
/* Exclude Broadcast Address */
|
||||
if (ip_pool->ue_addr == broadcast) continue;
|
||||
|
||||
/* Exclude TUN IP Address */
|
||||
if (ip_pool->ue_addr == self.ue_network[i].ipv4.addr) continue;
|
||||
|
||||
pool_index++;
|
||||
}
|
||||
#else /* Deprecated */
|
||||
/* Exclude X.X.X.0, X.X.X.255 addresses from ip pool */
|
||||
c_uint32_t exclude_mask[] = { 0, 255 };
|
||||
|
||||
for (j = 1; j < (0xffffffff >> self.ip_pool[i].mask) &&
|
||||
pool_index < MAX_NUM_OF_SESS; j++)
|
||||
{
|
||||
int exclude = 0;
|
||||
pgw_ip_pool_t *ip_pool = &pgw_ip_pool_pool.pool[pool_index];
|
||||
ip_pool->ue_addr = prefix + htonl(j);
|
||||
|
||||
for (k = 0; k < sizeof(exclude_mask)/sizeof(exclude_mask[0]); k++)
|
||||
{
|
||||
if ((htonl(ip_pool->ue_addr) & 0x000000ff) == exclude_mask[k])
|
||||
{
|
||||
exclude = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (exclude)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
pool_index++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return CORE_OK;
|
||||
}
|
||||
pgw_ip_pool_t* pgw_ip_pool_alloc()
|
||||
{
|
||||
pgw_ip_pool_t *ip_pool = NULL;
|
||||
|
||||
pool_alloc_node(&pgw_ip_pool_pool, &ip_pool);
|
||||
d_assert(ip_pool, return NULL, "IP Pool context allocation failed");
|
||||
|
||||
list_append(&self.ip_pool_list, ip_pool);
|
||||
|
||||
return ip_pool;
|
||||
}
|
||||
status_t pgw_ip_pool_free(pgw_ip_pool_t *ip_pool)
|
||||
{
|
||||
list_remove(&self.ip_pool_list, ip_pool);
|
||||
pool_free_node(&pgw_ip_pool_pool, ip_pool);
|
||||
|
||||
return CORE_OK;
|
||||
}
|
||||
|
||||
status_t pgw_ue_pool_generate()
|
||||
{
|
||||
status_t rv;
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "gtp_types.h"
|
||||
#include "gtp_message.h"
|
||||
|
||||
#define MAX_NUM_OF_UE_NETWORK 16
|
||||
#define MAX_NUM_OF_UE_POOL 16
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -50,16 +49,6 @@ typedef struct _pgw_context_t {
|
|||
} ue_pool[MAX_NUM_OF_UE_POOL];
|
||||
c_uint8_t num_of_ue_pool;
|
||||
|
||||
struct {
|
||||
sock_id tun_link; /* PGW Tun Interace for U-plane */
|
||||
const char *if_name;
|
||||
struct {
|
||||
c_uint32_t addr;
|
||||
c_uint8_t bits;
|
||||
} ipv4;
|
||||
} ue_network[MAX_NUM_OF_UE_NETWORK];
|
||||
c_uint8_t num_of_ue_network;
|
||||
|
||||
struct {
|
||||
c_uint32_t primary;
|
||||
c_uint32_t secondary;
|
||||
|
@ -219,10 +208,6 @@ CORE_DECLARE(pgw_pf_t*) pgw_pf_find_by_id(
|
|||
CORE_DECLARE(pgw_pf_t*) pgw_pf_first(pgw_bearer_t *bearer);
|
||||
CORE_DECLARE(pgw_pf_t*) pgw_pf_next(pgw_pf_t *pf);
|
||||
|
||||
CORE_DECLARE(status_t ) pgw_ip_pool_generate();
|
||||
CORE_DECLARE(pgw_ip_pool_t*) pgw_ip_pool_alloc();
|
||||
CORE_DECLARE(status_t ) pgw_ip_pool_free(pgw_ip_pool_t *ip_pool);
|
||||
|
||||
CORE_DECLARE(status_t ) pgw_ue_pool_generate();
|
||||
CORE_DECLARE(pgw_ue_ip_t *) pgw_ue_ip_alloc(int family, const char *apn);
|
||||
CORE_DECLARE(status_t) pgw_ue_ip_free(pgw_ue_ip_t *ip);
|
||||
|
|
|
@ -136,8 +136,7 @@ static int _gtpv1_u_recv_cb(sock_id sock, void *data)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (sock_write(pgw_self()->ue_network[(c_uintptr_t)data].tun_link,
|
||||
pkbuf->payload, pkbuf->len) <= 0)
|
||||
if (sock_write(pgw_self()->tun_sock, pkbuf->payload, pkbuf->len) <= 0)
|
||||
{
|
||||
d_error("Can not send packets to tuntap");
|
||||
}
|
||||
|
@ -175,67 +174,59 @@ status_t pgw_gtp_open()
|
|||
d_assert(pgw_self()->gtpu_addr || pgw_self()->gtpu_addr6,
|
||||
return CORE_ERROR, "No GTP Server");
|
||||
|
||||
for (i = 0; i < pgw_self()->num_of_ue_network; i++)
|
||||
/* NOTE : tun device can be created via following command.
|
||||
*
|
||||
* $ sudo ip tuntap add name pgwtun mode tun
|
||||
*
|
||||
* Also, before running pgw, assign the one IP from IP pool of UE
|
||||
* to pgwtun. The IP should not be assigned to UE
|
||||
*
|
||||
* $ sudo ifconfig pgwtun 45.45.0.1/16 up
|
||||
*
|
||||
*/
|
||||
|
||||
/* Open Tun interface */
|
||||
rc = tun_open(&pgw_self()->tun_sock, (char *)pgw_self()->tun_ifname, 0);
|
||||
if (rc != 0)
|
||||
{
|
||||
/* NOTE : tun device can be created via following command.
|
||||
*
|
||||
* $ sudo ip tuntap add name pgwtun mode tun
|
||||
*
|
||||
* Also, before running pgw, assign the one IP from IP pool of UE
|
||||
* to pgwtun. The IP should not be assigned to UE
|
||||
*
|
||||
* $ sudo ifconfig pgwtun 45.45.0.1/16 up
|
||||
*
|
||||
*/
|
||||
d_error("Can not open tun(dev : %s)", pgw_self()->tun_ifname);
|
||||
return CORE_ERROR;
|
||||
}
|
||||
|
||||
/* Open Tun interface */
|
||||
rc = tun_open(&pgw_self()->ue_network[i].tun_link,
|
||||
(char *)pgw_self()->ue_network[i].if_name, 0);
|
||||
/*
|
||||
* On Linux, it is possible to create a persistent tun/tap
|
||||
* interface which will continue to exist even if nextepc quit,
|
||||
* although this is normally not required.
|
||||
* It can be useful to set up a tun/tap interface owned
|
||||
* by a non-root user, so nextepc can be started without
|
||||
* needing any root privileges at all.
|
||||
*/
|
||||
|
||||
/* Set P-to-P IP address with Netmask
|
||||
* Note that Linux will skip this configuration */
|
||||
for (i = 0; i < pgw_self()->num_of_ue_pool; i++)
|
||||
{
|
||||
rc = tun_set_ip(pgw_self()->tun_sock,
|
||||
pgw_self()->ue_pool[i].ipstr,
|
||||
pgw_self()->ue_pool[i].mask_or_numbits);
|
||||
if (rc != 0)
|
||||
{
|
||||
d_error("Can not open tun(dev : %s)",
|
||||
pgw_self()->ue_network[i].if_name);
|
||||
d_error("Can not configure tun(dev : %s for %s/%s)",
|
||||
pgw_self()->tun_ifname,
|
||||
pgw_self()->ue_pool[i].ipstr,
|
||||
pgw_self()->ue_pool[i].mask_or_numbits);
|
||||
|
||||
return CORE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* On Linux, it is possible to create a persistent tun/tap
|
||||
* interface which will continue to exist even if nextepc quit,
|
||||
* although this is normally not required.
|
||||
* It can be useful to set up a tun/tap interface owned
|
||||
* by a non-root user, so nextepc can be started without
|
||||
* needing any root privileges at all.
|
||||
*/
|
||||
|
||||
/* Set P-to-P IP address with Netmask
|
||||
* Note that Linux will skip this configuration */
|
||||
rc = tun_set_ipv4(pgw_self()->ue_network[i].tun_link,
|
||||
pgw_self()->ue_network[i].ipv4.addr,
|
||||
pgw_self()->ue_network[i].ipv4.bits);
|
||||
if (rc != 0)
|
||||
{
|
||||
#if 0 /* ADDR */
|
||||
d_error("Can not configure tun(dev : %s for %s/%d)",
|
||||
pgw_self()->ue_network[i].if_name,
|
||||
INET_NTOP(&pgw_self()->ue_network[i].ipv4.addr, buf),
|
||||
pgw_self()->ue_network[i].ipv4.bits);
|
||||
#else
|
||||
d_error("Can not configure tun(dev : %s for /%d)",
|
||||
pgw_self()->ue_network[i].if_name,
|
||||
pgw_self()->ue_network[i].ipv4.bits);
|
||||
#endif
|
||||
return CORE_ERROR;
|
||||
}
|
||||
|
||||
rc = sock_register(pgw_self()->ue_network[i].tun_link,
|
||||
_gtpv1_tun_recv_cb, (void *)(c_uintptr_t)i);
|
||||
if (rc != 0)
|
||||
{
|
||||
d_error("Can not register tun(dev : %s)",
|
||||
pgw_self()->ue_network[i].if_name);
|
||||
sock_delete(pgw_self()->ue_network[i].tun_link);
|
||||
return CORE_ERROR;
|
||||
}
|
||||
rc = sock_register(pgw_self()->tun_sock, _gtpv1_tun_recv_cb, NULL);
|
||||
if (rc != 0)
|
||||
{
|
||||
d_error("Can not register tun(dev : %s)",
|
||||
pgw_self()->tun_ifname);
|
||||
sock_delete(pgw_self()->tun_sock);
|
||||
return CORE_ERROR;
|
||||
}
|
||||
|
||||
return CORE_OK;
|
||||
|
@ -243,18 +234,13 @@ status_t pgw_gtp_open()
|
|||
|
||||
status_t pgw_gtp_close()
|
||||
{
|
||||
int i;
|
||||
|
||||
sock_delete_list(&pgw_self()->gtpc_list);
|
||||
sock_delete_list(&pgw_self()->gtpc_list6);
|
||||
|
||||
sock_delete_list(&pgw_self()->gtpu_list);
|
||||
sock_delete_list(&pgw_self()->gtpu_list6);
|
||||
|
||||
for (i = 0; i < pgw_self()->num_of_ue_network; i++)
|
||||
{
|
||||
sock_delete(pgw_self()->ue_network[i].tun_link);
|
||||
}
|
||||
sock_delete(pgw_self()->tun_sock);
|
||||
|
||||
return CORE_OK;
|
||||
}
|
||||
|
|
|
@ -33,9 +33,6 @@ status_t pgw_initialize()
|
|||
rv = pgw_ue_pool_generate();
|
||||
if (rv != CORE_OK) return rv;
|
||||
|
||||
rv = pgw_ip_pool_generate();
|
||||
if (rv != CORE_OK) return rv;
|
||||
|
||||
ret = pgw_fd_init();
|
||||
if (ret != 0) return CORE_ERROR;
|
||||
|
||||
|
|
|
@ -324,10 +324,6 @@ pgw:
|
|||
- addr: 45.45.0.1/16
|
||||
- addr: cafe::1/64
|
||||
|
||||
ue_network:
|
||||
addr: 45.45.0.1/16
|
||||
dev: pgwtun
|
||||
|
||||
#
|
||||
# <Domain Name Server>
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue