Merge branch 'sysmocom-pespin/vrf' into main

This commit is contained in:
Sukchan Lee 2022-03-07 22:44:23 +09:00
commit 914bb0a40f
20 changed files with 95 additions and 25 deletions

View File

@ -290,6 +290,7 @@ pool:
#
# sockopt:
# no_delay : true
# so_bindtodevice : true
#
sockopt:

View File

@ -388,6 +388,7 @@ pool:
#
# sockopt:
# no_delay : true
# so_bindtodevice : true
#
sockopt:

View File

@ -160,6 +160,12 @@ max:
#
pool:
#
# sockopt:
# so_bindtodevice : true
#
sockopt:
#
# time:
#

View File

@ -149,6 +149,13 @@ max:
#
pool:
#
# sockopt:
# no_delay : true
# so_bindtodevice : true
#
sockopt:
#
# time:
#

View File

@ -498,6 +498,12 @@ max:
#
pool:
#
# sockopt:
# so_bindtodevice : true
#
sockopt:
#
# time:
#

View File

@ -220,6 +220,12 @@ max:
#
pool:
#
# sockopt:
# so_bindtodevice : true
#
sockopt:
#
# time:
#

View File

@ -187,6 +187,7 @@ static void app_context_prepare(void)
self.sctp.max_initial_timeout = 8000; /* 8 seconds */
self.sockopt.no_delay = true;
self.sockopt.so_bindtodevice = true;
#define MAX_NUM_OF_UE 1024 /* Num of UE per AMF/MME */
#define MAX_NUM_OF_GNB 64 /* Num of gNB per AMF/MME */
@ -376,6 +377,9 @@ int ogs_app_context_parse_config(void)
const char *v = ogs_yaml_iter_value(&sockopt_iter);
if (v) self.sockopt.l_linger = atoi(v);
self.sockopt.l_onoff = true;
} else if (!strcmp(sockopt_key, "so_bindtodevice")) {
self.sockopt.so_bindtodevice =
ogs_yaml_iter_bool(&sockopt_iter);
} else
ogs_warn("unknown key `%s`", sockopt_key);
}

View File

@ -84,6 +84,7 @@ typedef struct ogs_app_context_s {
int no_delay;
int l_onoff;
int l_linger;
int so_bindtodevice;
} sockopt;
struct {

View File

@ -331,3 +331,26 @@ int ogs_listen_reusable(ogs_socket_t fd)
return OGS_OK;
}
int ogs_bind_to_device(ogs_socket_t fd, const char *device)
{
#if defined(SO_BINDTODEVICE) && !defined(_WIN32)
int rc;
ogs_assert(fd != INVALID_SOCKET);
ogs_assert(device);
rc = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1);
if (rc != OGS_OK) {
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
"setsockopt(SOL_SOCKET, SO_BINDTODEVICE, %s) failed", device);
ogs_error("You need to grant privileges to use SO_BINDTODEVICE.");
ogs_error("OR disable SO_BINDTODEVICE "
"in the configuration file as below.");
ogs_log_print(OGS_LOG_ERROR, "\nsockopt:\n");
ogs_log_print(OGS_LOG_ERROR, " so_bindtodevice : false\n\n");
return OGS_ERROR;
}
#endif
return OGS_OK;
}

View File

@ -74,6 +74,7 @@ int ogs_closesocket(ogs_socket_t fd);
int ogs_nonblocking(ogs_socket_t fd);
int ogs_closeonexec(ogs_socket_t fd);
int ogs_listen_reusable(ogs_socket_t fd);
int ogs_bind_to_device(ogs_socket_t fd, const char *device);
#ifdef __cplusplus
}

View File

@ -51,6 +51,8 @@ void ogs_socknode_free(ogs_socknode_t *node)
ogs_assert(node);
ogs_freeaddrinfo(node->addr);
if (node->dev)
ogs_free(node->dev);
if (node->poll)
ogs_pollset_remove(node->poll);
if (node->sock) {
@ -164,6 +166,8 @@ int ogs_socknode_probe(
node = ogs_calloc(1, sizeof(ogs_socknode_t));
node->addr = addr;
if (dev)
node->dev = ogs_strdup(dev);
if (addr->ogs_sa_family == AF_INET) {
ogs_assert(list);

View File

@ -35,6 +35,7 @@ typedef struct ogs_socknode_s {
ogs_lnode_t node;
ogs_sockaddr_t *addr;
char *dev; /* !NULL: used with SO_BINDTODEVICE */
ogs_sock_t *sock;
void (*cleanup)(ogs_sock_t *sock);

View File

@ -33,7 +33,7 @@ ogs_sock_t *ogs_udp_socket(int family, ogs_socknode_t *node)
return sock;
}
ogs_sock_t *ogs_udp_server(ogs_socknode_t *node)
ogs_sock_t *ogs_udp_server(ogs_socknode_t *node, bool so_bindtodevice)
{
ogs_sock_t *new = NULL;
ogs_sockaddr_t *addr;
@ -45,17 +45,26 @@ ogs_sock_t *ogs_udp_server(ogs_socknode_t *node)
addr = node->addr;
while (addr) {
new = ogs_udp_socket(addr->ogs_sa_family, node);
if (new) {
if (ogs_sock_bind(new, addr) == OGS_OK) {
ogs_debug("udp_server() [%s]:%d",
OGS_ADDR(addr, buf), OGS_PORT(addr));
break;
}
ogs_sock_destroy(new);
if (!new) {
addr = addr->next;
continue;
}
addr = addr->next;
if (ogs_sock_bind(new, addr) != OGS_OK) {
ogs_sock_destroy(new);
addr = addr->next;
continue;
}
ogs_debug("udp_server() [%s]:%d", OGS_ADDR(addr, buf), OGS_PORT(addr));
if (so_bindtodevice == true && node->dev) {
if (ogs_bind_to_device(new->fd, node->dev) != OGS_OK) {
ogs_sock_destroy(new);
addr = addr->next;
continue;
}
ogs_debug("udp_server() [%s]:%d bound to device %s",
OGS_ADDR(addr, buf), OGS_PORT(addr), node->dev);
}
break;
}
if (addr == NULL) {

View File

@ -29,7 +29,7 @@ extern "C" {
#endif
ogs_sock_t *ogs_udp_socket(int family, ogs_socknode_t *node);
ogs_sock_t *ogs_udp_server(ogs_socknode_t *node);
ogs_sock_t *ogs_udp_server(ogs_socknode_t *node, bool so_bindtodevice);
ogs_sock_t *ogs_udp_client(ogs_socknode_t *node);
int ogs_udp_connect(ogs_sock_t *sock, ogs_sockaddr_t *sa_list);

View File

@ -25,7 +25,7 @@ ogs_sock_t *ogs_gtp_server(ogs_socknode_t *node)
ogs_sock_t *gtp;
ogs_assert(node);
gtp = ogs_udp_server(node);
gtp = ogs_udp_server(node, ogs_app()->sockopt.so_bindtodevice);
if (gtp) {
ogs_info("gtp_server() [%s]:%d",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));

View File

@ -25,7 +25,7 @@ ogs_sock_t *ogs_pfcp_server(ogs_socknode_t *node)
ogs_sock_t *pfcp;
ogs_assert(node);
pfcp = ogs_udp_server(node);
pfcp = ogs_udp_server(node, ogs_app()->sockopt.so_bindtodevice);
if (pfcp) {
ogs_info("pfcp_server() [%s]:%d",
OGS_ADDR(node->addr, buf), OGS_PORT(node->addr));

View File

@ -47,7 +47,7 @@ ogs_socknode_t *test_gtpu_server(int index, int family)
node = ogs_socknode_new(addr);
ogs_assert(node);
sock = ogs_udp_server(node);
sock = ogs_udp_server(node, false);
ogs_assert(sock);
return node;

View File

@ -62,7 +62,7 @@ static void test1_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, OGS_OK, rv);
server[i] = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, server[i]);
ogs_udp_server(server[i]);
ogs_udp_server(server[i], false, false);
ABTS_PTR_NOTNULL(tc, server[i]->sock);
rv = ogs_getaddrinfo(&addr, AF_INET, "127.0.0.1", PORT+i, AI_PASSIVE);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@ -293,7 +293,7 @@ static void test4_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node);
udp = ogs_udp_server(node, false);
ABTS_PTR_NOTNULL(tc, udp);
poll = ogs_pollset_add(pollset, OGS_POLLIN, udp->fd, test4_handler, tc);

View File

@ -40,7 +40,7 @@ static void test1_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node);
udp = ogs_udp_server(node, false);
ABTS_PTR_NOTNULL(tc, udp);
ogs_socknode_free(node);
@ -48,7 +48,7 @@ static void test1_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node);
udp = ogs_udp_server(node, false);
ABTS_PTR_NOTNULL(tc, udp);
ogs_socknode_free(node);
@ -56,7 +56,7 @@ static void test1_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node);
udp = ogs_udp_server(node, false);
ABTS_PTR_NOTNULL(tc, udp);
ogs_socknode_free(node);
}
@ -154,7 +154,7 @@ static void test3_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node);
udp = ogs_udp_server(node, false);
ABTS_PTR_NOTNULL(tc, udp);
test3_thread = ogs_thread_create(test3_main, tc);
@ -211,7 +211,7 @@ static void test4_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node);
udp = ogs_udp_server(node, false);
ABTS_PTR_NOTNULL(tc, udp);
test4_thread = ogs_thread_create(test4_main, tc);
@ -244,7 +244,7 @@ static void test5_main(void *data)
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node);
udp = ogs_udp_server(node, false);
ABTS_PTR_NOTNULL(tc, udp);
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, PORT, 0);
@ -277,7 +277,7 @@ static void test5_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, OGS_OK, rv);
node = ogs_socknode_new(addr);
ABTS_PTR_NOTNULL(tc, node);
udp = ogs_udp_server(node);
udp = ogs_udp_server(node, false);
ABTS_PTR_NOTNULL(tc, udp);
rv = ogs_getaddrinfo(&addr, AF_INET6, NULL, PORT2, 0);

View File

@ -38,7 +38,7 @@ ogs_socknode_t *test_epdg_server(uint16_t port)
node = ogs_socknode_new(addr);
ogs_assert(node);
sock = ogs_udp_server(node);
sock = ogs_udp_server(node, false);
ogs_assert(sock);
return node;